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;
|
struct nfs_delegation *delegation;
|
||||||
int delegation_flags = 0;
|
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();
|
rcu_read_lock();
|
||||||
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
|
delegation = rcu_dereference(NFS_I(state->inode)->delegation);
|
||||||
if (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)
|
if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
|
||||||
nfs_inode_set_delegation(state->inode,
|
nfs_inode_set_delegation(state->inode,
|
||||||
data->owner->so_cred,
|
data->owner->so_cred,
|
||||||
data->o_res.delegation_type,
|
data->o_res.delegation.type,
|
||||||
&data->o_res.delegation,
|
&data->o_res.delegation.stateid,
|
||||||
data->o_res.pagemod_limit);
|
data->o_res.delegation.pagemod_limit);
|
||||||
else
|
else
|
||||||
nfs_inode_reclaim_delegation(state->inode,
|
nfs_inode_reclaim_delegation(state->inode,
|
||||||
data->owner->so_cred,
|
data->owner->so_cred,
|
||||||
data->o_res.delegation_type,
|
data->o_res.delegation.type,
|
||||||
&data->o_res.delegation,
|
&data->o_res.delegation.stateid,
|
||||||
data->o_res.pagemod_limit);
|
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,
|
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)
|
if (ret)
|
||||||
return ERR_PTR(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,
|
if (!update_open_stateid(state, &data->o_res.stateid,
|
||||||
NULL, data->o_arg.fmode))
|
NULL, data->o_arg.fmode))
|
||||||
|
|
@ -2083,7 +2089,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
|
||||||
if (IS_ERR(state))
|
if (IS_ERR(state))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (data->o_res.delegation_type != 0)
|
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,
|
if (!update_open_stateid(state, &data->o_res.stateid,
|
||||||
NULL, data->o_arg.fmode)) {
|
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:
|
case NFS4_OPEN_CLAIM_DELEGATE_PREV:
|
||||||
if (!opendata->rpc_done)
|
if (!opendata->rpc_done)
|
||||||
break;
|
break;
|
||||||
if (opendata->o_res.delegation_type != 0)
|
if (opendata->o_res.delegation.type != 0)
|
||||||
dir_verifier = nfs_save_change_attribute(dir);
|
dir_verifier = nfs_save_change_attribute(dir);
|
||||||
nfs_set_verifier(dentry, dir_verifier);
|
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,
|
static int decode_rw_delegation(struct xdr_stream *xdr,
|
||||||
uint32_t delegation_type,
|
struct nfs4_open_delegation *res)
|
||||||
struct nfs_openres *res)
|
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = decode_delegation_stateid(xdr, &res->delegation);
|
status = decode_delegation_stateid(xdr, &res->stateid);
|
||||||
if (unlikely(status))
|
if (unlikely(status))
|
||||||
return status;
|
return status;
|
||||||
p = xdr_inline_decode(xdr, 4);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
|
|
@ -5162,52 +5161,53 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
res->do_recall = be32_to_cpup(p);
|
res->do_recall = be32_to_cpup(p);
|
||||||
|
|
||||||
switch (delegation_type) {
|
switch (res->open_delegation_type) {
|
||||||
case NFS4_OPEN_DELEGATE_READ:
|
case NFS4_OPEN_DELEGATE_READ:
|
||||||
res->delegation_type = FMODE_READ;
|
res->type = FMODE_READ;
|
||||||
break;
|
break;
|
||||||
case NFS4_OPEN_DELEGATE_WRITE:
|
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)
|
if (decode_space_limit(xdr, &res->pagemod_limit) < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
return decode_ace(xdr, NULL);
|
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;
|
__be32 *p;
|
||||||
uint32_t why_no_delegation;
|
|
||||||
|
|
||||||
p = xdr_inline_decode(xdr, 4);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
why_no_delegation = be32_to_cpup(p);
|
res->why_no_delegation = be32_to_cpup(p);
|
||||||
switch (why_no_delegation) {
|
switch (res->why_no_delegation) {
|
||||||
case WND4_CONTENTION:
|
case WND4_CONTENTION:
|
||||||
case WND4_RESOURCE:
|
case WND4_RESOURCE:
|
||||||
xdr_inline_decode(xdr, 4);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
/* Ignore for now */
|
if (unlikely(!p))
|
||||||
|
return -EIO;
|
||||||
|
res->will_notify = be32_to_cpup(p);
|
||||||
}
|
}
|
||||||
return 0;
|
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;
|
__be32 *p;
|
||||||
uint32_t delegation_type;
|
|
||||||
|
|
||||||
p = xdr_inline_decode(xdr, 4);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
delegation_type = be32_to_cpup(p);
|
res->open_delegation_type = be32_to_cpup(p);
|
||||||
res->delegation_type = 0;
|
switch (res->open_delegation_type) {
|
||||||
switch (delegation_type) {
|
|
||||||
case NFS4_OPEN_DELEGATE_NONE:
|
case NFS4_OPEN_DELEGATE_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
case NFS4_OPEN_DELEGATE_READ:
|
case NFS4_OPEN_DELEGATE_READ:
|
||||||
case NFS4_OPEN_DELEGATE_WRITE:
|
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:
|
case NFS4_OPEN_DELEGATE_NONE_EXT:
|
||||||
return decode_no_delegation(xdr, res);
|
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++)
|
for (; i < NFS4_BITMAP_SIZE; i++)
|
||||||
res->attrset[i] = 0;
|
res->attrset[i] = 0;
|
||||||
|
|
||||||
return decode_delegation(xdr, res);
|
return decode_delegation(xdr, &res->delegation);
|
||||||
xdr_error:
|
xdr_error:
|
||||||
dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
|
dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,22 @@ struct stateowner_id {
|
||||||
__u32 uniquifier;
|
__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.
|
* Arguments to the open call.
|
||||||
*/
|
*/
|
||||||
|
|
@ -490,13 +506,10 @@ struct nfs_openres {
|
||||||
struct nfs_fattr * f_attr;
|
struct nfs_fattr * f_attr;
|
||||||
struct nfs_seqid * seqid;
|
struct nfs_seqid * seqid;
|
||||||
const struct nfs_server *server;
|
const struct nfs_server *server;
|
||||||
fmode_t delegation_type;
|
|
||||||
nfs4_stateid delegation;
|
|
||||||
unsigned long pagemod_limit;
|
|
||||||
__u32 do_recall;
|
|
||||||
__u32 attrset[NFS4_BITMAP_SIZE];
|
__u32 attrset[NFS4_BITMAP_SIZE];
|
||||||
struct nfs4_string *owner;
|
struct nfs4_string *owner;
|
||||||
struct nfs4_string *group_owner;
|
struct nfs4_string *group_owner;
|
||||||
|
struct nfs4_open_delegation delegation;
|
||||||
__u32 access_request;
|
__u32 access_request;
|
||||||
__u32 access_supported;
|
__u32 access_supported;
|
||||||
__u32 access_result;
|
__u32 access_result;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue