diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-04-27 13:27:45 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:39 -0400 |
commit | 281cad46b34db4dbb1d1e603f7b9cfe25d1ae7c9 (patch) | |
tree | f13917030755776a4f80ffcc0d07c2b5da60066d /fs/nfs | |
parent | 2671bfc3beb44e70636bd0208274426db57f73b5 (diff) |
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>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/internal.h | 15 | ||||
-rw-r--r-- | fs/nfs/namespace.c | 75 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4namespace.c | 24 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 1 | ||||
-rw-r--r-- | fs/nfs/proc.c | 1 |
7 files changed, 52 insertions, 67 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index d6994443f285..0fd1efaf1cff 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -185,17 +185,6 @@ static inline void nfs_fs_proc_exit(void) | |||
185 | } | 185 | } |
186 | #endif | 186 | #endif |
187 | 187 | ||
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 | |||
199 | /* callback_xdr.c */ | 188 | /* callback_xdr.c */ |
200 | extern struct svc_version nfs4_callback_version1; | 189 | extern struct svc_version nfs4_callback_version1; |
201 | extern struct svc_version nfs4_callback_version4; | 190 | extern struct svc_version nfs4_callback_version4; |
@@ -286,6 +275,10 @@ extern void nfs_sb_deactive(struct super_block *sb); | |||
286 | extern char *nfs_path(char **p, struct dentry *dentry, | 275 | extern char *nfs_path(char **p, struct dentry *dentry, |
287 | char *buffer, ssize_t buflen); | 276 | char *buffer, ssize_t buflen); |
288 | extern struct vfsmount *nfs_d_automount(struct path *path); | 277 | 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); | ||
289 | 282 | ||
290 | /* getroot.c */ | 283 | /* getroot.c */ |
291 | extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, | 284 | extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, |
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 2a9591b0b150..e36fd8a51819 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -26,11 +26,6 @@ static LIST_HEAD(nfs_automount_list); | |||
26 | static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); | 26 | static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); |
27 | int nfs_mountpoint_expiry_timeout = 500 * HZ; | 27 | int nfs_mountpoint_expiry_timeout = 500 * HZ; |
28 | 28 | ||
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 | |||
34 | /* | 29 | /* |
35 | * nfs_path - reconstruct the path given an arbitrary dentry | 30 | * nfs_path - reconstruct the path given an arbitrary dentry |
36 | * @base - used to return pointer to the end of devname part of path | 31 | * @base - used to return pointer to the end of devname part of path |
@@ -118,35 +113,6 @@ Elong: | |||
118 | return ERR_PTR(-ENAMETOOLONG); | 113 | return ERR_PTR(-ENAMETOOLONG); |
119 | } | 114 | } |
120 | 115 | ||
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 | |||
150 | /* | 116 | /* |
151 | * nfs_d_automount - Handle crossing a mountpoint on the server | 117 | * nfs_d_automount - Handle crossing a mountpoint on the server |
152 | * @path - The mountpoint | 118 | * @path - The mountpoint |
@@ -162,10 +128,9 @@ static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, | |||
162 | struct vfsmount *nfs_d_automount(struct path *path) | 128 | struct vfsmount *nfs_d_automount(struct path *path) |
163 | { | 129 | { |
164 | struct vfsmount *mnt; | 130 | struct vfsmount *mnt; |
165 | struct dentry *parent; | 131 | struct nfs_server *server = NFS_SERVER(path->dentry->d_inode); |
166 | struct nfs_fh *fh = NULL; | 132 | struct nfs_fh *fh = NULL; |
167 | struct nfs_fattr *fattr = NULL; | 133 | struct nfs_fattr *fattr = NULL; |
168 | struct rpc_clnt *client; | ||
169 | 134 | ||
170 | dprintk("--> nfs_d_automount()\n"); | 135 | dprintk("--> nfs_d_automount()\n"); |
171 | 136 | ||
@@ -181,21 +146,7 @@ struct vfsmount *nfs_d_automount(struct path *path) | |||
181 | 146 | ||
182 | dprintk("%s: enter\n", __func__); | 147 | dprintk("%s: enter\n", __func__); |
183 | 148 | ||
184 | /* Look it up again to get its attributes */ | 149 | mnt = server->nfs_client->rpc_ops->submount(server, path->dentry, fh, fattr); |
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 | |||
199 | if (IS_ERR(mnt)) | 150 | if (IS_ERR(mnt)) |
200 | goto out; | 151 | goto out; |
201 | 152 | ||
@@ -268,10 +219,8 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, | |||
268 | * @authflavor - security flavor to use when performing the mount | 219 | * @authflavor - security flavor to use when performing the mount |
269 | * | 220 | * |
270 | */ | 221 | */ |
271 | static struct vfsmount *nfs_do_submount(struct dentry *dentry, | 222 | struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, |
272 | struct nfs_fh *fh, | 223 | struct nfs_fattr *fattr, rpc_authflavor_t authflavor) |
273 | struct nfs_fattr *fattr, | ||
274 | rpc_authflavor_t authflavor) | ||
275 | { | 224 | { |
276 | struct nfs_clone_mount mountdata = { | 225 | struct nfs_clone_mount mountdata = { |
277 | .sb = dentry->d_sb, | 226 | .sb = dentry->d_sb, |
@@ -304,3 +253,19 @@ out: | |||
304 | dprintk("<-- nfs_do_submount() = %p\n", mnt); | 253 | dprintk("<-- nfs_do_submount() = %p\n", mnt); |
305 | return mnt; | 254 | return mnt; |
306 | } | 255 | } |
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 | } | ||
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 56dcefc2f3f7..c23214d55ecf 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -885,6 +885,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = { | |||
885 | .file_inode_ops = &nfs3_file_inode_operations, | 885 | .file_inode_ops = &nfs3_file_inode_operations, |
886 | .file_ops = &nfs_file_operations, | 886 | .file_ops = &nfs_file_operations, |
887 | .getroot = nfs3_proc_get_root, | 887 | .getroot = nfs3_proc_get_root, |
888 | .submount = nfs_submount, | ||
888 | .getattr = nfs3_proc_getattr, | 889 | .getattr = nfs3_proc_getattr, |
889 | .setattr = nfs3_proc_setattr, | 890 | .setattr = nfs3_proc_setattr, |
890 | .lookup = nfs3_proc_lookup, | 891 | .lookup = nfs3_proc_lookup, |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 53a487ee9867..97365b0f9d3f 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -208,6 +208,8 @@ extern const struct inode_operations nfs4_dir_inode_operations; | |||
208 | /* nfs4namespace.c */ | 208 | /* nfs4namespace.c */ |
209 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); | 209 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); |
210 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); | 210 | 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 *); | ||
211 | 213 | ||
212 | /* nfs4proc.c */ | 214 | /* nfs4proc.c */ |
213 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); | 215 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index a69ee3952bbe..80fc0fe7095e 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -329,7 +329,7 @@ out: | |||
329 | * @dentry - dentry of referral | 329 | * @dentry - dentry of referral |
330 | * | 330 | * |
331 | */ | 331 | */ |
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) |
333 | { | 333 | { |
334 | struct vfsmount *mnt = ERR_PTR(-ENOMEM); | 334 | struct vfsmount *mnt = ERR_PTR(-ENOMEM); |
335 | struct dentry *parent; | 335 | struct dentry *parent; |
@@ -370,3 +370,25 @@ out: | |||
370 | dprintk("%s: done\n", __func__); | 370 | dprintk("%s: done\n", __func__); |
371 | return mnt; | 371 | return mnt; |
372 | } | 372 | } |
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 | } | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fa661b91e57c..2091af294c61 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -6571,6 +6571,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
6571 | .file_inode_ops = &nfs4_file_inode_operations, | 6571 | .file_inode_ops = &nfs4_file_inode_operations, |
6572 | .file_ops = &nfs4_file_operations, | 6572 | .file_ops = &nfs4_file_operations, |
6573 | .getroot = nfs4_proc_get_root, | 6573 | .getroot = nfs4_proc_get_root, |
6574 | .submount = nfs4_submount, | ||
6574 | .getattr = nfs4_proc_getattr, | 6575 | .getattr = nfs4_proc_getattr, |
6575 | .setattr = nfs4_proc_setattr, | 6576 | .setattr = nfs4_proc_setattr, |
6576 | .lookup = nfs4_proc_lookup, | 6577 | .lookup = nfs4_proc_lookup, |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 22ee70586875..76b3229fc527 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -742,6 +742,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = { | |||
742 | .file_inode_ops = &nfs_file_inode_operations, | 742 | .file_inode_ops = &nfs_file_inode_operations, |
743 | .file_ops = &nfs_file_operations, | 743 | .file_ops = &nfs_file_operations, |
744 | .getroot = nfs_proc_get_root, | 744 | .getroot = nfs_proc_get_root, |
745 | .submount = nfs_submount, | ||
745 | .getattr = nfs_proc_getattr, | 746 | .getattr = nfs_proc_getattr, |
746 | .setattr = nfs_proc_setattr, | 747 | .setattr = nfs_proc_setattr, |
747 | .lookup = nfs_proc_lookup, | 748 | .lookup = nfs_proc_lookup, |