NFSv4: set the delegation in nfs4_opendata_to_nfs4_state
This ensures that nfs4_open_release() and nfs4_open_confirm_release() can now handle an eventual delegation that was returned with out open. As such, it fixes a delegation "leak" when the user breaks out of an open call. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
1c816efa24
commit
549d6ed5e8
1 changed files with 16 additions and 18 deletions
|
@ -356,6 +356,21 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
goto put_inode;
|
goto put_inode;
|
||||||
update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags);
|
update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags);
|
||||||
|
if (data->o_res.delegation_type != 0) {
|
||||||
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
|
int delegation_flags = 0;
|
||||||
|
|
||||||
|
if (nfsi->delegation)
|
||||||
|
delegation_flags = nfsi->delegation->flags;
|
||||||
|
if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
|
||||||
|
nfs_inode_set_delegation(state->inode,
|
||||||
|
data->owner->so_cred,
|
||||||
|
&data->o_res);
|
||||||
|
else
|
||||||
|
nfs_inode_reclaim_delegation(state->inode,
|
||||||
|
data->owner->so_cred,
|
||||||
|
&data->o_res);
|
||||||
|
}
|
||||||
put_inode:
|
put_inode:
|
||||||
iput(inode);
|
iput(inode);
|
||||||
out:
|
out:
|
||||||
|
@ -433,23 +448,8 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
|
||||||
opendata->o_res.delegation_type = delegation;
|
opendata->o_res.delegation_type = delegation;
|
||||||
opendata->o_arg.open_flags |= mode;
|
opendata->o_arg.open_flags |= mode;
|
||||||
newstate = nfs4_opendata_to_nfs4_state(opendata);
|
newstate = nfs4_opendata_to_nfs4_state(opendata);
|
||||||
if (newstate != NULL) {
|
if (newstate != NULL)
|
||||||
if (opendata->o_res.delegation_type != 0) {
|
|
||||||
struct nfs_inode *nfsi = NFS_I(newstate->inode);
|
|
||||||
int delegation_flags = 0;
|
|
||||||
if (nfsi->delegation)
|
|
||||||
delegation_flags = nfsi->delegation->flags;
|
|
||||||
if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
|
|
||||||
nfs_inode_set_delegation(newstate->inode,
|
|
||||||
opendata->owner->so_cred,
|
|
||||||
&opendata->o_res);
|
|
||||||
else
|
|
||||||
nfs_inode_reclaim_delegation(newstate->inode,
|
|
||||||
opendata->owner->so_cred,
|
|
||||||
&opendata->o_res);
|
|
||||||
}
|
|
||||||
nfs4_close_state(&opendata->path, newstate, opendata->o_arg.open_flags);
|
nfs4_close_state(&opendata->path, newstate, opendata->o_arg.open_flags);
|
||||||
}
|
|
||||||
if (newstate != state)
|
if (newstate != state)
|
||||||
return -ESTALE;
|
return -ESTALE;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1005,8 +1005,6 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
|
||||||
state = nfs4_opendata_to_nfs4_state(opendata);
|
state = nfs4_opendata_to_nfs4_state(opendata);
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
goto err_opendata_put;
|
goto err_opendata_put;
|
||||||
if (opendata->o_res.delegation_type != 0)
|
|
||||||
nfs_inode_set_delegation(state->inode, cred, &opendata->o_res);
|
|
||||||
nfs4_opendata_put(opendata);
|
nfs4_opendata_put(opendata);
|
||||||
nfs4_put_state_owner(sp);
|
nfs4_put_state_owner(sp);
|
||||||
up_read(&clp->cl_sem);
|
up_read(&clp->cl_sem);
|
||||||
|
|
Loading…
Add table
Reference in a new issue