diff options
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 65 |
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. */ |
253 | static void prepare_to_resend_writes(struct nfs_write_data *data) | 253 | static 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 | ||
263 | static int filelayout_commit_done_cb(struct rpc_task *task, | 263 | static 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 | ||
318 | static void filelayout_commit_release(void *data) | 318 | static 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 | |||
330 | static 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 | |||
338 | static 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 | |||
345 | static 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 | ||
329 | static const struct rpc_call_ops filelayout_read_call_ops = { | 356 | static 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 | ||
343 | static const struct rpc_call_ops filelayout_commit_call_ops = { | 370 | static 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 | ||
925 | static int filelayout_initiate_commit(struct nfs_write_data *data, int how) | 952 | static 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 | |||
1044 | filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, | 1071 | filelayout_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; |