NFS: Create a common pgio_alloc and pgio_release function
authorAnna Schumaker <Anna.Schumaker@netapp.com>
Tue, 6 May 2014 13:12:29 +0000 (09:12 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 28 May 2014 22:39:55 +0000 (18:39 -0400)
These functions are identical for the read and write paths so they can
be combined.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/internal.h
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfs/read.c
fs/nfs/write.c

index b0e7a41d14a888b50cf288eec212ccb6b03e069e..5ddc142c5062229aee5804b42b7be686e6835ae0 100644 (file)
@@ -231,13 +231,15 @@ extern void nfs_destroy_writepagecache(void);
 
 extern int __init nfs_init_directcache(void);
 extern void nfs_destroy_directcache(void);
-extern bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount);
 extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
                              struct nfs_pgio_header *hdr,
                              void (*release)(struct nfs_pgio_header *hdr));
 void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
 int nfs_iocounter_wait(struct nfs_io_counter *c);
 
+struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *, unsigned int);
+void nfs_pgio_data_release(struct nfs_pgio_data *);
+
 static inline void nfs_iocounter_init(struct nfs_io_counter *c)
 {
        c->flags = 0;
@@ -407,7 +409,6 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
 extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
                              struct nfs_pgio_header *hdr);
 extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
-extern void nfs_readdata_release(struct nfs_pgio_data *rdata);
 
 /* super.c */
 void nfs_clone_super(struct super_block *, struct nfs_mount_info *);
@@ -429,7 +430,6 @@ extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
 extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
                             struct nfs_pgio_header *hdr);
 extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
