aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pagelist.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2014-06-09 11:48:33 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-06-24 18:46:59 -0400
commit1e7f3a485922211b6e4a082ebc6bf05810b0b6ea (patch)
tree409983ab4e7f9e880f31afd0648eb3ca039e1b5a /fs/nfs/pagelist.c
parent66b068604903849c5dee3842eb72564064c64c72 (diff)
nfs: move nfs_pgio_data and remove nfs_rw_header
nfs_rw_header was used to allocate an nfs_pgio_header along with an nfs_pgio_data, because a _header would need at least one _data. Now there is only ever one nfs_pgio_data for each nfs_pgio_header -- move it to nfs_pgio_header and get rid of nfs_rw_header. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Weston Andros Adamson <dros@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r--fs/nfs/pagelist.c94
1 files changed, 28 insertions, 66 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index b6ee3a6ee96d..e4cde476562f 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -452,95 +452,61 @@ size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
452} 452}
453EXPORT_SYMBOL_GPL(nfs_generic_pg_test); 453EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
454 454
455static inline struct nfs_rw_header *NFS_RW_HEADER(struct nfs_pgio_header *hdr) 455struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *ops)
456{ 456{
457 return container_of(hdr, struct nfs_rw_header, header); 457 struct nfs_pgio_header *hdr = ops->rw_alloc_header();
458}
459
460/**
461 * nfs_rw_header_alloc - Allocate a header for a read or write
462 * @ops: Read or write function vector
463 */
464struct nfs_rw_header *nfs_rw_header_alloc(const struct nfs_rw_ops *ops)
465{
466 struct nfs_rw_header *header = ops->rw_alloc_header();
467
468 if (header) {
469 struct nfs_pgio_header *hdr = &header->header;
470 458
459 if (hdr) {
471 INIT_LIST_HEAD(&hdr->pages); 460 INIT_LIST_HEAD(&hdr->pages);
472 spin_lock_init(&hdr->lock); 461 spin_lock_init(&hdr->lock);
473 atomic_set(&hdr->refcnt, 0); 462 atomic_set(&hdr->refcnt, 0);
474 hdr->rw_ops = ops; 463 hdr->rw_ops = ops;
475 } 464 }
476 return header; 465 return hdr;
477} 466}
478EXPORT_SYMBOL_GPL(nfs_rw_header_alloc); 467EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc);
479 468
480/* 469/*
481 * nfs_rw_header_free - Free a read or write header 470 * nfs_pgio_header_free - Free a read or write header
482 * @hdr: The header to free 471 * @hdr: The header to free
483 */ 472 */
484void nfs_rw_header_free(struct nfs_pgio_header *hdr) 473void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
485{ 474{
486 hdr->rw_ops->rw_free_header(NFS_RW_HEADER(hdr)); 475 hdr->rw_ops->rw_free_header(hdr);
487} 476}
488EXPORT_SYMBOL_GPL(nfs_rw_header_free); 477EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
489 478
490/** 479/**
491 * nfs_pgio_data_alloc - Allocate pageio data 480 * nfs_pgio_data_alloc - Allocate pageio data
492 * @hdr: The header making a request 481 * @hdr: The header making a request
493 * @pagecount: Number of pages to create 482 * @pagecount: Number of pages to create
494 */ 483 */
495static struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *hdr, 484static bool nfs_pgio_data_init(struct nfs_pgio_header *hdr,
496 unsigned int pagecount) 485 unsigned int pagecount)
497{ 486{
498 struct nfs_pgio_data *data, *prealloc; 487 if (nfs_pgarray_set(&hdr->data.pages, pagecount)) {
499 488 hdr->data.header = hdr;
500 prealloc = &NFS_RW_HEADER(hdr)->rpc_data;
501 if (prealloc->header == NULL)
502 data = prealloc;
503 else
504 data = kzalloc(sizeof(*data), GFP_KERNEL);
505 if (!data)
506 goto out;
507
508 if (nfs_pgarray_set(&data->pages, pagecount)) {
509 data->header = hdr;
510 atomic_inc(&hdr->refcnt); 489 atomic_inc(&hdr->refcnt);
511 } else { 490 return true;
512 if (data != prealloc)
513 kfree(data);
514 data = NULL;
515 } 491 }
516out: 492 return false;
517 return data;
518} 493}
519 494
520/** 495/**
521 * nfs_pgio_data_release - Properly free pageio data 496 * nfs_pgio_data_destroy - Properly free pageio data
522 * @data: The data to release 497 * @data: The data to destroy
523 */ 498 */
524void nfs_pgio_data_release(struct nfs_pgio_data *data) 499void nfs_pgio_data_destroy(struct nfs_pgio_data *data)
525{ 500{
526 struct nfs_pgio_header *hdr = data->header; 501 struct nfs_pgio_header *hdr = data->header;
527 struct nfs_rw_header *pageio_header = NFS_RW_HEADER(hdr);
528 502
529 put_nfs_open_context(data->args.context); 503 put_nfs_open_context(data->args.context);
530 if (data->pages.pagevec != data->pages.page_array) 504 if (data->pages.pagevec != data->pages.page_array)
531 kfree(data->pages.pagevec); 505 kfree(data->pages.pagevec);
532 if (data == &pageio_header->rpc_data) {
533 data->header = NULL;
534 data = NULL;
535 }
536 if (atomic_dec_and_test(&hdr->refcnt)) 506 if (atomic_dec_and_test(&hdr->refcnt))
537 hdr->completion_ops->completion(hdr); 507 hdr->completion_ops->completion(hdr);
538 /* Note: we only free the rpc_task after callbacks are done.
539 * See the comment in rpc_free_task() for why
540 */
541 kfree(data);
542} 508}
543EXPORT_SYMBOL_GPL(nfs_pgio_data_release); 509EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy);
544 510
545/** 511/**
546 * nfs_pgio_rpcsetup - Set up arguments for a pageio call 512 * nfs_pgio_rpcsetup - Set up arguments for a pageio call
@@ -655,8 +621,7 @@ static int nfs_pgio_error(struct nfs_pageio_descriptor *desc,
655 struct nfs_pgio_header *hdr) 621 struct nfs_pgio_header *hdr)
656{ 622{
657 set_bit(NFS_IOHDR_REDO, &hdr->flags); 623 set_bit(NFS_IOHDR_REDO, &hdr->flags);
658 nfs_pgio_data_release(hdr->data); 624 nfs_pgio_data_destroy(&hdr->data);
659 hdr->data = NULL;
660 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 625 desc->pg_completion_ops->error_cleanup(&desc->pg_list);
661 return -ENOMEM; 626 return -ENOMEM;
662} 627}
@@ -670,7 +635,7 @@ static void nfs_pgio_release(void *calldata)
670 struct nfs_pgio_data *data = calldata; 635 struct nfs_pgio_data *data = calldata;
671 if (data->header->rw_ops->rw_release) 636 if (data->header->rw_ops->rw_release)
672 data->header->rw_ops->rw_release(data); 637 data->header->rw_ops->rw_release(data);
673 nfs_pgio_data_release(data); 638 nfs_pgio_data_destroy(data);
674} 639}
675 640
676/** 641/**
@@ -746,11 +711,11 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
746 struct list_head *head = &desc->pg_list; 711 struct list_head *head = &desc->pg_list;
747 struct nfs_commit_info cinfo; 712 struct nfs_commit_info cinfo;
748 713
749 data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base, 714 if (!nfs_pgio_data_init(hdr, nfs_page_array_len(desc->pg_base,
750 desc->pg_count)); 715 desc->pg_count)))
751 if (!data)
752 return nfs_pgio_error(desc, hdr); 716 return nfs_pgio_error(desc, hdr);
753 717
718 data = &hdr->data;
754 nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); 719 nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq);
755 pages = data->pages.pagevec; 720 pages = data->pages.pagevec;
756 while (!list_empty(head)) { 721 while (!list_empty(head)) {
@@ -766,7 +731,6 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
766 731
767 /* Set up the argument struct */ 732 /* Set up the argument struct */
768 nfs_pgio_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo); 733 nfs_pgio_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo);
769 hdr->data = data;
770 desc->pg_rpc_callops = &nfs_pgio_common_ops; 734 desc->pg_rpc_callops = &nfs_pgio_common_ops;
771 return 0; 735 return 0;
772} 736}
@@ -774,22 +738,20 @@ EXPORT_SYMBOL_GPL(nfs_generic_pgio);
774 738
775static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) 739static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc)
776{ 740{
777 struct nfs_rw_header *rw_hdr;
778 struct nfs_pgio_header *hdr; 741 struct nfs_pgio_header *hdr;
779 int ret; 742 int ret;
780 743
781 rw_hdr = nfs_rw_header_alloc(desc->pg_rw_ops); 744 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
782 if (!rw_hdr) { 745 if (!hdr) {
783 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 746 desc->pg_completion_ops->error_cleanup(&desc->pg_list);
784 return -ENOMEM; 747 return -ENOMEM;
785 } 748 }
786 hdr = &rw_hdr->header; 749 nfs_pgheader_init(desc, hdr, nfs_pgio_header_free);
787 nfs_pgheader_init(desc, hdr, nfs_rw_header_free);
788 atomic_inc(&hdr->refcnt); 750 atomic_inc(&hdr->refcnt);
789 ret = nfs_generic_pgio(desc, hdr); 751 ret = nfs_generic_pgio(desc, hdr);
790 if (ret == 0) 752 if (ret == 0)
791 ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode), 753 ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode),
792 hdr->data, desc->pg_rpc_callops, 754 &hdr->data, desc->pg_rpc_callops,
793 desc->pg_ioflags, 0); 755 desc->pg_ioflags, 0);
794 if (atomic_dec_and_test(&hdr->refcnt)) 756 if (atomic_dec_and_test(&hdr->refcnt))
795 hdr->completion_ops->completion(hdr); 757 hdr->completion_ops->completion(hdr);