aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/read.c
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@netapp.com>2014-05-06 09:12:29 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-05-28 18:39:55 -0400
commit00bfa30abe86982ce1929e9cabd703e5546106bd (patch)
tree902a6cf951f53be35916332635016ad0378c60b7 /fs/nfs/read.c
parentf79d06f544a797d75cbf5256a5d06c4b3d2759cc (diff)
NFS: Create a common pgio_alloc and pgio_release function
These functions are identical for the read and write paths so they can be combined. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r--fs/nfs/read.c54
1 files changed, 4 insertions, 50 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index d29ca3673694..ab4c1a5b5fbd 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -51,31 +51,6 @@ struct nfs_rw_header *nfs_readhdr_alloc(void)
51} 51}
52EXPORT_SYMBOL_GPL(nfs_readhdr_alloc); 52EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
53 53
54static struct nfs_pgio_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
55 unsigned int pagecount)
56{
57 struct nfs_pgio_data *data, *prealloc;
58
59 prealloc = &container_of(hdr, struct nfs_rw_header, header)->rpc_data;
60 if (prealloc->header == NULL)
61 data = prealloc;
62 else
63 data = kzalloc(sizeof(*data), GFP_KERNEL);
64 if (!data)
65 goto out;
66
67 if (nfs_pgarray_set(&data->pages, pagecount)) {
68 data->header = hdr;
69 atomic_inc(&hdr->refcnt);
70 } else {
71 if (data != prealloc)
72 kfree(data);
73 data = NULL;
74 }
75out:
76 return data;
77}
78
79void nfs_readhdr_free(struct nfs_pgio_header *hdr) 54void nfs_readhdr_free(struct nfs_pgio_header *hdr)
80{ 55{
81 struct nfs_rw_header *rhdr = container_of(hdr, struct nfs_rw_header, header); 56 struct nfs_rw_header *rhdr = container_of(hdr, struct nfs_rw_header, header);
@@ -84,27 +59,6 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
84} 59}
85EXPORT_SYMBOL_GPL(nfs_readhdr_free); 60EXPORT_SYMBOL_GPL(nfs_readhdr_free);
86 61
87void nfs_readdata_release(struct nfs_pgio_data *rdata)
88{
89 struct nfs_pgio_header *hdr = rdata->header;
90 struct nfs_rw_header *read_header = container_of(hdr, struct nfs_rw_header, header);
91
92 put_nfs_open_context(rdata->args.context);
93 if (rdata->pages.pagevec != rdata->pages.page_array)
94 kfree(rdata->pages.pagevec);
95 if (rdata == &read_header->rpc_data) {
96 rdata->header = NULL;
97 rdata = NULL;
98 }
99 if (atomic_dec_and_test(&hdr->refcnt))
100 hdr->completion_ops->completion(hdr);
101 /* Note: we only free the rpc_task after callbacks are done.
102 * See the comment in rpc_free_task() for why
103 */
104 kfree(rdata);
105}
106EXPORT_SYMBOL_GPL(nfs_readdata_release);
107
108static 62static
109int nfs_return_empty_page(struct page *page) 63int nfs_return_empty_page(struct page *page)
110{ 64{
@@ -327,7 +281,7 @@ static void nfs_pagein_error(struct nfs_pageio_descriptor *desc,
327 struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list, 281 struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list,
328 struct nfs_pgio_data, list); 282 struct nfs_pgio_data, list);
329 list_del(&data->list); 283 list_del(&data->list);
330 nfs_readdata_release(data); 284 nfs_pgio_data_release(data);
331 } 285 }
332 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 286 desc->pg_completion_ops->error_cleanup(&desc->pg_list);
333} 287}
@@ -359,7 +313,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc,
359 do { 313 do {
360 size_t len = min(nbytes,rsize); 314 size_t len = min(nbytes,rsize);
361 315
362 data = nfs_readdata_alloc(hdr, 1); 316 data = nfs_pgio_data_alloc(hdr, 1);
363 if (!data) { 317 if (!data) {
364 nfs_pagein_error(desc, hdr); 318 nfs_pagein_error(desc, hdr);
365 return -ENOMEM; 319 return -ENOMEM;
@@ -385,7 +339,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc,
385 struct nfs_pgio_data *data; 339 struct nfs_pgio_data *data;
386 struct list_head *head = &desc->pg_list; 340 struct list_head *head = &desc->pg_list;
387 341
388 data = nfs_readdata_alloc(hdr, nfs_page_array_len(desc->pg_base, 342 data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base,
389 desc->pg_count)); 343 desc->pg_count));
390 if (!data) { 344 if (!data) {
391 nfs_pagein_error(desc, hdr); 345 nfs_pagein_error(desc, hdr);
@@ -515,7 +469,7 @@ static void nfs_readpage_result_common(struct rpc_task *task, void *calldata)
515 469
516static void nfs_readpage_release_common(void *calldata) 470static void nfs_readpage_release_common(void *calldata)
517{ 471{
518 nfs_readdata_release(calldata); 472 nfs_pgio_data_release(calldata);
519} 473}
520 474
521void nfs_read_prepare(struct rpc_task *task, void *calldata) 475void nfs_read_prepare(struct rpc_task *task, void *calldata)