aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-13 15:58:28 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-15 09:12:21 -0400
commit493292ddc78d18ee2ad2d5c24c2b7dd6a24641d2 (patch)
treecad42b32b7baa303189ddd6d791229c619f24f37 /fs/nfs/pnfs.c
parentd9156f9f364897e93bdd98b4ad22138de18f7c24 (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.c57
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}
1217EXPORT_SYMBOL_GPL(pnfs_ld_read_done); 1218EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
1218 1219
1220static void
1221pnfs_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 */
1222enum pnfs_try_status 1235static enum pnfs_try_status
1223pnfs_try_to_read_data(struct nfs_read_data *rdata, 1236pnfs_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
1261static void
1262pnfs_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
1282int
1283pnfs_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}
1297EXPORT_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 */