mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
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>
This commit is contained in:
parent
68d9318435
commit
ac6721a13e
@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
|
||||
}
|
||||
|
||||
/* 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,
|
||||
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
|
||||
|
||||
/*
|
||||
* 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,
|
||||
&resfh, open->op_createmode,
|
||||
(u32 *)open->op_verf.data,
|
||||
|
@ -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;
|
||||
|
@ -58,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
|
||||
int type, dev_t rdev, struct svc_fh *res);
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
__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,
|
||||
struct svc_fh *res, int createmode,
|
||||
u32 *verifier, int *truncp, int *created);
|
||||
|
Loading…
Reference in New Issue
Block a user