aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-06-10 13:30:23 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-12 13:40:28 -0400
commit1751c3638f2a07a8c66a803a31791bab9bd3fced (patch)
tree5c1f39f879c0a0049c50b4f36a256ba1986d82b2 /fs/nfs
parentf062eb6ced3b297277b94b4da3113b1d3782e539 (diff)
NFS: Cleanup of the nfs_pageio code in preparation for a pnfs bugfix
We need to ensure that the layouts are set up before we can decide to coalesce requests. To do so, we want to further split up the struct nfs_pageio_descriptor operations into an initialisation callback, a coalescing test callback, and a 'do i/o' callback. This patch cleans up the existing callback methods before adding the 'initialisation' callback. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4filelayout.c15
-rw-r--r--fs/nfs/objlayout/objio_osd.c13
-rw-r--r--fs/nfs/pagelist.c10
-rw-r--r--fs/nfs/pnfs.c24
-rw-r--r--fs/nfs/pnfs.h25
-rw-r--r--fs/nfs/read.c43
-rw-r--r--fs/nfs/write.c28
7 files changed, 120 insertions, 38 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index b690bb5ee58..46bb31b7968 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -658,7 +658,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
658 * return true : coalesce page 658 * return true : coalesce page
659 * return false : don't coalesce page 659 * return false : don't coalesce page
660 */ 660 */
661bool 661static bool
662filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 662filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
663 struct nfs_page *req) 663 struct nfs_page *req)
664{ 664{
@@ -681,6 +681,16 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
681 return (p_stripe == r_stripe); 681 return (p_stripe == r_stripe);
682} 682}
683 683
684static const struct nfs_pageio_ops filelayout_pg_read_ops = {
685 .pg_test = filelayout_pg_test,
686 .pg_doio = nfs_generic_pg_readpages,
687};
688
689static const struct nfs_pageio_ops filelayout_pg_write_ops = {
690 .pg_test = filelayout_pg_test,
691 .pg_doio = nfs_generic_pg_writepages,
692};
693
684static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg) 694static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg)
685{ 695{
686 return !FILELAYOUT_LSEG(lseg)->commit_through_mds; 696 return !FILELAYOUT_LSEG(lseg)->commit_through_mds;
@@ -878,7 +888,8 @@ static struct pnfs_layoutdriver_type filelayout_type = {
878 .owner = THIS_MODULE, 888 .owner = THIS_MODULE,
879 .alloc_lseg = filelayout_alloc_lseg, 889 .alloc_lseg = filelayout_alloc_lseg,
880 .free_lseg = filelayout_free_lseg, 890 .free_lseg = filelayout_free_lseg,
881 .pg_test = filelayout_pg_test, 891 .pg_read_ops = &filelayout_pg_read_ops,
892 .pg_write_ops = &filelayout_pg_write_ops,
882 .mark_pnfs_commit = filelayout_mark_pnfs_commit, 893 .mark_pnfs_commit = filelayout_mark_pnfs_commit,
883 .choose_commit_list = filelayout_choose_commit_list, 894 .choose_commit_list = filelayout_choose_commit_list,
884 .commit_pagelist = filelayout_commit_pagelist, 895 .commit_pagelist = filelayout_commit_pagelist,
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 8ff2ea3f10e..c203fab694a 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -1007,6 +1007,16 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
1007 OBJIO_LSEG(pgio->pg_lseg)->max_io_size; 1007 OBJIO_LSEG(pgio->pg_lseg)->max_io_size;
1008} 1008}
1009 1009
1010static const struct nfs_pageio_ops objio_pg_read_ops = {
1011 .pg_test = objio_pg_test,
1012 .pg_doio = nfs_generic_pg_readpages,
1013};
1014
1015static const struct nfs_pageio_ops objio_pg_write_ops = {
1016 .pg_test = objio_pg_test,
1017 .pg_doio = nfs_generic_pg_writepages,
1018};
1019
1010static struct pnfs_layoutdriver_type objlayout_type = { 1020static struct pnfs_layoutdriver_type objlayout_type = {
1011 .id = LAYOUT_OSD2_OBJECTS, 1021 .id = LAYOUT_OSD2_OBJECTS,
1012 .name = "LAYOUT_OSD2_OBJECTS", 1022 .name = "LAYOUT_OSD2_OBJECTS",
@@ -1020,7 +1030,8 @@ static struct pnfs_layoutdriver_type objlayout_type = {
1020 1030
1021 .read_pagelist = objlayout_read_pagelist, 1031 .read_pagelist = objlayout_read_pagelist,
1022 .write_pagelist = objlayout_write_pagelist, 1032 .write_pagelist = objlayout_write_pagelist,
1023 .pg_test = objio_pg_test, 1033 .pg_read_ops = &objio_pg_read_ops,
1034 .pg_write_ops = &objio_pg_write_ops,
1024 1035
1025 .free_deviceid_node = objio_free_deviceid_node, 1036 .free_deviceid_node = objio_free_deviceid_node,
1026 1037
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 00985571628..9b8a4730f0b 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -230,7 +230,7 @@ EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
230 */ 230 */
231void nfs_pageio_init(struct nfs_pageio_descriptor *desc, 231void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
232 struct inode *inode, 232 struct inode *inode,
233 int (*doio)(struct nfs_pageio_descriptor *), 233 const struct nfs_pageio_ops *pg_ops,
234 size_t bsize, 234 size_t bsize,
235 int io_flags) 235 int io_flags)
236{ 236{
@@ -241,12 +241,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
241 desc->pg_base = 0; 241 desc->pg_base = 0;
242 desc->pg_moreio = 0; 242 desc->pg_moreio = 0;
243 desc->pg_inode = inode; 243 desc->pg_inode = inode;
244 desc->pg_doio = doio; 244 desc->pg_ops = pg_ops;
245 desc->pg_ioflags = io_flags; 245 desc->pg_ioflags = io_flags;
246 desc->pg_error = 0; 246 desc->pg_error = 0;
247 desc->pg_lseg = NULL; 247 desc->pg_lseg = NULL;
248 desc->pg_test = nfs_generic_pg_test;
249 pnfs_pageio_init(desc, inode);
250} 248}
251 249
252/** 250/**
@@ -276,7 +274,7 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
276 return false; 274 return false;
277 if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) 275 if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE)
278 return false; 276 return false;
279 return pgio->pg_test(pgio, prev, req); 277 return pgio->pg_ops->pg_test(pgio, prev, req);
280} 278}
281 279
282/** 280/**
@@ -311,7 +309,7 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
311static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) 309static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
312{ 310{
313 if (!list_empty(&desc->pg_list)) { 311 if (!list_empty(&desc->pg_list)) {
314 int error = desc->pg_doio(desc); 312 int error = desc->pg_ops->pg_doio(desc);
315 if (error < 0) 313 if (error < 0)
316 desc->pg_error = error; 314 desc->pg_error = error;
317 else 315 else
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index ff820077237..7ec46d5f05a 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1056,6 +1056,30 @@ out_forget_reply:
1056} 1056}
1057 1057
1058bool 1058bool
1059pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
1060{
1061 struct nfs_server *server = NFS_SERVER(inode);
1062 struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
1063
1064 if (ld == NULL)
1065 return false;
1066 nfs_pageio_init(pgio, inode, ld->pg_read_ops, server->rsize, 0);
1067 return true;
1068}
1069
1070bool
1071pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode, int ioflags)
1072{
1073 struct nfs_server *server = NFS_SERVER(inode);
1074 struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
1075
1076 if (ld == NULL)
1077 return false;
1078 nfs_pageio_init(pgio, inode, ld->pg_write_ops, server->wsize, ioflags);
1079 return true;
1080}
1081
1082bool
1059pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 1083pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1060 struct nfs_page *req) 1084 struct nfs_page *req)
1061{ 1085{
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 96bf4e6f45b..137a2bd5c8c 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -87,7 +87,8 @@ struct pnfs_layoutdriver_type {
87 void (*free_lseg) (struct pnfs_layout_segment *lseg); 87 void (*free_lseg) (struct pnfs_layout_segment *lseg);
88 88
89 /* test for nfs page cache coalescing */ 89 /* test for nfs page cache coalescing */
90 bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); 90 const struct nfs_pageio_ops *pg_read_ops;
91 const struct nfs_pageio_ops *pg_write_ops;
91 92
92 /* Returns true if layoutdriver wants to divert this request to 93 /* Returns true if layoutdriver wants to divert this request to
93 * driver's commit routine. 94 * driver's commit routine.
@@ -152,6 +153,10 @@ struct pnfs_layout_segment *
152pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, 153pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
153 loff_t pos, u64 count, enum pnfs_iomode access_type, 154 loff_t pos, u64 count, enum pnfs_iomode access_type,
154 gfp_t gfp_flags); 155 gfp_t gfp_flags);
156
157bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
158bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int);
159
155void set_pnfs_layoutdriver(struct nfs_server *, u32 id); 160void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
156void unset_pnfs_layoutdriver(struct nfs_server *); 161void unset_pnfs_layoutdriver(struct nfs_server *);
157enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, 162enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *,
@@ -293,15 +298,6 @@ static inline int pnfs_return_layout(struct inode *ino)
293 return 0; 298 return 0;
294} 299}
295 300
296static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio,
297 struct inode *inode)
298{
299 struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
300
301 if (ld)
302 pgio->pg_test = ld->pg_test;
303}
304
305#else /* CONFIG_NFS_V4_1 */ 301#else /* CONFIG_NFS_V4_1 */
306 302
307static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) 303static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
@@ -385,9 +381,14 @@ static inline void unset_pnfs_layoutdriver(struct nfs_server *s)
385{ 381{
386} 382}
387 383
388static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio, 384static inline bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
389 struct inode *inode)
390{ 385{
386 return false;
387}
388
389static inline bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode, int ioflags)
390{
391 return false;
391} 392}
392 393
393static inline void 394static inline void
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 20a7f952e24..b6d9ec9a208 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -32,6 +32,7 @@
32 32
33static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc); 33static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc);
34static int nfs_pagein_one(struct nfs_pageio_descriptor *desc); 34static int nfs_pagein_one(struct nfs_pageio_descriptor *desc);
35static const struct nfs_pageio_ops nfs_pageio_read_ops;
35static const struct rpc_call_ops nfs_read_partial_ops; 36static const struct rpc_call_ops nfs_read_partial_ops;
36static const struct rpc_call_ops nfs_read_full_ops; 37static const struct rpc_call_ops nfs_read_full_ops;
37 38
@@ -113,6 +114,20 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data)
113 } 114 }
114} 115}
115 116
117static void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
118 struct inode *inode)
119{
120 nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops,
121 NFS_SERVER(inode)->rsize, 0);
122}
123
124static void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
125 struct inode *inode)
126{
127 if (!pnfs_pageio_init_read(pgio, inode))
128 nfs_pageio_init_read_mds(pgio, inode);
129}
130
116int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, 131int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
117 struct page *page) 132 struct page *page)
118{ 133{
@@ -131,14 +146,11 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
131 if (len < PAGE_CACHE_SIZE) 146 if (len < PAGE_CACHE_SIZE)
132 zero_user_segment(page, len, PAGE_CACHE_SIZE); 147 zero_user_segment(page, len, PAGE_CACHE_SIZE);
133 148
134 nfs_pageio_init(&pgio, inode, NULL, 0, 0); 149 nfs_pageio_init_read(&pgio, inode);
135 nfs_list_add_request(new, &pgio.pg_list); 150 nfs_list_add_request(new, &pgio.pg_list);
136 pgio.pg_count = len; 151 pgio.pg_count = len;
137 152
138 if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) 153 nfs_pageio_complete(&pgio);
139 nfs_pagein_multi(&pgio);
140 else
141 nfs_pagein_one(&pgio);
142 return 0; 154 return 0;
143} 155}
144 156
@@ -365,6 +377,20 @@ out:
365 return ret; 377 return ret;
366} 378}
367 379
380int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
381{
382 if (desc->pg_bsize < PAGE_CACHE_SIZE)
383 return nfs_pagein_multi(desc);
384 return nfs_pagein_one(desc);
385}
386EXPORT_SYMBOL_GPL(nfs_generic_pg_readpages);
387
388
389static const struct nfs_pageio_ops nfs_pageio_read_ops = {
390 .pg_test = nfs_generic_pg_test,
391 .pg_doio = nfs_generic_pg_readpages,
392};
393
368/* 394/*
369 * This is the callback from RPC telling us whether a reply was 395 * This is the callback from RPC telling us whether a reply was
370 * received or some error occurred (timeout or socket shutdown). 396 * received or some error occurred (timeout or socket shutdown).
@@ -635,8 +661,6 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
635 .pgio = &pgio, 661 .pgio = &pgio,
636 }; 662 };
637 struct inode *inode = mapping->host; 663 struct inode *inode = mapping->host;
638 struct nfs_server *server = NFS_SERVER(inode);
639 size_t rsize = server->rsize;
640 unsigned long npages; 664 unsigned long npages;
641 int ret = -ESTALE; 665 int ret = -ESTALE;
642 666
@@ -664,10 +688,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
664 if (ret == 0) 688 if (ret == 0)
665 goto read_complete; /* all pages were read */ 689 goto read_complete; /* all pages were read */
666 690
667 if (rsize < PAGE_CACHE_SIZE) 691 nfs_pageio_init_read(&pgio, inode);
668 nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
669 else
670 nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0);
671 692
672 ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); 693 ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
673 694
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 72716805968..b144b547454 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1033,15 +1033,31 @@ out:
1033 return ret; 1033 return ret;
1034} 1034}
1035 1035
1036static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, 1036int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
1037{
1038 if (desc->pg_bsize < PAGE_CACHE_SIZE)
1039 return nfs_flush_multi(desc);
1040 return nfs_flush_one(desc);
1041}
1042EXPORT_SYMBOL_GPL(nfs_generic_pg_writepages);
1043
1044static const struct nfs_pageio_ops nfs_pageio_write_ops = {
1045 .pg_test = nfs_generic_pg_test,
1046 .pg_doio = nfs_generic_pg_writepages,
1047};
1048
1049static void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
1037 struct inode *inode, int ioflags) 1050 struct inode *inode, int ioflags)
1038{ 1051{
1039 size_t wsize = NFS_SERVER(inode)->wsize; 1052 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops,
1053 NFS_SERVER(inode)->wsize, ioflags);
1054}
1040 1055
1041 if (wsize < PAGE_CACHE_SIZE) 1056static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
1042 nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); 1057 struct inode *inode, int ioflags)
1043 else 1058{
1044 nfs_pageio_init(pgio, inode, nfs_flush_one, wsize, ioflags); 1059 if (!pnfs_pageio_init_write(pgio, inode, ioflags))
1060 nfs_pageio_init_write_mds(pgio, inode, ioflags);
1045} 1061}
1046 1062
1047/* 1063/*