pnfs: release lseg in pnfs_generic_pg_cleanup
authorWeston Andros Adamson <dros@primarydata.com>
Wed, 10 Sep 2014 19:48:01 +0000 (15:48 -0400)
committerTom Haynes <loghyr@primarydata.com>
Tue, 3 Feb 2015 19:06:44 +0000 (11:06 -0800)
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>
fs/nfs/blocklayout/blocklayout.c
fs/nfs/filelayout/filelayout.c
fs/nfs/objlayout/objio_osd.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index 77fec6a55f5795b5aa0cc6142de72f1b10dbf0f3..1cac3c175d1870e63126c37ba4e1c377b5ffe5ca 100644 (file)
@@ -860,12 +860,14 @@ static const struct nfs_pageio_ops bl_pg_read_ops = {
        .pg_init = bl_pg_init_read,
        .pg_test = bl_pg_test_read,
        .pg_doio = pnfs_generic_pg_readpages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static const struct nfs_pageio_ops bl_pg_write_ops = {
        .pg_init = bl_pg_init_write,
        .pg_test = bl_pg_test_write,
        .pg_doio = pnfs_generic_pg_writepages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static struct pnfs_layoutdriver_type blocklayout_type = {
index 5d2eadc65167afe0a59bc0630bd70b667f6e9022..2af32fc39d600a7345e92c66f1ffa03d20ee8647 100644 (file)
@@ -933,12 +933,14 @@ static const struct nfs_pageio_ops filelayout_pg_read_ops = {
        .pg_init = filelayout_pg_init_read,
        .pg_test = filelayout_pg_test,
        .pg_doio = pnfs_generic_pg_readpages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static const struct nfs_pageio_ops filelayout_pg_write_ops = {
        .pg_init = filelayout_pg_init_write,
        .pg_test = filelayout_pg_test,
        .pg_doio = pnfs_generic_pg_writepages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
index 9e5bc42180e44d54311ceb3f853a21f42d78ad6b..d00778077df13e68b4ef14aad4333eb4ad990585 100644 (file)
@@ -607,12 +607,14 @@ static const struct nfs_pageio_ops objio_pg_read_ops = {
        .pg_init = objio_init_read,
        .pg_test = objio_pg_test,
        .pg_doio = pnfs_generic_pg_readpages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static const struct nfs_pageio_ops objio_pg_write_ops = {
        .pg_init = objio_init_write,
        .pg_test = objio_pg_test,
        .pg_doio = pnfs_generic_pg_writepages,
+       .pg_cleanup = pnfs_generic_pg_cleanup,
 };
 
 static struct pnfs_layoutdriver_type objlayout_type = {
index 63992c826faf0b4c7414b474d0b56297bcb05302..2da2e771fefe91231b3361544b0f6707b9ae91ee 100644 (file)
@@ -1631,6 +1631,16 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);
 
+void
+pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *desc)
+{
+       if (desc->pg_lseg) {
+               pnfs_put_lseg(desc->pg_lseg);
+               desc->pg_lseg = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup);
+
 /*
  * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number
  * of bytes (maximum @req->wb_bytes) that can be coalesced.
@@ -1756,11 +1766,9 @@ pnfs_do_write(struct nfs_pageio_descriptor *desc,
        struct pnfs_layout_segment *lseg = desc->pg_lseg;
        enum pnfs_try_status trypnfs;
 
-       desc->pg_lseg = NULL;
        trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how);
        if (trypnfs == PNFS_NOT_ATTEMPTED)
                pnfs_write_through_mds(desc, hdr);
-       pnfs_put_lseg(lseg);
 }
 
 static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
@@ -1779,17 +1787,13 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
        hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
        if (!hdr) {
                desc->pg_completion_ops->error_cleanup(&desc->pg_list);
-               pnfs_put_lseg(desc->pg_lseg);
-               desc->pg_lseg = NULL;
                return -ENOMEM;
        }
        nfs_pgheader_init(desc, hdr, pnfs_writehdr_free);
+
        hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
        ret = nfs_generic_pgio(desc, hdr);
-       if (ret != 0) {
-               pnfs_put_lseg(desc->pg_lseg);
-               desc->pg_lseg = NULL;
-       } else
+       if (!ret)
                pnfs_do_write(desc, hdr, desc->pg_ioflags);
        return ret;
 }
@@ -1874,11 +1878,9 @@ pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr)
        struct pnfs_layout_segment *lseg = desc->pg_lseg;
        enum pnfs_try_status trypnfs;
 
-       desc->pg_lseg = NULL;
        trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
        if (trypnfs == PNFS_NOT_ATTEMPTED)
                pnfs_read_through_mds(desc, hdr);
-       pnfs_put_lseg(lseg);
 }
 
 static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
@@ -1897,18 +1899,12 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
        hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
        if (!hdr) {
                desc->pg_completion_ops->error_cleanup(&desc->pg_list);
-               ret = -ENOMEM;
-               pnfs_put_lseg(desc->pg_lseg);
-               desc->pg_lseg = NULL;
-               return ret;
+               return -ENOMEM;
        }
        nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
        hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
        ret = nfs_generic_pgio(desc, hdr);
-       if (ret != 0) {
-               pnfs_put_lseg(desc->pg_lseg);
-               desc->pg_lseg = NULL;
-       } else
+       if (!ret)
                pnfs_do_read(desc, hdr);
        return ret;
 }
index 9e6edd1ebbc61ad17458e05e5232b54e7943d219..59c831efb5dee44e6078da06f2fe1050c3a1c545 100644 (file)
@@ -230,6 +230,7 @@ void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *
 int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
 void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
                                struct nfs_page *req, u64 wb_size);
+void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *);
 int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
 size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
                            struct nfs_page *prev, struct nfs_page *req);