double unlock

File: fs/nfs/.tmp_client.o.preproc
Full description: {AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml} in function 'nfs_put_client' double unlock [traces: 8]
Importance: 0
Checker: AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml
Trace:
line 1382: <context>When called from here.
line 926: The lock is unlocked here.
line 928: not affected ==> the lock is still unlocked.
line 928: not affected ==> the lock is still unlocked.
line 931: not affected ==> the lock is still unlocked.
line 931: not affected ==> the lock is still unlocked.
line 933: not affected ==> the lock is still unlocked.
line 933: not affected ==> the lock is still unlocked.
line 936: not affected ==> the lock is still unlocked.
line 181: not affected ==> the lock is still unlocked.
line 181: not affected ==> the lock is still unlocked.
line 184: not affected ==> the lock is still unlocked.
line 184: not affected ==> the lock is still unlocked.
line 184: not affected ==> the lock is still unlocked.
line 186: not affected ==> the lock is still unlocked.
line 186: not affected ==> the lock is still unlocked.
line 187: not affected ==> the lock is still unlocked.
line 188: The lock is unlocked and here is an attempt to unlock it twice.[& nfs_client_lock]
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
    1|static spinlock_t nfs_client_lock = (spinlock_t ) { { .rlock = { .raw_lock = { 0 }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "nfs_client_lock" } } } };
    2|static struct list_head nfs_client_list = { &(nfs_client_list), &(nfs_client_list) };
    3|static struct list_head nfs_volume_list = { &(nfs_volume_list), &(nfs_volume_list) };
    4|static wait_queue_head_t nfs_client_active_wq = { .lock = (spinlock_t ) { { .rlock = { .raw_lock = { 0 }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "nfs_client_active_wq.lock" } } } }, .task_list = { &(nfs_client_active_wq).task_list, &(nfs_client_active_wq).task_list } };
    5|
    6|
    7|
    8|
    9|static struct rpc_version *nfs_version[5] = {
   10| [2] = &nfs_version2,
   11|
   12| [3] = &nfs_version3,
   13|
   14|
   15| [4] = &nfs_version4,
   16|
   17|};
   18|
   19|struct rpc_program nfs_program = {
   20| .name = "nfs",
   21| .number = 100003,
   22| .nrvers = (sizeof(nfs_version) / sizeof((nfs_version)[0]) + (sizeof(struct { int:-!!(0); }))),
   23| .version = nfs_version,
   24| .stats = &nfs_rpcstat,
   25| .pipe_dir_name = "/nfs",
   26|};
   27|
   28|struct rpc_stat nfs_rpcstat = {
   29| .program = &nfs_program
   30|};
   31|
   32|
   33|
   34|static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
   35|static struct rpc_version * nfsacl_version[] = {
   36| [3] = &nfsacl_version3,
   37|};
   38|
   39|struct rpc_program nfsacl_program = {
   40| .name = "nfsacl",
   41| .number = 100227,
   42| .nrvers = (sizeof(nfsacl_version) / sizeof((nfsacl_version)[0]) + (sizeof(struct { int:-!!(0); }))),
   43| .version = nfsacl_version,
   44| .stats = &nfsacl_rpcstat,
   45|};
   46|
   47|
   48|struct nfs_client_initdata {
   49| const char *hostname;
   50| const struct sockaddr *addr;
   51| size_t addrlen;
   52| const struct nfs_rpc_ops *rpc_ops;
   53| int proto;
   54| u32 minorversion;
   55|};
   56|
   57|
   58|
   59|
   60|
   61|
   62|
   63|static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
   64|{
   65| struct nfs_client *clp;
   66| struct rpc_cred *cred;
   67| int err = -12;
   68|
   69| if ((clp = kzalloc(sizeof(*clp), __st_GFP_KERNEL_st__)) == ((void *)0))
   70|  goto error_0;
   71|
   72| clp->rpc_ops = cl_init->rpc_ops;
   73|
   74| atomic_set(&clp->cl_count, 1);
   75| clp->cl_cons_state = 1;
   76|
   77| __st_memcpy_st__(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
   78| clp->cl_addrlen = cl_init->addrlen;
   79|
   80| if (cl_init->hostname) {
   81|  err = -12;
   82|  clp->cl_hostname = kstrdup(cl_init->hostname, __st_GFP_KERNEL_st__);
   83|  if (!clp->cl_hostname)
   84|   goto error_cleanup;
   85| }
   86|
   87| INIT_LIST_HEAD(&clp->cl_superblocks);
   88| clp->cl_rpcclient = ERR_PTR(-22);
   89|
   90| clp->cl_proto = cl_init->proto;
   91|
   92|
   93| INIT_LIST_HEAD(&clp->cl_delegations);
   94| do { spinlock_check(&clp->cl_lock); do { static struct lock_class_key __key; __raw_spin_lock_init((&(&clp->cl_lock)->rlock), "&(&clp->cl_lock)->rlock", &__key); } while (0); } while (0);
   95| do { do { do { static struct lock_class_key __key; __init_work(((&(&clp->cl_renewd)->work)), 0); ((&(&clp->cl_renewd)->work))->data = (atomic_long_t) { (WORK_STRUCT_NO_CPU) }; lockdep_init_map(&((&(&clp->cl_renewd)->work))->lockdep_map, "(&(&clp->cl_renewd)->work)", &__key, 0); INIT_LIST_HEAD(&((&(&clp->cl_renewd)->work))->entry); do { (((&(&clp->cl_renewd)->work)))->func = ((((nfs4_renew_state)))); } while (0); } while (0); } while (0); do { static struct lock_class_key __key; init_timer_key((&(&clp->cl_renewd)->timer), "&(&clp->cl_renewd)->timer", &__key); } while (0); } while (0);
   96| rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
   97| clp->cl_boot_time = (current_kernel_time());
   98| clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
   99| clp->cl_minorversion = cl_init->minorversion;
  100| clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
  101|
  102| cred = rpc_lookup_machine_cred();
  103| if (!IS_ERR(cred))
  104|  clp->cl_machine_cred = cred;
  105|
  106| INIT_LIST_HEAD(&clp->cl_layouts);
  107|
  108| nfs_fscache_get_client_cookie(clp);
  109|
  110| return clp;
  111|
  112|error_cleanup:
  113| kfree(clp);
  114|error_0:
  115| return ERR_PTR(err);
  116|}
  117|
  118|
  119|
  120|
  121|
  122|
  123|static void nfs4_clear_client_minor_version(struct nfs_client *clp)
  124|{
  125|
  126| if (nfs4_has_session(clp)) {
  127|  nfs4_destroy_session(clp->cl_session);
  128|  clp->cl_session = ((void *)0);
  129| }
  130|
  131| clp->cl_mvops = nfs_v4_minor_ops[0];
  132|
  133|}
  134|
  135|
  136|
  137|
  138|static void nfs4_destroy_callback(struct nfs_client *clp)
  139|{
  140| if (__test_and_clear_bit(1, &clp->cl_res_state))
  141|  nfs_callback_down(clp->cl_mvops->minor_version);
  142|}
  143|
  144|static void nfs4_shutdown_client(struct nfs_client *clp)
  145|{
  146| if (__test_and_clear_bit(3, &clp->cl_res_state))
  147|  nfs4_kill_renewd(clp);
  148| nfs4_clear_client_minor_version(clp);
  149| nfs4_destroy_callback(clp);
  150| if (__test_and_clear_bit(2, &clp->cl_res_state))
  151|  nfs_idmap_delete(clp);
  152|
  153| rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
  154|}
  155|static void nfs_free_client(struct nfs_client *clp)
  156|{
  157| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); } while(0);
  158|
  159| nfs4_shutdown_client(clp);
  160|
  161| nfs_fscache_release_client_cookie(clp);
  162|
  163|
  164| if (!IS_ERR(clp->cl_rpcclient))
  165|  rpc_shutdown_client(clp->cl_rpcclient);
  166|
  167| if (clp->cl_machine_cred != ((void *)0))
  168|  put_rpccred(clp->cl_machine_cred);
  169|
  170| kfree(clp->cl_hostname);
  171| kfree(clp);
  172|
  173| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_free_client()\n"); } while(0);
  174|}
  175|
  176|
  177|
  178|
  179|void nfs_put_client(struct nfs_client *clp)
  180|{
  181| if (!clp)
     |not affected ==> the lock is still unlocked. prev next
  182|  return;
  183|
  184| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count)); } while(0);
     |not affected ==> the lock is still unlocked. prev next
  185|
  186| if ((_atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock))) {
     |not affected ==> the lock is still unlocked. prev next
  187|  list_del(&clp->cl_share_link);
     |not affected ==> the lock is still unlocked. prev next
  188|  __st_spin_unlock_st__(&nfs_client_lock);
     |The lock is unlocked and here is an attempt to unlock it twice.[& nfs_client_lock] prev
  189|
  190|  __st_BUG_ON_st__(!list_empty(&clp->cl_superblocks));
  191|
  192|  nfs_free_client(clp);
  193| }
  194|}
  195|extern typeof(nfs_put_client) nfs_put_client; extern void *__crc_nfs_put_client ; static const unsigned long __kcrctab_nfs_put_client = (unsigned long) &__crc_nfs_put_client; static const char __kstrtab_nfs_put_client[] = "" "nfs_put_client"; static const struct kernel_symbol __ksymtab_nfs_put_client = { (unsigned long)&nfs_put_client, __kstrtab_nfs_put_client };
  196|static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
  197|          const struct sockaddr *sa2)
  198|{
  199| const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
  200| const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
  201|
  202| if (ipv6_addr_scope(&sin1->sin6_addr) == 0x02 &&
  203|     sin1->sin6_scope_id != sin2->sin6_scope_id)
  204|  return 0;
  205|
  206| return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
  207|}
  208|static int nfs_sockaddr_match_ipaddr4(const struct sockaddr *sa1,
  209|          const struct sockaddr *sa2)
  210|{
  211| const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
  212| const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
  213|
  214| return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
  215|}
  216|
  217|static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1,
  218|    const struct sockaddr *sa2)
  219|{
  220| const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
  221| const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
  222|
  223| return nfs_sockaddr_match_ipaddr6(sa1, sa2) &&
  224|  (sin1->sin6_port == sin2->sin6_port);
  225|}
  226|
  227|static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
  228|    const struct sockaddr *sa2)
  229|{
  230| const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
  231| const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
  232|
  233| return nfs_sockaddr_match_ipaddr4(sa1, sa2) &&
  234|  (sin1->sin_port == sin2->sin_port);
  235|}
  236|
  237|
  238|
  239|
  240|
  241|static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
  242|         const struct sockaddr *sa2)
  243|{
  244| if (sa1->sa_family != sa2->sa_family)
  245|  return 0;
  246|
  247| switch (sa1->sa_family) {
  248| case 2:
  249|  return nfs_sockaddr_match_ipaddr4(sa1, sa2);
  250| case 10:
  251|  return nfs_sockaddr_match_ipaddr6(sa1, sa2);
  252| }
  253| return 0;
  254|}
  255|
  256|
  257|
  258|
  259|
  260|static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
  261|       const struct sockaddr *sa2)
  262|{
  263| if (sa1->sa_family != sa2->sa_family)
  264|  return 0;
  265|
  266| switch (sa1->sa_family) {
  267| case 2:
  268|  return nfs_sockaddr_cmp_ip4(sa1, sa2);
  269| case 10:
  270|  return nfs_sockaddr_cmp_ip6(sa1, sa2);
  271| }
  272| return 0;
  273|}
  274|
  275|
  276|
  277|
  278|
  279|struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
  280|{
  281| struct nfs_client *clp;
  282|
  283| __st_spin_lock_st__(&nfs_client_lock);
  284| for (clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = ((&nfs_client_list)->next); (typeof(*clp) *)( (char *)__mptr - 1 );}); __builtin_prefetch(clp->cl_share_link.next), &clp->cl_share_link != (&nfs_client_list); clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = (clp->cl_share_link.next); (typeof(*clp) *)( (char *)__mptr - 1 );})) {
  285|  struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
  286|
  287|
  288|  if (!(clp->cl_cons_state == 0 ||
  289|        clp->cl_cons_state == 2))
  290|   continue;
  291|
  292|
  293|  if (clp->rpc_ops->version != nfsversion)
  294|   continue;
  295|
  296|
  297|  if (!nfs_sockaddr_match_ipaddr(addr, clap))
  298|   continue;
  299|
  300|  atomic_inc(&clp->cl_count);
  301|  __st_spin_unlock_st__(&nfs_client_lock);
  302|  return clp;
  303| }
  304| __st_spin_unlock_st__(&nfs_client_lock);
  305| return ((void *)0);
  306|}
  307|
  308|
  309|
  310|
  311|
  312|struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
  313|{
  314| struct sockaddr *sap = (struct sockaddr *)&clp->cl_addr;
  315| u32 nfsvers = clp->rpc_ops->version;
  316|
  317| __st_spin_lock_st__(&nfs_client_lock);
  318| for (clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = (clp->cl_share_link.next); (typeof(*clp) *)( (char *)__mptr - 1 );}); __builtin_prefetch(clp->cl_share_link.next), &clp->cl_share_link != (&nfs_client_list); clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = (clp->cl_share_link.next); (typeof(*clp) *)( (char *)__mptr - 1 );})) {
  319|  struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
  320|
  321|
  322|  if (clp->cl_cons_state != 0)
  323|   continue;
  324|
  325|
  326|  if (clp->rpc_ops->version != nfsvers)
  327|   continue;
  328|
  329|
  330|  if (!nfs_sockaddr_match_ipaddr(sap, clap))
  331|   continue;
  332|
  333|  atomic_inc(&clp->cl_count);
  334|  __st_spin_unlock_st__(&nfs_client_lock);
  335|  return clp;
  336| }
  337| __st_spin_unlock_st__(&nfs_client_lock);
  338| return ((void *)0);
  339|}
  340|
  341|
  342|
  343|
  344|
  345|static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
  346|{
  347| struct nfs_client *clp;
  348| const struct sockaddr *sap = data->addr;
  349|
  350| for (clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = ((&nfs_client_list)->next); (typeof(*clp) *)( (char *)__mptr - 1 );}); __builtin_prefetch(clp->cl_share_link.next), &clp->cl_share_link != (&nfs_client_list); clp = ({ const typeof( ((typeof(*clp) *)0)->cl_share_link ) *__mptr = (clp->cl_share_link.next); (typeof(*clp) *)( (char *)__mptr - 1 );})) {
  351|         const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
  352|
  353|  if (clp->cl_cons_state < 0)
  354|   continue;
  355|
  356|
  357|  if (clp->rpc_ops != data->rpc_ops)
  358|   continue;
  359|
  360|  if (clp->cl_proto != data->proto)
  361|   continue;
  362|
  363|  if (clp->cl_minorversion != data->minorversion)
  364|   continue;
  365|
  366|  if (!nfs_sockaddr_cmp(sap, clap))
  367|   continue;
  368|
  369|  atomic_inc(&clp->cl_count);
  370|  return clp;
  371| }
  372| return ((void *)0);
  373|}
  374|
  375|
  376|
  377|
  378|
  379|static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
  380|{
  381| struct nfs_client *clp, *new = ((void *)0);
  382| int error;
  383|
  384| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_get_client(%s,v%u)\n", cl_init->hostname ?: "", cl_init->rpc_ops->version); } while(0)
  385|                                                     ;
  386|
  387|
  388| do {
  389|  __st_spin_lock_st__(&nfs_client_lock);
  390|
  391|  clp = nfs_match_client(cl_init);
  392|  if (clp)
  393|   goto found_client;
  394|  if (new)
  395|   goto install_client;
  396|
  397|  __st_spin_unlock_st__(&nfs_client_lock);
  398|
  399|  new = nfs_alloc_client(cl_init);
  400| } while (!IS_ERR(new));
  401|
  402| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_get_client() = %ld [failed]\n", PTR_ERR(new)); } while(0);
  403| return new;
  404|
  405|
  406|install_client:
  407| clp = new;
  408| list_add(&clp->cl_share_link, &nfs_client_list);
  409| __st_spin_unlock_st__(&nfs_client_lock);
  410| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_get_client() = %p [new]\n", clp); } while(0);
  411| return clp;
  412|
  413|
  414|
  415|
  416|found_client:
  417| __st_spin_unlock_st__(&nfs_client_lock);
  418|
  419| if (new)
  420|  nfs_free_client(new);
  421|
  422| error = ({ int __ret = 0; if (!(clp->cl_cons_state < 1)) do { wait_queue_t __wait = { .private = get_current(), .func = autoremove_wake_function, .task_list = { &((__wait).task_list), &((__wait).task_list) }, }; for (;;) { prepare_to_wait(&nfs_client_active_wq, &__wait, (128 | 2)); if (clp->cl_cons_state < 1) break; if (!fatal_signal_pending(get_current())) { schedule(); continue; } __ret = -512; break; } finish_wait(&nfs_client_active_wq, &__wait); } while (0); __ret; })
  423|                                        ;
  424| if (error < 0) {
  425|  nfs_put_client(clp);
  426|  return ERR_PTR(-512);
  427| }
  428|
  429| if (clp->cl_cons_state < 0) {
  430|  error = clp->cl_cons_state;
  431|  nfs_put_client(clp);
  432|  return ERR_PTR(error);
  433| }
  434|
  435| __st_BUG_ON_st__(clp->cl_cons_state != 0);
  436|
  437| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_get_client() = %p [share]\n", clp); } while(0);
  438| return clp;
  439|}
  440|
  441|
  442|
  443|
  444|void nfs_mark_client_ready(struct nfs_client *clp, int state)
  445|{
  446| clp->cl_cons_state = state;
  447| __wake_up(&nfs_client_active_wq, (1 | 2), 0, ((void *)0));
  448|}
  449|int nfs4_check_client_ready(struct nfs_client *clp)
  450|{
  451| if (!nfs4_has_session(clp))
  452|  return 0;
  453| if (clp->cl_cons_state < 0)
  454|  return -93;
  455| return 0;
  456|}
  457|
  458|
  459|
  460|
  461|static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
  462|        unsigned int timeo, unsigned int retrans)
  463|{
  464| to->to_initval = timeo * 250 / 10;
  465| to->to_retries = retrans;
  466|
  467| switch (proto) {
  468| case XPRT_TRANSPORT_TCP:
  469| case XPRT_TRANSPORT_RDMA:
  470|  if (to->to_retries == 0)
  471|   to->to_retries = (2);
  472|  if (to->to_initval == 0)
  473|   to->to_initval = (600) * 250 / 10;
  474|  if (to->to_initval > (600*250))
  475|   to->to_initval = (600*250);
  476|  to->to_increment = to->to_initval;
  477|  to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
  478|  if (to->to_maxval > (600*250))
  479|   to->to_maxval = (600*250);
  480|  if (to->to_maxval < to->to_initval)
  481|   to->to_maxval = to->to_initval;
  482|  to->to_exponential = 0;
  483|  break;
  484| case XPRT_TRANSPORT_UDP:
  485|  if (to->to_retries == 0)
  486|   to->to_retries = (3);
  487|  if (!to->to_initval)
  488|   to->to_initval = (11) * 250 / 10;
  489|  if (to->to_initval > (60*250))
  490|   to->to_initval = (60*250);
  491|  to->to_maxval = (60*250);
  492|  to->to_exponential = 1;
  493|  break;
  494| default:
  495|  __st_BUG_st__();
  496| }
  497|}
  498|
  499|
  500|
  501|
  502|static int nfs_create_rpc_client(struct nfs_client *clp,
  503|     const struct rpc_timeout *timeparms,
  504|     rpc_authflavor_t flavor,
  505|     int discrtry, int noresvport)
  506|{
  507| struct rpc_clnt *clnt = ((void *)0);
  508| struct rpc_create_args args = {
  509|  .net = &init_net,
  510|  .protocol = clp->cl_proto,
  511|  .address = (struct sockaddr *)&clp->cl_addr,
  512|  .addrsize = clp->cl_addrlen,
  513|  .timeout = timeparms,
  514|  .servername = clp->cl_hostname,
  515|  .program = &nfs_program,
  516|  .version = clp->rpc_ops->version,
  517|  .authflavor = flavor,
  518| };
  519|
  520| if (discrtry)
  521|  args.flags |= (1UL << 5);
  522| if (noresvport)
  523|  args.flags |= (1UL << 3);
  524|
  525| if (!IS_ERR(clp->cl_rpcclient))
  526|  return 0;
  527|
  528| clnt = rpc_create(&args);
  529| if (IS_ERR(clnt)) {
  530|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("%s: cannot create RPC client. Error = %ld\n", __func__, PTR_ERR(clnt)); } while(0)
  531|                            ;
  532|  return PTR_ERR(clnt);
  533| }
  534|
  535| clp->cl_rpcclient = clnt;
  536| return 0;
  537|}
  538|
  539|
  540|
  541|
  542|static void nfs_destroy_server(struct nfs_server *server)
  543|{
  544| if (!(server->flags & 0x100000) ||
  545|   !(server->flags & 0x200000))
  546|  nlmclnt_done(server->nlm_host);
  547|}
  548|
  549|
  550|
  551|
  552|static int nfs_start_lockd(struct nfs_server *server)
  553|{
  554| struct nlm_host *host;
  555| struct nfs_client *clp = server->nfs_client;
  556| struct nlmclnt_initdata nlm_init = {
  557|  .hostname = clp->cl_hostname,
  558|  .address = (struct sockaddr *)&clp->cl_addr,
  559|  .addrlen = clp->cl_addrlen,
  560|  .nfs_version = clp->rpc_ops->version,
  561|  .noresvport = server->flags & 0x40000 ?
  562|     1 : 0,
  563| };
  564|
  565| if (nlm_init.nfs_version > 3)
  566|  return 0;
  567| if ((server->flags & 0x100000) &&
  568|   (server->flags & 0x200000))
  569|  return 0;
  570|
  571| switch (clp->cl_proto) {
  572|  default:
  573|   nlm_init.protocol = IPPROTO_TCP;
  574|   break;
  575|  case XPRT_TRANSPORT_UDP:
  576|   nlm_init.protocol = IPPROTO_UDP;
  577| }
  578|
  579| host = nlmclnt_init(&nlm_init);
  580| if (IS_ERR(host))
  581|  return PTR_ERR(host);
  582|
  583| server->nlm_host = host;
  584| server->destroy = nfs_destroy_server;
  585| return 0;
  586|}
  587|
  588|
  589|
  590|
  591|
  592|static void nfs_init_server_aclclient(struct nfs_server *server)
  593|{
  594| if (server->nfs_client->rpc_ops->version != 3)
  595|  goto out_noacl;
  596| if (server->flags & 0x0800)
  597|  goto out_noacl;
  598|
  599| server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
  600| if (IS_ERR(server->client_acl))
  601|  goto out_noacl;
  602|
  603|
  604| server->caps |= (1U << 3);
  605| return;
  606|
  607|out_noacl:
  608| server->caps &= ~(1U << 3);
  609|}
  610|static int nfs_init_server_rpcclient(struct nfs_server *server,
  611|  const struct rpc_timeout *timeo,
  612|  rpc_authflavor_t pseudoflavour)
  613|{
  614| struct nfs_client *clp = server->nfs_client;
  615|
  616| server->client = rpc_clone_client(clp->cl_rpcclient);
  617| if (IS_ERR(server->client)) {
  618|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("%s: couldn't create rpc_client!\n", __func__); } while(0);
  619|  return PTR_ERR(server->client);
  620| }
  621|
  622| __st_memcpy_st__(&server->client->cl_timeout_default,
  623|   timeo,
  624|   sizeof(server->client->cl_timeout_default));
  625| server->client->cl_timeout = &server->client->cl_timeout_default;
  626|
  627| if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
  628|  struct rpc_auth *auth;
  629|
  630|  auth = rpcauth_create(pseudoflavour, server->client);
  631|  if (IS_ERR(auth)) {
  632|   do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("%s: couldn't create credcache!\n", __func__); } while(0);
  633|   return PTR_ERR(auth);
  634|  }
  635| }
  636| server->client->cl_softrtry = 0;
  637| if (server->flags & 0x0001)
  638|  server->client->cl_softrtry = 1;
  639|
  640| return 0;
  641|}
  642|
  643|
  644|
  645|
  646|static int nfs_init_client(struct nfs_client *clp,
  647|      const struct rpc_timeout *timeparms,
  648|      const struct nfs_parsed_mount_data *data)
  649|{
  650| int error;
  651|
  652| if (clp->cl_cons_state == 0) {
  653|
  654|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_init_client() = 0 [already %p]\n", clp); } while(0);
  655|  return 0;
  656| }
  657|
  658|
  659|
  660|
  661|
  662| error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX,
  663|          0, data->flags & 0x40000);
  664| if (error < 0)
  665|  goto error;
  666| nfs_mark_client_ready(clp, 0);
  667| return 0;
  668|
  669|error:
  670| nfs_mark_client_ready(clp, error);
  671| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_init_client() = xerror %d\n", error); } while(0);
  672| return error;
  673|}
  674|
  675|
  676|
  677|
  678|static int nfs_init_server(struct nfs_server *server,
  679|      const struct nfs_parsed_mount_data *data)
  680|{
  681| struct nfs_client_initdata cl_init = {
  682|  .hostname = data->nfs_server.hostname,
  683|  .addr = (const struct sockaddr *)&data->nfs_server.address,
  684|  .addrlen = data->nfs_server.addrlen,
  685|  .rpc_ops = &nfs_v2_clientops,
  686|  .proto = data->nfs_server.protocol,
  687| };
  688| struct rpc_timeout timeparms;
  689| struct nfs_client *clp;
  690| int error;
  691|
  692| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_init_server()\n"); } while(0);
  693|
  694|
  695| if (data->version == 3)
  696|  cl_init.rpc_ops = &nfs_v3_clientops;
  697|
  698|
  699|
  700| clp = nfs_get_client(&cl_init);
  701| if (IS_ERR(clp)) {
  702|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); } while(0);
  703|  return PTR_ERR(clp);
  704| }
  705|
  706| nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
  707|   data->timeo, data->retrans);
  708| error = nfs_init_client(clp, &timeparms, data);
  709| if (error < 0)
  710|  goto error;
  711|
  712| server->nfs_client = clp;
  713|
  714|
  715| server->flags = data->flags;
  716| server->options = data->options;
  717| server->caps |= (1U << 1)|(1U << 2)|(1U << 6)|
  718|  (1U << 7)|(1U << 8)|(1U << 9)|(1U << 10)|
  719|  (1U << 11)|(1U << 12)|(1U << 13);
  720|
  721| if (data->rsize)
  722|  server->rsize = nfs_block_size(data->rsize, ((void *)0));
  723| if (data->wsize)
  724|  server->wsize = nfs_block_size(data->wsize, ((void *)0));
  725|
  726| server->acregmin = data->acregmin * 250;
  727| server->acregmax = data->acregmax * 250;
  728| server->acdirmin = data->acdirmin * 250;
  729| server->acdirmax = data->acdirmax * 250;
  730|
  731|
  732| error = nfs_start_lockd(server);
  733| if (error < 0)
  734|  goto error;
  735|
  736| server->port = data->nfs_server.port;
  737|
  738| error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
  739| if (error < 0)
  740|  goto error;
  741|
  742|
  743| if (data->mount_server.addrlen) {
  744|  __st_memcpy_st__(&server->mountd_address, &data->mount_server.address,
  745|   data->mount_server.addrlen);
  746|  server->mountd_addrlen = data->mount_server.addrlen;
  747| }
  748| server->mountd_version = data->mount_server.version;
  749| server->mountd_port = data->mount_server.port;
  750| server->mountd_protocol = data->mount_server.protocol;
  751|
  752| server->namelen = data->namlen;
  753|
  754| nfs_init_server_aclclient(server);
  755| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_init_server() = 0 [new %p]\n", clp); } while(0);
  756| return 0;
  757|
  758|error:
  759| server->nfs_client = ((void *)0);
  760| nfs_put_client(clp);
  761| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_init_server() = xerror %d\n", error); } while(0);
  762| return error;
  763|}
  764|
  765|
  766|
  767|
  768|static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo)
  769|{
  770| unsigned long max_rpc_payload;
  771|
  772|
  773| if (server->rsize == 0)
  774|  server->rsize = nfs_block_size(fsinfo->rtpref, ((void *)0));
  775| if (server->wsize == 0)
  776|  server->wsize = nfs_block_size(fsinfo->wtpref, ((void *)0));
  777|
  778| if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
  779|  server->rsize = nfs_block_size(fsinfo->rtmax, ((void *)0));
  780| if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
  781|  server->wsize = nfs_block_size(fsinfo->wtmax, ((void *)0));
  782|
  783| max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), ((void *)0));
  784| if (server->rsize > max_rpc_payload)
  785|  server->rsize = max_rpc_payload;
  786| if (server->rsize > (1048576U))
  787|  server->rsize = (1048576U);
  788| server->rpages = (server->rsize + ((1UL) << 12) - 1) >> 12;
  789|
  790| server->backing_dev_info.name = "nfs";
  791| server->backing_dev_info.ra_pages = server->rpages * ((16U) - 1);
  792|
  793| if (server->wsize > max_rpc_payload)
  794|  server->wsize = max_rpc_payload;
  795| if (server->wsize > (1048576U))
  796|  server->wsize = (1048576U);
  797| server->wpages = (server->wsize + ((1UL) << 12) - 1) >> 12;
  798| set_pnfs_layoutdriver(server, fsinfo->layouttype);
  799|
  800| server->wtmult = nfs_block_bits(fsinfo->wtmult, ((void *)0));
  801|
  802| server->dtsize = nfs_block_size(fsinfo->dtpref, ((void *)0));
  803| if (server->dtsize > ((1UL) << 12) * 8)
  804|  server->dtsize = ((1UL) << 12) * 8;
  805| if (server->dtsize > server->rsize)
  806|  server->dtsize = server->rsize;
  807|
  808| if (server->flags & 0x0020) {
  809|  server->acregmin = server->acregmax = 0;
  810|  server->acdirmin = server->acdirmax = 0;
  811| }
  812|
  813| server->maxfilesize = fsinfo->maxfilesize;
  814|
  815| server->time_delta = fsinfo->time_delta;
  816|
  817|
  818| rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
  819|}
  820|
  821|
  822|
  823|
  824|static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
  825|{
  826| struct nfs_fsinfo fsinfo;
  827| struct nfs_client *clp = server->nfs_client;
  828| int error;
  829|
  830| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_probe_fsinfo()\n"); } while(0);
  831|
  832| if (clp->rpc_ops->set_capabilities != ((void *)0)) {
  833|  error = clp->rpc_ops->set_capabilities(server, mntfh);
  834|  if (error < 0)
  835|   goto out_error;
  836| }
  837|
  838| fsinfo.fattr = fattr;
  839| fsinfo.layouttype = 0;
  840| error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
  841| if (error < 0)
  842|  goto out_error;
  843|
  844| nfs_server_set_fsinfo(server, &fsinfo);
  845|
  846|
  847| if (server->namelen == 0) {
  848|  struct nfs_pathconf pathinfo;
  849|
  850|  pathinfo.fattr = fattr;
  851|  nfs_fattr_init(fattr);
  852|
  853|  if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
  854|   server->namelen = pathinfo.max_namelen;
  855| }
  856|
  857| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_probe_fsinfo() = 0\n"); } while(0);
  858| return 0;
  859|
  860|out_error:
  861| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("nfs_probe_fsinfo: error = %d\n", -error); } while(0);
  862| return error;
  863|}
  864|
  865|
  866|
  867|
  868|static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
  869|{
  870| target->flags = source->flags;
  871| target->rsize = source->rsize;
  872| target->wsize = source->wsize;
  873| target->acregmin = source->acregmin;
  874| target->acregmax = source->acregmax;
  875| target->acdirmin = source->acdirmin;
  876| target->acdirmax = source->acdirmax;
  877| target->caps = source->caps;
  878| target->options = source->options;
  879|}
  880|
  881|
  882|
  883|
  884|static struct nfs_server *nfs_alloc_server(void)
  885|{
  886| struct nfs_server *server;
  887|
  888| server = kzalloc(sizeof(struct nfs_server), __st_GFP_KERNEL_st__);
  889| if (!server)
  890|  return ((void *)0);
  891|
  892| server->client = server->client_acl = ERR_PTR(-22);
  893|
  894|
  895| INIT_LIST_HEAD(&server->client_link);
  896| INIT_LIST_HEAD(&server->master_link);
  897|
  898| atomic_set(&server->active, 0);
  899|
  900| server->io_stats = nfs_alloc_iostats();
  901| if (!server->io_stats) {
  902|  kfree(server);
  903|  return ((void *)0);
  904| }
  905|
  906| if (bdi_init(&server->backing_dev_info)) {
  907|  nfs_free_iostats(server->io_stats);
  908|  kfree(server);
  909|  return ((void *)0);
  910| }
  911|
  912| return server;
  913|}
  914|
  915|
  916|
  917|
  918|void nfs_free_server(struct nfs_server *server)
  919|{
  920| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_free_server()\n"); } while(0);
  921|
  922| unset_pnfs_layoutdriver(server);
  923| __st_spin_lock_st__(&nfs_client_lock);
  924| list_del(&server->client_link);
  925| list_del(&server->master_link);
  926| __st_spin_unlock_st__(&nfs_client_lock);
     |The lock is unlocked here. prev next
  927|
  928| if (server->destroy != ((void *)0))
     |not affected ==> the lock is still unlocked. prev next
  929|  server->destroy(server);
  930|
  931| if (!IS_ERR(server->client_acl))
     |not affected ==> the lock is still unlocked. prev next
  932|  rpc_shutdown_client(server->client_acl);
  933| if (!IS_ERR(server->client))
     |not affected ==> the lock is still unlocked. prev next
  934|  rpc_shutdown_client(server->client);
  935|
  936| nfs_put_client(server->nfs_client);
     |not affected ==> the lock is still unlocked. prev next
  937|
  938| nfs_free_iostats(server->io_stats);
  939| bdi_destroy(&server->backing_dev_info);
  940| kfree(server);
  941| nfs_release_automount_timer();
  942| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_free_server()\n"); } while(0);
  943|}
  944|
  945|
  946|
  947|
  948|
  949|struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
  950|         struct nfs_fh *mntfh)
  951|{
  952| struct nfs_server *server;
  953| struct nfs_fattr *fattr;
  954| int error;
  955|
  956| server = nfs_alloc_server();
  957| if (!server)
  958|  return ERR_PTR(-12);
  959|
  960| error = -12;
  961| fattr = nfs_alloc_fattr();
  962| if (fattr == ((void *)0))
  963|  goto error;
  964|
  965|
  966| error = nfs_init_server(server, data);
  967| if (error < 0)
  968|  goto error;
  969|
  970| __st_BUG_ON_st__(!server->nfs_client);
  971| __st_BUG_ON_st__(!server->nfs_client->rpc_ops);
  972| __st_BUG_ON_st__(!server->nfs_client->rpc_ops->file_inode_ops);
  973|
  974|
  975| error = nfs_probe_fsinfo(server, mntfh, fattr);
  976| if (error < 0)
  977|  goto error;
  978| if (server->nfs_client->rpc_ops->version == 3) {
  979|  if (server->namelen == 0 || server->namelen > 255)
  980|   server->namelen = 255;
  981|  if (!(data->flags & 0x4000))
  982|   server->caps |= (1U << 0);
  983| } else {
  984|  if (server->namelen == 0 || server->namelen > 255)
  985|   server->namelen = 255;
  986| }
  987|
  988| if (!(fattr->valid & ((1U << 0) | (1U << 1) | (1U << 2) | (1U << 3) | (1U << 4) | (1U << 5) | (1U << 6) | (1U << 10) | (1U << 11) | (1U << 12) | (1U << 13) | (1U << 14)))) {
  989|  error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
  990|  if (error < 0) {
  991|   do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("nfs_create_server: getattr error = %d\n", -error); } while(0);
  992|   goto error;
  993|  }
  994| }
  995| __st_memcpy_st__(&server->fsid, &fattr->fsid, sizeof(server->fsid));
  996|
  997| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("Server FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, (unsigned long long) server->fsid.minor); } while(0)
  998|
  999|                                          ;
 1000|
 1001| __st_spin_lock_st__(&nfs_client_lock);
 1002| list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
 1003| list_add_tail(&server->master_link, &nfs_volume_list);
 1004| __st_spin_unlock_st__(&nfs_client_lock);
 1005|
 1006| server->mount_time = jiffies;
 1007| nfs_free_fattr(fattr);
 1008| return server;
 1009|
 1010|error:
 1011| nfs_free_fattr(fattr);
 1012| nfs_free_server(server);
 1013| return ERR_PTR(error);
 1014|}
 1015|
 1016|
 1017|
 1018|
 1019|
 1020|static int nfs4_init_callback(struct nfs_client *clp)
 1021|{
 1022| int error;
 1023|
 1024| if (clp->rpc_ops->version == 4) {
 1025|  if (nfs4_has_session(clp)) {
 1026|   error = xprt_setup_backchannel(
 1027|      clp->cl_rpcclient->cl_xprt,
 1028|      1);
 1029|   if (error < 0)
 1030|    return error;
 1031|  }
 1032|
 1033|  error = nfs_callback_up(clp->cl_mvops->minor_version,
 1034|     clp->cl_rpcclient->cl_xprt);
 1035|  if (error < 0) {
 1036|   do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("%s: failed to start callback. Error = %d\n", __func__, error); } while(0)
 1037|                    ;
 1038|   return error;
 1039|  }
 1040|  __set_bit(1, &clp->cl_res_state);
 1041| }
 1042| return 0;
 1043|}
 1044|
 1045|
 1046|
 1047|
 1048|static int nfs4_init_client_minor_version(struct nfs_client *clp)
 1049|{
 1050|
 1051| if (clp->cl_mvops->minor_version) {
 1052|  struct nfs4_session *session = ((void *)0);
 1053|
 1054|
 1055|
 1056|
 1057|
 1058|  session = nfs4_alloc_session(clp);
 1059|  if (!session)
 1060|   return -12;
 1061|
 1062|  clp->cl_session = session;
 1063|
 1064|
 1065|
 1066|
 1067|
 1068|
 1069|  clp->cl_cons_state = 2;
 1070| }
 1071|
 1072|
 1073| return nfs4_init_callback(clp);
 1074|}
 1075|
 1076|
 1077|
 1078|
 1079|static int nfs4_init_client(struct nfs_client *clp,
 1080|  const struct rpc_timeout *timeparms,
 1081|  const char *ip_addr,
 1082|  rpc_authflavor_t authflavour,
 1083|  int flags)
 1084|{
 1085| int error;
 1086|
 1087| if (clp->cl_cons_state == 0) {
 1088|
 1089|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_init_client() = 0 [already %p]\n", clp); } while(0);
 1090|  return 0;
 1091| }
 1092|
 1093|
 1094| clp->rpc_ops = &nfs_v4_clientops;
 1095|
 1096| error = nfs_create_rpc_client(clp, timeparms, authflavour,
 1097|          1, flags & 0x40000);
 1098| if (error < 0)
 1099|  goto error;
 1100| strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
 1101|
 1102| error = nfs_idmap_new(clp);
 1103| if (error < 0) {
 1104|  do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("%s: failed to create idmapper. Error = %d\n", __func__, error); } while(0)
 1105|                   ;
 1106|  goto error;
 1107| }
 1108| __set_bit(2, &clp->cl_res_state);
 1109|
 1110| error = nfs4_init_client_minor_version(clp);
 1111| if (error < 0)
 1112|  goto error;
 1113|
 1114| if (!nfs4_has_session(clp))
 1115|  nfs_mark_client_ready(clp, 0);
 1116| return 0;
 1117|
 1118|error:
 1119| nfs_mark_client_ready(clp, error);
 1120| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_init_client() = xerror %d\n", error); } while(0);
 1121| return error;
 1122|}
 1123|
 1124|
 1125|
 1126|
 1127|static int nfs4_set_client(struct nfs_server *server,
 1128|  const char *hostname,
 1129|  const struct sockaddr *addr,
 1130|  const size_t addrlen,
 1131|  const char *ip_addr,
 1132|  rpc_authflavor_t authflavour,
 1133|  int proto, const struct rpc_timeout *timeparms,
 1134|  u32 minorversion)
 1135|{
 1136| struct nfs_client_initdata cl_init = {
 1137|  .hostname = hostname,
 1138|  .addr = addr,
 1139|  .addrlen = addrlen,
 1140|  .rpc_ops = &nfs_v4_clientops,
 1141|  .proto = proto,
 1142|  .minorversion = minorversion,
 1143| };
 1144| struct nfs_client *clp;
 1145| int error;
 1146|
 1147| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs4_set_client()\n"); } while(0);
 1148|
 1149|
 1150| clp = nfs_get_client(&cl_init);
 1151| if (IS_ERR(clp)) {
 1152|  error = PTR_ERR(clp);
 1153|  goto error;
 1154| }
 1155| error = nfs4_init_client(clp, timeparms, ip_addr, authflavour,
 1156|     server->flags);
 1157| if (error < 0)
 1158|  goto error_put;
 1159|
 1160| server->nfs_client = clp;
 1161| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_set_client() = 0 [new %p]\n", clp); } while(0);
 1162| return 0;
 1163|
 1164|error_put:
 1165| nfs_put_client(clp);
 1166|error:
 1167| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_set_client() = xerror %d\n", error); } while(0);
 1168| return error;
 1169|}
 1170|
 1171|
 1172|
 1173|
 1174|
 1175|
 1176|
 1177|static void nfs4_session_set_rwsize(struct nfs_server *server)
 1178|{
 1179|
 1180| struct nfs4_session *sess;
 1181| u32 server_resp_sz;
 1182| u32 server_rqst_sz;
 1183|
 1184| if (!nfs4_has_session(server->nfs_client))
 1185|  return;
 1186| sess = server->nfs_client->cl_session;
 1187| server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
 1188| server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
 1189|
 1190| if (server->rsize > server_resp_sz)
 1191|  server->rsize = server_resp_sz;
 1192| if (server->wsize > server_rqst_sz)
 1193|  server->wsize = server_rqst_sz;
 1194|
 1195|}
 1196|
 1197|static int nfs4_server_common_setup(struct nfs_server *server,
 1198|  struct nfs_fh *mntfh)
 1199|{
 1200| struct nfs_fattr *fattr;
 1201| int error;
 1202|
 1203| __st_BUG_ON_st__(!server->nfs_client);
 1204| __st_BUG_ON_st__(!server->nfs_client->rpc_ops);
 1205| __st_BUG_ON_st__(!server->nfs_client->rpc_ops->file_inode_ops);
 1206|
 1207| fattr = nfs_alloc_fattr();
 1208| if (fattr == ((void *)0))
 1209|  return -12;
 1210|
 1211|
 1212| error = nfs4_init_session(server);
 1213| if (error < 0)
 1214|  goto out;
 1215|
 1216|
 1217| error = nfs4_get_rootfh(server, mntfh);
 1218| if (error < 0)
 1219|  goto out;
 1220|
 1221| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("Server FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, (unsigned long long) server->fsid.minor); } while(0)
 1222|
 1223|                                           ;
 1224| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("Mount FH: %d\n", mntfh->size); } while(0);
 1225|
 1226| nfs4_session_set_rwsize(server);
 1227|
 1228| error = nfs_probe_fsinfo(server, mntfh, fattr);
 1229| if (error < 0)
 1230|  goto out;
 1231|
 1232| if (server->namelen == 0 || server->namelen > 255)
 1233|  server->namelen = 255;
 1234|
 1235| __st_spin_lock_st__(&nfs_client_lock);
 1236| list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
 1237| list_add_tail(&server->master_link, &nfs_volume_list);
 1238| __st_spin_unlock_st__(&nfs_client_lock);
 1239|
 1240| server->mount_time = jiffies;
 1241|out:
 1242| nfs_free_fattr(fattr);
 1243| return error;
 1244|}
 1245|
 1246|
 1247|
 1248|
 1249|static int nfs4_init_server(struct nfs_server *server,
 1250|  const struct nfs_parsed_mount_data *data)
 1251|{
 1252| struct rpc_timeout timeparms;
 1253| int error;
 1254|
 1255| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs4_init_server()\n"); } while(0);
 1256|
 1257| nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
 1258|   data->timeo, data->retrans);
 1259|
 1260|
 1261| server->flags = data->flags;
 1262| server->caps |= (1U << 4)|(1U << 5)|(1U << 14);
 1263| if (!(data->flags & 0x4000))
 1264|   server->caps |= (1U << 0);
 1265| server->options = data->options;
 1266|
 1267|
 1268| error = nfs4_set_client(server,
 1269|   data->nfs_server.hostname,
 1270|   (const struct sockaddr *)&data->nfs_server.address,
 1271|   data->nfs_server.addrlen,
 1272|   data->client_address,
 1273|   data->auth_flavors[0],
 1274|   data->nfs_server.protocol,
 1275|   &timeparms,
 1276|   data->minorversion);
 1277| if (error < 0)
 1278|  goto error;
 1279|
 1280| if (data->rsize)
 1281|  server->rsize = nfs_block_size(data->rsize, ((void *)0));
 1282| if (data->wsize)
 1283|  server->wsize = nfs_block_size(data->wsize, ((void *)0));
 1284|
 1285| server->acregmin = data->acregmin * 250;
 1286| server->acregmax = data->acregmax * 250;
 1287| server->acdirmin = data->acdirmin * 250;
 1288| server->acdirmax = data->acdirmax * 250;
 1289|
 1290| server->port = data->nfs_server.port;
 1291|
 1292| error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
 1293|
 1294|error:
 1295|
 1296| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_init_server() = %d\n", error); } while(0);
 1297| return error;
 1298|}
 1299|
 1300|
 1301|
 1302|
 1303|
 1304|struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
 1305|          struct nfs_fh *mntfh)
 1306|{
 1307| struct nfs_server *server;
 1308| int error;
 1309|
 1310| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs4_create_server()\n"); } while(0);
 1311|
 1312| server = nfs_alloc_server();
 1313| if (!server)
 1314|  return ERR_PTR(-12);
 1315|
 1316|
 1317| error = nfs4_init_server(server, data);
 1318| if (error < 0)
 1319|  goto error;
 1320|
 1321| error = nfs4_server_common_setup(server, mntfh);
 1322| if (error < 0)
 1323|  goto error;
 1324|
 1325| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_create_server() = %p\n", server); } while(0);
 1326| return server;
 1327|
 1328|error:
 1329| nfs_free_server(server);
 1330| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_create_server() = error %d\n", error); } while(0);
 1331| return ERR_PTR(error);
 1332|}
 1333|
 1334|
 1335|
 1336|
 1337|struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 1338|            struct nfs_fh *mntfh)
 1339|{
 1340| struct nfs_client *parent_client;
 1341| struct nfs_server *server, *parent_server;
 1342| int error;
 1343|
 1344| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs4_create_referral_server()\n"); } while(0);
 1345|
 1346| server = nfs_alloc_server();
 1347| if (!server)
 1348|  return ERR_PTR(-12);
 1349|
 1350| parent_server = NFS_SB(data->sb);
 1351| parent_client = parent_server->nfs_client;
 1352|
 1353|
 1354| nfs_server_copy_userdata(server, parent_server);
 1355| server->caps |= (1U << 4)|(1U << 5);
 1356|
 1357|
 1358|
 1359| error = nfs4_set_client(server, data->hostname,
 1360|    data->addr,
 1361|    data->addrlen,
 1362|    parent_client->cl_ipaddr,
 1363|    data->authflavor,
 1364|    parent_server->client->cl_xprt->prot,
 1365|    parent_server->client->cl_timeout,
 1366|    parent_client->cl_mvops->minor_version);
 1367| if (error < 0)
 1368|  goto error;
 1369|
 1370| error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
 1371| if (error < 0)
 1372|  goto error;
 1373|
 1374| error = nfs4_server_common_setup(server, mntfh);
 1375| if (error < 0)
 1376|  goto error;
 1377|
 1378| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_create_referral_server() = %p\n", server); } while(0);
 1379| return server;
 1380|
 1381|error:
 1382| nfs_free_server(server);
     |<context>When called from here. next
 1383| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs4_create_referral_server() = error %d\n", error); } while(0);
 1384| return ERR_PTR(error);
 1385|}
 1386|
 1387|
 1388|
 1389|
 1390|
 1391|
 1392|struct nfs_server *nfs_clone_server(struct nfs_server *source,
 1393|        struct nfs_fh *fh,
 1394|        struct nfs_fattr *fattr)
 1395|{
 1396| struct nfs_server *server;
 1397| struct nfs_fattr *fattr_fsinfo;
 1398| int error;
 1399|
 1400| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("--> nfs_clone_server(,%llx:%llx,)\n", (unsigned long long) fattr->fsid.major, (unsigned long long) fattr->fsid.minor); } while(0)
 1401|
 1402|                                         ;
 1403|
 1404| server = nfs_alloc_server();
 1405| if (!server)
 1406|  return ERR_PTR(-12);
 1407|
 1408| error = -12;
 1409| fattr_fsinfo = nfs_alloc_fattr();
 1410| if (fattr_fsinfo == ((void *)0))
 1411|  goto out_free_server;
 1412|
 1413|
 1414| server->nfs_client = source->nfs_client;
 1415| atomic_inc(&server->nfs_client->cl_count);
 1416| nfs_server_copy_userdata(server, source);
 1417|
 1418| server->fsid = fattr->fsid;
 1419|
 1420| error = nfs_init_server_rpcclient(server,
 1421|   source->client->cl_timeout,
 1422|   source->client->cl_auth->au_flavor);
 1423| if (error < 0)
 1424|  goto out_free_server;
 1425| if (!IS_ERR(source->client_acl))
 1426|  nfs_init_server_aclclient(server);
 1427|
 1428|
 1429| error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
 1430| if (error < 0)
 1431|  goto out_free_server;
 1432|
 1433| if (server->namelen == 0 || server->namelen > 255)
 1434|  server->namelen = 255;
 1435|
 1436| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("Cloned FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, (unsigned long long) server->fsid.minor); } while(0)
 1437|
 1438|                                          ;
 1439|
 1440| error = nfs_start_lockd(server);
 1441| if (error < 0)
 1442|  goto out_free_server;
 1443|
 1444| __st_spin_lock_st__(&nfs_client_lock);
 1445| list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
 1446| list_add_tail(&server->master_link, &nfs_volume_list);
 1447| __st_spin_unlock_st__(&nfs_client_lock);
 1448|
 1449| server->mount_time = jiffies;
 1450|
 1451| nfs_free_fattr(fattr_fsinfo);
 1452| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_clone_server() = %p\n", server); } while(0);
 1453| return server;
 1454|
 1455|out_free_server:
 1456| nfs_free_fattr(fattr_fsinfo);
 1457| nfs_free_server(server);
 1458| do { if (__builtin_expect(!!(nfs_debug & 0x0200), 0)) printk("<-- nfs_clone_server() = error %d\n", error); } while(0);
 1459| return ERR_PTR(error);
 1460|}
 1461|
 1462|
 1463|static struct proc_dir_entry *proc_fs_nfs;
 1464|
 1465|static int nfs_server_list_open(struct inode *inode, struct file *file);
 1466|static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
 1467|static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
 1468|static void nfs_server_list_stop(struct seq_file *p, void *v);
 1469|static int nfs_server_list_show(struct seq_file *m, void *v);
 1470|
 1471|static const struct seq_operations nfs_server_list_ops = {
 1472| .start = nfs_server_list_start,
 1473| .next = nfs_server_list_next,
 1474| .stop = nfs_server_list_stop,
 1475| .show = nfs_server_list_show,
 1476|};
 1477|
 1478|static const struct file_operations nfs_server_list_fops = {
 1479| .open = nfs_server_list_open,
 1480| .read = seq_read,
 1481| .llseek = seq_lseek,
 1482| .release = seq_release,
 1483| .owner = (&__this_module),
 1484|};
 1485|
 1486|static int nfs_volume_list_open(struct inode *inode, struct file *file);
 1487|static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
 1488|static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
 1489|static void nfs_volume_list_stop(struct seq_file *p, void *v);
 1490|static int nfs_volume_list_show(struct seq_file *m, void *v);
 1491|
 1492|static const struct seq_operations nfs_volume_list_ops = {
 1493| .start = nfs_volume_list_start,
 1494| .next = nfs_volume_list_next,
 1495| .stop = nfs_volume_list_stop,
 1496| .show = nfs_volume_list_show,
 1497|};
 1498|
 1499|static const struct file_operations nfs_volume_list_fops = {
 1500| .open = nfs_volume_list_open,
 1501| .read = seq_read,
 1502| .llseek = seq_lseek,
 1503| .release = seq_release,
 1504| .owner = (&__this_module),
 1505|};
 1506|
 1507|
 1508|
 1509|
 1510|
 1511|static int nfs_server_list_open(struct inode *inode, struct file *file)
 1512|{
 1513| struct seq_file *m;
 1514| int ret;
 1515|
 1516| ret = seq_open(file, &nfs_server_list_ops);
 1517| if (ret < 0)
 1518|  return ret;
 1519|
 1520| m = file->private_data;
 1521| m->private = PDE(inode)->data;
 1522|
 1523| return 0;
 1524|}
 1525|
 1526|
 1527|
 1528|
 1529|static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
 1530|{
 1531|
 1532| __st_spin_lock_st__(&nfs_client_lock);
 1533| return seq_list_start_head(&nfs_client_list, *_pos);
 1534|}
 1535|
 1536|
 1537|
 1538|
 1539|static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
 1540|{
 1541| return seq_list_next(v, &nfs_client_list, pos);
 1542|}
 1543|
 1544|
 1545|
 1546|
 1547|static void nfs_server_list_stop(struct seq_file *p, void *v)
 1548|{
 1549| __st_spin_unlock_st__(&nfs_client_lock);
 1550|}
 1551|
 1552|
 1553|
 1554|
 1555|static int nfs_server_list_show(struct seq_file *m, void *v)
 1556|{
 1557| struct nfs_client *clp;
 1558|
 1559|
 1560| if (v == &nfs_client_list) {
 1561|  seq_puts(m, "NV SERVER   PORT USE HOSTNAME\n");
 1562|  return 0;
 1563| }
 1564|
 1565|
 1566| clp = ({ const typeof( ((struct nfs_client *)0)->cl_share_link ) *__mptr = (v); (struct nfs_client *)( (char *)__mptr - 1 );});
 1567|
 1568| seq_printf(m, "v%u %s %s %3d %s\n",
 1569|     clp->rpc_ops->version,
 1570|     rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
 1571|     rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
 1572|     atomic_read(&clp->cl_count),
 1573|     clp->cl_hostname);
 1574|
 1575| return 0;
 1576|}
 1577|
 1578|
 1579|
 1580|
 1581|static int nfs_volume_list_open(struct inode *inode, struct file *file)
 1582|{
 1583| struct seq_file *m;
 1584| int ret;
 1585|
 1586| ret = seq_open(file, &nfs_volume_list_ops);
 1587| if (ret < 0)
 1588|  return ret;
 1589|
 1590| m = file->private_data;
 1591| m->private = PDE(inode)->data;
 1592|
 1593| return 0;
 1594|}
 1595|
 1596|
 1597|
 1598|
 1599|static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
 1600|{
 1601|
 1602| __st_spin_lock_st__(&nfs_client_lock);
 1603| return seq_list_start_head(&nfs_volume_list, *_pos);
 1604|}
 1605|
 1606|
 1607|
 1608|
 1609|static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
 1610|{
 1611| return seq_list_next(v, &nfs_volume_list, pos);
 1612|}
 1613|
 1614|
 1615|
 1616|
 1617|static void nfs_volume_list_stop(struct seq_file *p, void *v)
 1618|{
 1619| __st_spin_unlock_st__(&nfs_client_lock);
 1620|}
 1621|
 1622|
 1623|
 1624|
 1625|static int nfs_volume_list_show(struct seq_file *m, void *v)
 1626|{
 1627| struct nfs_server *server;
 1628| struct nfs_client *clp;
 1629| char dev[8], fsid[17];
 1630|
 1631|
 1632| if (v == &nfs_volume_list) {
 1633|  seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
 1634|  return 0;
 1635| }
 1636|
 1637| server = ({ const typeof( ((struct nfs_server *)0)->master_link ) *__mptr = (v); (struct nfs_server *)( (char *)__mptr - 1 );});
 1638| clp = server->nfs_client;
 1639|
 1640| snprintf(dev, 8, "%u:%u",
 1641|   ((unsigned int) ((server->s_dev) >> 20)), ((unsigned int) ((server->s_dev) & ((1U << 20) - 1))));
 1642|
 1643| snprintf(fsid, 17, "%llx:%llx",
 1644|   (unsigned long long) server->fsid.major,
 1645|   (unsigned long long) server->fsid.minor);
 1646|
 1647| seq_printf(m, "v%u %s %s %-7s %-17s %s\n",
 1648|     clp->rpc_ops->version,
 1649|     rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
 1650|     rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
 1651|     dev,
 1652|     fsid,
 1653|     nfs_server_fscache_state(server));
 1654|
 1655| return 0;
 1656|}
 1657|
 1658|
 1659|
 1660|
 1661|int nfs_fs_proc_init(void)
 1662|{
 1663| struct proc_dir_entry *p;
 1664|
 1665| proc_fs_nfs = proc_mkdir("fs/nfsfs", ((void *)0));
 1666| if (!proc_fs_nfs)
 1667|  goto error_0;
 1668|
 1669|
 1670| p = proc_create("servers", 0100000|(00400|00040|00004),
 1671|   proc_fs_nfs, &nfs_server_list_fops);
 1672| if (!p)
 1673|  goto error_1;
 1674|
 1675|
 1676| p = proc_create("volumes", 0100000|(00400|00040|00004),
 1677|   proc_fs_nfs, &nfs_volume_list_fops);
 1678| if (!p)
 1679|  goto error_2;
 1680| return 0;
 1681|
 1682|error_2:
 1683| remove_proc_entry("servers", proc_fs_nfs);
 1684|error_1:
 1685| remove_proc_entry("fs/nfsfs", ((void *)0));
 1686|error_0:
 1687| return -12;
 1688|}
 1689|
 1690|
 1691|
 1692|
 1693|void nfs_fs_proc_exit(void)
 1694|{
 1695| remove_proc_entry("volumes", proc_fs_nfs);
 1696| remove_proc_entry("servers", proc_fs_nfs);
 1697| remove_proc_entry("fs/nfsfs", ((void *)0));
 1698|}