diff options
author | Fred Isaman <iisaman@netapp.com> | 2012-04-20 14:47:48 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:38 -0400 |
commit | 061ae2edb7375ab6776468b075da71008a098b55 (patch) | |
tree | a34f25d4d85d90a196b058b879eef3ba374f6d16 /fs/nfs/write.c | |
parent | 6c75dc0d498caa402fb17b1bf769835a9db875c8 (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.c | 41 |
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 | */ |
42 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, | 42 | static 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); | ||
44 | static void nfs_redirty_request(struct nfs_page *req); | 45 | static void nfs_redirty_request(struct nfs_page *req); |
45 | static const struct rpc_call_ops nfs_write_common_ops; | 46 | static const struct rpc_call_ops nfs_write_common_ops; |
46 | static const struct rpc_call_ops nfs_commit_ops; | 47 | static const struct rpc_call_ops nfs_commit_ops; |
48 | static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; | ||
47 | 49 | ||
48 | static struct kmem_cache *nfs_wdata_cachep; | 50 | static struct kmem_cache *nfs_wdata_cachep; |
49 | static mempool_t *nfs_wdata_mempool; | 51 | static 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 | ||
134 | static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | 136 | static 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 | ||
561 | void nfs_write_completion(struct nfs_pgio_header *hdr) | 565 | static 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 | ||
1003 | void nfs_async_write_error(struct list_head *head) | 1007 | static 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 | ||
1018 | static 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 | ||
1151 | void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, | 1160 | void 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) | |||
1163 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); | 1173 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); |
1164 | 1174 | ||
1165 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, | 1175 | static 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 | ||
1172 | void nfs_write_prepare(struct rpc_task *task, void *calldata) | 1183 | void nfs_write_prepare(struct rpc_task *task, void *calldata) |