Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* client.c: NFS client sharing and management code
0003  *
0004  * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/sched.h>
0012 #include <linux/time.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mm.h>
0015 #include <linux/string.h>
0016 #include <linux/stat.h>
0017 #include <linux/errno.h>
0018 #include <linux/unistd.h>
0019 #include <linux/sunrpc/addr.h>
0020 #include <linux/sunrpc/clnt.h>
0021 #include <linux/sunrpc/stats.h>
0022 #include <linux/sunrpc/metrics.h>
0023 #include <linux/sunrpc/xprtsock.h>
0024 #include <linux/sunrpc/xprtrdma.h>
0025 #include <linux/nfs_fs.h>
0026 #include <linux/nfs_mount.h>
0027 #include <linux/nfs4_mount.h>
0028 #include <linux/lockd/bind.h>
0029 #include <linux/seq_file.h>
0030 #include <linux/mount.h>
0031 #include <linux/vfs.h>
0032 #include <linux/inet.h>
0033 #include <linux/in6.h>
0034 #include <linux/slab.h>
0035 #include <linux/idr.h>
0036 #include <net/ipv6.h>
0037 #include <linux/nfs_xdr.h>
0038 #include <linux/sunrpc/bc_xprt.h>
0039 #include <linux/nsproxy.h>
0040 #include <linux/pid_namespace.h>
0041 
0042 
0043 #include "nfs4_fs.h"
0044 #include "callback.h"
0045 #include "delegation.h"
0046 #include "iostat.h"
0047 #include "internal.h"
0048 #include "fscache.h"
0049 #include "pnfs.h"
0050 #include "nfs.h"
0051 #include "netns.h"
0052 #include "sysfs.h"
0053 #include "nfs42.h"
0054 
0055 #define NFSDBG_FACILITY     NFSDBG_CLIENT
0056 
0057 static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
0058 static DEFINE_SPINLOCK(nfs_version_lock);
0059 static DEFINE_MUTEX(nfs_version_mutex);
0060 static LIST_HEAD(nfs_versions);
0061 
0062 /*
0063  * RPC cruft for NFS
0064  */
0065 static const struct rpc_version *nfs_version[5] = {
0066     [2] = NULL,
0067     [3] = NULL,
0068     [4] = NULL,
0069 };
0070 
0071 const struct rpc_program nfs_program = {
0072     .name           = "nfs",
0073     .number         = NFS_PROGRAM,
0074     .nrvers         = ARRAY_SIZE(nfs_version),
0075     .version        = nfs_version,
0076     .stats          = &nfs_rpcstat,
0077     .pipe_dir_name      = NFS_PIPE_DIRNAME,
0078 };
0079 
0080 struct rpc_stat nfs_rpcstat = {
0081     .program        = &nfs_program
0082 };
0083 
0084 static struct nfs_subversion *find_nfs_version(unsigned int version)
0085 {
0086     struct nfs_subversion *nfs;
0087     spin_lock(&nfs_version_lock);
0088 
0089     list_for_each_entry(nfs, &nfs_versions, list) {
0090         if (nfs->rpc_ops->version == version) {
0091             spin_unlock(&nfs_version_lock);
0092             return nfs;
0093         }
0094     }
0095 
0096     spin_unlock(&nfs_version_lock);
0097     return ERR_PTR(-EPROTONOSUPPORT);
0098 }
0099 
0100 struct nfs_subversion *get_nfs_version(unsigned int version)
0101 {
0102     struct nfs_subversion *nfs = find_nfs_version(version);
0103 
0104     if (IS_ERR(nfs)) {
0105         mutex_lock(&nfs_version_mutex);
0106         request_module("nfsv%d", version);
0107         nfs = find_nfs_version(version);
0108         mutex_unlock(&nfs_version_mutex);
0109     }
0110 
0111     if (!IS_ERR(nfs) && !try_module_get(nfs->owner))
0112         return ERR_PTR(-EAGAIN);
0113     return nfs;
0114 }
0115 
0116 void put_nfs_version(struct nfs_subversion *nfs)
0117 {
0118     module_put(nfs->owner);
0119 }
0120 
0121 void register_nfs_version(struct nfs_subversion *nfs)
0122 {
0123     spin_lock(&nfs_version_lock);
0124 
0125     list_add(&nfs->list, &nfs_versions);
0126     nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers;
0127 
0128     spin_unlock(&nfs_version_lock);
0129 }
0130 EXPORT_SYMBOL_GPL(register_nfs_version);
0131 
0132 void unregister_nfs_version(struct nfs_subversion *nfs)
0133 {
0134     spin_lock(&nfs_version_lock);
0135 
0136     nfs_version[nfs->rpc_ops->version] = NULL;
0137     list_del(&nfs->list);
0138 
0139     spin_unlock(&nfs_version_lock);
0140 }
0141 EXPORT_SYMBOL_GPL(unregister_nfs_version);
0142 
0143 /*
0144  * Allocate a shared client record
0145  *
0146  * Since these are allocated/deallocated very rarely, we don't
0147  * bother putting them in a slab cache...
0148  */
0149 struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
0150 {
0151     struct nfs_client *clp;
0152     int err = -ENOMEM;
0153 
0154     if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
0155         goto error_0;
0156 
0157     clp->cl_minorversion = cl_init->minorversion;
0158     clp->cl_nfs_mod = cl_init->nfs_mod;
0159     if (!try_module_get(clp->cl_nfs_mod->owner))
0160         goto error_dealloc;
0161 
0162     clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
0163 
0164     refcount_set(&clp->cl_count, 1);
0165     clp->cl_cons_state = NFS_CS_INITING;
0166 
0167     memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
0168     clp->cl_addrlen = cl_init->addrlen;
0169 
0170     if (cl_init->hostname) {
0171         err = -ENOMEM;
0172         clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
0173         if (!clp->cl_hostname)
0174             goto error_cleanup;
0175     }
0176 
0177     INIT_LIST_HEAD(&clp->cl_superblocks);
0178     clp->cl_rpcclient = ERR_PTR(-EINVAL);
0179 
0180     clp->cl_flags = cl_init->init_flags;
0181     clp->cl_proto = cl_init->proto;
0182     clp->cl_nconnect = cl_init->nconnect;
0183     clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
0184     clp->cl_net = get_net(cl_init->net);
0185 
0186     clp->cl_principal = "*";
0187     return clp;
0188 
0189 error_cleanup:
0190     put_nfs_version(clp->cl_nfs_mod);
0191 error_dealloc:
0192     kfree(clp);
0193 error_0:
0194     return ERR_PTR(err);
0195 }
0196 EXPORT_SYMBOL_GPL(nfs_alloc_client);
0197 
0198 #if IS_ENABLED(CONFIG_NFS_V4)
0199 static void nfs_cleanup_cb_ident_idr(struct net *net)
0200 {
0201     struct nfs_net *nn = net_generic(net, nfs_net_id);
0202 
0203     idr_destroy(&nn->cb_ident_idr);
0204 }
0205 
0206 /* nfs_client_lock held */
0207 static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
0208 {
0209     struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
0210 
0211     if (clp->cl_cb_ident)
0212         idr_remove(&nn->cb_ident_idr, clp->cl_cb_ident);
0213 }
0214 
0215 static void pnfs_init_server(struct nfs_server *server)
0216 {
0217     rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
0218 }
0219 
0220 #else
0221 static void nfs_cleanup_cb_ident_idr(struct net *net)
0222 {
0223 }
0224 
0225 static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
0226 {
0227 }
0228 
0229 static void pnfs_init_server(struct nfs_server *server)
0230 {
0231 }
0232 
0233 #endif /* CONFIG_NFS_V4 */
0234 
0235 /*
0236  * Destroy a shared client record
0237  */
0238 void nfs_free_client(struct nfs_client *clp)
0239 {
0240     /* -EIO all pending I/O */
0241     if (!IS_ERR(clp->cl_rpcclient))
0242         rpc_shutdown_client(clp->cl_rpcclient);
0243 
0244     put_net(clp->cl_net);
0245     put_nfs_version(clp->cl_nfs_mod);
0246     kfree(clp->cl_hostname);
0247     kfree(clp->cl_acceptor);
0248     kfree(clp);
0249 }
0250 EXPORT_SYMBOL_GPL(nfs_free_client);
0251 
0252 /*
0253  * Release a reference to a shared client record
0254  */
0255 void nfs_put_client(struct nfs_client *clp)
0256 {
0257     struct nfs_net *nn;
0258 
0259     if (!clp)
0260         return;
0261 
0262     nn = net_generic(clp->cl_net, nfs_net_id);
0263 
0264     if (refcount_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) {
0265         list_del(&clp->cl_share_link);
0266         nfs_cb_idr_remove_locked(clp);
0267         spin_unlock(&nn->nfs_client_lock);
0268 
0269         WARN_ON_ONCE(!list_empty(&clp->cl_superblocks));
0270 
0271         clp->rpc_ops->free_client(clp);
0272     }
0273 }
0274 EXPORT_SYMBOL_GPL(nfs_put_client);
0275 
0276 /*
0277  * Find an nfs_client on the list that matches the initialisation data
0278  * that is supplied.
0279  */
0280 static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
0281 {
0282     struct nfs_client *clp;
0283     const struct sockaddr *sap = data->addr;
0284     struct nfs_net *nn = net_generic(data->net, nfs_net_id);
0285     int error;
0286 
0287 again:
0288     list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
0289             const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
0290         /* Don't match clients that failed to initialise properly */
0291         if (clp->cl_cons_state < 0)
0292             continue;
0293 
0294         /* If a client is still initializing then we need to wait */
0295         if (clp->cl_cons_state > NFS_CS_READY) {
0296             refcount_inc(&clp->cl_count);
0297             spin_unlock(&nn->nfs_client_lock);
0298             error = nfs_wait_client_init_complete(clp);
0299             nfs_put_client(clp);
0300             spin_lock(&nn->nfs_client_lock);
0301             if (error < 0)
0302                 return ERR_PTR(error);
0303             goto again;
0304         }
0305 
0306         /* Different NFS versions cannot share the same nfs_client */
0307         if (clp->rpc_ops != data->nfs_mod->rpc_ops)
0308             continue;
0309 
0310         if (clp->cl_proto != data->proto)
0311             continue;
0312         /* Match nfsv4 minorversion */
0313         if (clp->cl_minorversion != data->minorversion)
0314             continue;
0315 
0316         /* Match request for a dedicated DS */
0317         if (test_bit(NFS_CS_DS, &data->init_flags) !=
0318             test_bit(NFS_CS_DS, &clp->cl_flags))
0319             continue;
0320 
0321         /* Match the full socket address */
0322         if (!rpc_cmp_addr_port(sap, clap))
0323             /* Match all xprt_switch full socket addresses */
0324             if (IS_ERR(clp->cl_rpcclient) ||
0325                             !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient,
0326                                sap))
0327                 continue;
0328 
0329         refcount_inc(&clp->cl_count);
0330         return clp;
0331     }
0332     return NULL;
0333 }
0334 
0335 /*
0336  * Return true if @clp is done initializing, false if still working on it.
0337  *
0338  * Use nfs_client_init_status to check if it was successful.
0339  */
0340 bool nfs_client_init_is_complete(const struct nfs_client *clp)
0341 {
0342     return clp->cl_cons_state <= NFS_CS_READY;
0343 }
0344 EXPORT_SYMBOL_GPL(nfs_client_init_is_complete);
0345 
0346 /*
0347  * Return 0 if @clp was successfully initialized, -errno otherwise.
0348  *
0349  * This must be called *after* nfs_client_init_is_complete() returns true,
0350  * otherwise it will pop WARN_ON_ONCE and return -EINVAL
0351  */
0352 int nfs_client_init_status(const struct nfs_client *clp)
0353 {
0354     /* called without checking nfs_client_init_is_complete */
0355     if (clp->cl_cons_state > NFS_CS_READY) {
0356         WARN_ON_ONCE(1);
0357         return -EINVAL;
0358     }
0359     return clp->cl_cons_state;
0360 }
0361 EXPORT_SYMBOL_GPL(nfs_client_init_status);
0362 
0363 int nfs_wait_client_init_complete(const struct nfs_client *clp)
0364 {
0365     return wait_event_killable(nfs_client_active_wq,
0366             nfs_client_init_is_complete(clp));
0367 }
0368 EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);
0369 
0370 /*
0371  * Found an existing client.  Make sure it's ready before returning.
0372  */
0373 static struct nfs_client *
0374 nfs_found_client(const struct nfs_client_initdata *cl_init,
0375          struct nfs_client *clp)
0376 {
0377     int error;
0378 
0379     error = nfs_wait_client_init_complete(clp);
0380     if (error < 0) {
0381         nfs_put_client(clp);
0382         return ERR_PTR(-ERESTARTSYS);
0383     }
0384 
0385     if (clp->cl_cons_state < NFS_CS_READY) {
0386         error = clp->cl_cons_state;
0387         nfs_put_client(clp);
0388         return ERR_PTR(error);
0389     }
0390 
0391     smp_rmb();
0392     return clp;
0393 }
0394 
0395 /*
0396  * Look up a client by IP address and protocol version
0397  * - creates a new record if one doesn't yet exist
0398  */
0399 struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
0400 {
0401     struct nfs_client *clp, *new = NULL;
0402     struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
0403     const struct nfs_rpc_ops *rpc_ops = cl_init->nfs_mod->rpc_ops;
0404 
0405     if (cl_init->hostname == NULL) {
0406         WARN_ON(1);
0407         return ERR_PTR(-EINVAL);
0408     }
0409 
0410     /* see if the client already exists */
0411     do {
0412         spin_lock(&nn->nfs_client_lock);
0413 
0414         clp = nfs_match_client(cl_init);
0415         if (clp) {
0416             spin_unlock(&nn->nfs_client_lock);
0417             if (new)
0418                 new->rpc_ops->free_client(new);
0419             if (IS_ERR(clp))
0420                 return clp;
0421             return nfs_found_client(cl_init, clp);
0422         }
0423         if (new) {
0424             list_add_tail(&new->cl_share_link,
0425                     &nn->nfs_client_list);
0426             spin_unlock(&nn->nfs_client_lock);
0427             return rpc_ops->init_client(new, cl_init);
0428         }
0429 
0430         spin_unlock(&nn->nfs_client_lock);
0431 
0432         new = rpc_ops->alloc_client(cl_init);
0433     } while (!IS_ERR(new));
0434 
0435     return new;
0436 }
0437 EXPORT_SYMBOL_GPL(nfs_get_client);
0438 
0439 /*
0440  * Mark a server as ready or failed
0441  */
0442 void nfs_mark_client_ready(struct nfs_client *clp, int state)
0443 {
0444     smp_wmb();
0445     clp->cl_cons_state = state;
0446     wake_up_all(&nfs_client_active_wq);
0447 }
0448 EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
0449 
0450 /*
0451  * Initialise the timeout values for a connection
0452  */
0453 void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
0454                     int timeo, int retrans)
0455 {
0456     to->to_initval = timeo * HZ / 10;
0457     to->to_retries = retrans;
0458 
0459     switch (proto) {
0460     case XPRT_TRANSPORT_TCP:
0461     case XPRT_TRANSPORT_RDMA:
0462         if (retrans == NFS_UNSPEC_RETRANS)
0463             to->to_retries = NFS_DEF_TCP_RETRANS;
0464         if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0)
0465             to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10;
0466         if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
0467             to->to_initval = NFS_MAX_TCP_TIMEOUT;
0468         to->to_increment = to->to_initval;
0469         to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
0470         if (to->to_maxval > NFS_MAX_TCP_TIMEOUT)
0471             to->to_maxval = NFS_MAX_TCP_TIMEOUT;
0472         if (to->to_maxval < to->to_initval)
0473             to->to_maxval = to->to_initval;
0474         to->to_exponential = 0;
0475         break;
0476     case XPRT_TRANSPORT_UDP:
0477         if (retrans == NFS_UNSPEC_RETRANS)
0478             to->to_retries = NFS_DEF_UDP_RETRANS;
0479         if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0)
0480             to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10;
0481         if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
0482             to->to_initval = NFS_MAX_UDP_TIMEOUT;
0483         to->to_maxval = NFS_MAX_UDP_TIMEOUT;
0484         to->to_exponential = 1;
0485         break;
0486     default:
0487         BUG();
0488     }
0489 }
0490 EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
0491 
0492 /*
0493  * Create an RPC client handle
0494  */
0495 int nfs_create_rpc_client(struct nfs_client *clp,
0496               const struct nfs_client_initdata *cl_init,
0497               rpc_authflavor_t flavor)
0498 {
0499     struct rpc_clnt     *clnt = NULL;
0500     struct rpc_create_args args = {
0501         .net        = clp->cl_net,
0502         .protocol   = clp->cl_proto,
0503         .nconnect   = clp->cl_nconnect,
0504         .address    = (struct sockaddr *)&clp->cl_addr,
0505         .addrsize   = clp->cl_addrlen,
0506         .timeout    = cl_init->timeparms,
0507         .servername = clp->cl_hostname,
0508         .nodename   = cl_init->nodename,
0509         .program    = &nfs_program,
0510         .version    = clp->rpc_ops->version,
0511         .authflavor = flavor,
0512         .cred       = cl_init->cred,
0513     };
0514 
0515     if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
0516         args.flags |= RPC_CLNT_CREATE_DISCRTRY;
0517     if (test_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags))
0518         args.flags |= RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT;
0519     if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
0520         args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
0521     if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
0522         args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
0523     if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
0524         args.flags |= RPC_CLNT_CREATE_NOPING;
0525     if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
0526         args.flags |= RPC_CLNT_CREATE_REUSEPORT;
0527 
0528     if (!IS_ERR(clp->cl_rpcclient))
0529         return 0;
0530 
0531     clnt = rpc_create(&args);
0532     if (IS_ERR(clnt)) {
0533         dprintk("%s: cannot create RPC client. Error = %ld\n",
0534                 __func__, PTR_ERR(clnt));
0535         return PTR_ERR(clnt);
0536     }
0537 
0538     clnt->cl_principal = clp->cl_principal;
0539     clp->cl_rpcclient = clnt;
0540     clnt->cl_max_connect = clp->cl_max_connect;
0541     return 0;
0542 }
0543 EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
0544 
0545 /*
0546  * Version 2 or 3 client destruction
0547  */
0548 static void nfs_destroy_server(struct nfs_server *server)
0549 {
0550     if (server->nlm_host)
0551         nlmclnt_done(server->nlm_host);
0552 }
0553 
0554 /*
0555  * Version 2 or 3 lockd setup
0556  */
0557 static int nfs_start_lockd(struct nfs_server *server)
0558 {
0559     struct nlm_host *host;
0560     struct nfs_client *clp = server->nfs_client;
0561     struct nlmclnt_initdata nlm_init = {
0562         .hostname   = clp->cl_hostname,
0563         .address    = (struct sockaddr *)&clp->cl_addr,
0564         .addrlen    = clp->cl_addrlen,
0565         .nfs_version    = clp->rpc_ops->version,
0566         .noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
0567                     1 : 0,
0568         .net        = clp->cl_net,
0569         .nlmclnt_ops    = clp->cl_nfs_mod->rpc_ops->nlmclnt_ops,
0570         .cred       = server->cred,
0571     };
0572 
0573     if (nlm_init.nfs_version > 3)
0574         return 0;
0575     if ((server->flags & NFS_MOUNT_LOCAL_FLOCK) &&
0576             (server->flags & NFS_MOUNT_LOCAL_FCNTL))
0577         return 0;
0578 
0579     switch (clp->cl_proto) {
0580         default:
0581             nlm_init.protocol = IPPROTO_TCP;
0582             break;
0583 #ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
0584         case XPRT_TRANSPORT_UDP:
0585             nlm_init.protocol = IPPROTO_UDP;
0586 #endif
0587     }
0588 
0589     host = nlmclnt_init(&nlm_init);
0590     if (IS_ERR(host))
0591         return PTR_ERR(host);
0592 
0593     server->nlm_host = host;
0594     server->destroy = nfs_destroy_server;
0595     return 0;
0596 }
0597 
0598 /*
0599  * Create a general RPC client
0600  */
0601 int nfs_init_server_rpcclient(struct nfs_server *server,
0602         const struct rpc_timeout *timeo,
0603         rpc_authflavor_t pseudoflavour)
0604 {
0605     struct nfs_client *clp = server->nfs_client;
0606 
0607     server->client = rpc_clone_client_set_auth(clp->cl_rpcclient,
0608                             pseudoflavour);
0609     if (IS_ERR(server->client)) {
0610         dprintk("%s: couldn't create rpc_client!\n", __func__);
0611         return PTR_ERR(server->client);
0612     }
0613 
0614     memcpy(&server->client->cl_timeout_default,
0615             timeo,
0616             sizeof(server->client->cl_timeout_default));
0617     server->client->cl_timeout = &server->client->cl_timeout_default;
0618     server->client->cl_softrtry = 0;
0619     if (server->flags & NFS_MOUNT_SOFTERR)
0620         server->client->cl_softerr = 1;
0621     if (server->flags & NFS_MOUNT_SOFT)
0622         server->client->cl_softrtry = 1;
0623 
0624     return 0;
0625 }
0626 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
0627 
0628 /**
0629  * nfs_init_client - Initialise an NFS2 or NFS3 client
0630  *
0631  * @clp: nfs_client to initialise
0632  * @cl_init: Initialisation parameters
0633  *
0634  * Returns pointer to an NFS client, or an ERR_PTR value.
0635  */
0636 struct nfs_client *nfs_init_client(struct nfs_client *clp,
0637                    const struct nfs_client_initdata *cl_init)
0638 {
0639     int error;
0640 
0641     /* the client is already initialised */
0642     if (clp->cl_cons_state == NFS_CS_READY)
0643         return clp;
0644 
0645     /*
0646      * Create a client RPC handle for doing FSSTAT with UNIX auth only
0647      * - RFC 2623, sec 2.3.2
0648      */
0649     error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
0650     nfs_mark_client_ready(clp, error == 0 ? NFS_CS_READY : error);
0651     if (error < 0) {
0652         nfs_put_client(clp);
0653         clp = ERR_PTR(error);
0654     }
0655     return clp;
0656 }
0657 EXPORT_SYMBOL_GPL(nfs_init_client);
0658 
0659 /*
0660  * Create a version 2 or 3 client
0661  */
0662 static int nfs_init_server(struct nfs_server *server,
0663                const struct fs_context *fc)
0664 {
0665     const struct nfs_fs_context *ctx = nfs_fc2context(fc);
0666     struct rpc_timeout timeparms;
0667     struct nfs_client_initdata cl_init = {
0668         .hostname = ctx->nfs_server.hostname,
0669         .addr = (const struct sockaddr *)&ctx->nfs_server.address,
0670         .addrlen = ctx->nfs_server.addrlen,
0671         .nfs_mod = ctx->nfs_mod,
0672         .proto = ctx->nfs_server.protocol,
0673         .net = fc->net_ns,
0674         .timeparms = &timeparms,
0675         .cred = server->cred,
0676         .nconnect = ctx->nfs_server.nconnect,
0677         .init_flags = (1UL << NFS_CS_REUSEPORT),
0678     };
0679     struct nfs_client *clp;
0680     int error;
0681 
0682     nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
0683                 ctx->timeo, ctx->retrans);
0684     if (ctx->flags & NFS_MOUNT_NORESVPORT)
0685         set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
0686 
0687     /* Allocate or find a client reference we can use */
0688     clp = nfs_get_client(&cl_init);
0689     if (IS_ERR(clp))
0690         return PTR_ERR(clp);
0691 
0692     server->nfs_client = clp;
0693 
0694     /* Initialise the client representation from the mount data */
0695     server->flags = ctx->flags;
0696     server->options = ctx->options;
0697     server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
0698 
0699     switch (clp->rpc_ops->version) {
0700     case 2:
0701         server->fattr_valid = NFS_ATTR_FATTR_V2;
0702         break;
0703     case 3:
0704         server->fattr_valid = NFS_ATTR_FATTR_V3;
0705         break;
0706     default:
0707         server->fattr_valid = NFS_ATTR_FATTR_V4;
0708     }
0709 
0710     if (ctx->rsize)
0711         server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto);
0712     if (ctx->wsize)
0713         server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto);
0714 
0715     server->acregmin = ctx->acregmin * HZ;
0716     server->acregmax = ctx->acregmax * HZ;
0717     server->acdirmin = ctx->acdirmin * HZ;
0718     server->acdirmax = ctx->acdirmax * HZ;
0719 
0720     /* Start lockd here, before we might error out */
0721     error = nfs_start_lockd(server);
0722     if (error < 0)
0723         goto error;
0724 
0725     server->port = ctx->nfs_server.port;
0726     server->auth_info = ctx->auth_info;
0727 
0728     error = nfs_init_server_rpcclient(server, &timeparms,
0729                       ctx->selected_flavor);
0730     if (error < 0)
0731         goto error;
0732 
0733     /* Preserve the values of mount_server-related mount options */
0734     if (ctx->mount_server.addrlen) {
0735         memcpy(&server->mountd_address, &ctx->mount_server.address,
0736             ctx->mount_server.addrlen);
0737         server->mountd_addrlen = ctx->mount_server.addrlen;
0738     }
0739     server->mountd_version = ctx->mount_server.version;
0740     server->mountd_port = ctx->mount_server.port;
0741     server->mountd_protocol = ctx->mount_server.protocol;
0742 
0743     server->namelen  = ctx->namlen;
0744     return 0;
0745 
0746 error:
0747     server->nfs_client = NULL;
0748     nfs_put_client(clp);
0749     return error;
0750 }
0751 
0752 /*
0753  * Load up the server record from information gained in an fsinfo record
0754  */
0755 static void nfs_server_set_fsinfo(struct nfs_server *server,
0756                   struct nfs_fsinfo *fsinfo)
0757 {
0758     struct nfs_client *clp = server->nfs_client;
0759     unsigned long max_rpc_payload, raw_max_rpc_payload;
0760 
0761     /* Work out a lot of parameters */
0762     if (server->rsize == 0)
0763         server->rsize = nfs_io_size(fsinfo->rtpref, clp->cl_proto);
0764     if (server->wsize == 0)
0765         server->wsize = nfs_io_size(fsinfo->wtpref, clp->cl_proto);
0766 
0767     if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
0768         server->rsize = nfs_io_size(fsinfo->rtmax, clp->cl_proto);
0769     if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
0770         server->wsize = nfs_io_size(fsinfo->wtmax, clp->cl_proto);
0771 
0772     raw_max_rpc_payload = rpc_max_payload(server->client);
0773     max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL);
0774 
0775     if (server->rsize > max_rpc_payload)
0776         server->rsize = max_rpc_payload;
0777     if (server->rsize > NFS_MAX_FILE_IO_SIZE)
0778         server->rsize = NFS_MAX_FILE_IO_SIZE;
0779     server->rpages = (server->rsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
0780 
0781     if (server->wsize > max_rpc_payload)
0782         server->wsize = max_rpc_payload;
0783     if (server->wsize > NFS_MAX_FILE_IO_SIZE)
0784         server->wsize = NFS_MAX_FILE_IO_SIZE;
0785     server->wpages = (server->wsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
0786 
0787     server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
0788 
0789     server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
0790     if (server->dtsize > NFS_MAX_FILE_IO_SIZE)
0791         server->dtsize = NFS_MAX_FILE_IO_SIZE;
0792     if (server->dtsize > server->rsize)
0793         server->dtsize = server->rsize;
0794 
0795     if (server->flags & NFS_MOUNT_NOAC) {
0796         server->acregmin = server->acregmax = 0;
0797         server->acdirmin = server->acdirmax = 0;
0798     }
0799 
0800     server->maxfilesize = fsinfo->maxfilesize;
0801 
0802     server->time_delta = fsinfo->time_delta;
0803     server->change_attr_type = fsinfo->change_attr_type;
0804 
0805     server->clone_blksize = fsinfo->clone_blksize;
0806     /* We're airborne Set socket buffersize */
0807     rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
0808 
0809 #ifdef CONFIG_NFS_V4_2
0810     /*
0811      * Defaults until limited by the session parameters.
0812      */
0813     server->gxasize = min_t(unsigned int, raw_max_rpc_payload,
0814                 XATTR_SIZE_MAX);
0815     server->sxasize = min_t(unsigned int, raw_max_rpc_payload,
0816                 XATTR_SIZE_MAX);
0817     server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
0818                 nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
0819 
0820     if (fsinfo->xattr_support)
0821         server->caps |= NFS_CAP_XATTR;
0822 #endif
0823 }
0824 
0825 /*
0826  * Probe filesystem information, including the FSID on v2/v3
0827  */
0828 static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
0829 {
0830     struct nfs_fsinfo fsinfo;
0831     struct nfs_client *clp = server->nfs_client;
0832     int error;
0833 
0834     if (clp->rpc_ops->set_capabilities != NULL) {
0835         error = clp->rpc_ops->set_capabilities(server, mntfh);
0836         if (error < 0)
0837             return error;
0838     }
0839 
0840     fsinfo.fattr = fattr;
0841     fsinfo.nlayouttypes = 0;
0842     memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype));
0843     error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
0844     if (error < 0)
0845         return error;
0846 
0847     nfs_server_set_fsinfo(server, &fsinfo);
0848 
0849     /* Get some general file system info */
0850     if (server->namelen == 0) {
0851         struct nfs_pathconf pathinfo;
0852 
0853         pathinfo.fattr = fattr;
0854         nfs_fattr_init(fattr);
0855 
0856         if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
0857             server->namelen = pathinfo.max_namelen;
0858     }
0859 
0860     if (clp->rpc_ops->discover_trunking != NULL &&
0861             (server->caps & NFS_CAP_FS_LOCATIONS &&
0862              (server->flags & NFS_MOUNT_TRUNK_DISCOVERY))) {
0863         error = clp->rpc_ops->discover_trunking(server, mntfh);
0864         if (error < 0)
0865             return error;
0866     }
0867 
0868     return 0;
0869 }
0870 
0871 /*
0872  * Grab the destination's particulars, including lease expiry time.
0873  *
0874  * Returns zero if probe succeeded and retrieved FSID matches the FSID
0875  * we have cached.
0876  */
0877 int nfs_probe_server(struct nfs_server *server, struct nfs_fh *mntfh)
0878 {
0879     struct nfs_fattr *fattr;
0880     int error;
0881 
0882     fattr = nfs_alloc_fattr();
0883     if (fattr == NULL)
0884         return -ENOMEM;
0885 
0886     /* Sanity: the probe won't work if the destination server
0887      * does not recognize the migrated FH. */
0888     error = nfs_probe_fsinfo(server, mntfh, fattr);
0889 
0890     nfs_free_fattr(fattr);
0891     return error;
0892 }
0893 EXPORT_SYMBOL_GPL(nfs_probe_server);
0894 
0895 /*
0896  * Copy useful information when duplicating a server record
0897  */
0898 void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
0899 {
0900     target->flags = source->flags;
0901     target->rsize = source->rsize;
0902     target->wsize = source->wsize;
0903     target->acregmin = source->acregmin;
0904     target->acregmax = source->acregmax;
0905     target->acdirmin = source->acdirmin;
0906     target->acdirmax = source->acdirmax;
0907     target->caps = source->caps;
0908     target->options = source->options;
0909     target->auth_info = source->auth_info;
0910     target->port = source->port;
0911 }
0912 EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
0913 
0914 void nfs_server_insert_lists(struct nfs_server *server)
0915 {
0916     struct nfs_client *clp = server->nfs_client;
0917     struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
0918 
0919     spin_lock(&nn->nfs_client_lock);
0920     list_add_tail_rcu(&server->client_link, &clp->cl_superblocks);
0921     list_add_tail(&server->master_link, &nn->nfs_volume_list);
0922     clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
0923     spin_unlock(&nn->nfs_client_lock);
0924 
0925 }
0926 EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
0927 
0928 void nfs_server_remove_lists(struct nfs_server *server)
0929 {
0930     struct nfs_client *clp = server->nfs_client;
0931     struct nfs_net *nn;
0932 
0933     if (clp == NULL)
0934         return;
0935     nn = net_generic(clp->cl_net, nfs_net_id);
0936     spin_lock(&nn->nfs_client_lock);
0937     list_del_rcu(&server->client_link);
0938     if (list_empty(&clp->cl_superblocks))
0939         set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
0940     list_del(&server->master_link);
0941     spin_unlock(&nn->nfs_client_lock);
0942 
0943     synchronize_rcu();
0944 }
0945 EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
0946 
0947 /*
0948  * Allocate and initialise a server record
0949  */
0950 struct nfs_server *nfs_alloc_server(void)
0951 {
0952     struct nfs_server *server;
0953 
0954     server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
0955     if (!server)
0956         return NULL;
0957 
0958     server->client = server->client_acl = ERR_PTR(-EINVAL);
0959 
0960     /* Zero out the NFS state stuff */
0961     INIT_LIST_HEAD(&server->client_link);
0962     INIT_LIST_HEAD(&server->master_link);
0963     INIT_LIST_HEAD(&server->delegations);
0964     INIT_LIST_HEAD(&server->layouts);
0965     INIT_LIST_HEAD(&server->state_owners_lru);
0966     INIT_LIST_HEAD(&server->ss_copies);
0967 
0968     atomic_set(&server->active, 0);
0969 
0970     server->io_stats = nfs_alloc_iostats();
0971     if (!server->io_stats) {
0972         kfree(server);
0973         return NULL;
0974     }
0975 
0976     server->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
0977 
0978     ida_init(&server->openowner_id);
0979     ida_init(&server->lockowner_id);
0980     pnfs_init_server(server);
0981     rpc_init_wait_queue(&server->uoc_rpcwaitq, "NFS UOC");
0982 
0983     return server;
0984 }
0985 EXPORT_SYMBOL_GPL(nfs_alloc_server);
0986 
0987 /*
0988  * Free up a server record
0989  */
0990 void nfs_free_server(struct nfs_server *server)
0991 {
0992     nfs_server_remove_lists(server);
0993 
0994     if (server->destroy != NULL)
0995         server->destroy(server);
0996 
0997     if (!IS_ERR(server->client_acl))
0998         rpc_shutdown_client(server->client_acl);
0999     if (!IS_ERR(server->client))
1000         rpc_shutdown_client(server->client);
1001 
1002     nfs_put_client(server->nfs_client);
1003 
1004     ida_destroy(&server->lockowner_id);
1005     ida_destroy(&server->openowner_id);
1006     nfs_free_iostats(server->io_stats);
1007     put_cred(server->cred);
1008     kfree(server);
1009     nfs_release_automount_timer();
1010 }
1011 EXPORT_SYMBOL_GPL(nfs_free_server);
1012 
1013 /*
1014  * Create a version 2 or 3 volume record
1015  * - keyed on server and FSID
1016  */
1017 struct nfs_server *nfs_create_server(struct fs_context *fc)
1018 {
1019     struct nfs_fs_context *ctx = nfs_fc2context(fc);
1020     struct nfs_server *server;
1021     struct nfs_fattr *fattr;
1022     int error;
1023 
1024     server = nfs_alloc_server();
1025     if (!server)
1026         return ERR_PTR(-ENOMEM);
1027 
1028     server->cred = get_cred(fc->cred);
1029 
1030     error = -ENOMEM;
1031     fattr = nfs_alloc_fattr();
1032     if (fattr == NULL)
1033         goto error;
1034 
1035     /* Get a client representation */
1036     error = nfs_init_server(server, fc);
1037     if (error < 0)
1038         goto error;
1039 
1040     /* Probe the root fh to retrieve its FSID */
1041     error = nfs_probe_fsinfo(server, ctx->mntfh, fattr);
1042     if (error < 0)
1043         goto error;
1044     if (server->nfs_client->rpc_ops->version == 3) {
1045         if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
1046             server->namelen = NFS3_MAXNAMLEN;
1047         if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS))
1048             server->caps |= NFS_CAP_READDIRPLUS;
1049     } else {
1050         if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
1051             server->namelen = NFS2_MAXNAMLEN;
1052     }
1053 
1054     if (!(fattr->valid & NFS_ATTR_FATTR)) {
1055         error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
1056                                fattr, NULL);
1057         if (error < 0) {
1058             dprintk("nfs_create_server: getattr error = %d\n", -error);
1059             goto error;
1060         }
1061     }
1062     memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
1063 
1064     dprintk("Server FSID: %llx:%llx\n",
1065         (unsigned long long) server->fsid.major,
1066         (unsigned long long) server->fsid.minor);
1067 
1068     nfs_server_insert_lists(server);
1069     server->mount_time = jiffies;
1070     nfs_free_fattr(fattr);
1071     return server;
1072 
1073 error:
1074     nfs_free_fattr(fattr);
1075     nfs_free_server(server);
1076     return ERR_PTR(error);
1077 }
1078 EXPORT_SYMBOL_GPL(nfs_create_server);
1079 
1080 /*
1081  * Clone an NFS2, NFS3 or NFS4 server record
1082  */
1083 struct nfs_server *nfs_clone_server(struct nfs_server *source,
1084                     struct nfs_fh *fh,
1085                     struct nfs_fattr *fattr,
1086                     rpc_authflavor_t flavor)
1087 {
1088     struct nfs_server *server;
1089     int error;
1090 
1091     server = nfs_alloc_server();
1092     if (!server)
1093         return ERR_PTR(-ENOMEM);
1094 
1095     server->cred = get_cred(source->cred);
1096 
1097     /* Copy data from the source */
1098     server->nfs_client = source->nfs_client;
1099     server->destroy = source->destroy;
1100     refcount_inc(&server->nfs_client->cl_count);
1101     nfs_server_copy_userdata(server, source);
1102 
1103     server->fsid = fattr->fsid;
1104 
1105     error = nfs_init_server_rpcclient(server,
1106             source->client->cl_timeout,
1107             flavor);
1108     if (error < 0)
1109         goto out_free_server;
1110 
1111     /* probe the filesystem info for this server filesystem */
1112     error = nfs_probe_server(server, fh);
1113     if (error < 0)
1114         goto out_free_server;
1115 
1116     if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1117         server->namelen = NFS4_MAXNAMLEN;
1118 
1119     error = nfs_start_lockd(server);
1120     if (error < 0)
1121         goto out_free_server;
1122 
1123     nfs_server_insert_lists(server);
1124     server->mount_time = jiffies;
1125 
1126     return server;
1127 
1128 out_free_server:
1129     nfs_free_server(server);
1130     return ERR_PTR(error);
1131 }
1132 EXPORT_SYMBOL_GPL(nfs_clone_server);
1133 
1134 void nfs_clients_init(struct net *net)
1135 {
1136     struct nfs_net *nn = net_generic(net, nfs_net_id);
1137 
1138     INIT_LIST_HEAD(&nn->nfs_client_list);
1139     INIT_LIST_HEAD(&nn->nfs_volume_list);
1140 #if IS_ENABLED(CONFIG_NFS_V4)
1141     idr_init(&nn->cb_ident_idr);
1142 #endif
1143     spin_lock_init(&nn->nfs_client_lock);
1144     nn->boot_time = ktime_get_real();
1145 
1146     nfs_netns_sysfs_setup(nn, net);
1147 }
1148 
1149 void nfs_clients_exit(struct net *net)
1150 {
1151     struct nfs_net *nn = net_generic(net, nfs_net_id);
1152 
1153     nfs_netns_sysfs_destroy(nn);
1154     nfs_cleanup_cb_ident_idr(net);
1155     WARN_ON_ONCE(!list_empty(&nn->nfs_client_list));
1156     WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list));
1157 }
1158 
1159 #ifdef CONFIG_PROC_FS
1160 static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
1161 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
1162 static void nfs_server_list_stop(struct seq_file *p, void *v);
1163 static int nfs_server_list_show(struct seq_file *m, void *v);
1164 
1165 static const struct seq_operations nfs_server_list_ops = {
1166     .start  = nfs_server_list_start,
1167     .next   = nfs_server_list_next,
1168     .stop   = nfs_server_list_stop,
1169     .show   = nfs_server_list_show,
1170 };
1171 
1172 static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
1173 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
1174 static void nfs_volume_list_stop(struct seq_file *p, void *v);
1175 static int nfs_volume_list_show(struct seq_file *m, void *v);
1176 
1177 static const struct seq_operations nfs_volume_list_ops = {
1178     .start  = nfs_volume_list_start,
1179     .next   = nfs_volume_list_next,
1180     .stop   = nfs_volume_list_stop,
1181     .show   = nfs_volume_list_show,
1182 };
1183 
1184 /*
1185  * set up the iterator to start reading from the server list and return the first item
1186  */
1187 static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
1188                 __acquires(&nn->nfs_client_lock)
1189 {
1190     struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1191 
1192     /* lock the list against modification */
1193     spin_lock(&nn->nfs_client_lock);
1194     return seq_list_start_head(&nn->nfs_client_list, *_pos);
1195 }
1196 
1197 /*
1198  * move to next server
1199  */
1200 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
1201 {
1202     struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1203 
1204     return seq_list_next(v, &nn->nfs_client_list, pos);
1205 }
1206 
1207 /*
1208  * clean up after reading from the transports list
1209  */
1210 static void nfs_server_list_stop(struct seq_file *p, void *v)
1211                 __releases(&nn->nfs_client_lock)
1212 {
1213     struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1214 
1215     spin_unlock(&nn->nfs_client_lock);
1216 }
1217 
1218 /*
1219  * display a header line followed by a load of call lines
1220  */
1221 static int nfs_server_list_show(struct seq_file *m, void *v)
1222 {
1223     struct nfs_client *clp;
1224     struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1225 
1226     /* display header on line 1 */
1227     if (v == &nn->nfs_client_list) {
1228         seq_puts(m, "NV SERVER   PORT USE HOSTNAME\n");
1229         return 0;
1230     }
1231 
1232     /* display one transport per line on subsequent lines */
1233     clp = list_entry(v, struct nfs_client, cl_share_link);
1234 
1235     /* Check if the client is initialized */
1236     if (clp->cl_cons_state != NFS_CS_READY)
1237         return 0;
1238 
1239     rcu_read_lock();
1240     seq_printf(m, "v%u %s %s %3d %s\n",
1241            clp->rpc_ops->version,
1242            rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1243            rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1244            refcount_read(&clp->cl_count),
1245            clp->cl_hostname);
1246     rcu_read_unlock();
1247 
1248     return 0;
1249 }
1250 
1251 /*
1252  * set up the iterator to start reading from the volume list and return the first item
1253  */
1254 static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1255                 __acquires(&nn->nfs_client_lock)
1256 {
1257     struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1258 
1259     /* lock the list against modification */
1260     spin_lock(&nn->nfs_client_lock);
1261     return seq_list_start_head(&nn->nfs_volume_list, *_pos);
1262 }
1263 
1264 /*
1265  * move to next volume
1266  */
1267 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
1268 {
1269     struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1270 
1271     return seq_list_next(v, &nn->nfs_volume_list, pos);
1272 }
1273 
1274 /*
1275  * clean up after reading from the transports list
1276  */
1277 static void nfs_volume_list_stop(struct seq_file *p, void *v)
1278                 __releases(&nn->nfs_client_lock)
1279 {
1280     struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1281 
1282     spin_unlock(&nn->nfs_client_lock);
1283 }
1284 
1285 /*
1286  * display a header line followed by a load of call lines
1287  */
1288 static int nfs_volume_list_show(struct seq_file *m, void *v)
1289 {
1290     struct nfs_server *server;
1291     struct nfs_client *clp;
1292     char dev[13];   // 8 for 2^24, 1 for ':', 3 for 2^8, 1 for '\0'
1293     char fsid[34];  // 2 * 16 for %llx, 1 for ':', 1 for '\0'
1294     struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1295 
1296     /* display header on line 1 */
1297     if (v == &nn->nfs_volume_list) {
1298         seq_puts(m, "NV SERVER   PORT DEV          FSID"
1299                 "                              FSC\n");
1300         return 0;
1301     }
1302     /* display one transport per line on subsequent lines */
1303     server = list_entry(v, struct nfs_server, master_link);
1304     clp = server->nfs_client;
1305 
1306     snprintf(dev, sizeof(dev), "%u:%u",
1307          MAJOR(server->s_dev), MINOR(server->s_dev));
1308 
1309     snprintf(fsid, sizeof(fsid), "%llx:%llx",
1310          (unsigned long long) server->fsid.major,
1311          (unsigned long long) server->fsid.minor);
1312 
1313     rcu_read_lock();
1314     seq_printf(m, "v%u %s %s %-12s %-33s %s\n",
1315            clp->rpc_ops->version,
1316            rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1317            rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1318            dev,
1319            fsid,
1320            nfs_server_fscache_state(server));
1321     rcu_read_unlock();
1322 
1323     return 0;
1324 }
1325 
1326 int nfs_fs_proc_net_init(struct net *net)
1327 {
1328     struct nfs_net *nn = net_generic(net, nfs_net_id);
1329     struct proc_dir_entry *p;
1330 
1331     nn->proc_nfsfs = proc_net_mkdir(net, "nfsfs", net->proc_net);
1332     if (!nn->proc_nfsfs)
1333         goto error_0;
1334 
1335     /* a file of servers with which we're dealing */
1336     p = proc_create_net("servers", S_IFREG|S_IRUGO, nn->proc_nfsfs,
1337             &nfs_server_list_ops, sizeof(struct seq_net_private));
1338     if (!p)
1339         goto error_1;
1340 
1341     /* a file of volumes that we have mounted */
1342     p = proc_create_net("volumes", S_IFREG|S_IRUGO, nn->proc_nfsfs,
1343             &nfs_volume_list_ops, sizeof(struct seq_net_private));
1344     if (!p)
1345         goto error_1;
1346     return 0;
1347 
1348 error_1:
1349     remove_proc_subtree("nfsfs", net->proc_net);
1350 error_0:
1351     return -ENOMEM;
1352 }
1353 
1354 void nfs_fs_proc_net_exit(struct net *net)
1355 {
1356     remove_proc_subtree("nfsfs", net->proc_net);
1357 }
1358 
1359 /*
1360  * initialise the /proc/fs/nfsfs/ directory
1361  */
1362 int __init nfs_fs_proc_init(void)
1363 {
1364     if (!proc_mkdir("fs/nfsfs", NULL))
1365         goto error_0;
1366 
1367     /* a file of servers with which we're dealing */
1368     if (!proc_symlink("fs/nfsfs/servers", NULL, "../../net/nfsfs/servers"))
1369         goto error_1;
1370 
1371     /* a file of volumes that we have mounted */
1372     if (!proc_symlink("fs/nfsfs/volumes", NULL, "../../net/nfsfs/volumes"))
1373         goto error_1;
1374 
1375     return 0;
1376 error_1:
1377     remove_proc_subtree("fs/nfsfs", NULL);
1378 error_0:
1379     return -ENOMEM;
1380 }
1381 
1382 /*
1383  * clean up the /proc/fs/nfsfs/ directory
1384  */
1385 void nfs_fs_proc_exit(void)
1386 {
1387     remove_proc_subtree("fs/nfsfs", NULL);
1388 }
1389 
1390 #endif /* CONFIG_PROC_FS */