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.c98
1 files changed, 95 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d0e15dba7a5a..d2c4b59c896d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2363,6 +2363,9 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2363 struct nfs4_state *state = NULL; 2363 struct nfs4_state *state = NULL;
2364 int status; 2364 int status;
2365 2365
2366 if (pnfs_ld_layoutret_on_setattr(inode))
2367 pnfs_return_layout(inode);
2368
2366 nfs_fattr_init(fattr); 2369 nfs_fattr_init(fattr);
2367 2370
2368 /* Search for an existing open(O_WRITE) file */ 2371 /* Search for an existing open(O_WRITE) file */
@@ -3177,6 +3180,11 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
3177 return err; 3180 return err;
3178} 3181}
3179 3182
3183void __nfs4_read_done_cb(struct nfs_read_data *data)
3184{
3185 nfs_invalidate_atime(data->inode);
3186}
3187
3180static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) 3188static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3181{ 3189{
3182 struct nfs_server *server = NFS_SERVER(data->inode); 3190 struct nfs_server *server = NFS_SERVER(data->inode);
@@ -3186,7 +3194,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3186 return -EAGAIN; 3194 return -EAGAIN;
3187 } 3195 }
3188 3196
3189 nfs_invalidate_atime(data->inode); 3197 __nfs4_read_done_cb(data);
3190 if (task->tk_status > 0) 3198 if (task->tk_status > 0)
3191 renew_lease(server, data->timestamp); 3199 renew_lease(server, data->timestamp);
3192 return 0; 3200 return 0;
@@ -3200,7 +3208,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
3200 if (!nfs4_sequence_done(task, &data->res.seq_res)) 3208 if (!nfs4_sequence_done(task, &data->res.seq_res))
3201 return -EAGAIN; 3209 return -EAGAIN;
3202 3210
3203 return data->read_done_cb(task, data); 3211 return data->read_done_cb ? data->read_done_cb(task, data) :
3212 nfs4_read_done_cb(task, data);
3204} 3213}
3205 3214
3206static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) 3215static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
@@ -3245,7 +3254,8 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
3245{ 3254{
3246 if (!nfs4_sequence_done(task, &data->res.seq_res)) 3255 if (!nfs4_sequence_done(task, &data->res.seq_res))
3247 return -EAGAIN; 3256 return -EAGAIN;
3248 return data->write_done_cb(task, data); 3257 return data->write_done_cb ? data->write_done_cb(task, data) :
3258 nfs4_write_done_cb(task, data);
3249} 3259}
3250 3260
3251/* Reset the the nfs_write_data to send the write to the MDS. */ 3261/* Reset the the nfs_write_data to send the write to the MDS. */
@@ -5671,6 +5681,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
5671 return status; 5681 return status;
5672} 5682}
5673 5683
5684static void
5685nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
5686{
5687 struct nfs4_layoutreturn *lrp = calldata;
5688
5689 dprintk("--> %s\n", __func__);
5690 if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args,
5691 &lrp->res.seq_res, 0, task))
5692 return;
5693 rpc_call_start(task);
5694}
5695
5696static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
5697{
5698 struct nfs4_layoutreturn *lrp = calldata;
5699 struct nfs_server *server;
5700
5701 dprintk("--> %s\n", __func__);
5702
5703 if (!nfs4_sequence_done(task, &lrp->res.seq_res))
5704 return;
5705
5706 server = NFS_SERVER(lrp->args.inode);
5707 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
5708 nfs_restart_rpc(task, lrp->clp);
5709 return;
5710 }
5711 if (task->tk_status == 0) {
5712 struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
5713
5714 if (lrp->res.lrs_present) {
5715 spin_lock(&lo->plh_inode->i_lock);
5716 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
5717 spin_unlock(&lo->plh_inode->i_lock);
5718 } else
5719 BUG_ON(!list_empty(&lo->plh_segs));
5720 }
5721 dprintk("<-- %s\n", __func__);
5722}
5723
5724static void nfs4_layoutreturn_release(void *calldata)
5725{
5726 struct nfs4_layoutreturn *lrp = calldata;
5727
5728 dprintk("--> %s\n", __func__);
5729 put_layout_hdr(NFS_I(lrp->args.inode)->layout);
5730 kfree(calldata);
5731 dprintk("<-- %s\n", __func__);
5732}
5733
5734static const struct rpc_call_ops nfs4_layoutreturn_call_ops = {
5735 .rpc_call_prepare = nfs4_layoutreturn_prepare,
5736 .rpc_call_done = nfs4_layoutreturn_done,
5737 .rpc_release = nfs4_layoutreturn_release,
5738};
5739
5740int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
5741{
5742 struct rpc_task *task;
5743 struct rpc_message msg = {
5744 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN],
5745 .rpc_argp = &lrp->args,
5746 .rpc_resp = &lrp->res,
5747 };
5748 struct rpc_task_setup task_setup_data = {
5749 .rpc_client = lrp->clp->cl_rpcclient,
5750 .rpc_message = &msg,
5751 .callback_ops = &nfs4_layoutreturn_call_ops,
5752 .callback_data = lrp,
5753 };
5754 int status;
5755
5756 dprintk("--> %s\n", __func__);
5757 task = rpc_run_task(&task_setup_data);
5758 if (IS_ERR(task))
5759 return PTR_ERR(task);
5760 status = task->tk_status;
5761 dprintk("<-- %s status=%d\n", __func__, status);
5762 rpc_put_task(task);
5763 return status;
5764}
5765
5674static int 5766static int
5675_nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) 5767_nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
5676{ 5768{