-extern void nfs_writedata_release(struct nfs_pgio_data *wdata);
 extern void nfs_commit_free(struct nfs_commit_data *p);
 extern int nfs_initiate_write(struct rpc_clnt *clnt,
                              struct nfs_pgio_data *data,
index 2ffebf2081ceb5c779cf7f53644fa453bff45ca2..a98ccf722d7b5b4e8643ee6a3f3bdcd77b258fc5 100644 (file)
@@ -26,7 +26,7 @@
 
 static struct kmem_cache *nfs_page_cachep;
 
-bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
+static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
 {
        p->npages = pagecount;
        if (pagecount <= ARRAY_SIZE(p->page_array))
@@ -295,6 +295,66 @@ bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *pr
 }
 EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
 
+static inline struct nfs_rw_header *NFS_RW_HEADER(struct nfs_pgio_header *hdr)
+{
+       return container_of(hdr, struct nfs_rw_header, header);
+}
+
+/**
+ * nfs_pgio_data_alloc - Allocate pageio data
+ * @hdr: The header making a request
+ * @pagecount: Number of pages to create
+ */
+struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *hdr,
+                                         unsigned int pagecount)
+{
+       struct nfs_pgio_data *data, *prealloc;
+
+       prealloc = &NFS_RW_HEADER(hdr)->rpc_data;
+       if (prealloc->header == NULL)
+               data = prealloc;
+       else
+               data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               goto out;
+
+       if (nfs_pgarray_set(&data->pages, pagecount)) {
+               data->header = hdr;
+               atomic_inc(&hdr->refcnt);
+       } else {
+               if (data != prealloc)
+                       kfree(data);
+               data = NULL;
+       }
+out:
+       return data;
+}
+
+/**
+ * nfs_pgio_data_release - Properly free pageio data
+ * @data: The data to release
+ */
+void nfs_pgio_data_release(struct nfs_pgio_data *data)
+{
+       struct nfs_pgio_header *hdr = data->header;
+       struct nfs_rw_header *pageio_header = NFS_RW_HEADER(hdr);
+
+       put_nfs_open_context(data->args.context);
+       if (data->pages.pagevec != data->pages.page_array)
+               kfree(data->pages.pagevec);
+       if (data == &pageio_header->rpc_data) {
+               data->header = NULL;
+               data = NULL;
+       }
+       if (atomic_dec_and_test(&hdr->refcnt))
+               hdr->completion_ops->completion(hdr);
+       /* Note: we only free the rpc_task after callbacks are done.
+        * See the comment in rpc_free_task() for why
+        */
+       kfree(data);
+}
+EXPORT_SYMBOL_GPL(nfs_pgio_data_release);
+
 /**
  * nfs_pageio_init - initialise a page io descriptor
  * @desc: pointer to descriptor
index 43cfe11aa1a4245b6ce1e6aed88bcc58b55a138e..e192ba69a7d47ee0d9d33903bc45a0f225d0b692 100644 (file)
@@ -1536,7 +1536,7 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
                nfs_pageio_reset_write_mds(desc);
                desc->pg_recoalesce = 1;
        }
-       nfs_writedata_release(data);
+       nfs_pgio_data_release(data);
 }
 
 static enum pnfs_try_status
@@ -1691,7 +1691,7 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
                nfs_pageio_reset_read_mds(desc);
                desc->pg_recoalesce = 1;
        }
-       nfs_readdata_release(data);
+       nfs_pgio_data_release(data);
 }
 
 /*
index d29ca3673694847c78888ec41a12b6f6b50d47e6..ab4c1a5b5fbd238dc0b3715605d88e639e88ca28 100644 (file)
@@ -51,31 +51,6 @@ struct nfs_rw_header *nfs_readhdr_alloc(void)
 }
 EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
 
-static struct nfs_pgio_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
-                                               unsigned int pagecount)
-{
-       struct nfs_pgio_data *data, *prealloc;
-
-       prealloc = &container_of(hdr, struct nfs_rw_header, header)->rpc_data;
-       if (prealloc->header == NULL)
-               data = prealloc;
-       else
-               data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               goto out;
-
-       if (nfs_pgarray_set(&data->pages, pagecount)) {
-               data->header = hdr;
-               atomic_inc(&hdr->refcnt);
-       } else {
-               if (data != prealloc)
-                       kfree(data);
-               data = NULL;
-       }
-out:
-       return data;
-}
-
 void nfs_readhdr_free(struct nfs_pgio_header *hdr)
 {
        struct nfs_rw_header *rhdr = container_of(hdr, struct nfs_rw_header, header);
@@ -84,27 +59,6 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
 }
 EXPORT_SYMBOL_GPL(nfs_readhdr_free);
 
-void nfs_readdata_release(struct nfs_pgio_data *rdata)
-{
-       struct nfs_pgio_header *hdr = rdata->header;
-       struct nfs_rw_header *read_header = container_of(hdr, struct nfs_rw_header, header);
-
-       put_nfs_open_context(rdata->args.context);
-       if (rdata->pages.pagevec != rdata->pages.page_array)
-               kfree(rdata->pages.pagevec);
-       if (rdata == &read_header->rpc_data) {
-               rdata->header = NULL;
-               rdata = NULL;
-       }
-       if (atomic_dec_and_test(&hdr->refcnt))
-               hdr->completion_ops->completion(hdr);
-       /* Note: we only free the rpc_task after callbacks are done.
-        * See the comment in rpc_free_task() for why
-        */
-       kfree(rdata);
-}
-EXPORT_SYMBOL_GPL(nfs_readdata_release);
-
 static
 int nfs_return_empty_page(struct page *page)
 {
@@ -327,7 +281,7 @@ static void nfs_pagein_error(struct nfs_pageio_descriptor *desc,
                struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list,
                                struct nfs_pgio_data, list);
                list_del(&data->list);
-               nfs_readdata_release(data);
+               nfs_pgio_data_release(data);
        }
        desc->pg_completion_ops->error_cleanup(&desc->pg_list);
 }
