summaryrefslogtreecommitdiff
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorMi Jinlong <mijinlong@cn.fujitsu.com>2011-04-20 13:06:25 +0400
committerJ. Bruce Fields <bfields@redhat.com>2011-04-30 04:47:52 +0400
commitac6721a13e5b1a90728e790600f827a5e5f5da2f (patch)
treef39f1faaaa4059956d8fde5fbb29fc5500d1e513 /fs/nfsd/vfs.c
parent68d93184352f2e723f135b0a9bad93b58f9d120b (diff)
downloadlinux-ac6721a13e5b1a90728e790600f827a5e5f5da2f.tar.xz
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.c20
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:
}
#ifdef CONFIG_NFSD_V3
+
+static inline int nfsd_create_is_exclusive(int createmode)
+{
+ return createmode == NFS3_CREATE_EXCLUSIVE
+ || createmode == NFS4_CREATE_EXCLUSIVE4_1;
+}
+
/*
- * NFSv3 version of nfsd_create
+ * NFSv3 and NFSv4 version of nfsd_create
*/
__be32
-nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
+do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
char *fname, int flen, struct iattr *iap,
struct svc_fh *resfhp, int createmode, u32 *verifier,
int *truncp, int *created)
@@ -1386,7 +1393,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (err)
goto out;
- if (createmode == NFS3_CREATE_EXCLUSIVE) {
+ if (nfsd_create_is_exclusive(createmode)) {
/* solaris7 gets confused (bugid 4218508) if these have
* the high bit set, so just clear the high bits. If this is
* ever changed to use different attrs for storing the
@@ -1427,6 +1434,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
&& dchild->d_inode->i_atime.tv_sec == v_atime
&& dchild->d_inode->i_size == 0 )
break;
+ case NFS4_CREATE_EXCLUSIVE4_1:
+ if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
+ && dchild->d_inode->i_atime.tv_sec == v_atime
+ && dchild->d_inode->i_size == 0 )
+ goto set_attr;
/* fallthru */
case NFS3_CREATE_GUARDED:
err = nfserr_exist;
@@ -1445,7 +1457,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
nfsd_check_ignore_resizing(iap);
- if (createmode == NFS3_CREATE_EXCLUSIVE) {
+ if (nfsd_create_is_exclusive(createmode)) {
/* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME
| ATTR_MTIME_SET|ATTR_ATIME_SET;