Skip to content

Commit 281cad4

Browse files
Bryan SchumakerTrond Myklebust
authored andcommitted
NFS: Create a submount rpc_op
This simplifies the code for v2 and v3 and gives v4 a chance to decide on referrals without needing to modify the generic client. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
1 parent 2671bfc commit 281cad4

File tree

8 files changed

+54
-67
lines changed

8 files changed

+54
-67
lines changed

fs/nfs/internal.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,6 @@ static inline void nfs_fs_proc_exit(void)
185185
}
186186
#endif
187187

188-
/* nfs4namespace.c */
189-
#ifdef CONFIG_NFS_V4
190-
extern struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry);
191-
#else
192-
static inline
193-
struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
194-
{
195-
return ERR_PTR(-ENOENT);
196-
}
197-
#endif
198-
199188
/* callback_xdr.c */
200189
extern struct svc_version nfs4_callback_version1;
201190
extern struct svc_version nfs4_callback_version4;
@@ -286,6 +275,10 @@ extern void nfs_sb_deactive(struct super_block *sb);
286275
extern char *nfs_path(char **p, struct dentry *dentry,
287276
char *buffer, ssize_t buflen);
288277
extern struct vfsmount *nfs_d_automount(struct path *path);
278+
struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
279+
struct nfs_fh *, struct nfs_fattr *);
280+
struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
281+
struct nfs_fattr *, rpc_authflavor_t);
289282

290283
/* getroot.c */
291284
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,

fs/nfs/namespace.c

Lines changed: 20 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ static LIST_HEAD(nfs_automount_list);
2626
static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts);
2727
int nfs_mountpoint_expiry_timeout = 500 * HZ;
2828

29-
static struct vfsmount *nfs_do_submount(struct dentry *dentry,
30-
struct nfs_fh *fh,
31-
struct nfs_fattr *fattr,
32-
rpc_authflavor_t authflavor);
33-
3429
/*
3530
* nfs_path - reconstruct the path given an arbitrary dentry
3631
* @base - used to return pointer to the end of devname part of path
@@ -118,35 +113,6 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
118113
return ERR_PTR(-ENAMETOOLONG);
119114
}
120115

121-
#ifdef CONFIG_NFS_V4
122-
static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
123-
struct qstr *name,
124-
struct nfs_fh *fh,
125-
struct nfs_fattr *fattr)
126-
{
127-
int err;
128-
129-
if (NFS_PROTO(dir)->version == 4)
130-
return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr);
131-
132-
err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
133-
if (err)
134-
return ERR_PTR(err);
135-
return rpc_clone_client(NFS_SERVER(dir)->client);
136-
}
137-
#else /* CONFIG_NFS_V4 */
138-
static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
139-
struct qstr *name,
140-
struct nfs_fh *fh,
141-
struct nfs_fattr *fattr)
142-
{
143-
int err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
144-
if (err)
145-
return ERR_PTR(err);
146-
return rpc_clone_client(NFS_SERVER(dir)->client);
147-
}
148-
#endif /* CONFIG_NFS_V4 */
149-
150116
/*
151117
* nfs_d_automount - Handle crossing a mountpoint on the server
152118
* @path - The mountpoint
@@ -162,10 +128,9 @@ static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
162128
struct vfsmount *nfs_d_automount(struct path *path)
163129
{
164130
struct vfsmount *mnt;
165-
struct dentry *parent;
131+
struct nfs_server *server = NFS_SERVER(path->dentry->d_inode);
166132
struct nfs_fh *fh = NULL;
167133
struct nfs_fattr *fattr = NULL;
168-
struct rpc_clnt *client;
169134

170135
dprintk("--> nfs_d_automount()\n");
171136

@@ -181,21 +146,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
181146

182147
dprintk("%s: enter\n", __func__);
183148

184-
/* Look it up again to get its attributes */
185-
parent = dget_parent(path->dentry);
186-
client = nfs_lookup_mountpoint(parent->d_inode, &path->dentry->d_name, fh, fattr);
187-
dput(parent);
188-
if (IS_ERR(client)) {
189-
mnt = ERR_CAST(client);
190-
goto out;
191-
}
192-
193-
if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
194-
mnt = nfs_do_refmount(client, path->dentry);
195-
else
196-
mnt = nfs_do_submount(path->dentry, fh, fattr, client->cl_auth->au_flavor);
197-
rpc_shutdown_client(client);
198-
149+
mnt = server->nfs_client->rpc_ops->submount(server, path->dentry, fh, fattr);
199150
if (IS_ERR(mnt))
200151
goto out;
201152

