aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 15aeba20d57d..675ce3b8663c 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -250,7 +250,7 @@ static int filelayout_write_done_cb(struct rpc_task *task,
250} 250}
251 251
252/* Fake up some data that will cause nfs_commit_release to retry the writes. */ 252/* Fake up some data that will cause nfs_commit_release to retry the writes. */
253static void prepare_to_resend_writes(struct nfs_write_data *data) 253static void prepare_to_resend_writes(struct nfs_commit_data *data)
254{ 254{
255 struct nfs_page *first = nfs_list_entry(data->pages.next); 255 struct nfs_page *first = nfs_list_entry(data->pages.next);
256 256
@@ -261,11 +261,11 @@ static void prepare_to_resend_writes(struct nfs_write_data *data)
261} 261}
262 262
263static int filelayout_commit_done_cb(struct rpc_task *task, 263static int filelayout_commit_done_cb(struct rpc_task *task,
264 struct nfs_write_data *data) 264 struct nfs_commit_data *data)
265{ 265{
266 int reset = 0; 266 int reset = 0;
267 267
268 if (filelayout_async_handle_error(task, data->args.context->state, 268 if (filelayout_async_handle_error(task, data->context->state,
269 data->ds_clp, &reset) == -EAGAIN) { 269 data->ds_clp, &reset) == -EAGAIN) {
270 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 270 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
271 __func__, data->ds_clp, data->ds_clp->cl_session); 271 __func__, data->ds_clp, data->ds_clp->cl_session);
@@ -315,15 +315,42 @@ static void filelayout_write_release(void *data)
315 wdata->mds_ops->rpc_release(data); 315 wdata->mds_ops->rpc_release(data);
316} 316}
317 317
318static void filelayout_commit_release(void *data) 318static void filelayout_commit_prepare(struct rpc_task *task, void *data)
319{ 319{
320 struct nfs_write_data *wdata = (struct nfs_write_data *)data; 320 struct nfs_commit_data *wdata = data;
321 321
322 nfs_commit_release_pages(wdata); 322 if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
323 if (atomic_dec_and_test(&NFS_I(wdata->inode)->commits_outstanding)) 323 &wdata->args.seq_args, &wdata->res.seq_res,
324 nfs_commit_clear_lock(NFS_I(wdata->inode)); 324 task))
325 put_lseg(wdata->lseg); 325 return;
326 nfs_commitdata_release(wdata); 326
327 rpc_call_start(task);
328}
329
330static void filelayout_write_commit_done(struct rpc_task *task, void *data)
331{
332 struct nfs_commit_data *wdata = data;
333
334 /* Note this may cause RPC to be resent */
335 wdata->mds_ops->rpc_call_done(task, data);
336}
337
338static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
339{
340 struct nfs_commit_data *cdata = data;
341
342 rpc_count_iostats(task, NFS_SERVER(cdata->inode)->client->cl_metrics);
343}
344
345static void filelayout_commit_release(void *calldata)
346{
347 struct nfs_commit_data *data = calldata;
348
349 nfs_commit_release_pages(data);
350 if (atomic_dec_and_test(&NFS_I(data->inode)->commits_outstanding))
351 nfs_commit_clear_lock(NFS_I(data->inode));
352 put_lseg(data->lseg);
353 nfs_commitdata_release(data);
327} 354}
328 355
329static const struct rpc_call_ops filelayout_read_call_ops = { 356static const struct rpc_call_ops filelayout_read_call_ops = {
@@ -341,9 +368,9 @@ static const struct rpc_call_ops filelayout_write_call_ops = {
341}; 368};
342 369
343static const struct rpc_call_ops filelayout_commit_call_ops = { 370static const struct rpc_call_ops filelayout_commit_call_ops = {
344 .rpc_call_prepare = filelayout_write_prepare, 371 .rpc_call_prepare = filelayout_commit_prepare,
345 .rpc_call_done = filelayout_write_call_done, 372 .rpc_call_done = filelayout_write_commit_done,
346 .rpc_count_stats = filelayout_write_count_stats, 373 .rpc_count_stats = filelayout_commit_count_stats,
347 .rpc_release = filelayout_commit_release, 374 .rpc_release = filelayout_commit_release,
348}; 375};
349 376
@@ -922,7 +949,7 @@ select_ds_fh_from_commit(struct pnfs_layout_segment *lseg, u32 i)
922 return flseg->fh_array[i]; 949 return flseg->fh_array[i];
923} 950}
924 951
925static int filelayout_initiate_commit(struct nfs_write_data *data, int how) 952static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
926{ 953{
927 struct pnfs_layout_segment *lseg = data->lseg; 954 struct pnfs_layout_segment *lseg = data->lseg;
928 struct nfs4_pnfs_ds *ds; 955 struct nfs4_pnfs_ds *ds;
@@ -941,12 +968,12 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
941 return -EAGAIN; 968 return -EAGAIN;
942 } 969 }
943 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how); 970 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how);
944 data->write_done_cb = filelayout_commit_done_cb; 971 data->commit_done_cb = filelayout_commit_done_cb;
945 data->ds_clp = ds->ds_clp; 972 data->ds_clp = ds->ds_clp;
946 fh = select_ds_fh_from_commit(lseg, data->ds_commit_index); 973 fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
947 if (fh) 974 if (fh)
948 data->args.fh = fh; 975 data->args.fh = fh;
949 return nfs_initiate_commit(data, ds->ds_clp->cl_rpcclient, 976 return nfs_initiate_commit(ds->ds_clp->cl_rpcclient, data,
950 &filelayout_commit_call_ops, how); 977 &filelayout_commit_call_ops, how);
951} 978}
952 979
@@ -1008,7 +1035,7 @@ alloc_ds_commits(struct inode *inode, struct list_head *list)
1008{ 1035{
1009 struct nfs4_fl_commit_info *fl_cinfo; 1036 struct nfs4_fl_commit_info *fl_cinfo;
1010 struct nfs4_fl_commit_bucket *bucket; 1037 struct nfs4_fl_commit_bucket *bucket;
1011 struct nfs_write_data *data; 1038 struct nfs_commit_data *data;
1012 int i, j; 1039 int i, j;
1013 unsigned int nreq = 0; 1040 unsigned int nreq = 0;
1014 1041
@@ -1044,7 +1071,7 @@ static int
1044filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, 1071filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1045 int how) 1072 int how)
1046{ 1073{
1047 struct nfs_write_data *data, *tmp; 1074 struct nfs_commit_data *data, *tmp;
1048 LIST_HEAD(list); 1075 LIST_HEAD(list);
1049 unsigned int nreq = 0; 1076 unsigned int nreq = 0;
1050 1077
@@ -1071,7 +1098,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1071 list_del_init(&data->pages); 1098 list_del_init(&data->pages);
1072 if (!data->lseg) { 1099 if (!data->lseg) {
1073 nfs_init_commit(data, mds_pages, NULL); 1100 nfs_init_commit(data, mds_pages, NULL);
1074 nfs_initiate_commit(data, NFS_CLIENT(inode), 1101 nfs_initiate_commit(NFS_CLIENT(inode), data,
1075 data->mds_ops, how); 1102 data->mds_ops, how);
1076 } else { 1103 } else {
1077 struct nfs4_fl_commit_info *fl_cinfo; 1104 struct nfs4_fl_commit_info *fl_cinfo;