diff options
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 65043af232ee..627f460a4007 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -135,21 +135,10 @@ out: | |||
135 | return err; | 135 | return err; |
136 | } | 136 | } |
137 | 137 | ||
138 | /* | ||
139 | * Look up one component of a pathname. | ||
140 | * N.B. After this call _both_ fhp and resfh need an fh_put | ||
141 | * | ||
142 | * If the lookup would cross a mountpoint, and the mounted filesystem | ||
143 | * is exported to the client with NFSEXP_NOHIDE, then the lookup is | ||
144 | * accepted as it stands and the mounted directory is | ||
145 | * returned. Otherwise the covered directory is returned. | ||
146 | * NOTE: this mountpoint crossing is not supported properly by all | ||
147 | * clients and is explicitly disallowed for NFSv3 | ||
148 | * NeilBrown <neilb@cse.unsw.edu.au> | ||
149 | */ | ||
150 | __be32 | 138 | __be32 |
151 | nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | 139 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, |
152 | int len, struct svc_fh *resfh) | 140 | const char *name, int len, |
141 | struct svc_export **exp_ret, struct dentry **dentry_ret) | ||
153 | { | 142 | { |
154 | struct svc_export *exp; | 143 | struct svc_export *exp; |
155 | struct dentry *dparent; | 144 | struct dentry *dparent; |
@@ -219,6 +208,38 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | |||
219 | } | 208 | } |
220 | } | 209 | } |
221 | } | 210 | } |
211 | *dentry_ret = dentry; | ||
212 | *exp_ret = exp; | ||
213 | return 0; | ||
214 | |||
215 | out_nfserr: | ||
216 | exp_put(exp); | ||
217 | return nfserrno(host_err); | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Look up one component of a pathname. | ||
222 | * N.B. After this call _both_ fhp and resfh need an fh_put | ||
223 | * | ||
224 | * If the lookup would cross a mountpoint, and the mounted filesystem | ||
225 | * is exported to the client with NFSEXP_NOHIDE, then the lookup is | ||
226 | * accepted as it stands and the mounted directory is | ||
227 | * returned. Otherwise the covered directory is returned. | ||
228 | * NOTE: this mountpoint crossing is not supported properly by all | ||
229 | * clients and is explicitly disallowed for NFSv3 | ||
230 | * NeilBrown <neilb@cse.unsw.edu.au> | ||
231 | */ | ||
232 | __be32 | ||
233 | nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | ||
234 | int len, struct svc_fh *resfh) | ||
235 | { | ||
236 | struct svc_export *exp; | ||
237 | struct dentry *dentry; | ||
238 | __be32 err; | ||
239 | |||
240 | err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); | ||
241 | if (err) | ||
242 | return err; | ||
222 | /* | 243 | /* |
223 | * Note: we compose the file handle now, but as the | 244 | * Note: we compose the file handle now, but as the |
224 | * dentry may be negative, it may need to be updated. | 245 | * dentry may be negative, it may need to be updated. |
@@ -227,15 +248,11 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | |||
227 | if (!err && !dentry->d_inode) | 248 | if (!err && !dentry->d_inode) |
228 | err = nfserr_noent; | 249 | err = nfserr_noent; |
229 | dput(dentry); | 250 | dput(dentry); |
230 | out: | ||
231 | exp_put(exp); | 251 | exp_put(exp); |
232 | return err; | 252 | return err; |
233 | |||
234 | out_nfserr: | ||
235 | err = nfserrno(host_err); | ||
236 | goto out; | ||
237 | } | 253 | } |
238 | 254 | ||
255 | |||
239 | /* | 256 | /* |
240 | * Set various file attributes. | 257 | * Set various file attributes. |
241 | * N.B. After this call fhp needs an fh_put | 258 | * N.B. After this call fhp needs an fh_put |