Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);


+2 −2
Original line number Original line Diff line number Diff line
@@ -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,
+16 −4
Original line number Original line Diff line number Diff line
@@ -1337,11 +1337,18 @@ out_nfserr:
}
}


#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,
	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,
			    && 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,


	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;
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);