aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c82
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
5676static void
5677nfs4_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
5688static 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
5716static 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
5726static 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
5732int 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
5676static int 5758static 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{