diff options
author | Anna Schumaker <Anna.Schumaker@netapp.com> | 2014-05-06 09:12:29 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-05-28 18:39:55 -0400 |
commit | 00bfa30abe86982ce1929e9cabd703e5546106bd (patch) | |
tree | 902a6cf951f53be35916332635016ad0378c60b7 /fs/nfs/read.c | |
parent | f79d06f544a797d75cbf5256a5d06c4b3d2759cc (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.c | 54 |
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 | } |
52 | EXPORT_SYMBOL_GPL(nfs_readhdr_alloc); | 52 | EXPORT_SYMBOL_GPL(nfs_readhdr_alloc); |
53 | 53 | ||
54 | static 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 | } | ||
75 | out: | ||
76 | return data; | ||
77 | } | ||
78 | |||
79 | void nfs_readhdr_free(struct nfs_pgio_header *hdr) | 54 | void 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 | } |
85 | EXPORT_SYMBOL_GPL(nfs_readhdr_free); | 60 | EXPORT_SYMBOL_GPL(nfs_readhdr_free); |
86 | 61 | ||
87 | void 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 | } | ||
106 | EXPORT_SYMBOL_GPL(nfs_readdata_release); | ||
107 | |||
108 | static | 62 | static |
109 | int nfs_return_empty_page(struct page *page) | 63 | int 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 | ||
516 | static void nfs_readpage_release_common(void *calldata) | 470 | static void nfs_readpage_release_common(void *calldata) |
517 | { | 471 | { |
518 | nfs_readdata_release(calldata); | 472 | nfs_pgio_data_release(calldata); |
519 | } | 473 | } |
520 | 474 | ||
521 | void nfs_read_prepare(struct rpc_task *task, void *calldata) | 475 | void nfs_read_prepare(struct rpc_task *task, void *calldata) |