aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMi Jinlong <mijinlong@cn.fujitsu.com>2011-04-20 05:06:25 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-04-29 20:47:52 -0400
commitac6721a13e5b1a90728e790600f827a5e5f5da2f (patch)
treef39f1faaaa4059956d8fde5fbb29fc5500d1e513
parent68d93184352f2e723f135b0a9bad93b58f9d120b (diff)
nfsd41: make sure nfs server process OPEN with EXCLUSIVE4_1 correctly
The NFS server uses nfsd_create_v3 to handle EXCLUSIVE4_1 opens, but that function is not prepared to handle them. Rename nfsd_create_v3() to do_nfsd_create(), and add handling of EXCLUSIVE4_1. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs3proc.c2
-rw-r--r--fs/nfsd/nfs4proc.c4
-rw-r--r--fs/nfsd/vfs.c20
-rw-r--r--fs/nfsd/vfs.h2
4 files changed, 20 insertions, 8 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 2247fc91d5e9..9095f3c21df9 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
245 } 245 }
246 246
247 /* Now create the file and set attributes */ 247 /* Now create the file and set attributes */
248 nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, 248 nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len,
249 attr, newfhp, 249 attr, newfhp,
250 argp->createmode, argp->verf, NULL, NULL); 250 argp->createmode, argp->verf, NULL, NULL);
251 251
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index ad32568a1aa7..3a6dbd70b34b 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
196 196
197 /* 197 /*
198 * Note: create modes (UNCHECKED,GUARDED...) are the same 198 * Note: create modes (UNCHECKED,GUARDED...) are the same
199 * in NFSv4 as in v3. 199 * in NFSv4 as in v3 except EXCLUSIVE4_1.
200 */ 200 */
201 status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, 201 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
202 open->op_fname.len, &open->op_iattr, 202 open->op_fname.len, &open->op_iattr,
203 &resfh, open->op_createmode, 203 &resfh, open->op_createmode,
204 (u32 *)open->op_verf.data, 204 (u32 *)open->op_verf.data,
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index e53313972c30..389e45ad200b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1337,11 +1337,18 @@ out_nfserr:
1337} 1337}
1338 1338
1339#ifdef CONFIG_NFSD_V3 1339#ifdef CONFIG_NFSD_V3
1340
1341static inline int nfsd_create_is_exclusive(int createmode)
1342{
1343 return createmode == NFS3_CREATE_EXCLUSIVE
1344 || createmode == NFS4_CREATE_EXCLUSIVE4_1;
1345}
1346
1340/* 1347/*
1341 * NFSv3 version of nfsd_create 1348 * NFSv3 and NFSv4 version of nfsd_create
1342 */ 1349 */
1343__be32 1350__be32
1344nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, 1351do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1345 char *fname, int flen, struct iattr *iap, 1352 char *fname, int flen, struct iattr *iap,
1346 struct svc_fh *resfhp, int createmode, u32 *verifier, 1353 struct svc_fh *resfhp, int createmode, u32 *verifier,
1347 int *truncp, int *created) 1354 int *truncp, int *created)
@@ -1386,7 +1393,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1386 if (err) 1393 if (err)
1387 goto out; 1394 goto out;
1388 1395
1389 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1396 if (nfsd_create_is_exclusive(createmode)) {
1390 /* solaris7 gets confused (bugid 4218508) if these have 1397 /* solaris7 gets confused (bugid 4218508) if these have
1391 * the high bit set, so just clear the high bits. If this is 1398 * the high bit set, so just clear the high bits. If this is
1392 * ever changed to use different attrs for storing the 1399 * ever changed to use different attrs for storing the
@@ -1427,6 +1434,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1427 && dchild->d_inode->i_atime.tv_sec == v_atime 1434 && dchild->d_inode->i_atime.tv_sec == v_atime
1428 && dchild->d_inode->i_size == 0 ) 1435 && dchild->d_inode->i_size == 0 )
1429 break; 1436 break;
1437 case NFS4_CREATE_EXCLUSIVE4_1:
1438 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
1439 && dchild->d_inode->i_atime.tv_sec == v_atime
1440 && dchild->d_inode->i_size == 0 )
1441 goto set_attr;
1430 /* fallthru */ 1442 /* fallthru */
1431 case NFS3_CREATE_GUARDED: 1443 case NFS3_CREATE_GUARDED:
1432 err = nfserr_exist; 1444 err = nfserr_exist;
@@ -1445,7 +1457,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1445 1457
1446 nfsd_check_ignore_resizing(iap); 1458 nfsd_check_ignore_resizing(iap);
1447 1459
1448 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1460 if (nfsd_create_is_exclusive(createmode)) {
1449 /* Cram the verifier into atime/mtime */ 1461 /* Cram the verifier into atime/mtime */
1450 iap->ia_valid = ATTR_MTIME|ATTR_ATIME 1462 iap->ia_valid = ATTR_MTIME|ATTR_ATIME
1451 | ATTR_MTIME_SET|ATTR_ATIME_SET; 1463 | ATTR_MTIME_SET|ATTR_ATIME_SET;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 4d2509f766d4..e0bbac04d1dd 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -58,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
58 int type, dev_t rdev, struct svc_fh *res); 58 int type, dev_t rdev, struct svc_fh *res);
59#ifdef CONFIG_NFSD_V3 59#ifdef CONFIG_NFSD_V3
60__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); 60__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
61__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, 61__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *,
62 char *name, int len, struct iattr *attrs, 62 char *name, int len, struct iattr *attrs,
63 struct svc_fh *res, int createmode, 63 struct svc_fh *res, int createmode,
64 u32 *verifier, int *truncp, int *created); 64 u32 *verifier, int *truncp, int *created);