NFS: Optimize allocation of nfs_read/write_data structures
authorChuck Lever <cel@netapp.com>
Thu, 25 May 2006 05:40:53 +0000 (01:40 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 9 Jun 2006 13:34:07 +0000 (09:34 -0400)
Clean up use of page_array, and fix an off-by-one error noticed by Tom
Talpey which causes kmalloc calls in cases where using the page_array
is sufficient.

Test plan:
Normal client functional testing with r/wsize=32768.

Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/read.c
fs/nfs/write.c
include/linux/nfs_xdr.h

index 4b5f58da565083a229cabb0021492671de1cb663..fd9018c692bbf76bfbeda8cbf4c2766af01fcb20 100644 (file)
@@ -51,14 +51,11 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->pages);
-               if (pagecount < NFS_PAGEVEC_SIZE)
-                       p->pagevec = &p->page_array[0];
+               if (pagecount <= ARRAY_SIZE(p->page_array))
+                       p->pagevec = p->page_array;
                else {
-                       size_t size = ++pagecount * sizeof(struct page *);
-                       p->pagevec = kmalloc(size, GFP_NOFS);
-                       if (p->pagevec) {
-                               memset(p->pagevec, 0, size);
-                       } else {
+                       p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
+                       if (!p->pagevec) {
                                mempool_free(p, nfs_rdata_mempool);
                                p = NULL;
                        }
index 4cfada2cc09f4fca67bac31756d018b13a8cdef1..a515ec714bb6a5ba5caf2bbc2aa4f9a1b9818c6d 100644 (file)
@@ -98,11 +98,10 @@ struct nfs_write_data *nfs_commit_alloc(unsigned int pagecount)
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->pages);
-               if (pagecount < NFS_PAGEVEC_SIZE)
-                       p->pagevec = &p->page_array[0];
+               if (pagecount <= ARRAY_SIZE(p->page_array))
+                       p->pagevec = p->page_array;
                else {
-                       size_t size = ++pagecount * sizeof(struct page *);
-                       p->pagevec = kzalloc(size, GFP_NOFS);
+                       p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
                        if (!p->pagevec) {
                                mempool_free(p, nfs_commit_mempool);
                                p = NULL;
@@ -126,14 +125,11 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
        if (p) {
                memset(p, 0, sizeof(*p));
                INIT_LIST_HEAD(&p->pages);
-               if (pagecount < NFS_PAGEVEC_SIZE)
-                       p->pagevec = &p->page_array[0];
+               if (pagecount <= ARRAY_SIZE(p->page_array))
+                       p->pagevec = p->page_array;
                else {
-                       size_t size = ++pagecount * sizeof(struct page *);
-                       p->pagevec = kmalloc(size, GFP_NOFS);
-                       if (p->pagevec) {
-                               memset(p->pagevec, 0, size);
-                       } else {
+                       p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
+                       if (!p->pagevec) {
                                mempool_free(p, nfs_wdata_mempool);
                                p = NULL;
                        }
index c483e239f99340ac7905cc4d676a929be17e66c5..e206c07080fe4725c15403b3fab7cfeb0527ec9f 100644 (file)
@@ -694,7 +694,7 @@ struct nfs_read_data {
 #ifdef CONFIG_NFS_V4
        unsigned long           timestamp;      /* For lease renewal */
 #endif
-       struct page             *page_array[NFS_PAGEVEC_SIZE + 1];
+       struct page             *page_array[NFS_PAGEVEC_SIZE];
 };
 
 struct nfs_write_data {
@@ -712,7 +712,7 @@ struct nfs_write_data {
 #ifdef CONFIG_NFS_V4
        unsigned long           timestamp;      /* For lease renewal */
 #endif
-       struct page             *page_array[NFS_PAGEVEC_SIZE + 1];
+       struct page             *page_array[NFS_PAGEVEC_SIZE];
 };
 
 struct nfs_access_entry;