diff options
-rw-r--r-- | fs/nfs/pagelist.c | 39 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 41 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 5 |
3 files changed, 24 insertions, 61 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index ec4311df05d9..fab78d13ee14 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -470,7 +470,6 @@ struct nfs_rw_header *nfs_rw_header_alloc(const struct nfs_rw_ops *ops) | |||
470 | struct nfs_pgio_header *hdr = &header->header; | 470 | struct nfs_pgio_header *hdr = &header->header; |
471 | 471 | ||
472 | INIT_LIST_HEAD(&hdr->pages); | 472 | INIT_LIST_HEAD(&hdr->pages); |
473 | INIT_LIST_HEAD(&hdr->rpc_list); | ||
474 | spin_lock_init(&hdr->lock); | 473 | spin_lock_init(&hdr->lock); |
475 | atomic_set(&hdr->refcnt, 0); | 474 | atomic_set(&hdr->refcnt, 0); |
476 | hdr->rw_ops = ops; | 475 | hdr->rw_ops = ops; |
@@ -648,27 +647,6 @@ out: | |||
648 | } | 647 | } |
649 | EXPORT_SYMBOL_GPL(nfs_initiate_pgio); | 648 | EXPORT_SYMBOL_GPL(nfs_initiate_pgio); |
650 | 649 | ||
651 | static int nfs_do_multiple_pgios(struct list_head *head, | ||
652 | const struct rpc_call_ops *call_ops, | ||
653 | int how) | ||
654 | { | ||
655 | struct nfs_pgio_data *data; | ||
656 | int ret = 0; | ||
657 | |||
658 | while (!list_empty(head)) { | ||
659 | int ret2; | ||
660 | |||
661 | data = list_first_entry(head, struct nfs_pgio_data, list); | ||
662 | list_del_init(&data->list); | ||
663 | |||
664 | ret2 = nfs_initiate_pgio(NFS_CLIENT(data->header->inode), | ||
665 | data, call_ops, how, 0); | ||
666 | if (ret == 0) | ||
667 | ret = ret2; | ||
668 | } | ||
669 | return ret; | ||
670 | } | ||
671 | |||
672 | /** | 650 | /** |
673 | * nfs_pgio_error - Clean up from a pageio error | 651 | * nfs_pgio_error - Clean up from a pageio error |
674 | * @desc: IO descriptor | 652 | * @desc: IO descriptor |
@@ -677,14 +655,9 @@ static int nfs_do_multiple_pgios(struct list_head *head, | |||
677 | static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, | 655 | static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, |
678 | struct nfs_pgio_header *hdr) | 656 | struct nfs_pgio_header *hdr) |
679 | { | 657 | { |
680 | struct nfs_pgio_data *data; | ||
681 | |||
682 | set_bit(NFS_IOHDR_REDO, &hdr->flags); | 658 | set_bit(NFS_IOHDR_REDO, &hdr->flags); |
683 | while (!list_empty(&hdr->rpc_list)) { | 659 | nfs_pgio_data_release(hdr->data); |
684 | data = list_first_entry(&hdr->rpc_list, struct nfs_pgio_data, list); | 660 | hdr->data = NULL; |
685 | list_del(&data->list); | ||
686 | nfs_pgio_data_release(data); | ||
687 | } | ||
688 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | 661 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); |
689 | return -ENOMEM; | 662 | return -ENOMEM; |
690 | } | 663 | } |
@@ -794,7 +767,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, | |||
794 | 767 | ||
795 | /* Set up the argument struct */ | 768 | /* Set up the argument struct */ |
796 | nfs_pgio_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo); | 769 | nfs_pgio_rpcsetup(data, desc->pg_count, 0, desc->pg_ioflags, &cinfo); |
797 | list_add(&data->list, &hdr->rpc_list); | 770 | hdr->data = data; |
798 | desc->pg_rpc_callops = &nfs_pgio_common_ops; | 771 | desc->pg_rpc_callops = &nfs_pgio_common_ops; |
799 | return 0; | 772 | return 0; |
800 | } | 773 | } |
@@ -816,9 +789,9 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) | |||
816 | atomic_inc(&hdr->refcnt); | 789 | atomic_inc(&hdr->refcnt); |
817 | ret = nfs_generic_pgio(desc, hdr); | 790 | ret = nfs_generic_pgio(desc, hdr); |
818 | if (ret == 0) | 791 | if (ret == 0) |
819 | ret = nfs_do_multiple_pgios(&hdr->rpc_list, | 792 | ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode), |
820 | desc->pg_rpc_callops, | 793 | hdr->data, desc->pg_rpc_callops, |
821 | desc->pg_ioflags); | 794 | desc->pg_ioflags, 0); |
822 | if (atomic_dec_and_test(&hdr->refcnt)) | 795 | if (atomic_dec_and_test(&hdr->refcnt)) |
823 | hdr->completion_ops->completion(hdr); | 796 | hdr->completion_ops->completion(hdr); |
824 | return ret; | 797 | return ret; |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 354c53cd4095..6ef108b1d85f 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -1573,23 +1573,18 @@ pnfs_try_to_write_data(struct nfs_pgio_data *wdata, | |||
1573 | } | 1573 | } |
1574 | 1574 | ||
1575 | static void | 1575 | static void |
1576 | pnfs_do_multiple_writes(struct nfs_pageio_descriptor *desc, struct list_head *head, int how) | 1576 | pnfs_do_write(struct nfs_pageio_descriptor *desc, |
1577 | struct nfs_pgio_header *hdr, int how) | ||
1577 | { | 1578 | { |
1578 | struct nfs_pgio_data *data; | 1579 | struct nfs_pgio_data *data = hdr->data; |
1579 | const struct rpc_call_ops *call_ops = desc->pg_rpc_callops; | 1580 | const struct rpc_call_ops *call_ops = desc->pg_rpc_callops; |
1580 | struct pnfs_layout_segment *lseg = desc->pg_lseg; | 1581 | struct pnfs_layout_segment *lseg = desc->pg_lseg; |
1582 | enum pnfs_try_status trypnfs; | ||
1581 | 1583 | ||
1582 | desc->pg_lseg = NULL; | 1584 | desc->pg_lseg = NULL; |
1583 | while (!list_empty(head)) { | 1585 | trypnfs = pnfs_try_to_write_data(data, call_ops, lseg, how); |
1584 | enum pnfs_try_status trypnfs; | 1586 | if (trypnfs == PNFS_NOT_ATTEMPTED) |
1585 | 1587 | pnfs_write_through_mds(desc, data); | |
1586 | data = list_first_entry(head, struct nfs_pgio_data, list); | ||
1587 | list_del_init(&data->list); | ||
1588 | |||
1589 | trypnfs = pnfs_try_to_write_data(data, call_ops, lseg, how); | ||
1590 | if (trypnfs == PNFS_NOT_ATTEMPTED) | ||
1591 | pnfs_write_through_mds(desc, data); | ||
1592 | } | ||
1593 | pnfs_put_lseg(lseg); | 1588 | pnfs_put_lseg(lseg); |
1594 | } | 1589 | } |
1595 | 1590 | ||
@@ -1623,7 +1618,7 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | |||
1623 | pnfs_put_lseg(desc->pg_lseg); | 1618 | pnfs_put_lseg(desc->pg_lseg); |
1624 | desc->pg_lseg = NULL; | 1619 | desc->pg_lseg = NULL; |
1625 | } else | 1620 | } else |
1626 | pnfs_do_multiple_writes(desc, &hdr->rpc_list, desc->pg_ioflags); | 1621 | pnfs_do_write(desc, hdr, desc->pg_ioflags); |
1627 | if (atomic_dec_and_test(&hdr->refcnt)) | 1622 | if (atomic_dec_and_test(&hdr->refcnt)) |
1628 | hdr->completion_ops->completion(hdr); | 1623 | hdr->completion_ops->completion(hdr); |
1629 | return ret; | 1624 | return ret; |
@@ -1731,23 +1726,17 @@ pnfs_try_to_read_data(struct nfs_pgio_data *rdata, | |||
1731 | } | 1726 | } |
1732 | 1727 | ||
1733 | static void | 1728 | static void |
1734 | pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *head) | 1729 | pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr) |
1735 | { | 1730 | { |
1736 | struct nfs_pgio_data *data; | 1731 | struct nfs_pgio_data *data = hdr->data; |
1737 | const struct rpc_call_ops *call_ops = desc->pg_rpc_callops; | 1732 | const struct rpc_call_ops *call_ops = desc->pg_rpc_callops; |
1738 | struct pnfs_layout_segment *lseg = desc->pg_lseg; | 1733 | struct pnfs_layout_segment *lseg = desc->pg_lseg; |
1734 | enum pnfs_try_status trypnfs; | ||
1739 | 1735 | ||
1740 | desc->pg_lseg = NULL; | 1736 | desc->pg_lseg = NULL; |
1741 | while (!list_empty(head)) { | 1737 | trypnfs = pnfs_try_to_read_data(data, call_ops, lseg); |
1742 | enum pnfs_try_status trypnfs; | 1738 | if (trypnfs == PNFS_NOT_ATTEMPTED) |
1743 | 1739 | pnfs_read_through_mds(desc, data); | |
1744 | data = list_first_entry(head, struct nfs_pgio_data, list); | ||
1745 | list_del_init(&data->list); | ||
1746 | |||
1747 | trypnfs = pnfs_try_to_read_data(data, call_ops, lseg); | ||
1748 | if (trypnfs == PNFS_NOT_ATTEMPTED) | ||
1749 | pnfs_read_through_mds(desc, data); | ||
1750 | } | ||
1751 | pnfs_put_lseg(lseg); | 1740 | pnfs_put_lseg(lseg); |
1752 | } | 1741 | } |
1753 | 1742 | ||
@@ -1782,7 +1771,7 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | |||
1782 | pnfs_put_lseg(desc->pg_lseg); | 1771 | pnfs_put_lseg(desc->pg_lseg); |
1783 | desc->pg_lseg = NULL; | 1772 | desc->pg_lseg = NULL; |
1784 | } else | 1773 | } else |
1785 | pnfs_do_multiple_reads(desc, &hdr->rpc_list); | 1774 | pnfs_do_read(desc, hdr); |
1786 | if (atomic_dec_and_test(&hdr->refcnt)) | 1775 | if (atomic_dec_and_test(&hdr->refcnt)) |
1787 | hdr->completion_ops->completion(hdr); | 1776 | hdr->completion_ops->completion(hdr); |
1788 | return ret; | 1777 | return ret; |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index adef7bd2d06d..ae636013fb1f 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -1256,11 +1256,13 @@ enum { | |||
1256 | NFS_IOHDR_NEED_RESCHED, | 1256 | NFS_IOHDR_NEED_RESCHED, |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | struct nfs_pgio_data; | ||
1260 | |||
1259 | struct nfs_pgio_header { | 1261 | struct nfs_pgio_header { |
1260 | struct inode *inode; | 1262 | struct inode *inode; |
1261 | struct rpc_cred *cred; | 1263 | struct rpc_cred *cred; |
1262 | struct list_head pages; | 1264 | struct list_head pages; |
1263 | struct list_head rpc_list; | 1265 | struct nfs_pgio_data *data; |
1264 | atomic_t refcnt; | 1266 | atomic_t refcnt; |
1265 | struct nfs_page *req; | 1267 | struct nfs_page *req; |
1266 | struct nfs_writeverf verf; /* Used for writes */ | 1268 | struct nfs_writeverf verf; /* Used for writes */ |
@@ -1282,7 +1284,6 @@ struct nfs_pgio_header { | |||
1282 | 1284 | ||
1283 | struct nfs_pgio_data { | 1285 | struct nfs_pgio_data { |
1284 | struct nfs_pgio_header *header; | 1286 | struct nfs_pgio_header *header; |
1285 | struct list_head list; | ||
1286 | struct rpc_task task; | 1287 | struct rpc_task task; |
1287 | struct nfs_fattr fattr; | 1288 | struct nfs_fattr fattr; |
1288 | struct nfs_writeverf verf; /* Used for writes */ | 1289 | struct nfs_writeverf verf; /* Used for writes */ |