Commit 1708e50b authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Add helper to decode OPEN's open_claim4 argument



Refactor for clarity.

Note that op_fname is the only instance of an NFSv4 filename stored
in a struct xdr_netobj. Convert it to a u32/char * pair so that the
new nfsd4_decode_filename() helper can be used.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent b07bebd9
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -257,8 +257,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
		 * in NFSv4 as in v3 except EXCLUSIVE4_1.
		 */
		current->fs->umask = open->op_umask;
		status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
					open->op_fname.len, &open->op_iattr,
		status = do_nfsd_create(rqstp, current_fh, open->op_fname,
					open->op_fnamelen, &open->op_iattr,
					*resfh, open->op_createmode,
					(u32 *)open->op_verf.data,
					&open->op_truncate, &open->op_created);
@@ -283,7 +283,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
		 * a chance to an acquire a delegation if appropriate.
		 */
		status = nfsd_lookup(rqstp, current_fh,
				     open->op_fname.data, open->op_fname.len, *resfh);
				     open->op_fname, open->op_fnamelen, *resfh);
	if (status)
		goto out;
	status = nfsd_check_obj_isreg(*resfh);
@@ -360,7 +360,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	bool reclaim = false;

	dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
		(int)open->op_fname.len, open->op_fname.data,
		(int)open->op_fnamelen, open->op_fname,
		open->op_openowner);

	/* This check required by spec. */
+50 −45
Original line number Diff line number Diff line
@@ -1072,6 +1072,55 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
	return nfs_ok;
}

static __be32
nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp,
			 struct nfsd4_open *open)
{
	__be32 status;

	if (xdr_stream_decode_u32(argp->xdr, &open->op_claim_type) < 0)
		return nfserr_bad_xdr;
	switch (open->op_claim_type) {
	case NFS4_OPEN_CLAIM_NULL:
	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
		status = nfsd4_decode_component4(argp, &open->op_fname,
						 &open->op_fnamelen);
		if (status)
			return status;
		break;
	case NFS4_OPEN_CLAIM_PREVIOUS:
		if (xdr_stream_decode_u32(argp->xdr, &open->op_delegate_type) < 0)
			return nfserr_bad_xdr;
		break;
	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
		if (status)
			return status;
		status = nfsd4_decode_component4(argp, &open->op_fname,
						 &open->op_fnamelen);
		if (status)
			return status;
		break;
	case NFS4_OPEN_CLAIM_FH:
	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
		if (argp->minorversion < 1)
			return nfserr_bad_xdr;
		/* void */
		break;
	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
		if (argp->minorversion < 1)
			return nfserr_bad_xdr;
		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
		if (status)
			return status;
		break;
	default:
		return nfserr_bad_xdr;
	}

	return nfs_ok;
}

static __be32
nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
{
@@ -1102,51 +1151,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
	status = nfsd4_decode_openflag4(argp, open);
	if (status)
		return status;

	/* open_claim */
	READ_BUF(4);
	open->op_claim_type = be32_to_cpup(p++);
	switch (open->op_claim_type) {
	case NFS4_OPEN_CLAIM_NULL:
	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
		READ_BUF(4);
		open->op_fname.len = be32_to_cpup(p++);
		READ_BUF(open->op_fname.len);
		SAVEMEM(open->op_fname.data, open->op_fname.len);
		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
			return status;
		break;
	case NFS4_OPEN_CLAIM_PREVIOUS:
		READ_BUF(4);
		open->op_delegate_type = be32_to_cpup(p++);
		break;
	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
		if (status)
			return status;
		READ_BUF(4);
		open->op_fname.len = be32_to_cpup(p++);
		READ_BUF(open->op_fname.len);
		SAVEMEM(open->op_fname.data, open->op_fname.len);
		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
			return status;
		break;
	case NFS4_OPEN_CLAIM_FH:
	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
		if (argp->minorversion < 1)
			goto xdr_error;
		/* void */
		break;
	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
		if (argp->minorversion < 1)
			goto xdr_error;
		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
		if (status)
			return status;
		break;
	default:
		goto xdr_error;
	}
	status = nfsd4_decode_open_claim4(argp, open);

	DECODE_TAIL;
}
+2 −1
Original line number Diff line number Diff line
@@ -252,7 +252,8 @@ struct nfsd4_listxattrs {

struct nfsd4_open {
	u32		op_claim_type;      /* request */
	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
	u32		op_fnamelen;
	char *		op_fname;	    /* request - everything but CLAIM_PREV */
	u32		op_delegate_type;   /* request - CLAIM_PREV only */
	stateid_t       op_delegate_stateid; /* request - response */
	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */