aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2012-04-20 14:47:48 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 14:10:38 -0400
commit061ae2edb7375ab6776468b075da71008a098b55 (patch)
treea34f25d4d85d90a196b058b879eef3ba374f6d16 /fs/nfs/write.c
parent6c75dc0d498caa402fb17b1bf769835a9db875c8 (diff)
NFS: create completion structure to pass into page_init functions
Factors out the code that will need to change when directio starts using these code paths. This will allow directio to use the generic pagein and flush routines Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
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)