summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-03 16:42:45 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:40 -0400
commit549d6ed5e85003370fe858e70864a71882491d28 (patch)
treea5094cbce64f07560f0e3511279260e40c0ae669 /fs/nfs/nfs4proc.c
parent1c816efa245111c52858fbe55d99474f3c149dd3 (diff)
downloadlwn-549d6ed5e85003370fe858e70864a71882491d28.tar.gz
lwn-549d6ed5e85003370fe858e70864a71882491d28.zip
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>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 69aab8db4947..4f0b06d549fa 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -356,6 +356,21 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
if (state == NULL)
goto put_inode;
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:
iput(inode);
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_arg.open_flags |= mode;
newstate = nfs4_opendata_to_nfs4_state(opendata);
- 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);
- }
+ if (newstate != NULL)
nfs4_close_state(&opendata->path, newstate, opendata->o_arg.open_flags);
- }
if (newstate != state)
return -ESTALE;
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);
if (state == NULL)
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_put_state_owner(sp);
up_read(&clp->cl_sem);