diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-05 16:50:30 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-02-05 22:16:33 -0500 |
commit | 472e259449819d939b5a5188b6f4c7d59aa4304c (patch) | |
tree | 8ba4fa5bd74f3fccf84ebdea8f63b6c85b921466 /fs/nfs | |
parent | ea7c38fef0b774a5dc16fb0ca5935f0ae8568176 (diff) |
NFSv4.1: Pin the inode and super block in asynchronous layoutcommit
If we're sending an asynchronous layoutcommit, then we need to ensure
that the inode and the super block remain pinned.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Peng Tao <tao.peng@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index dd892a4e7eb3..e092b8540e2e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -7989,6 +7989,7 @@ static void nfs4_layoutcommit_release(void *calldata) | |||
7989 | nfs_post_op_update_inode_force_wcc(data->args.inode, | 7989 | nfs_post_op_update_inode_force_wcc(data->args.inode, |
7990 | data->res.fattr); | 7990 | data->res.fattr); |
7991 | put_rpccred(data->cred); | 7991 | put_rpccred(data->cred); |
7992 | nfs_iput_and_deactive(data->inode); | ||
7992 | kfree(data); | 7993 | kfree(data); |
7993 | } | 7994 | } |
7994 | 7995 | ||
@@ -8013,7 +8014,6 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync) | |||
8013 | .rpc_message = &msg, | 8014 | .rpc_message = &msg, |
8014 | .callback_ops = &nfs4_layoutcommit_ops, | 8015 | .callback_ops = &nfs4_layoutcommit_ops, |
8015 | .callback_data = data, | 8016 | .callback_data = data, |
8016 | .flags = RPC_TASK_ASYNC, | ||
8017 | }; | 8017 | }; |
8018 | struct rpc_task *task; | 8018 | struct rpc_task *task; |
8019 | int status = 0; | 8019 | int status = 0; |
@@ -8024,18 +8024,21 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync) | |||
8024 | data->args.lastbytewritten, | 8024 | data->args.lastbytewritten, |
8025 | data->args.inode->i_ino); | 8025 | data->args.inode->i_ino); |
8026 | 8026 | ||
8027 | if (!sync) { | ||
8028 | data->inode = nfs_igrab_and_active(data->args.inode); | ||
8029 | if (data->inode == NULL) { | ||
8030 | nfs4_layoutcommit_release(data); | ||
8031 | return -EAGAIN; | ||
8032 | } | ||
8033 | task_setup_data.flags = RPC_TASK_ASYNC; | ||
8034 | } | ||
8027 | nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); | 8035 | nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); |
8028 | task = rpc_run_task(&task_setup_data); | 8036 | task = rpc_run_task(&task_setup_data); |
8029 | if (IS_ERR(task)) | 8037 | if (IS_ERR(task)) |
8030 | return PTR_ERR(task); | 8038 | return PTR_ERR(task); |
8031 | if (sync == false) | 8039 | if (sync) |
8032 | goto out; | 8040 | status = task->tk_status; |
8033 | status = nfs4_wait_for_completion_rpc_task(task); | ||
8034 | if (status != 0) | ||
8035 | goto out; | ||
8036 | status = task->tk_status; | ||
8037 | trace_nfs4_layoutcommit(data->args.inode, status); | 8041 | trace_nfs4_layoutcommit(data->args.inode, status); |
8038 | out: | ||
8039 | dprintk("%s: status %d\n", __func__, status); | 8042 | dprintk("%s: status %d\n", __func__, status); |
8040 | rpc_put_task(task); | 8043 | rpc_put_task(task); |
8041 | return status; | 8044 | return status; |