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/pagelist.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/pagelist.c')
-rw-r--r-- | fs/nfs/pagelist.c | 62 |
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 | ||
27 | static struct kmem_cache *nfs_page_cachep; | 27 | static struct kmem_cache *nfs_page_cachep; |
28 | 28 | ||
29 | bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount) | 29 | static 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 | } |
296 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); | 296 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); |
297 | 297 | ||
298 | static 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 | */ | ||
308 | struct 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 | } | ||
329 | out: | ||
330 | return data; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * nfs_pgio_data_release - Properly free pageio data | ||
335 | * @data: The data to release | ||
336 | */ | ||
337 | void 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 | } | ||
356 | EXPORT_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 |