Commit 82062051 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFSv4: Clean up open delegation return structure



Instead of having the fields open coded in the struct nfs_openres,
add a separate structure for them so that we can reuse that code
for the WANT_DELEGATION case.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarLance Shelton <lance.shelton@hammerspace.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent d3318990
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -1960,6 +1960,13 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
	struct nfs_delegation *delegation;
	int delegation_flags = 0;

	switch (data->o_res.delegation.open_delegation_type) {
	case NFS4_OPEN_DELEGATE_READ:
	case NFS4_OPEN_DELEGATE_WRITE:
		break;
	default:
		return;
	};
	rcu_read_lock();
	delegation = rcu_dereference(NFS_I(state->inode)->delegation);
	if (delegation)
@@ -1979,19 +1986,19 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
	if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
		nfs_inode_set_delegation(state->inode,
				data->owner->so_cred,
				data->o_res.delegation_type,
				&data->o_res.delegation,
				data->o_res.pagemod_limit);
				data->o_res.delegation.type,
				&data->o_res.delegation.stateid,
				data->o_res.delegation.pagemod_limit);
	else
		nfs_inode_reclaim_delegation(state->inode,
				data->owner->so_cred,
				data->o_res.delegation_type,
				&data->o_res.delegation,
				data->o_res.pagemod_limit);
				data->o_res.delegation.type,
				&data->o_res.delegation.stateid,
				data->o_res.delegation.pagemod_limit);

	if (data->o_res.do_recall)
	if (data->o_res.delegation.do_recall)
		nfs_async_inode_return_delegation(state->inode,
						  &data->o_res.delegation);
						  &data->o_res.delegation.stateid);
}

/*
@@ -2015,7 +2022,6 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
	if (ret)
		return ERR_PTR(ret);

	if (data->o_res.delegation_type != 0)
	nfs4_opendata_check_deleg(data, state);

	if (!update_open_stateid(state, &data->o_res.stateid,
@@ -2083,7 +2089,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
	if (IS_ERR(state))
		goto out;

	if (data->o_res.delegation_type != 0)
	if (data->o_res.delegation.type != 0)
		nfs4_opendata_check_deleg(data, state);
	if (!update_open_stateid(state, &data->o_res.stateid,
				NULL, data->o_arg.fmode)) {
@@ -3111,7 +3117,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
		if (!opendata->rpc_done)
			break;
		if (opendata->o_res.delegation_type != 0)
		if (opendata->o_res.delegation.type != 0)
			dir_verifier = nfs_save_change_attribute(dir);
		nfs_set_verifier(dentry, dir_verifier);
	}
+19 −19
Original line number Diff line number Diff line
@@ -5148,13 +5148,12 @@ static int decode_space_limit(struct xdr_stream *xdr,
}

static int decode_rw_delegation(struct xdr_stream *xdr,
		uint32_t delegation_type,
		struct nfs_openres *res)
		struct nfs4_open_delegation *res)
{
	__be32 *p;
	int status;

	status = decode_delegation_stateid(xdr, &res->delegation);
	status = decode_delegation_stateid(xdr, &res->stateid);
	if (unlikely(status))
		return status;
	p = xdr_inline_decode(xdr, 4);
@@ -5162,52 +5161,53 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
		return -EIO;
	res->do_recall = be32_to_cpup(p);

	switch (delegation_type) {
	switch (res->open_delegation_type) {
	case NFS4_OPEN_DELEGATE_READ:
		res->delegation_type = FMODE_READ;
		res->type = FMODE_READ;
		break;
	case NFS4_OPEN_DELEGATE_WRITE:
		res->delegation_type = FMODE_WRITE|FMODE_READ;
		res->type = FMODE_WRITE|FMODE_READ;
		if (decode_space_limit(xdr, &res->pagemod_limit) < 0)
				return -EIO;
	}
	return decode_ace(xdr, NULL);
}

static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
static int decode_no_delegation(struct xdr_stream *xdr,
		struct nfs4_open_delegation *res)
{
	__be32 *p;
	uint32_t why_no_delegation;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(!p))
		return -EIO;
	why_no_delegation = be32_to_cpup(p);
	switch (why_no_delegation) {
	res->why_no_delegation = be32_to_cpup(p);
	switch (res->why_no_delegation) {
		case WND4_CONTENTION:
		case WND4_RESOURCE:
			xdr_inline_decode(xdr, 4);
			/* Ignore for now */
			p = xdr_inline_decode(xdr, 4);
			if (unlikely(!p))
				return -EIO;
			res->will_notify = be32_to_cpup(p);
	}
	return 0;
}

static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
static int decode_delegation(struct xdr_stream *xdr,
		struct nfs4_open_delegation *res)
{
	__be32 *p;
	uint32_t delegation_type;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(!p))
		return -EIO;
	delegation_type = be32_to_cpup(p);
	res->delegation_type = 0;
	switch (delegation_type) {
	res->open_delegation_type = be32_to_cpup(p);
	switch (res->open_delegation_type) {
	case NFS4_OPEN_DELEGATE_NONE:
		return 0;
	case NFS4_OPEN_DELEGATE_READ:
	case NFS4_OPEN_DELEGATE_WRITE:
		return decode_rw_delegation(xdr, delegation_type, res);
		return decode_rw_delegation(xdr, res);
	case NFS4_OPEN_DELEGATE_NONE_EXT:
		return decode_no_delegation(xdr, res);
	}
@@ -5248,7 +5248,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
	for (; i < NFS4_BITMAP_SIZE; i++)
		res->attrset[i] = 0;

	return decode_delegation(xdr, res);
	return decode_delegation(xdr, &res->delegation);
xdr_error:
	dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
	return -EIO;
+17 −4
Original line number Diff line number Diff line
@@ -449,6 +449,22 @@ struct stateowner_id {
	__u32	uniquifier;
};

struct nfs4_open_delegation {
	__u32 open_delegation_type;
	union {
		struct {
			fmode_t			type;
			__u32			do_recall;
			nfs4_stateid		stateid;
			unsigned long		pagemod_limit;
		};
		struct {
			__u32			why_no_delegation;
			__u32			will_notify;
		};
	};
};

/*
 * Arguments to the open call.
 */
@@ -490,13 +506,10 @@ struct nfs_openres {
	struct nfs_fattr *      f_attr;
	struct nfs_seqid *	seqid;
	const struct nfs_server *server;
	fmode_t			delegation_type;
	nfs4_stateid		delegation;
	unsigned long		pagemod_limit;
	__u32			do_recall;
	__u32			attrset[NFS4_BITMAP_SIZE];
	struct nfs4_string	*owner;
	struct nfs4_string	*group_owner;
	struct nfs4_open_delegation	delegation;
	__u32			access_request;
	__u32			access_supported;
	__u32			access_result;