aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pagelist.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/pagelist.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/pagelist.c')
-rw-r--r--fs/nfs/pagelist.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 2ffebf2081ce..a98ccf722d7b 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -26,7 +26,7 @@
26 26
27static struct kmem_cache *nfs_page_cachep; 27static struct kmem_cache *nfs_page_cachep;
28 28
29bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount) 29static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
30{ 30{
31 p->npages = pagecount; 31 p->npages = pagecount;
32 if (pagecount <= ARRAY_SIZE(p->page_array)) 32 if (pagecount <= ARRAY_SIZE(p->page_array))
@@ -295,6 +295,66 @@ bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *pr
295} 295}
296EXPORT_SYMBOL_GPL(nfs_generic_pg_test); 296EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
297 297
298static inline struct nfs_rw_header *NFS_RW_HEADER(struct nfs_pgio_header *hdr)
299{
300 return container_of(hdr, struct nfs_rw_header, header);
301}
302
303/**
304 * nfs_pgio_data_alloc - Allocate pageio data
305 * @hdr: The header making a request
306 * @pagecount: Number of pages to create
307 */
308struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *hdr,
309 unsigned int pagecount)
310{
311 struct nfs_pgio_data *data, *prealloc;
312
313 prealloc = &NFS_RW_HEADER(hdr)->rpc_data;
314 if (prealloc->header == NULL)
315 data = prealloc;
316 else
317 data = kzalloc(sizeof(*data), GFP_KERNEL);
318 if (!data)
319 goto out;
320
321 if (nfs_pgarray_set(&data->pages, pagecount)) {
322 data->header = hdr;
323 atomic_inc(&hdr->refcnt);
324 } else {
325 if (data != prealloc)
326 kfree(data);
327 data = NULL;
328 }
329out:
330 return data;
331}
332
333/**
334 * nfs_pgio_data_release - Properly free pageio data
335 * @data: The data to release
336 */
337void nfs_pgio_data_release(struct nfs_pgio_data *data)
338{
339 struct nfs_pgio_header *hdr = data->header;
340 struct nfs_rw_header *pageio_header = NFS_RW_HEADER(hdr);
341
342 put_nfs_open_context(data->args.context);
343 if (data->pages.pagevec != data->pages.page_array)
344 kfree(data->pages.pagevec);
345 if (data == &pageio_header->rpc_data) {
346 data->header = NULL;
347 data = NULL;
348 }
349 if (atomic_dec_and_test(&hdr->refcnt))
350 hdr->completion_ops->completion(hdr);
351 /* Note: we only free the rpc_task after callbacks are done.
352 * See the comment in rpc_free_task() for why
353 */
354 kfree(data);
355}
356EXPORT_SYMBOL_GPL(nfs_pgio_data_release);
357
298/** 358/**
299 * nfs_pageio_init - initialise a page io descriptor 359 * nfs_pageio_init - initialise a page io descriptor
300 * @desc: pointer to descriptor 360 * @desc: pointer to descriptor