@@ -359,7 +313,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc,
        do {
                size_t len = min(nbytes,rsize);
 
-               data = nfs_readdata_alloc(hdr, 1);
+               data = nfs_pgio_data_alloc(hdr, 1);
                if (!data) {
                        nfs_pagein_error(desc, hdr);
                        return -ENOMEM;
@@ -385,7 +339,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc,
        struct nfs_pgio_data    *data;
        struct list_head *head = &desc->pg_list;
 
-       data = nfs_readdata_alloc(hdr, nfs_page_array_len(desc->pg_base,
+       data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base,
                                                          desc->pg_count));
        if (!data) {
                nfs_pagein_error(desc, hdr);
@@ -515,7 +469,7 @@ static void nfs_readpage_result_common(struct rpc_task *task, void *calldata)
 
 static void nfs_readpage_release_common(void *calldata)
 {
-       nfs_readdata_release(calldata);
+       nfs_pgio_data_release(calldata);
 }
 
 void nfs_read_prepare(struct rpc_task *task, void *calldata)
index 321a791c72bfc5d61df59991f538dcf4c9e08a19..0dc4d6a28bd0d7f25f3bc6b937224a3c62ef34c3 100644 (file)
@@ -87,31 +87,6 @@ struct nfs_rw_header *nfs_writehdr_alloc(void)
 }
 EXPORT_SYMBOL_GPL(nfs_writehdr_alloc);
 
-static struct nfs_pgio_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
-                                                 unsigned int pagecount)
-{
-       struct nfs_pgio_data *data, *prealloc;
-
-       prealloc = &container_of(hdr, struct nfs_rw_header, header)->rpc_data;
-       if (prealloc->header == NULL)
-               data = prealloc;
-       else
-               data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               goto out;
-
-       if (nfs_pgarray_set(&data->pages, pagecount)) {
-               data->header = hdr;
-               atomic_inc(&hdr->refcnt);
-       } else {
-               if (data != prealloc)
-                       kfree(data);
-               data = NULL;
-       }
-out:
-       return data;
-}
-
 void nfs_writehdr_free(struct nfs_pgio_header *hdr)
 {
        struct nfs_rw_header *whdr = container_of(hdr, struct nfs_rw_header, header);
@@ -119,27 +94,6 @@ void nfs_writehdr_free(struct nfs_pgio_header *hdr)
 }
 EXPORT_SYMBOL_GPL(nfs_writehdr_free);
 
-void nfs_writedata_release(struct nfs_pgio_data *wdata)
-{
-       struct nfs_pgio_header *hdr = wdata->header;
-       struct nfs_rw_header *write_header = container_of(hdr, struct nfs_rw_header, header);
-
-       put_nfs_open_context(wdata->args.context);
-       if (wdata->pages.pagevec != wdata->pages.page_array)
-               kfree(wdata->pages.pagevec);
-       if (wdata == &write_header->rpc_data) {
-               wdata->header = NULL;
-               wdata = NULL;
-       }
-       if (atomic_dec_and_test(&hdr->refcnt))
-               hdr->completion_ops->completion(hdr);
-       /* Note: we only free the rpc_task after callbacks are done.
-        * See the comment in rpc_free_task() for why
-        */
-       kfree(wdata);
-}
-EXPORT_SYMBOL_GPL(nfs_writedata_release);
-
 static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
 {
        ctx->error = error;
@@ -1146,7 +1100,7 @@ static void nfs_flush_error(struct nfs_pageio_descriptor *desc,
                struct nfs_pgio_data *data = list_first_entry(&hdr->rpc_list,
                                struct nfs_pgio_data, list);
                list_del(&data->list);
-               nfs_writedata_release(data);
+               nfs_pgio_data_release(data);
        }
        desc->pg_completion_ops->error_cleanup(&desc->pg_list);
 }
@@ -1179,7 +1133,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc,
        do {
                size_t len = min(nbytes, wsize);
 
-               data = nfs_writedata_alloc(hdr, 1);
+               data = nfs_pgio_data_alloc(hdr, 1);
                if (!data) {
                        nfs_flush_error(desc, hdr);
                        return -ENOMEM;
@@ -1214,7 +1168,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc,
        struct list_head *head = &desc->pg_list;
        struct nfs_commit_info cinfo;
 
-       data = nfs_writedata_alloc(hdr, nfs_page_array_len(desc->pg_base,
+       data = nfs_pgio_data_alloc(hdr, nfs_page_array_len(desc->pg_base,
                                                           desc->pg_count));
        if (!data) {
                nfs_flush_error(desc, hdr);
@@ -1348,7 +1302,7 @@ static void nfs_writeback_release_common(void *calldata)
                        set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags);
                spin_unlock(&hdr->lock);
        }
-       nfs_writedata_release(data);
+       nfs_pgio_data_release(data);
 }
 
 static const struct rpc_call_ops nfs_write_common_ops = {