diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92c8bc4b5f97..5b4124e4c22f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -5673,6 +5673,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
5673 | return status; | 5673 | return status; |
5674 | } | 5674 | } |
5675 | 5675 | ||
5676 | static void | ||
5677 | nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata) | ||
5678 | { | ||
5679 | struct nfs4_layoutreturn *lrp = calldata; | ||
5680 | |||
5681 | dprintk("--> %s\n", __func__); | ||
5682 | if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, | ||
5683 | &lrp->res.seq_res, 0, task)) | ||
5684 | return; | ||
5685 | rpc_call_start(task); | ||
5686 | } | ||
5687 | |||
5688 | static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | ||
5689 | { | ||
5690 | struct nfs4_layoutreturn *lrp = calldata; | ||
5691 | struct nfs_server *server; | ||
5692 | |||
5693 | dprintk("--> %s\n", __func__); | ||
5694 | |||
5695 | if (!nfs4_sequence_done(task, &lrp->res.seq_res)) | ||
5696 | return; | ||
5697 | |||
5698 | server = NFS_SERVER(lrp->args.inode); | ||
5699 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { | ||
5700 | nfs_restart_rpc(task, lrp->clp); | ||
5701 | return; | ||
5702 | } | ||
5703 | if (task->tk_status == 0) { | ||
5704 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
5705 | |||
5706 | if (lrp->res.lrs_present) { | ||
5707 | spin_lock(&lo->plh_inode->i_lock); | ||
5708 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | ||
5709 | spin_unlock(&lo->plh_inode->i_lock); | ||
5710 | } else | ||
5711 | BUG_ON(!list_empty(&lo->plh_segs)); | ||
5712 | } | ||
5713 | dprintk("<-- %s\n", __func__); | ||
5714 | } | ||
5715 | |||
5716 | static void nfs4_layoutreturn_release(void *calldata) | ||
5717 | { | ||
5718 | struct nfs4_layoutreturn *lrp = calldata; | ||
5719 | |||
5720 | dprintk("--> %s\n", __func__); | ||
5721 | put_layout_hdr(NFS_I(lrp->args.inode)->layout); | ||
5722 | kfree(calldata); | ||
5723 | dprintk("<-- %s\n", __func__); | ||
5724 | } | ||
5725 | |||
5726 | static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { | ||
5727 | .rpc_call_prepare = nfs4_layoutreturn_prepare, | ||
5728 | .rpc_call_done = nfs4_layoutreturn_done, | ||
5729 | .rpc_release = nfs4_layoutreturn_release, | ||
5730 | }; | ||
5731 | |||
5732 | int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) | ||
5733 | { | ||
5734 | struct rpc_task *task; | ||
5735 | struct rpc_message msg = { | ||
5736 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], | ||
5737 | .rpc_argp = &lrp->args, | ||
5738 | .rpc_resp = &lrp->res, | ||
5739 | }; | ||
5740 | struct rpc_task_setup task_setup_data = { | ||
5741 | .rpc_client = lrp->clp->cl_rpcclient, | ||
5742 | .rpc_message = &msg, | ||
5743 | .callback_ops = &nfs4_layoutreturn_call_ops, | ||
5744 | .callback_data = lrp, | ||
5745 | }; | ||
5746 | int status; | ||
5747 | |||
5748 | dprintk("--> %s\n", __func__); | ||
5749 | task = rpc_run_task(&task_setup_data); | ||
5750 | if (IS_ERR(task)) | ||
5751 | return PTR_ERR(task); | ||
5752 | status = task->tk_status; | ||
5753 | dprintk("<-- %s status=%d\n", __func__, status); | ||
5754 | rpc_put_task(task); | ||
5755 | return status; | ||
5756 | } | ||
5757 | |||
5676 | static int | 5758 | static int |
5677 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) | 5759 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) |
5678 | { | 5760 | { |