diff options
author | Mi Jinlong <mijinlong@cn.fujitsu.com> | 2011-04-20 05:06:25 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-04-29 20:47:52 -0400 |
commit | ac6721a13e5b1a90728e790600f827a5e5f5da2f (patch) | |
tree | f39f1faaaa4059956d8fde5fbb29fc5500d1e513 /fs/nfsd/vfs.c | |
parent | 68d93184352f2e723f135b0a9bad93b58f9d120b (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>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 20 |
1 files changed, 16 insertions, 4 deletions
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 | |||
1341 | static 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 |
1344 | nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | 1351 | do_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; |