Commit ac6721a1 authored by Mi Jinlong's avatar Mi Jinlong Committed by J. Bruce Fields

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: default avatarMi Jinlong <mijinlong@cn.fujitsu.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 68d93184
...@@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, ...@@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
} }
/* Now create the file and set attributes */ /* Now create the file and set attributes */
nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len,
attr, newfhp, attr, newfhp,
argp->createmode, argp->verf, NULL, NULL); argp->createmode, argp->verf, NULL, NULL);
......
...@@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o ...@@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
/* /*
* Note: create modes (UNCHECKED,GUARDED...) are the same * Note: create modes (UNCHECKED,GUARDED...) are the same
* in NFSv4 as in v3. * in NFSv4 as in v3 except EXCLUSIVE4_1.
*/ */
status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
open->op_fname.len, &open->op_iattr, open->op_fname.len, &open->op_iattr,
&resfh, open->op_createmode, &resfh, open->op_createmode,
(u32 *)open->op_verf.data, (u32 *)open->op_verf.data,
......
...@@ -1337,11 +1337,18 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1337,11 +1337,18 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
} }
#ifdef CONFIG_NFSD_V3 #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 __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, char *fname, int flen, struct iattr *iap,
struct svc_fh *resfhp, int createmode, u32 *verifier, struct svc_fh *resfhp, int createmode, u32 *verifier,
int *truncp, int *created) int *truncp, int *created)
...@@ -1386,7 +1393,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1386,7 +1393,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (err) if (err)
goto out; goto out;
if (createmode == NFS3_CREATE_EXCLUSIVE) { if (nfsd_create_is_exclusive(createmode)) {
/* solaris7 gets confused (bugid 4218508) if these have /* solaris7 gets confused (bugid 4218508) if these have
* the high bit set, so just clear the high bits. If this is * the high bit set, so just clear the high bits. If this is
* ever changed to use different attrs for storing the * 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,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_atime.tv_sec == v_atime
&& dchild->d_inode->i_size == 0 ) && dchild->d_inode->i_size == 0 )
break; 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 */ /* fallthru */
case NFS3_CREATE_GUARDED: case NFS3_CREATE_GUARDED:
err = nfserr_exist; err = nfserr_exist;
...@@ -1445,7 +1457,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1445,7 +1457,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
nfsd_check_ignore_resizing(iap); nfsd_check_ignore_resizing(iap);
if (createmode == NFS3_CREATE_EXCLUSIVE) { if (nfsd_create_is_exclusive(createmode)) {
/* Cram the verifier into atime/mtime */ /* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME iap->ia_valid = ATTR_MTIME|ATTR_ATIME
| ATTR_MTIME_SET|ATTR_ATIME_SET; | ATTR_MTIME_SET|ATTR_ATIME_SET;
......
...@@ -58,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, ...@@ -58,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
int type, dev_t rdev, struct svc_fh *res); int type, dev_t rdev, struct svc_fh *res);
#ifdef CONFIG_NFSD_V3 #ifdef CONFIG_NFSD_V3
__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *,
char *name, int len, struct iattr *attrs, char *name, int len, struct iattr *attrs,
struct svc_fh *res, int createmode, struct svc_fh *res, int createmode,
u32 *verifier, int *truncp, int *created); u32 *verifier, int *truncp, int *created);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment