aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <cel@netapp.com>2006-05-25 01:40:53 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:07 -0400
commit0d0b5cb36faf7002a11736032313f06d6f3d881c (patch)
treed767ae12fde00b553546aab9f5aa3e23cd86069d
parentbf3fcf89552f24657bcfb6a9d73cd167ebb496c6 (diff)
NFS: Optimize allocation of nfs_read/write_data structures
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>
-rw-r--r--fs/nfs/read.c11
-rw-r--r--fs/nfs/write.c18
-rw-r--r--include/linux/nfs_xdr.h4
3 files changed, 13 insertions, 20 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 4b5f58da5650..fd9018c692bb 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -51,14 +51,11 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
51 if (p) { 51 if (p) {
52 memset(p, 0, sizeof(*p)); 52 memset(p, 0, sizeof(*p));
53 INIT_LIST_HEAD(&p->pages); 53 INIT_LIST_HEAD(&p->pages);
54 if (pagecount < NFS_PAGEVEC_SIZE) 54 if (pagecount <= ARRAY_SIZE(p->page_array))
55 p->pagevec = &p->page_array[0]; 55 p->pagevec = p->page_array;
56 else { 56 else {
57 size_t size = ++pagecount * sizeof(struct page *); 57 p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
58 p->pagevec = kmalloc(size, GFP_NOFS); 58 if (!p->pagevec) {
59 if (p->pagevec) {
60 memset(p->pagevec, 0, size);
61 } else {
62 mempool_free(p, nfs_rdata_mempool); 59 mempool_free(p, nfs_rdata_mempool);
63 p = NULL; 60 p = NULL;
64 } 61 }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 4cfada2cc09f..a515ec714bb6 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -98,11 +98,10 @@ struct nfs_write_data *nfs_commit_alloc(unsigned int pagecount)
98 if (p) { 98 if (p) {
99 memset(p, 0, sizeof(*p)); 99 memset(p, 0, sizeof(*p));
100 INIT_LIST_HEAD(&p->pages); 100 INIT_LIST_HEAD(&p->pages);
101 if (pagecount < NFS_PAGEVEC_SIZE) 101 if (pagecount <= ARRAY_SIZE(p->page_array))
102 p->pagevec = &p->page_array[0]; 102 p->pagevec = p->page_array;
103 else { 103 else {
104 size_t size = ++pagecount * sizeof(struct page *); 104 p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
105 p->pagevec = kzalloc(size, GFP_NOFS);
106 if (!p->pagevec) { 105 if (!p->pagevec) {
107 mempool_free(p, nfs_commit_mempool); 106 mempool_free(p, nfs_commit_mempool);
108 p = NULL; 107 p = NULL;
@@ -126,14 +125,11 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
126 if (p) { 125 if (p) {
127 memset(p, 0, sizeof(*p)); 126 memset(p, 0, sizeof(*p));
128 INIT_LIST_HEAD(&p->pages); 127 INIT_LIST_HEAD(&p->pages);
129 if (pagecount < NFS_PAGEVEC_SIZE) 128 if (pagecount <= ARRAY_SIZE(p->page_array))
130 p->pagevec = &p->page_array[0]; 129 p->pagevec = p->page_array;
131 else { 130 else {
132 size_t size = ++pagecount * sizeof(struct page *); 131 p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
133 p->pagevec = kmalloc(size, GFP_NOFS); 132 if (!p->pagevec) {
134 if (p->pagevec) {
135 memset(p->pagevec, 0, size);
136 } else {
137 mempool_free(p, nfs_wdata_mempool); 133 mempool_free(p, nfs_wdata_mempool);
138 p = NULL; 134 p = NULL;
139 } 135 }
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index c483e239f993..e206c07080fe 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -694,7 +694,7 @@ struct nfs_read_data {
694#ifdef CONFIG_NFS_V4 694#ifdef CONFIG_NFS_V4
695 unsigned long timestamp; /* For lease renewal */ 695 unsigned long timestamp; /* For lease renewal */
696#endif 696#endif
697 struct page *page_array[NFS_PAGEVEC_SIZE + 1]; 697 struct page *page_array[NFS_PAGEVEC_SIZE];
698}; 698};
699 699
700struct nfs_write_data { 700struct nfs_write_data {
@@ -712,7 +712,7 @@ struct nfs_write_data {
712#ifdef CONFIG_NFS_V4 712#ifdef CONFIG_NFS_V4
713 unsigned long timestamp; /* For lease renewal */ 713 unsigned long timestamp; /* For lease renewal */
714#endif 714#endif
715 struct page *page_array[NFS_PAGEVEC_SIZE + 1]; 715 struct page *page_array[NFS_PAGEVEC_SIZE];
716}; 716};
717 717
718struct nfs_access_entry; 718struct nfs_access_entry;