diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-24 17:03:14 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-24 17:03:14 -0400 |
commit | 0acd2201920d0968919f4f5797d63f7b6f2b19d4 (patch) | |
tree | 9b241d264f42eff3ff4eeffb67616fca0490e460 /fs/nfs/nfs4proc.c | |
parent | 8f70e95f9f4159184f557a1db60c909d7c1bd2e3 (diff) | |
parent | 35124a0994fc02545b14b9fa3aad000b3331f1c0 (diff) |
Merge branch 'nfs-for-2.6.39' into nfs-for-next
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 125 |
1 files changed, 111 insertions, 14 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f9150f03d640..dfd1e6d7e6c3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3253,12 +3253,9 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag | |||
3253 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; | 3253 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; |
3254 | } | 3254 | } |
3255 | 3255 | ||
3256 | static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | 3256 | static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *data) |
3257 | { | 3257 | { |
3258 | struct inode *inode = data->inode; | 3258 | struct inode *inode = data->inode; |
3259 | |||
3260 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | ||
3261 | return -EAGAIN; | ||
3262 | 3259 | ||
3263 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { | 3260 | if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { |
3264 | nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); | 3261 | nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); |
@@ -3268,11 +3265,24 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | |||
3268 | return 0; | 3265 | return 0; |
3269 | } | 3266 | } |
3270 | 3267 | ||
3268 | static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | ||
3269 | { | ||
3270 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | ||
3271 | return -EAGAIN; | ||
3272 | return data->write_done_cb(task, data); | ||
3273 | } | ||
3274 | |||
3271 | static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) | 3275 | static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) |
3272 | { | 3276 | { |
3273 | struct nfs_server *server = NFS_SERVER(data->inode); | 3277 | struct nfs_server *server = NFS_SERVER(data->inode); |
3274 | 3278 | ||
3275 | data->args.bitmask = server->cache_consistency_bitmask; | 3279 | if (data->lseg) { |
3280 | data->args.bitmask = NULL; | ||
3281 | data->res.fattr = NULL; | ||
3282 | } else | ||
3283 | data->args.bitmask = server->cache_consistency_bitmask; | ||
3284 | if (!data->write_done_cb) | ||
3285 | data->write_done_cb = nfs4_commit_done_cb; | ||
3276 | data->res.server = server; | 3286 | data->res.server = server; |
3277 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; | 3287 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; |
3278 | } | 3288 | } |
@@ -5608,8 +5618,6 @@ static void nfs4_layoutget_release(void *calldata) | |||
5608 | struct nfs4_layoutget *lgp = calldata; | 5618 | struct nfs4_layoutget *lgp = calldata; |
5609 | 5619 | ||
5610 | dprintk("--> %s\n", __func__); | 5620 | dprintk("--> %s\n", __func__); |
5611 | if (lgp->res.layout.buf != NULL) | ||
5612 | free_page((unsigned long) lgp->res.layout.buf); | ||
5613 | put_nfs_open_context(lgp->args.ctx); | 5621 | put_nfs_open_context(lgp->args.ctx); |
5614 | kfree(calldata); | 5622 | kfree(calldata); |
5615 | dprintk("<-- %s\n", __func__); | 5623 | dprintk("<-- %s\n", __func__); |
@@ -5641,12 +5649,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
5641 | 5649 | ||
5642 | dprintk("--> %s\n", __func__); | 5650 | dprintk("--> %s\n", __func__); |
5643 | 5651 | ||
5644 | lgp->res.layout.buf = (void *)__get_free_page(GFP_NOFS); | 5652 | lgp->res.layoutp = &lgp->args.layout; |
5645 | if (lgp->res.layout.buf == NULL) { | ||
5646 | nfs4_layoutget_release(lgp); | ||
5647 | return -ENOMEM; | ||
5648 | } | ||
5649 | |||
5650 | lgp->res.seq_res.sr_slot = NULL; | 5653 | lgp->res.seq_res.sr_slot = NULL; |
5651 | task = rpc_run_task(&task_setup_data); | 5654 | task = rpc_run_task(&task_setup_data); |
5652 | if (IS_ERR(task)) | 5655 | if (IS_ERR(task)) |
@@ -5698,6 +5701,100 @@ int nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) | |||
5698 | } | 5701 | } |
5699 | EXPORT_SYMBOL_GPL(nfs4_proc_getdeviceinfo); | 5702 | EXPORT_SYMBOL_GPL(nfs4_proc_getdeviceinfo); |
5700 | 5703 | ||
5704 | static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata) | ||
5705 | { | ||
5706 | struct nfs4_layoutcommit_data *data = calldata; | ||
5707 | struct nfs_server *server = NFS_SERVER(data->args.inode); | ||
5708 | |||
5709 | if (nfs4_setup_sequence(server, &data->args.seq_args, | ||
5710 | &data->res.seq_res, 1, task)) | ||
5711 | return; | ||
5712 | rpc_call_start(task); | ||
5713 | } | ||
5714 | |||
5715 | static void | ||
5716 | nfs4_layoutcommit_done(struct rpc_task *task, void *calldata) | ||
5717 | { | ||
5718 | struct nfs4_layoutcommit_data *data = calldata; | ||
5719 | struct nfs_server *server = NFS_SERVER(data->args.inode); | ||
5720 | |||
5721 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | ||
5722 | return; | ||
5723 | |||
5724 | switch (task->tk_status) { /* Just ignore these failures */ | ||
5725 | case NFS4ERR_DELEG_REVOKED: /* layout was recalled */ | ||
5726 | case NFS4ERR_BADIOMODE: /* no IOMODE_RW layout for range */ | ||
5727 | case NFS4ERR_BADLAYOUT: /* no layout */ | ||
5728 | case NFS4ERR_GRACE: /* loca_recalim always false */ | ||
5729 | task->tk_status = 0; | ||
5730 | } | ||
5731 | |||
5732 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { | ||
5733 | nfs_restart_rpc(task, server->nfs_client); | ||
5734 | return; | ||
5735 | } | ||
5736 | |||
5737 | if (task->tk_status == 0) | ||
5738 | nfs_post_op_update_inode_force_wcc(data->args.inode, | ||
5739 | data->res.fattr); | ||
5740 | } | ||
5741 | |||
5742 | static void nfs4_layoutcommit_release(void *calldata) | ||
5743 | { | ||
5744 | struct nfs4_layoutcommit_data *data = calldata; | ||
5745 | |||
5746 | /* Matched by references in pnfs_set_layoutcommit */ | ||
5747 | put_lseg(data->lseg); | ||
5748 | put_rpccred(data->cred); | ||
5749 | kfree(data); | ||
5750 | } | ||
5751 | |||
5752 | static const struct rpc_call_ops nfs4_layoutcommit_ops = { | ||
5753 | .rpc_call_prepare = nfs4_layoutcommit_prepare, | ||
5754 | .rpc_call_done = nfs4_layoutcommit_done, | ||
5755 | .rpc_release = nfs4_layoutcommit_release, | ||
5756 | }; | ||
5757 | |||
5758 | int | ||
5759 | nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync) | ||
5760 | { | ||
5761 | struct rpc_message msg = { | ||
5762 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTCOMMIT], | ||
5763 | .rpc_argp = &data->args, | ||
5764 | .rpc_resp = &data->res, | ||
5765 | .rpc_cred = data->cred, | ||
5766 | }; | ||
5767 | struct rpc_task_setup task_setup_data = { | ||
5768 | .task = &data->task, | ||
5769 | .rpc_client = NFS_CLIENT(data->args.inode), | ||
5770 | .rpc_message = &msg, | ||
5771 | .callback_ops = &nfs4_layoutcommit_ops, | ||
5772 | .callback_data = data, | ||
5773 | .flags = RPC_TASK_ASYNC, | ||
5774 | }; | ||
5775 | struct rpc_task *task; | ||
5776 | int status = 0; | ||
5777 | |||
5778 | dprintk("NFS: %4d initiating layoutcommit call. sync %d " | ||
5779 | "lbw: %llu inode %lu\n", | ||
5780 | data->task.tk_pid, sync, | ||
5781 | data->args.lastbytewritten, | ||
5782 | data->args.inode->i_ino); | ||
5783 | |||
5784 | task = rpc_run_task(&task_setup_data); | ||
5785 | if (IS_ERR(task)) | ||
5786 | return PTR_ERR(task); | ||
5787 | if (sync == false) | ||
5788 | goto out; | ||
5789 | status = nfs4_wait_for_completion_rpc_task(task); | ||
5790 | if (status != 0) | ||
5791 | goto out; | ||
5792 | status = task->tk_status; | ||
5793 | out: | ||
5794 | dprintk("%s: status %d\n", __func__, status); | ||
5795 | rpc_put_task(task); | ||
5796 | return status; | ||
5797 | } | ||
5701 | #endif /* CONFIG_NFS_V4_1 */ | 5798 | #endif /* CONFIG_NFS_V4_1 */ |
5702 | 5799 | ||
5703 | struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { | 5800 | struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { |