aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 368b75b3bcba..c7bec4319236 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -206,6 +206,17 @@ static int nfs4_call_async(struct rpc_clnt *clnt,
206 return 0; 206 return 0;
207} 207}
208 208
209static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
210{
211 sigset_t oldset;
212 int ret;
213
214 rpc_clnt_sigmask(task->tk_client, &oldset);
215 ret = rpc_wait_for_completion_task(task);
216 rpc_clnt_sigunmask(task->tk_client, &oldset);
217 return ret;
218}
219
209static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags) 220static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
210{ 221{
211 struct inode *inode = state->inode; 222 struct inode *inode = state->inode;
@@ -2867,31 +2878,23 @@ struct nfs4_unlockdata {
2867 struct nfs_lockres res; 2878 struct nfs_lockres res;
2868 struct nfs4_lock_state *lsp; 2879 struct nfs4_lock_state *lsp;
2869 struct nfs_open_context *ctx; 2880 struct nfs_open_context *ctx;
2870 atomic_t refcount;
2871 struct completion completion;
2872}; 2881};
2873 2882
2874static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata) 2883static void nfs4_locku_release_calldata(void *data)
2875{
2876 if (atomic_dec_and_test(&calldata->refcount)) {
2877 nfs_free_seqid(calldata->luargs.seqid);
2878 nfs4_put_lock_state(calldata->lsp);
2879 put_nfs_open_context(calldata->ctx);
2880 kfree(calldata);
2881 }
2882}
2883
2884static void nfs4_locku_complete(void *data)
2885{ 2884{
2886 struct nfs4_unlockdata *calldata = data; 2885 struct nfs4_unlockdata *calldata = data;
2887 complete(&calldata->completion); 2886 nfs_free_seqid(calldata->luargs.seqid);
2888 nfs4_locku_release_calldata(calldata); 2887 nfs4_put_lock_state(calldata->lsp);
2888 put_nfs_open_context(calldata->ctx);
2889 kfree(calldata);
2889} 2890}
2890 2891
2891static void nfs4_locku_done(struct rpc_task *task, void *data) 2892static void nfs4_locku_done(struct rpc_task *task, void *data)
2892{ 2893{
2893 struct nfs4_unlockdata *calldata = data; 2894 struct nfs4_unlockdata *calldata = data;
2894 2895
2896 if (RPC_ASSASSINATED(task))
2897 return;
2895 nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid); 2898 nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
2896 switch (task->tk_status) { 2899 switch (task->tk_status) {
2897 case 0: 2900 case 0:
@@ -2935,7 +2938,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
2935static const struct rpc_call_ops nfs4_locku_ops = { 2938static const struct rpc_call_ops nfs4_locku_ops = {
2936 .rpc_call_prepare = nfs4_locku_prepare, 2939 .rpc_call_prepare = nfs4_locku_prepare,
2937 .rpc_call_done = nfs4_locku_done, 2940 .rpc_call_done = nfs4_locku_done,
2938 .rpc_release = nfs4_locku_complete, 2941 .rpc_release = nfs4_locku_release_calldata,
2939}; 2942};
2940 2943
2941static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) 2944static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
@@ -2944,26 +2947,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
2944 struct inode *inode = state->inode; 2947 struct inode *inode = state->inode;
2945 struct nfs_server *server = NFS_SERVER(inode); 2948 struct nfs_server *server = NFS_SERVER(inode);
2946 struct nfs4_lock_state *lsp; 2949 struct nfs4_lock_state *lsp;
2947 int status; 2950 struct rpc_task *task;
2951 int status = 0;
2948 2952
2949 /* Is this a delegated lock? */ 2953 /* Is this a delegated lock? */
2950 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) 2954 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
2951 return do_vfs_lock(request->fl_file, request); 2955 goto out;
2952 2956
2953 status = nfs4_set_lock_state(state, request); 2957 status = nfs4_set_lock_state(state, request);
2954 if (status != 0) 2958 if (status != 0)
2955 return status; 2959 goto out;
2956 lsp = request->fl_u.nfs4_fl.owner; 2960 lsp = request->fl_u.nfs4_fl.owner;
2957 /* We might have lost the locks! */ 2961 /* We might have lost the locks! */
2958 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) 2962 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
2959 return 0; 2963 goto out;
2964 status = -ENOMEM;
2960 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); 2965 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
2961 if (calldata == NULL) 2966 if (calldata == NULL)
2962 return -ENOMEM; 2967 goto out;
2963 calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid); 2968 calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
2964 if (calldata->luargs.seqid == NULL) { 2969 if (calldata->luargs.seqid == NULL) {
2965 kfree(calldata); 2970 kfree(calldata);
2966 return -ENOMEM; 2971 goto out;
2967 } 2972 }
2968 calldata->luargs.stateid = &lsp->ls_stateid; 2973 calldata->luargs.stateid = &lsp->ls_stateid;
2969 calldata->arg.fh = NFS_FH(inode); 2974 calldata->arg.fh = NFS_FH(inode);
@@ -2978,14 +2983,16 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
2978 /* Ensure we don't close file until we're done freeing locks! */ 2983 /* Ensure we don't close file until we're done freeing locks! */
2979 calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data); 2984 calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data);
2980 2985
2981 atomic_set(&calldata->refcount, 2); 2986 task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_locku_ops, calldata);
2982 init_completion(&calldata->completion); 2987 if (!IS_ERR(task)) {
2983 2988 status = nfs4_wait_for_completion_rpc_task(task);
2984 status = nfs4_call_async(NFS_SERVER(inode)->client, &nfs4_locku_ops, calldata); 2989 rpc_release_task(task);
2985 if (status == 0) 2990 } else {
2986 wait_for_completion_interruptible(&calldata->completion); 2991 status = PTR_ERR(task);
2992 nfs4_locku_release_calldata(calldata);
2993 }
2994out:
2987 do_vfs_lock(request->fl_file, request); 2995 do_vfs_lock(request->fl_file, request);
2988 nfs4_locku_release_calldata(calldata);
2989 return status; 2996 return status;
2990} 2997}
2991 2998