@@ -268,10 +219,8 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
268219
* @authflavor - security flavor to use when performing the mount
269220
*
270221
*/
271-
static struct vfsmount *nfs_do_submount(struct dentry *dentry,
272-
struct nfs_fh *fh,
273-
struct nfs_fattr *fattr,
274-
rpc_authflavor_t authflavor)
222+
struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh,
223+
struct nfs_fattr *fattr, rpc_authflavor_t authflavor)
275224
{
276225
struct nfs_clone_mount mountdata = {
277226
.sb = dentry->d_sb,
@@ -304,3 +253,19 @@ static struct vfsmount *nfs_do_submount(struct dentry *dentry,
304253
dprintk("<-- nfs_do_submount() = %p\n", mnt);
305254
return mnt;
306255
}
256+
257+
struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
258+
struct nfs_fh *fh, struct nfs_fattr *fattr)
259+
{
260+
int err;
261+
struct dentry *parent = dget_parent(dentry);
262+
263+
/* Look it up again to get its attributes */
264+
err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode,
265+
&dentry->d_name, fh, fattr);
266+
dput(parent);
267+
if (err != 0)
268+
return ERR_PTR(err);
269+
270+
return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor);
271+
}

fs/nfs/nfs3proc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
885885
.file_inode_ops = &nfs3_file_inode_operations,
886886
.file_ops = &nfs_file_operations,
887887
.getroot = nfs3_proc_get_root,
888+
.submount = nfs_submount,
888889
.getattr = nfs3_proc_getattr,
889890
.setattr = nfs3_proc_setattr,
890891
.lookup = nfs3_proc_lookup,

fs/nfs/nfs4_fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ extern const struct inode_operations nfs4_dir_inode_operations;
208208
/* nfs4namespace.c */
209209
rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
210210
struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
211+
struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
212+
struct nfs_fh *, struct nfs_fattr *);
211213

212214
/* nfs4proc.c */
213215
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);

fs/nfs/nfs4namespace.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static struct vfsmount *nfs_follow_referral(struct dentry *dentry,
329329
* @dentry - dentry of referral
330330
*
331331
*/
332-
struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
332+
static struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
333333
{
334334
struct vfsmount *mnt = ERR_PTR(-ENOMEM);
335335
struct dentry *parent;
@@ -370,3 +370,25 @@ struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
370370
dprintk("%s: done\n", __func__);
371371
return mnt;
372372
}
373+
374+
struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry,
375+
struct nfs_fh *fh, struct nfs_fattr *fattr)
376+
{
377+
struct dentry *parent = dget_parent(dentry);
378+
struct rpc_clnt *client;
379+
struct vfsmount *mnt;
380+
381+
/* Look it up again to get its attributes and sec flavor */
382+
client = nfs4_proc_lookup_mountpoint(parent->d_inode, &dentry->d_name, fh, fattr);
383+
dput(parent);
384+
if (IS_ERR(client))
385+
return ERR_CAST(client);
386+
387+
if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
388+
mnt = nfs_do_refmount(client, dentry);
389+
else
390+
mnt = nfs_do_submount(dentry, fh, fattr, client->cl_auth->au_flavor);
391+
392+
rpc_shutdown_client(client);
393+
return mnt;
394+
}

fs/nfs/nfs4proc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6571,6 +6571,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
65716571
.file_inode_ops = &nfs4_file_inode_operations,
65726572
.file_ops = &nfs4_file_operations,
65736573
.getroot = nfs4_proc_get_root,
6574+
.submount = nfs4_submount,
65746575
.getattr = nfs4_proc_getattr,
65756576
.setattr = nfs4_proc_setattr,
65766577
.lookup = nfs4_proc_lookup,

fs/nfs/proc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
742742
.file_inode_ops = &nfs_file_inode_operations,
743743
.file_ops = &nfs_file_operations,
744744
.getroot = nfs_proc_get_root,
745+
.submount = nfs_submount,
745746
.getattr = nfs_proc_getattr,
746747
.setattr = nfs_proc_setattr,
747748
.lookup = nfs_proc_lookup,

include/linux/nfs_xdr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,8 @@ struct nfs_rpc_ops {
13411341

13421342
int (*getroot) (struct nfs_server *, struct nfs_fh *,
13431343
struct nfs_fsinfo *);
1344+
struct vfsmount *(*submount) (struct nfs_server *, struct dentry *,
1345+
struct nfs_fh *, struct nfs_fattr *);
13441346
int (*getattr) (struct nfs_server *, struct nfs_fh *,
13451347
struct nfs_fattr *);
13461348
int (*setattr) (struct dentry *, struct nfs_fattr *,

0 commit comments

Comments
 (0)