aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsfh.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsfh.c')
-rw-r--r--fs/nfsd/nfsfh.c51
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 @@
27static int nfsd_nr_verified; 29static int nfsd_nr_verified;
28static int nfsd_nr_put; 30static int nfsd_nr_put;
29 31
30extern 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:
286static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, 289static 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/*