diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-13 15:58:28 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-15 09:12:21 -0400 |
commit | 493292ddc78d18ee2ad2d5c24c2b7dd6a24641d2 (patch) | |
tree | cad42b32b7baa303189ddd6d791229c619f24f37 /fs/nfs/pnfs.c | |
parent | d9156f9f364897e93bdd98b4ad22138de18f7c24 (diff) |
NFS: Move the pnfs read code into pnfs.c
...and ensure that we recoalese to take into account differences in
block sizes when falling back to read through the MDS.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r-- | fs/nfs/pnfs.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 5b3cc3f4bb39..9eca5a8cdbdd 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -28,6 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/nfs_fs.h> | 30 | #include <linux/nfs_fs.h> |
31 | #include <linux/nfs_page.h> | ||
31 | #include "internal.h" | 32 | #include "internal.h" |
32 | #include "pnfs.h" | 33 | #include "pnfs.h" |
33 | #include "iostat.h" | 34 | #include "iostat.h" |
@@ -1216,18 +1217,32 @@ pnfs_ld_read_done(struct nfs_read_data *data) | |||
1216 | } | 1217 | } |
1217 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); | 1218 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); |
1218 | 1219 | ||
1220 | static void | ||
1221 | pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, | ||
1222 | struct nfs_read_data *data) | ||
1223 | { | ||
1224 | list_splice_tail_init(&data->pages, &desc->pg_list); | ||
1225 | if (data->req && list_empty(&data->req->wb_list)) | ||
1226 | nfs_list_add_request(data->req, &desc->pg_list); | ||
1227 | nfs_pageio_reset_read_mds(desc); | ||
1228 | desc->pg_recoalesce = 1; | ||
1229 | nfs_readdata_release(data); | ||
1230 | } | ||
1231 | |||
1219 | /* | 1232 | /* |
1220 | * Call the appropriate parallel I/O subsystem read function. | 1233 | * Call the appropriate parallel I/O subsystem read function. |
1221 | */ | 1234 | */ |
1222 | enum pnfs_try_status | 1235 | static enum pnfs_try_status |
1223 | pnfs_try_to_read_data(struct nfs_read_data *rdata, | 1236 | pnfs_try_to_read_data(struct nfs_read_data *rdata, |
1224 | const struct rpc_call_ops *call_ops) | 1237 | const struct rpc_call_ops *call_ops, |
1238 | struct pnfs_layout_segment *lseg) | ||
1225 | { | 1239 | { |
1226 | struct inode *inode = rdata->inode; | 1240 | struct inode *inode = rdata->inode; |
1227 | struct nfs_server *nfss = NFS_SERVER(inode); | 1241 | struct nfs_server *nfss = NFS_SERVER(inode); |
1228 | enum pnfs_try_status trypnfs; | 1242 | enum pnfs_try_status trypnfs; |
1229 | 1243 | ||
1230 | rdata->mds_ops = call_ops; | 1244 | rdata->mds_ops = call_ops; |
1245 | rdata->lseg = get_lseg(lseg); | ||
1231 | 1246 | ||
1232 | dprintk("%s: Reading ino:%lu %u@%llu\n", | 1247 | dprintk("%s: Reading ino:%lu %u@%llu\n", |
1233 | __func__, inode->i_ino, rdata->args.count, rdata->args.offset); | 1248 | __func__, inode->i_ino, rdata->args.count, rdata->args.offset); |
@@ -1243,6 +1258,44 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata, | |||
1243 | return trypnfs; | 1258 | return trypnfs; |
1244 | } | 1259 | } |
1245 | 1260 | ||
1261 | static void | ||
1262 | pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *head) | ||
1263 | { | ||
1264 | struct nfs_read_data *data; | ||
1265 | const struct rpc_call_ops *call_ops = desc->pg_rpc_callops; | ||
1266 | struct pnfs_layout_segment *lseg = desc->pg_lseg; | ||
1267 | |||
1268 | desc->pg_lseg = NULL; | ||
1269 | while (!list_empty(head)) { | ||
1270 | enum pnfs_try_status trypnfs; | ||
1271 | |||
1272 | data = list_entry(head->next, struct nfs_read_data, list); | ||
1273 | list_del_init(&data->list); | ||
1274 | |||
1275 | trypnfs = pnfs_try_to_read_data(data, call_ops, lseg); | ||
1276 | if (trypnfs == PNFS_NOT_ATTEMPTED) | ||
1277 | pnfs_read_through_mds(desc, data); | ||
1278 | } | ||
1279 | put_lseg(lseg); | ||
1280 | } | ||
1281 | |||
1282 | int | ||
1283 | pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | ||
1284 | { | ||
1285 | LIST_HEAD(head); | ||
1286 | int ret; | ||
1287 | |||
1288 | ret = nfs_generic_pagein(desc, &head); | ||
1289 | if (ret != 0) { | ||
1290 | put_lseg(desc->pg_lseg); | ||
1291 | desc->pg_lseg = NULL; | ||
1292 | return ret; | ||
1293 | } | ||
1294 | pnfs_do_multiple_reads(desc, &head); | ||
1295 | return 0; | ||
1296 | } | ||
1297 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages); | ||
1298 | |||
1246 | /* | 1299 | /* |
1247 | * Currently there is only one (whole file) write lseg. | 1300 | * Currently there is only one (whole file) write lseg. |
1248 | */ | 1301 | */ |