aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-07 13:49:12 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-07 13:49:12 -0500
commitcf470c3e004efe16d73dc8ba9b29bdc9a5327cda (patch)
tree57f8f72ef5af7d33d760570bd8d78e9b0face719 /fs/nfs/nfs4proc.c
parent9cb8196839ab4ec87710526e9c43ac7f5dba69d3 (diff)
NFSv4: Don't free the nfs4_lock_state until after the release_lockowner
Otherwise we can end up with sequence id problems if the client reuses the owner_id before the server has processed the release_lockowner Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1ec05222ccbc..32e0d08a9771 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4745,8 +4745,15 @@ out:
4745 return err; 4745 return err;
4746} 4746}
4747 4747
4748struct nfs_release_lockowner_data {
4749 struct nfs4_lock_state *lsp;
4750 struct nfs_release_lockowner_args args;
4751};
4752
4748static void nfs4_release_lockowner_release(void *calldata) 4753static void nfs4_release_lockowner_release(void *calldata)
4749{ 4754{
4755 struct nfs_release_lockowner_data *data = calldata;
4756 nfs4_free_lock_state(data->lsp);
4750 kfree(calldata); 4757 kfree(calldata);
4751} 4758}
4752 4759
@@ -4754,24 +4761,26 @@ const struct rpc_call_ops nfs4_release_lockowner_ops = {
4754 .rpc_release = nfs4_release_lockowner_release, 4761 .rpc_release = nfs4_release_lockowner_release,
4755}; 4762};
4756 4763
4757void nfs4_release_lockowner(const struct nfs4_lock_state *lsp) 4764int nfs4_release_lockowner(struct nfs4_lock_state *lsp)
4758{ 4765{
4759 struct nfs_server *server = lsp->ls_state->owner->so_server; 4766 struct nfs_server *server = lsp->ls_state->owner->so_server;
4760 struct nfs_release_lockowner_args *args; 4767 struct nfs_release_lockowner_data *data;
4761 struct rpc_message msg = { 4768 struct rpc_message msg = {
4762 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER], 4769 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER],
4763 }; 4770 };
4764 4771
4765 if (server->nfs_client->cl_mvops->minor_version != 0) 4772 if (server->nfs_client->cl_mvops->minor_version != 0)
4766 return; 4773 return -EINVAL;
4767 args = kmalloc(sizeof(*args), GFP_NOFS); 4774 data = kmalloc(sizeof(*data), GFP_NOFS);
4768 if (!args) 4775 if (!data)
4769 return; 4776 return -ENOMEM;
4770 args->lock_owner.clientid = server->nfs_client->cl_clientid; 4777 data->lsp = lsp;
4771 args->lock_owner.id = lsp->ls_seqid.owner_id; 4778 data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
4772 args->lock_owner.s_dev = server->s_dev; 4779 data->args.lock_owner.id = lsp->ls_seqid.owner_id;
4773 msg.rpc_argp = args; 4780 data->args.lock_owner.s_dev = server->s_dev;
4774 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, args); 4781 msg.rpc_argp = &data->args;
4782 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data);
4783 return 0;
4775} 4784}
4776 4785
4777#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" 4786#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"