diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-06-10 13:30:23 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-12 13:40:28 -0400 |
commit | d8007d4dd6ff8749cc8a4063c3ec87442db76d82 (patch) | |
tree | f778176d24666f2e2c7cd7ef4dc5917aa11cc207 /fs/nfs | |
parent | 1751c3638f2a07a8c66a803a31791bab9bd3fced (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.c | 2 | ||||
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 2 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 2 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 57 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 14 | ||||
-rw-r--r-- | fs/nfs/read.c | 16 | ||||
-rw-r--r-- | fs/nfs/write.c | 12 |
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 | ||
684 | static const struct nfs_pageio_ops filelayout_pg_read_ops = { | 684 | static 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 | ||
689 | static const struct nfs_pageio_ops filelayout_pg_write_ops = { | 690 | static 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 | ||
1010 | static const struct nfs_pageio_ops objio_pg_read_ops = { | 1010 | static 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 | ||
1015 | static const struct nfs_pageio_ops objio_pg_write_ops = { | 1016 | static 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 | */ |
914 | struct pnfs_layout_segment * | 914 | static struct pnfs_layout_segment * |
915 | pnfs_update_layout(struct inode *ino, | 915 | pnfs_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 | ||
1058 | void | ||
1059 | pnfs_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 | } | ||
1070 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read); | ||
1071 | |||
1072 | void | ||
1073 | pnfs_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 | } | ||
1084 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write); | ||
1085 | |||
1058 | bool | 1086 | bool |
1059 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) | 1087 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) |
1060 | { | 1088 | { |
@@ -1083,31 +1111,8 @@ bool | |||
1083 | pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | 1111 | pnfs_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 */ |
150 | void get_layout_hdr(struct pnfs_layout_hdr *lo); | 150 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
151 | void put_lseg(struct pnfs_layout_segment *lseg); | 151 | void put_lseg(struct pnfs_layout_segment *lseg); |
152 | struct pnfs_layout_segment * | ||
153 | pnfs_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 | ||
157 | bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); | 153 | bool pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); |
158 | bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *, int); | 154 | bool 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); |
164 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, | 160 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, |
165 | const struct rpc_call_ops *); | 161 | const struct rpc_call_ops *); |
162 | void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *); | ||
163 | void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *); | ||
166 | bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); | 164 | bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); |
167 | int pnfs_layout_process(struct nfs4_layoutget *lgp); | 165 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
168 | void pnfs_free_lseg_list(struct list_head *tmp_list); | 166 | void 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 | ||
321 | static inline struct pnfs_layout_segment * | ||
322 | pnfs_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 | |||
329 | static inline enum pnfs_try_status | 319 | static inline enum pnfs_try_status |
330 | pnfs_try_to_read_data(struct nfs_read_data *data, | 320 | pnfs_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)) |