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
commitd8007d4dd6ff8749cc8a4063c3ec87442db76d82 (patch)
treef778176d24666f2e2c7cd7ef4dc5917aa11cc207 /fs/nfs
parent1751c3638f2a07a8c66a803a31791bab9bd3fced (diff)
NFSv4.1: Add an initialisation callback for pNFS
Ensure that we always get a layout before setting up the i/o request. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4filelayout.c2
-rw-r--r--fs/nfs/objlayout/objio_osd.c2
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/pnfs.c57
-rw-r--r--fs/nfs/pnfs.h14
-rw-r--r--fs/nfs/read.c16
-rw-r--r--fs/nfs/write.c12
7 files changed, 46 insertions, 59 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 46bb31b79683..faac87f24797 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -682,11 +682,13 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
682} 682}
683 683
684static const struct nfs_pageio_ops filelayout_pg_read_ops = { 684static const struct nfs_pageio_ops filelayout_pg_read_ops = {
685 .pg_init = pnfs_generic_pg_init_read,
685 .pg_test = filelayout_pg_test, 686 .pg_test = filelayout_pg_test,
686 .pg_doio = nfs_generic_pg_readpages, 687 .pg_doio = nfs_generic_pg_readpages,
687}; 688};
688 689
689static const struct nfs_pageio_ops filelayout_pg_write_ops = { 690static const struct nfs_pageio_ops filelayout_pg_write_ops = {
691 .pg_init = pnfs_generic_pg_init_write,
690 .pg_test = filelayout_pg_test, 692 .pg_test = filelayout_pg_test,
691 .pg_doio = nfs_generic_pg_writepages, 693 .pg_doio = nfs_generic_pg_writepages,
692}; 694};
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index c203fab694af..b759aeba57b9 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -1008,11 +1008,13 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
1008} 1008}
1009 1009
1010static const struct nfs_pageio_ops objio_pg_read_ops = { 1010static const struct nfs_pageio_ops objio_pg_read_ops = {
1011 .pg_init = pnfs_generic_pg_init_read,
1011 .pg_test = objio_pg_test, 1012 .pg_test = objio_pg_test,
1012 .pg_doio = nfs_generic_pg_readpages, 1013 .pg_doio = nfs_generic_pg_readpages,
1013}; 1014};
1014 1015
1015static const struct nfs_pageio_ops objio_pg_write_ops = { 1016static const struct nfs_pageio_ops objio_pg_write_ops = {
1017 .pg_init = pnfs_generic_pg_init_write,
1016 .pg_test = objio_pg_test, 1018 .pg_test = objio_pg_test,
1017 .pg_doio = nfs_generic_pg_writepages, 1019 .pg_doio = nfs_generic_pg_writepages,
1018}; 1020};
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 9b8a4730f0bd..d421e19557a5 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -295,6 +295,8 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
295 if (!nfs_can_coalesce_requests(prev, req, desc)) 295 if (!nfs_can_coalesce_requests(prev, req, desc))
296 return 0; 296 return 0;
297 } else { 297 } else {
298 if (desc->pg_ops->pg_init)
299 desc->pg_ops->pg_init(desc, req);
298 desc->pg_base = req->wb_pgbase; 300 desc->pg_base = req->wb_pgbase;
299 } 301 }
300 nfs_list_remove_request(req); 302 nfs_list_remove_request(req);
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 7ec46d5f05ab..69a0c3f1e462 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -911,7 +911,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
911 * Layout segment is retreived from the server if not cached. 911 * Layout segment is retreived from the server if not cached.
912 * The appropriate layout segment is referenced and returned to the caller. 912 * The appropriate layout segment is referenced and returned to the caller.
913 */ 913 */
914struct pnfs_layout_segment * 914static struct pnfs_layout_segment *
915pnfs_update_layout(struct inode *ino, 915pnfs_update_layout(struct inode *ino,
916 struct nfs_open_context *ctx, 916 struct nfs_open_context *ctx,
917 loff_t pos, 917 loff_t pos,
@@ -1055,6 +1055,34 @@ out_forget_reply:
1055 goto out; 1055 goto out;
1056} 1056}
1057 1057
1058void
1059pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
1060{
1061 BUG_ON(pgio->pg_lseg != NULL);
1062
1063 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
1064 req->wb_context,
1065 req_offset(req),
1066 req->wb_bytes,
1067 IOMODE_READ,
1068 GFP_KERNEL);
1069}
1070EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read);
1071
1072void
1073pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
1074{
1075 BUG_ON(pgio->pg_lseg != NULL);
1076
1077 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
1078 req->wb_context,
1079 req_offset(req),
1080 req->wb_bytes,
1081 IOMODE_RW,
1082 GFP_NOFS);
1083}
1084EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);
1085
1058bool 1086bool
1059pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) 1087pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
1060{ 1088{
@@ -1083,31 +1111,8 @@ bool
1083pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 1111pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1084 struct nfs_page *req) 1112 struct nfs_page *req)
1085{ 1113{
1086 enum pnfs_iomode access_type; 1114 if (pgio->pg_lseg == NULL)
1087 gfp_t gfp_flags; 1115 return nfs_generic_pg_test(pgio, prev, req);
1088
1089 /* We assume that pg_ioflags == 0 iff we're reading a page */
1090 if (pgio->pg_ioflags == 0) {
1091 access_type = IOMODE_READ;
1092 gfp_flags = GFP_KERNEL;
1093 } else {
1094 access_type = IOMODE_RW;
1095 gfp_flags = GFP_NOFS;
1096 }
1097
1098 if (pgio->pg_lseg == NULL) {
1099 if (pgio->pg_count != prev->wb_bytes)
1100 return true;
1101 /* This is first coelesce call for a series of nfs_pages */
1102 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
1103 prev->wb_context,
1104 req_offset(prev),
1105 pgio->pg_count,
1106 access_type,
1107 gfp_flags);
1108 if (pgio->pg_lseg == NULL)
1109 return true;
1110 }
1111 1116
1112 /* 1117 /*
1113 * Test if a nfs_page is fully contained in the pnfs_layout_range. 1118 * Test if a nfs_page is fully contained in the pnfs_layout_range.
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 137a2bd5c8c7..dd54351ae6ac 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -149,10 +149,6 @@ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
149/* pnfs.c */ 149/* pnfs.c */
150void get_layout_hdr(struct pnfs_layout_hdr *lo); 150void get_layout_hdr(struct pnfs_layout_hdr *lo);
151void put_lseg(struct pnfs_layout_segment *lseg); 151void put_lseg(struct pnfs_layout_segment *lseg);
152struct pnfs_layout_segment *
153pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
154 loff_t pos, u64 count, enum pnfs_iomode access_type,
155 gfp_t gfp_flags);
156 152
157bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); 153bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
158bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int); 154bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int);
@@ -163,6 +159,8 @@ enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *,
163 const struct rpc_call_ops *, int); 159 const struct rpc_call_ops *, int);
164enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, 160enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
165 const struct rpc_call_ops *); 161 const struct rpc_call_ops *);
162void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
163void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
166bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); 164bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
167int pnfs_layout_process(struct nfs4_layoutget *lgp); 165int pnfs_layout_process(struct nfs4_layoutget *lgp);
168void pnfs_free_lseg_list(struct list_head *tmp_list); 166void pnfs_free_lseg_list(struct list_head *tmp_list);
@@ -318,14 +316,6 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg)
318{ 316{
319} 317}
320 318
321static inline struct pnfs_layout_segment *
322pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
323 loff_t pos, u64 count, enum pnfs_iomode access_type,
324 gfp_t gfp_flags)
325{
326 return NULL;
327}
328
329static inline enum pnfs_try_status 319static inline enum pnfs_try_status
330pnfs_try_to_read_data(struct nfs_read_data *data, 320pnfs_try_to_read_data(struct nfs_read_data *data,
331 const struct rpc_call_ops *call_ops) 321 const struct rpc_call_ops *call_ops)
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index b6d9ec9a208b..2cf728b832cd 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -147,9 +147,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
147 zero_user_segment(page, len, PAGE_CACHE_SIZE); 147 zero_user_segment(page, len, PAGE_CACHE_SIZE);
148 148
149 nfs_pageio_init_read(&pgio, inode); 149 nfs_pageio_init_read(&pgio, inode);
150 nfs_list_add_request(new, &pgio.pg_list); 150 nfs_pageio_add_request(&pgio, new);
151 pgio.pg_count = len;
152
153 nfs_pageio_complete(&pgio); 151 nfs_pageio_complete(&pgio);
154 return 0; 152 return 0;
155} 153}
@@ -281,7 +279,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc)
281 unsigned int offset; 279 unsigned int offset;
282 int requests = 0; 280 int requests = 0;
283 int ret = 0; 281 int ret = 0;
284 struct pnfs_layout_segment *lseg; 282 struct pnfs_layout_segment *lseg = desc->pg_lseg;
285 LIST_HEAD(list); 283 LIST_HEAD(list);
286 284
287 nfs_list_remove_request(req); 285 nfs_list_remove_request(req);
@@ -299,10 +297,6 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc)
299 } while(nbytes != 0); 297 } while(nbytes != 0);
300 atomic_set(&req->wb_complete, requests); 298 atomic_set(&req->wb_complete, requests);
301 299
302 BUG_ON(desc->pg_lseg != NULL);
303 lseg = pnfs_update_layout(desc->pg_inode, req->wb_context,
304 req_offset(req), desc->pg_count,
305 IOMODE_READ, GFP_KERNEL);
306 ClearPageError(page); 300 ClearPageError(page);
307 offset = 0; 301 offset = 0;
308 nbytes = desc->pg_count; 302 nbytes = desc->pg_count;
@@ -336,6 +330,8 @@ out_bad:
336 } 330 }
337 SetPageError(page); 331 SetPageError(page);
338 nfs_readpage_release(req); 332 nfs_readpage_release(req);
333 put_lseg(lseg);
334 desc->pg_lseg = NULL;
339 return -ENOMEM; 335 return -ENOMEM;
340} 336}
341 337
@@ -364,10 +360,6 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc)
364 *pages++ = req->wb_page; 360 *pages++ = req->wb_page;
365 } 361 }
366 req = nfs_list_entry(data->pages.next); 362 req = nfs_list_entry(data->pages.next);
367 if ((!lseg) && list_is_singular(&data->pages))
368 lseg = pnfs_update_layout(desc->pg_inode, req->wb_context,
369 req_offset(req), desc->pg_count,
370 IOMODE_READ, GFP_KERNEL);
371 363
372 ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, 364 ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count,
373 0, lseg); 365 0, lseg);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index b144b5474546..d1ae7e45886f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -916,7 +916,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc)
916 unsigned int offset; 916 unsigned int offset;
917 int requests = 0; 917 int requests = 0;
918 int ret = 0; 918 int ret = 0;
919 struct pnfs_layout_segment *lseg; 919 struct pnfs_layout_segment *lseg = desc->pg_lseg;
920 LIST_HEAD(list); 920 LIST_HEAD(list);
921 921
922 nfs_list_remove_request(req); 922 nfs_list_remove_request(req);
@@ -940,10 +940,6 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc)
940 } while (nbytes != 0); 940 } while (nbytes != 0);
941 atomic_set(&req->wb_complete, requests); 941 atomic_set(&req->wb_complete, requests);
942 942
943 BUG_ON(desc->pg_lseg);
944 lseg = pnfs_update_layout(desc->pg_inode, req->wb_context,
945 req_offset(req), desc->pg_count,
946 IOMODE_RW, GFP_NOFS);
947 ClearPageError(page); 943 ClearPageError(page);
948 offset = 0; 944 offset = 0;
949 nbytes = desc->pg_count; 945 nbytes = desc->pg_count;
@@ -976,6 +972,8 @@ out_bad:
976 nfs_writedata_free(data); 972 nfs_writedata_free(data);
977 } 973 }
978 nfs_redirty_request(req); 974 nfs_redirty_request(req);
975 put_lseg(lseg);
976 desc->pg_lseg = NULL;
979 return -ENOMEM; 977 return -ENOMEM;
980} 978}
981 979
@@ -1016,10 +1014,6 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc)
1016 *pages++ = req->wb_page; 1014 *pages++ = req->wb_page;
1017 } 1015 }
1018 req = nfs_list_entry(data->pages.next); 1016 req = nfs_list_entry(data->pages.next);
1019 if ((!lseg) && list_is_singular(&data->pages))
1020 lseg = pnfs_update_layout(desc->pg_inode, req->wb_context,
1021 req_offset(req), desc->pg_count,
1022 IOMODE_RW, GFP_NOFS);
1023 1017
1024 if ((desc->pg_ioflags & FLUSH_COND_STABLE) && 1018 if ((desc->pg_ioflags & FLUSH_COND_STABLE) &&
1025 (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) 1019 (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit))