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

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
......@@ -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,8 +2022,7 @@ _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);
nfs4_opendata_check_deleg(data, state);
if (!update_open_stateid(state, &data->o_res.stateid,
NULL, data->o_arg.fmode))
......@@ -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);
}
......
......@@ -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;
......
......@@ -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;
......
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