aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 076075eb676c..150397279b8d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -40,10 +40,12 @@
40 * Local function declarations 40 * Local function declarations
41 */ 41 */
42static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, 42static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc,
43 struct inode *inode, int ioflags); 43 struct inode *inode, int ioflags,
44 const struct nfs_pgio_completion_ops *compl_ops);
44static void nfs_redirty_request(struct nfs_page *req); 45static void nfs_redirty_request(struct nfs_page *req);
45static const struct rpc_call_ops nfs_write_common_ops; 46static const struct rpc_call_ops nfs_write_common_ops;
46static const struct rpc_call_ops nfs_commit_ops; 47static const struct rpc_call_ops nfs_commit_ops;
48static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
47 49
48static struct kmem_cache *nfs_wdata_cachep; 50static struct kmem_cache *nfs_wdata_cachep;
49static mempool_t *nfs_wdata_mempool; 51static mempool_t *nfs_wdata_mempool;
@@ -128,7 +130,7 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
128 else 130 else
129 wdata->header = NULL; 131 wdata->header = NULL;
130 if (atomic_dec_and_test(&hdr->refcnt)) 132 if (atomic_dec_and_test(&hdr->refcnt))
131 nfs_write_completion(hdr); 133 hdr->completion_ops->completion(hdr);
132} 134}
133 135
134static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) 136static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
@@ -337,7 +339,8 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc
337 struct nfs_pageio_descriptor pgio; 339 struct nfs_pageio_descriptor pgio;
338 int err; 340 int err;
339 341
340 nfs_pageio_init_write(&pgio, page->mapping->host, wb_priority(wbc)); 342 nfs_pageio_init_write(&pgio, page->mapping->host, wb_priority(wbc),
343 &nfs_async_write_completion_ops);
341 err = nfs_do_writepage(page, wbc, &pgio); 344 err = nfs_do_writepage(page, wbc, &pgio);
342 nfs_pageio_complete(&pgio); 345 nfs_pageio_complete(&pgio);
343 if (err < 0) 346 if (err < 0)
@@ -380,7 +383,8 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
380 383
381 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); 384 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
382 385
383 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc)); 386 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc),
387 &nfs_async_write_completion_ops);
384 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio); 388 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
385 nfs_pageio_complete(&pgio); 389 nfs_pageio_complete(&pgio);
386 390
@@ -558,7 +562,7 @@ int nfs_write_need_commit(struct nfs_write_data *data)
558 562
559#endif 563#endif
560 564
561void nfs_write_completion(struct nfs_pgio_header *hdr) 565static void nfs_write_completion(struct nfs_pgio_header *hdr)
562{ 566{
563 unsigned long bytes = 0; 567 unsigned long bytes = 0;
564 568
@@ -1000,7 +1004,7 @@ static void nfs_redirty_request(struct nfs_page *req)
1000 nfs_end_page_writeback(page); 1004 nfs_end_page_writeback(page);
1001} 1005}
1002 1006
1003void nfs_async_write_error(struct list_head *head) 1007static void nfs_async_write_error(struct list_head *head)
1004{ 1008{
1005 struct nfs_page *req; 1009 struct nfs_page *req;
1006 1010
@@ -1011,6 +1015,11 @@ void nfs_async_write_error(struct list_head *head)
1011 } 1015 }
1012} 1016}
1013 1017
1018static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
1019 .error_cleanup = nfs_async_write_error,
1020 .completion = nfs_write_completion,
1021};
1022
1014/* 1023/*
1015 * Generate multiple small requests to write out a single 1024 * Generate multiple small requests to write out a single
1016 * contiguous dirty area on one page. 1025 * contiguous dirty area on one page.
@@ -1060,7 +1069,7 @@ out_bad:
1060 list_del(&data->list); 1069 list_del(&data->list);
1061 nfs_writedata_release(data); 1070 nfs_writedata_release(data);
1062 } 1071 }
1063 nfs_async_write_error(&hdr->pages); 1072 desc->pg_completion_ops->error_cleanup(&hdr->pages);
1064 return -ENOMEM; 1073 return -ENOMEM;
1065} 1074}
1066 1075
@@ -1084,7 +1093,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc,
1084 data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base, 1093 data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base,
1085 desc->pg_count)); 1094 desc->pg_count));
1086 if (!data) { 1095 if (!data) {
1087 nfs_async_write_error(head); 1096 desc->pg_completion_ops->error_cleanup(head);
1088 ret = -ENOMEM; 1097 ret = -ENOMEM;
1089 goto out; 1098 goto out;
1090 } 1099 }
@@ -1125,7 +1134,7 @@ static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
1125 1134
1126 whdr = nfs_writehdr_alloc(); 1135 whdr = nfs_writehdr_alloc();
1127 if (!whdr) { 1136 if (!whdr) {
1128 nfs_async_write_error(&desc->pg_list); 1137 desc->pg_completion_ops->error_cleanup(&hdr->pages);
1129 return -ENOMEM; 1138 return -ENOMEM;
1130 } 1139 }
1131 hdr = &whdr->header; 1140 hdr = &whdr->header;
@@ -1139,7 +1148,7 @@ static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
1139 else 1148 else
1140 set_bit(NFS_IOHDR_REDO, &hdr->flags); 1149 set_bit(NFS_IOHDR_REDO, &hdr->flags);
1141 if (atomic_dec_and_test(&hdr->refcnt)) 1150 if (atomic_dec_and_test(&hdr->refcnt))
1142 nfs_write_completion(hdr); 1151 hdr->completion_ops->completion(hdr);
1143 return ret; 1152 return ret;
1144} 1153}
1145 1154
@@ -1149,9 +1158,10 @@ static const struct nfs_pageio_ops nfs_pageio_write_ops = {
1149}; 1158};
1150 1159
1151void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, 1160void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
1152 struct inode *inode, int ioflags) 1161 struct inode *inode, int ioflags,
1162 const struct nfs_pgio_completion_ops *compl_ops)
1153{ 1163{
1154 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, 1164 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, compl_ops,
1155 NFS_SERVER(inode)->wsize, ioflags); 1165 NFS_SERVER(inode)->wsize, ioflags);
1156} 1166}
1157 1167
@@ -1163,10 +1173,11 @@ void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
1163EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); 1173EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds);
1164 1174
1165static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, 1175static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
1166 struct inode *inode, int ioflags) 1176 struct inode *inode, int ioflags,
1177 const struct nfs_pgio_completion_ops *compl_ops)
1167{ 1178{
1168 if (!pnfs_pageio_init_write(pgio, inode, ioflags)) 1179 if (!pnfs_pageio_init_write(pgio, inode, ioflags, compl_ops))
1169 nfs_pageio_init_write_mds(pgio, inode, ioflags); 1180 nfs_pageio_init_write_mds(pgio, inode, ioflags, compl_ops);
1170} 1181}
1171 1182
1172void nfs_write_prepare(struct rpc_task *task, void *calldata) 1183void nfs_write_prepare(struct rpc_task *task, void *calldata)