From: "Kirill A. Shutemov" Subject: Re: [PATCH 11/12] nfs: introduce mount option 'rpcmount' Date: Mon, 20 Dec 2010 16:38:19 +0200 Message-ID: <20101220143818.GA428@shutemov.name> References: <1292846078-31793-1-git-send-email-kirill@shutemov.name> <1292846078-31793-12-git-send-email-kirill@shutemov.name> <20101220143703.GB20643@fieldses.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Trond Myklebust , Neil Brown , Pavel Emelyanov , linux-nfs@vger.kernel.org, "David S. Miller" , netdev@vger.kernel.org, linux-kernel@vger.kernel.org To: "J. Bruce Fields" Return-path: In-Reply-To: <20101220143703.GB20643@fieldses.org> Sender: netdev-owner@vger.kernel.org List-ID: On Mon, Dec 20, 2010 at 09:37:03AM -0500, J. Bruce Fields wrote: > On Mon, Dec 20, 2010 at 01:54:37PM +0200, Kirill A. Shutsemov wrote: > > From: Kirill A. Shutemov > > > > It specifies rpc_pipefs to use. init_rpc_pipefs, by default. > > You also need to export get_rpc_pipefs() for the nfs module to use. Oh, sure. Thanks. > > --b. > > > > > Signed-off-by: Kirill A. Shutemov > > --- > > fs/nfs/callback.c | 6 ++-- > > fs/nfs/callback.h | 3 +- > > fs/nfs/client.c | 46 ++++++++++++++++++++++++++++++++++++-------- > > fs/nfs/internal.h | 10 +++++++- > > fs/nfs/mount_clnt.c | 3 +- > > fs/nfs/namespace.c | 3 +- > > fs/nfs/nfs4namespace.c | 22 +++++++++++--------- > > fs/nfs/super.c | 20 +++++++++++++++++++ > > include/linux/nfs_fs_sb.h | 1 + > > 9 files changed, 86 insertions(+), 28 deletions(-) > > > > diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c > > index bef6abd..ef6d206 100644 > > --- a/fs/nfs/callback.c > > +++ b/fs/nfs/callback.c > > @@ -16,7 +16,6 @@ > > #include > > #include > > #include > > -#include > > #if defined(CONFIG_NFS_V4_1) > > #include > > #endif > > @@ -239,7 +238,8 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, > > /* > > * Bring up the callback thread if it is not already up. > > */ > > -int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) > > +int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt, > > + struct vfsmount *rpcmount) > > { > > struct svc_serv *serv = NULL; > > struct svc_rqst *rqstp; > > @@ -254,7 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) > > nfs_callback_bc_serv(minorversion, xprt, cb_info); > > goto out; > > } > > - serv = svc_create(&nfs4_callback_program, init_rpc_pipefs, > > + serv = svc_create(&nfs4_callback_program, rpcmount, > > NFS4_CALLBACK_BUFSIZE, NULL); > > if (!serv) { > > ret = -ENOMEM; > > diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h > > index 85a7cfd..ae27385 100644 > > --- a/fs/nfs/callback.h > > +++ b/fs/nfs/callback.h > > @@ -133,7 +133,8 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getat > > extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy); > > > > #ifdef CONFIG_NFS_V4 > > -extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); > > +extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt, > > + struct vfsmount *rpcmount); > > extern void nfs_callback_down(int minorversion); > > extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, > > const nfs4_stateid *stateid); > > diff --git a/fs/nfs/client.c b/fs/nfs/client.c > > index fbc013d..ccc400a 100644 > > --- a/fs/nfs/client.c > > +++ b/fs/nfs/client.c > > @@ -107,6 +107,7 @@ struct nfs_client_initdata { > > const struct nfs_rpc_ops *rpc_ops; > > int proto; > > u32 minorversion; > > + struct vfsmount *rpcmount; > > }; > > > > /* > > @@ -143,6 +144,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ > > clp->cl_rpcclient = ERR_PTR(-EINVAL); > > > > clp->cl_proto = cl_init->proto; > > + clp->cl_rpcmount = mntget(cl_init->rpcmount); > > > > #ifdef CONFIG_NFS_V4 > > INIT_LIST_HEAD(&clp->cl_delegations); > > @@ -231,6 +233,7 @@ static void nfs_free_client(struct nfs_client *clp) > > if (clp->cl_machine_cred != NULL) > > put_rpccred(clp->cl_machine_cred); > > > > + mntput(clp->cl_rpcmount); > > kfree(clp->cl_hostname); > > kfree(clp); > > > > @@ -457,6 +460,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat > > /* Match the full socket address */ > > if (!nfs_sockaddr_cmp(sap, clap)) > > continue; > > + /* Match rpc_pipefs mount point */ > > + if (clp->cl_rpcmount->mnt_sb != data->rpcmount->mnt_sb) > > + continue; > > > > atomic_inc(&clp->cl_count); > > return clp; > > @@ -615,7 +621,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, > > .program = &nfs_program, > > .version = clp->rpc_ops->version, > > .authflavor = flavor, > > - .rpcmount = init_rpc_pipefs, > > + .rpcmount = clp->cl_rpcmount, > > }; > > > > if (discrtry) > > @@ -650,7 +656,7 @@ static void nfs_destroy_server(struct nfs_server *server) > > /* > > * Version 2 or 3 lockd setup > > */ > > -static int nfs_start_lockd(struct nfs_server *server) > > +static int nfs_start_lockd(struct nfs_server *server, struct vfsmount *rpcmount) > > { > > struct nlm_host *host; > > struct nfs_client *clp = server->nfs_client; > > @@ -661,7 +667,7 @@ static int nfs_start_lockd(struct nfs_server *server) > > .nfs_version = clp->rpc_ops->version, > > .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? > > 1 : 0, > > - .rpcmount = init_rpc_pipefs, > > + .rpcmount = rpcmount, > > }; > > > > if (nlm_init.nfs_version > 3) > > @@ -809,8 +815,16 @@ static int nfs_init_server(struct nfs_server *server, > > cl_init.rpc_ops = &nfs_v3_clientops; > > #endif > > > > + cl_init.rpcmount = get_rpc_pipefs(data->rpcmount); > > + if (IS_ERR(cl_init.rpcmount)) { > > + dprintk("<-- nfs_init_server() = error %ld\n", > > + PTR_ERR(cl_init.rpcmount)); > > + return PTR_ERR(cl_init.rpcmount); > > + } > > + > > /* Allocate or find a client reference we can use */ > > clp = nfs_get_client(&cl_init); > > + mntput(cl_init.rpcmount); > > if (IS_ERR(clp)) { > > dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); > > return PTR_ERR(clp); > > @@ -842,7 +856,7 @@ static int nfs_init_server(struct nfs_server *server, > > server->acdirmax = data->acdirmax * HZ; > > > > /* Start lockd here, before we might error out */ > > - error = nfs_start_lockd(server); > > + error = nfs_start_lockd(server, clp->cl_rpcmount); > > if (error < 0) > > goto error; > > > > @@ -1144,7 +1158,8 @@ static int nfs4_init_callback(struct nfs_client *clp) > > } > > > > error = nfs_callback_up(clp->cl_mvops->minor_version, > > - clp->cl_rpcclient->cl_xprt); > > + clp->cl_rpcclient->cl_xprt, > > + clp->cl_rpcmount); > > if (error < 0) { > > dprintk("%s: failed to start callback. Error = %d\n", > > __func__, error); > > @@ -1244,7 +1259,8 @@ static int nfs4_set_client(struct nfs_server *server, > > const char *ip_addr, > > rpc_authflavor_t authflavour, > > int proto, const struct rpc_timeout *timeparms, > > - u32 minorversion) > > + u32 minorversion, > > + struct vfsmount *rpcmount) > > { > > struct nfs_client_initdata cl_init = { > > .hostname = hostname, > > @@ -1253,6 +1269,7 @@ static int nfs4_set_client(struct nfs_server *server, > > .rpc_ops = &nfs_v4_clientops, > > .proto = proto, > > .minorversion = minorversion, > > + .rpcmount = rpcmount, > > }; > > struct nfs_client *clp; > > int error; > > @@ -1363,6 +1380,7 @@ static int nfs4_init_server(struct nfs_server *server, > > const struct nfs_parsed_mount_data *data) > > { > > struct rpc_timeout timeparms; > > + struct vfsmount *rpcmount; > > int error; > > > > dprintk("--> nfs4_init_server()\n"); > > @@ -1377,6 +1395,11 @@ static int nfs4_init_server(struct nfs_server *server, > > server->caps |= NFS_CAP_READDIRPLUS; > > server->options = data->options; > > > > + rpcmount = get_rpc_pipefs(data->rpcmount); > > + if (IS_ERR(rpcmount)) { > > + error = PTR_ERR(rpcmount); > > + goto error; > > + } > > /* Get a client record */ > > error = nfs4_set_client(server, > > data->nfs_server.hostname, > > @@ -1386,7 +1409,9 @@ static int nfs4_init_server(struct nfs_server *server, > > data->auth_flavors[0], > > data->nfs_server.protocol, > > &timeparms, > > - data->minorversion); > > + data->minorversion, > > + rpcmount); > > + mntput(rpcmount); > > if (error < 0) > > goto error; > > > > @@ -1476,7 +1501,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, > > data->authflavor, > > parent_server->client->cl_xprt->prot, > > parent_server->client->cl_timeout, > > - parent_client->cl_mvops->minor_version); > > + parent_client->cl_mvops->minor_version, > > + parent_client->cl_rpcmount); > > + > > + > > if (error < 0) > > goto error; > > > > @@ -1550,7 +1578,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, > > (unsigned long long) server->fsid.major, > > (unsigned long long) server->fsid.minor); > > > > - error = nfs_start_lockd(server); > > + error = nfs_start_lockd(server, server->nfs_client->cl_rpcmount); > > if (error < 0) > > goto out_free_server; > > > > diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h > > index e6356b7..cb31fd9 100644 > > --- a/fs/nfs/internal.h > > +++ b/fs/nfs/internal.h > > @@ -86,6 +86,7 @@ struct nfs_parsed_mount_data { > > unsigned int version; > > unsigned int minorversion; > > char *fscache_uniq; > > + char *rpcmount; > > > > struct { > > struct sockaddr_storage address; > > @@ -120,6 +121,7 @@ struct nfs_mount_request { > > int noresvport; > > unsigned int *auth_flav_len; > > rpc_authflavor_t *auth_flavs; > > + struct vfsmount *rpcmount; > > }; > > > > extern int nfs_mount(struct nfs_mount_request *info); > > @@ -160,10 +162,14 @@ static inline void nfs_fs_proc_exit(void) > > > > /* nfs4namespace.c */ > > #ifdef CONFIG_NFS_V4 > > -extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); > > +extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, > > + struct dentry *dentry, > > + struct vfsmount *rpcmount); > > #else > > static inline > > -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) > > +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, > > + struct dentry *dentry, > > + struct vfsmount *rpcmount) > > { > > return ERR_PTR(-ENOENT); > > } > > diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c > > index 67b4b8d..9fd4157 100644 > > --- a/fs/nfs/mount_clnt.c > > +++ b/fs/nfs/mount_clnt.c > > @@ -13,7 +13,6 @@ > > #include > > #include > > #include > > -#include > > #include > > #include "internal.h" > > > > @@ -162,7 +161,7 @@ int nfs_mount(struct nfs_mount_request *info) > > .program = &mnt_program, > > .version = info->version, > > .authflavor = RPC_AUTH_UNIX, > > - .rpcmount = init_rpc_pipefs, > > + .rpcmount = info->rpcmount, > > }; > > struct rpc_clnt *mnt_clnt; > > int status; > > diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c > > index db6aa36..d47f6f5 100644 > > --- a/fs/nfs/namespace.c > > +++ b/fs/nfs/namespace.c > > @@ -135,7 +135,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) > > goto out_err; > > > > if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) > > - mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry); > > + mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry, > > + server->nfs_client->cl_rpcmount); > > else > > mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh, > > fattr); > > diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c > > index 7a61fdb..92d5d63 100644 > > --- a/fs/nfs/nfs4namespace.c > > +++ b/fs/nfs/nfs4namespace.c > > @@ -14,7 +14,6 @@ > > #include > > #include > > #include > > -#include > > #include > > #include > > #include "internal.h" > > @@ -99,14 +98,13 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent, > > } > > > > static size_t nfs_parse_server_name(char *string, size_t len, > > - struct sockaddr *sa, size_t salen) > > + struct sockaddr *sa, size_t salen, struct vfsmount *rpcmount) > > { > > ssize_t ret; > > > > ret = rpc_pton(string, len, sa, salen); > > if (ret == 0) { > > - ret = nfs_dns_resolve_name(string, len, sa, salen, > > - init_rpc_pipefs); > > + ret = nfs_dns_resolve_name(string, len, sa, salen, rpcmount); > > if (ret < 0) > > ret = 0; > > } > > @@ -115,7 +113,8 @@ static size_t nfs_parse_server_name(char *string, size_t len, > > > > static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, > > char *page, char *page2, > > - const struct nfs4_fs_location *location) > > + const struct nfs4_fs_location *location, > > + struct vfsmount *rpcmount) > > { > > const size_t addr_bufsize = sizeof(struct sockaddr_storage); > > struct vfsmount *mnt = ERR_PTR(-ENOENT); > > @@ -143,7 +142,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, > > continue; > > > > mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, > > - mountdata->addr, addr_bufsize); > > + mountdata->addr, addr_bufsize, rpcmount); > > if (mountdata->addrlen == 0) > > continue; > > > > @@ -174,7 +173,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, > > */ > > static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, > > const struct dentry *dentry, > > - const struct nfs4_fs_locations *locations) > > + const struct nfs4_fs_locations *locations, > > + struct vfsmount *rpcmount) > > { > > struct vfsmount *mnt = ERR_PTR(-ENOENT); > > struct nfs_clone_mount mountdata = { > > @@ -213,7 +213,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, > > location->rootpath.ncomponents == 0) > > continue; > > > > - mnt = try_location(&mountdata, page, page2, location); > > + mnt = try_location(&mountdata, page, page2, location, rpcmount); > > if (!IS_ERR(mnt)) > > break; > > } > > @@ -231,7 +231,9 @@ out: > > * @dentry - dentry of referral > > * > > */ > > -struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) > > +struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, > > + struct dentry *dentry, > > + struct vfsmount *rpcmount) > > { > > struct vfsmount *mnt = ERR_PTR(-ENOMEM); > > struct dentry *parent; > > @@ -264,7 +266,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr > > fs_locations->fs_path.ncomponents <= 0) > > goto out_free; > > > > - mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations); > > + mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations, rpcmount); > > out_free: > > __free_page(page); > > kfree(fs_locations); > > diff --git a/fs/nfs/super.c b/fs/nfs/super.c > > index 4100630..32b7e35 100644 > > --- a/fs/nfs/super.c > > +++ b/fs/nfs/super.c > > @@ -35,6 +35,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -106,6 +107,7 @@ enum { > > Opt_lookupcache, > > Opt_fscache_uniq, > > Opt_local_lock, > > + Opt_rpcmount, > > > > /* Special mount options */ > > Opt_userspace, Opt_deprecated, Opt_sloppy, > > @@ -178,6 +180,7 @@ static const match_table_t nfs_mount_option_tokens = { > > { Opt_lookupcache, "lookupcache=%s" }, > > { Opt_fscache_uniq, "fsc=%s" }, > > { Opt_local_lock, "local_lock=%s" }, > > + { Opt_rpcmount, "rpcmount=%s" }, > > > > { Opt_err, NULL } > > }; > > @@ -1484,6 +1487,13 @@ static int nfs_parse_mount_options(char *raw, > > return 0; > > }; > > break; > > + case Opt_rpcmount: > > + string = match_strdup(args); > > + if (string == NULL) > > + goto out_nomem; > > + kfree(mnt->rpcmount); > > + mnt->rpcmount = string; > > + break; > > > > /* > > * Special options > > @@ -1644,11 +1654,19 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, > > request.salen = args->mount_server.addrlen; > > nfs_set_port(request.sap, &args->mount_server.port, 0); > > > > + request.rpcmount = get_rpc_pipefs(args->rpcmount); > > + if (IS_ERR(request.rpcmount)) { > > + dfprintk(MOUNT, "NFS: unable get rpc_pipefs mount point, " > > + "error %ld\n", PTR_ERR(request.rpcmount)); > > + return PTR_ERR(request.rpcmount); > > + } > > + > > /* > > * Now ask the mount server to map our export path > > * to a file handle. > > */ > > status = nfs_mount(&request); > > + mntput(request.rpcmount); > > if (status != 0) { > > dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", > > request.hostname, status); > > @@ -2352,6 +2370,7 @@ out: > > kfree(data->nfs_server.hostname); > > kfree(data->mount_server.hostname); > > kfree(data->fscache_uniq); > > + kfree(data->rpcmount); > > security_free_mnt_opts(&data->lsm_opts); > > out_free_fh: > > nfs_free_fhandle(mntfh); > > @@ -2947,6 +2966,7 @@ out: > > kfree(data->nfs_server.export_path); > > kfree(data->nfs_server.hostname); > > kfree(data->fscache_uniq); > > + kfree(data->rpcmount); > > out_free_data: > > kfree(data); > > dprintk("<-- nfs4_get_sb() = %d%s\n", error, > > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > > index 452d964..ee417c9 100644 > > --- a/include/linux/nfs_fs_sb.h > > +++ b/include/linux/nfs_fs_sb.h > > @@ -36,6 +36,7 @@ struct nfs_client { > > struct list_head cl_share_link; /* link in global client list */ > > struct list_head cl_superblocks; /* List of nfs_server structs */ > > > > + struct vfsmount *cl_rpcmount; /* rpc_pipefs mount point */ > > struct rpc_clnt * cl_rpcclient; > > const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ > > int cl_proto; /* Network transport protocol */ > > -- > > 1.7.3.4 > > -- Kirill A. Shutemov