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: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>pull/815/merge
parent
d331899019
commit
8206205169
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue