diff options
Diffstat (limited to 'fs/nfsd/nfsfh.c')
-rw-r--r-- | fs/nfsd/nfsfh.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 6ca2d24fc216..0eb464a39aae 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -15,10 +15,12 @@ | |||
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/stat.h> | 16 | #include <linux/stat.h> |
17 | #include <linux/dcache.h> | 17 | #include <linux/dcache.h> |
18 | #include <linux/exportfs.h> | ||
18 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
19 | 20 | ||
20 | #include <linux/sunrpc/clnt.h> | 21 | #include <linux/sunrpc/clnt.h> |
21 | #include <linux/sunrpc/svc.h> | 22 | #include <linux/sunrpc/svc.h> |
23 | #include <linux/sunrpc/svcauth_gss.h> | ||
22 | #include <linux/nfsd/nfsd.h> | 24 | #include <linux/nfsd/nfsd.h> |
23 | 25 | ||
24 | #define NFSDDBG_FACILITY NFSDDBG_FH | 26 | #define NFSDDBG_FACILITY NFSDDBG_FH |
@@ -27,10 +29,6 @@ | |||
27 | static int nfsd_nr_verified; | 29 | static int nfsd_nr_verified; |
28 | static int nfsd_nr_put; | 30 | static int nfsd_nr_put; |
29 | 31 | ||
30 | extern struct export_operations export_op_default; | ||
31 | |||
32 | #define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun) | ||
33 | |||
34 | /* | 32 | /* |
35 | * our acceptability function. | 33 | * our acceptability function. |
36 | * if NOSUBTREECHECK, accept anything | 34 | * if NOSUBTREECHECK, accept anything |
@@ -123,8 +121,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
123 | int data_left = fh->fh_size/4; | 121 | int data_left = fh->fh_size/4; |
124 | 122 | ||
125 | error = nfserr_stale; | 123 | error = nfserr_stale; |
126 | if (rqstp->rq_client == NULL) | ||
127 | goto out; | ||
128 | if (rqstp->rq_vers > 2) | 124 | if (rqstp->rq_vers > 2) |
129 | error = nfserr_badhandle; | 125 | error = nfserr_badhandle; |
130 | if (rqstp->rq_vers == 4 && fh->fh_size == 0) | 126 | if (rqstp->rq_vers == 4 && fh->fh_size == 0) |
@@ -148,7 +144,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
148 | fh->fh_fsid[1] = fh->fh_fsid[2]; | 144 | fh->fh_fsid[1] = fh->fh_fsid[2]; |
149 | } | 145 | } |
150 | if ((data_left -= len)<0) goto out; | 146 | if ((data_left -= len)<0) goto out; |
151 | exp = exp_find(rqstp->rq_client, fh->fh_fsid_type, datap, &rqstp->rq_chandle); | 147 | exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap); |
152 | datap += len; | 148 | datap += len; |
153 | } else { | 149 | } else { |
154 | dev_t xdev; | 150 | dev_t xdev; |
@@ -159,19 +155,17 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
159 | xdev = old_decode_dev(fh->ofh_xdev); | 155 | xdev = old_decode_dev(fh->ofh_xdev); |
160 | xino = u32_to_ino_t(fh->ofh_xino); | 156 | xino = u32_to_ino_t(fh->ofh_xino); |
161 | mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL); | 157 | mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL); |
162 | exp = exp_find(rqstp->rq_client, FSID_DEV, tfh, | 158 | exp = rqst_exp_find(rqstp, FSID_DEV, tfh); |
163 | &rqstp->rq_chandle); | ||
164 | } | 159 | } |
165 | 160 | ||
166 | if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN | 161 | error = nfserr_stale; |
167 | || PTR_ERR(exp) == -ETIMEDOUT)) { | 162 | if (PTR_ERR(exp) == -ENOENT) |
168 | error = nfserrno(PTR_ERR(exp)); | ||
169 | goto out; | 163 | goto out; |
170 | } | ||
171 | 164 | ||
172 | error = nfserr_stale; | 165 | if (IS_ERR(exp)) { |
173 | if (!exp || IS_ERR(exp)) | 166 | error = nfserrno(PTR_ERR(exp)); |
174 | goto out; | 167 | goto out; |
168 | } | ||
175 | 169 | ||
176 | /* Check if the request originated from a secure port. */ | 170 | /* Check if the request originated from a secure port. */ |
177 | error = nfserr_perm; | 171 | error = nfserr_perm; |
@@ -211,11 +205,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
211 | if (fileid_type == 0) | 205 | if (fileid_type == 0) |
212 | dentry = dget(exp->ex_dentry); | 206 | dentry = dget(exp->ex_dentry); |
213 | else { | 207 | else { |
214 | struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; | 208 | dentry = exportfs_decode_fh(exp->ex_mnt, datap, |
215 | dentry = CALL(nop,decode_fh)(exp->ex_mnt->mnt_sb, | 209 | data_left, fileid_type, |
216 | datap, data_left, | 210 | nfsd_acceptable, exp); |
217 | fileid_type, | ||
218 | nfsd_acceptable, exp); | ||
219 | } | 211 | } |
220 | if (dentry == NULL) | 212 | if (dentry == NULL) |
221 | goto out; | 213 | goto out; |
@@ -257,8 +249,19 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
257 | if (error) | 249 | if (error) |
258 | goto out; | 250 | goto out; |
259 | 251 | ||
252 | if (!(access & MAY_LOCK)) { | ||
253 | /* | ||
254 | * pseudoflavor restrictions are not enforced on NLM, | ||
255 | * which clients virtually always use auth_sys for, | ||
256 | * even while using RPCSEC_GSS for NFS. | ||
257 | */ | ||
258 | error = check_nfsd_access(exp, rqstp); | ||
259 | if (error) | ||
260 | goto out; | ||
261 | } | ||
262 | |||
260 | /* Finally, check access permissions. */ | 263 | /* Finally, check access permissions. */ |
261 | error = nfsd_permission(exp, dentry, access); | 264 | error = nfsd_permission(rqstp, exp, dentry, access); |
262 | 265 | ||
263 | if (error) { | 266 | if (error) { |
264 | dprintk("fh_verify: %s/%s permission failure, " | 267 | dprintk("fh_verify: %s/%s permission failure, " |
@@ -286,15 +289,13 @@ out: | |||
286 | static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, | 289 | static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, |
287 | __u32 *datap, int *maxsize) | 290 | __u32 *datap, int *maxsize) |
288 | { | 291 | { |
289 | struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; | ||
290 | |||
291 | if (dentry == exp->ex_dentry) { | 292 | if (dentry == exp->ex_dentry) { |
292 | *maxsize = 0; | 293 | *maxsize = 0; |
293 | return 0; | 294 | return 0; |
294 | } | 295 | } |
295 | 296 | ||
296 | return CALL(nop,encode_fh)(dentry, datap, maxsize, | 297 | return exportfs_encode_fh(dentry, datap, maxsize, |
297 | !(exp->ex_flags&NFSEXP_NOSUBTREECHECK)); | 298 | !(exp->ex_flags & NFSEXP_NOSUBTREECHECK)); |
298 | } | 299 | } |
299 | 300 | ||
300 | /* | 301 | /* |