aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2014-09-10 15:48:01 -0400
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:44 -0500
commit180bb5ec06ce3a95dccc751fbf6bf11d3003da98 (patch)
treee73fcf03e30e0bdb6b2e97767782fa53a0912ff7
parent2176bf4269a37a7742230ed6c91668241bfe1b2b (diff)
pnfs: release lseg in pnfs_generic_pg_cleanup
This is needed to support mirrored writes - the first write can't just trash the lseg, we need to keep it around until all mirrors have written. Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
-rw-r--r--fs/nfs/blocklayout/blocklayout.c2
-rw-r--r--fs/nfs/filelayout/filelayout.c2
-rw-r--r--fs/nfs/objlayout/objio_osd.c2
-rw-r--r--fs/nfs/pnfs.c32
-rw-r--r--fs/nfs/pnfs.h1
5 files changed, 21 insertions, 18 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 77fec6a55f57..1cac3c175d18 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -860,12 +860,14 @@ static const struct nfs_pageio_ops bl_pg_read_ops = {
860 .pg_init = bl_pg_init_read, 860 .pg_init = bl_pg_init_read,
861 .pg_test = bl_pg_test_read, 861 .pg_test = bl_pg_test_read,
862 .pg_doio = pnfs_generic_pg_readpages, 862 .pg_doio = pnfs_generic_pg_readpages,
863 .pg_cleanup = pnfs_generic_pg_cleanup,
863}; 864};
864 865
865static const struct nfs_pageio_ops bl_pg_write_ops = { 866static const struct nfs_pageio_ops bl_pg_write_ops = {
866 .pg_init = bl_pg_init_write, 867 .pg_init = bl_pg_init_write,
867 .pg_test = bl_pg_test_write, 868 .pg_test = bl_pg_test_write,
868 .pg_doio = pnfs_generic_pg_writepages, 869 .pg_doio = pnfs_generic_pg_writepages,
870 .pg_cleanup = pnfs_generic_pg_cleanup,
869}; 871};
870 872
871static struct pnfs_layoutdriver_type blocklayout_type = { 873static struct pnfs_layoutdriver_type blocklayout_type = {
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 5d2eadc65167..2af32fc39d60 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -933,12 +933,14 @@ static const struct nfs_pageio_ops filelayout_pg_read_ops = {
933 .pg_init = filelayout_pg_init_read, 933 .pg_init = filelayout_pg_init_read,
934 .pg_test = filelayout_pg_test, 934 .pg_test = filelayout_pg_test,
935 .pg_doio = pnfs_generic_pg_readpages, 935 .pg_doio = pnfs_generic_pg_readpages,
936 .pg_cleanup = pnfs_generic_pg_cleanup,
936}; 937};
937 938
938static const struct nfs_pageio_ops filelayout_pg_write_ops = { 939static const struct nfs_pageio_ops filelayout_pg_write_ops = {
939 .pg_init = filelayout_pg_init_write, 940 .pg_init = filelayout_pg_init_write,
940 .pg_test = filelayout_pg_test, 941 .pg_test = filelayout_pg_test,
941 .pg_doio = pnfs_generic_pg_writepages, 942 .pg_doio = pnfs_generic_pg_writepages,
943 .pg_cleanup = pnfs_generic_pg_cleanup,
942}; 944};
943 945
944static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j) 946static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 9e5bc42180e4..d00778077df1 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -607,12 +607,14 @@ static const struct nfs_pageio_ops objio_pg_read_ops = {
607 .pg_init = objio_init_read, 607 .pg_init = objio_init_read,
608 .pg_test = objio_pg_test, 608 .pg_test = objio_pg_test,
609 .pg_doio = pnfs_generic_pg_readpages, 609 .pg_doio = pnfs_generic_pg_readpages,
610 .pg_cleanup = pnfs_generic_pg_cleanup,
610}; 611};
611 612
612static const struct nfs_pageio_ops objio_pg_write_ops = { 613static const struct nfs_pageio_ops objio_pg_write_ops = {
613 .pg_init = objio_init_write, 614 .pg_init = objio_init_write,
614 .pg_test = objio_pg_test, 615 .pg_test = objio_pg_test,
615 .pg_doio = pnfs_generic_pg_writepages, 616 .pg_doio = pnfs_generic_pg_writepages,
617 .pg_cleanup = pnfs_generic_pg_cleanup,
616}; 618};
617 619
618static struct pnfs_layoutdriver_type objlayout_type = { 620static struct pnfs_layoutdriver_type objlayout_type = {
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 63992c826faf..2da2e771fefe 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1631,6 +1631,16 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
1631} 1631}
1632EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write); 1632EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);
1633 1633
1634void
1635pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *desc)
1636{
1637 if (desc->pg_lseg) {
1638 pnfs_put_lseg(desc->pg_lseg);
1639 desc->pg_lseg = NULL;
1640 }
1641}
1642EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup);
1643
1634/* 1644/*
1635 * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number 1645 * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number
1636 * of bytes (maximum @req->wb_bytes) that can be coalesced. 1646 * of bytes (maximum @req->wb_bytes) that can be coalesced.
@@ -1756,11 +1766,9 @@ pnfs_do_write(struct nfs_pageio_descriptor *desc,
1756 struct pnfs_layout_segment *lseg = desc->pg_lseg; 1766 struct pnfs_layout_segment *lseg = desc->pg_lseg;
1757 enum pnfs_try_status trypnfs; 1767 enum pnfs_try_status trypnfs;
1758 1768
1759 desc->pg_lseg = NULL;
1760 trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how); 1769 trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how);
1761 if (trypnfs == PNFS_NOT_ATTEMPTED) 1770 if (trypnfs == PNFS_NOT_ATTEMPTED)
1762 pnfs_write_through_mds(desc, hdr); 1771 pnfs_write_through_mds(desc, hdr);
1763 pnfs_put_lseg(lseg);
1764} 1772}
1765 1773
1766static void pnfs_writehdr_free(struct nfs_pgio_header *hdr) 1774static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
@@ -1779,17 +1787,13 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
1779 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); 1787 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
1780 if (!hdr) { 1788 if (!hdr) {
1781 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 1789 desc->pg_completion_ops->error_cleanup(&desc->pg_list);
1782 pnfs_put_lseg(desc->pg_lseg);
1783 desc->pg_lseg = NULL;
1784 return -ENOMEM; 1790 return -ENOMEM;
1785 } 1791 }
1786 nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); 1792 nfs_pgheader_init(desc, hdr, pnfs_writehdr_free);
1793
1787 hdr->lseg = pnfs_get_lseg(desc->pg_lseg); 1794 hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
1788 ret = nfs_generic_pgio(desc, hdr); 1795 ret = nfs_generic_pgio(desc, hdr);
1789 if (ret != 0) { 1796 if (!ret)
1790 pnfs_put_lseg(desc->pg_lseg);
1791 desc->pg_lseg = NULL;
1792 } else
1793 pnfs_do_write(desc, hdr, desc->pg_ioflags); 1797 pnfs_do_write(desc, hdr, desc->pg_ioflags);
1794 return ret; 1798 return ret;
1795} 1799}
@@ -1874,11 +1878,9 @@ pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr)
1874 struct pnfs_layout_segment *lseg = desc->pg_lseg; 1878 struct pnfs_layout_segment *lseg = desc->pg_lseg;
1875 enum pnfs_try_status trypnfs; 1879 enum pnfs_try_status trypnfs;
1876 1880
1877 desc->pg_lseg = NULL;
1878 trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg); 1881 trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
1879 if (trypnfs == PNFS_NOT_ATTEMPTED) 1882 if (trypnfs == PNFS_NOT_ATTEMPTED)
1880 pnfs_read_through_mds(desc, hdr); 1883 pnfs_read_through_mds(desc, hdr);
1881 pnfs_put_lseg(lseg);
1882} 1884}
1883 1885
1884static void pnfs_readhdr_free(struct nfs_pgio_header *hdr) 1886static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
@@ -1897,18 +1899,12 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
1897 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); 1899 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
1898 if (!hdr) { 1900 if (!hdr) {
1899 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 1901 desc->pg_completion_ops->error_cleanup(&desc->pg_list);
1900 ret = -ENOMEM; 1902 return -ENOMEM;
1901 pnfs_put_lseg(desc->pg_lseg);
1902 desc->pg_lseg = NULL;
1903 return ret;
1904 } 1903 }
1905 nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); 1904 nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
1906 hdr->lseg = pnfs_get_lseg(desc->pg_lseg); 1905 hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
1907 ret = nfs_generic_pgio(desc, hdr); 1906 ret = nfs_generic_pgio(desc, hdr);
1908 if (ret != 0) { 1907 if (!ret)
1909 pnfs_put_lseg(desc->pg_lseg);
1910 desc->pg_lseg = NULL;
1911 } else
1912 pnfs_do_read(desc, hdr); 1908 pnfs_do_read(desc, hdr);
1913 return ret; 1909 return ret;
1914} 1910}
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 9e6edd1ebbc6..59c831efb5de 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -230,6 +230,7 @@ void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *
230int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc); 230int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
231void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, 231void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
232 struct nfs_page *req, u64 wb_size); 232 struct nfs_page *req, u64 wb_size);
233void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *);
233int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); 234int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
234size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, 235size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
235 struct nfs_page *prev, struct nfs_page *req); 236 struct nfs_page *prev, struct nfs_page *req);