Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Weston Andros Adamson and committed by
Tom Haynes
180bb5ec 2176bf42

+21 -18
+2
fs/nfs/blocklayout/blocklayout.c
··· 860 860 .pg_init = bl_pg_init_read, 861 861 .pg_test = bl_pg_test_read, 862 862 .pg_doio = pnfs_generic_pg_readpages, 863 + .pg_cleanup = pnfs_generic_pg_cleanup, 863 864 }; 864 865 865 866 static const struct nfs_pageio_ops bl_pg_write_ops = { 866 867 .pg_init = bl_pg_init_write, 867 868 .pg_test = bl_pg_test_write, 868 869 .pg_doio = pnfs_generic_pg_writepages, 870 + .pg_cleanup = pnfs_generic_pg_cleanup, 869 871 }; 870 872 871 873 static struct pnfs_layoutdriver_type blocklayout_type = {
+2
fs/nfs/filelayout/filelayout.c
··· 933 933 .pg_init = filelayout_pg_init_read, 934 934 .pg_test = filelayout_pg_test, 935 935 .pg_doio = pnfs_generic_pg_readpages, 936 + .pg_cleanup = pnfs_generic_pg_cleanup, 936 937 }; 937 938 938 939 static const struct nfs_pageio_ops filelayout_pg_write_ops = { 939 940 .pg_init = filelayout_pg_init_write, 940 941 .pg_test = filelayout_pg_test, 941 942 .pg_doio = pnfs_generic_pg_writepages, 943 + .pg_cleanup = pnfs_generic_pg_cleanup, 942 944 }; 943 945 944 946 static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
+2
fs/nfs/objlayout/objio_osd.c
··· 607 607 .pg_init = objio_init_read, 608 608 .pg_test = objio_pg_test, 609 609 .pg_doio = pnfs_generic_pg_readpages, 610 + .pg_cleanup = pnfs_generic_pg_cleanup, 610 611 }; 611 612 612 613 static const struct nfs_pageio_ops objio_pg_write_ops = { 613 614 .pg_init = objio_init_write, 614 615 .pg_test = objio_pg_test, 615 616 .pg_doio = pnfs_generic_pg_writepages, 617 + .pg_cleanup = pnfs_generic_pg_cleanup, 616 618 }; 617 619 618 620 static struct pnfs_layoutdriver_type objlayout_type = {
+14 -18
fs/nfs/pnfs.c
··· 1631 1631 } 1632 1632 EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write); 1633 1633 1634 + void 1635 + pnfs_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 + } 1642 + EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup); 1643 + 1634 1644 /* 1635 1645 * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number 1636 1646 * of bytes (maximum @req->wb_bytes) that can be coalesced. ··· 1766 1756 struct pnfs_layout_segment *lseg = desc->pg_lseg; 1767 1757 enum pnfs_try_status trypnfs; 1768 1758 1769 - desc->pg_lseg = NULL; 1770 1759 trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how); 1771 1760 if (trypnfs == PNFS_NOT_ATTEMPTED) 1772 1761 pnfs_write_through_mds(desc, hdr); 1773 - pnfs_put_lseg(lseg); 1774 1762 } 1775 1763 1776 1764 static void pnfs_writehdr_free(struct nfs_pgio_header *hdr) ··· 1787 1779 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); 1788 1780 if (!hdr) { 1789 1781 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 1790 - pnfs_put_lseg(desc->pg_lseg); 1791 - desc->pg_lseg = NULL; 1792 1782 return -ENOMEM; 1793 1783 } 1794 1784 nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); 1785 + 1795 1786 hdr->lseg = pnfs_get_lseg(desc->pg_lseg); 1796 1787 ret = nfs_generic_pgio(desc, hdr); 1797 - if (ret != 0) { 1798 - pnfs_put_lseg(desc->pg_lseg); 1799 - desc->pg_lseg = NULL; 1800 - } else 1788 + if (!ret) 1801 1789 pnfs_do_write(desc, hdr, desc->pg_ioflags); 1802 1790 return ret; 1803 1791 } ··· 1878 1874 struct pnfs_layout_segment *lseg = desc->pg_lseg; 1879 1875 enum pnfs_try_status trypnfs; 1880 1876 1881 - desc->pg_lseg = NULL; 1882 1877 trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg); 1883 1878 if (trypnfs == PNFS_NOT_ATTEMPTED) 1884 1879 pnfs_read_through_mds(desc, hdr); 1885 - pnfs_put_lseg(lseg); 1886 1880 } 1887 1881 1888 1882 static void pnfs_readhdr_free(struct nfs_pgio_header *hdr) ··· 1899 1897 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); 1900 1898 if (!hdr) { 1901 1899 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 1902 - ret = -ENOMEM; 1903 - pnfs_put_lseg(desc->pg_lseg); 1904 - desc->pg_lseg = NULL; 1905 - return ret; 1900 + return -ENOMEM; 1906 1901 } 1907 1902 nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); 1908 1903 hdr->lseg = pnfs_get_lseg(desc->pg_lseg); 1909 1904 ret = nfs_generic_pgio(desc, hdr); 1910 - if (ret != 0) { 1911 - pnfs_put_lseg(desc->pg_lseg); 1912 - desc->pg_lseg = NULL; 1913 - } else 1905 + if (!ret) 1914 1906 pnfs_do_read(desc, hdr); 1915 1907 return ret; 1916 1908 }
+1
fs/nfs/pnfs.h
··· 230 230 int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc); 231 231 void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, 232 232 struct nfs_page *req, u64 wb_size); 233 + void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *); 233 234 int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); 234 235 size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, 235 236 struct nfs_page *prev, struct nfs_page *req);