aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2012-04-20 14:47:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 14:10:37 -0400
commit4db6e0b74c0f6dfc2f9c0690e8df512e3b635983 (patch)
tree19d8a2a7051bdab220b0bdcf3da1e350a53ce428 /fs/nfs/pnfs.c
parent30dd374f6fc1b202db3a1b57b61afff1326bad92 (diff)
NFS: merge _full and _partial read rpc_ops
Decouple nfs_pgio_header and nfs_read_data, and have (possibly multiple) nfs_read_datas each take a refcount on nfs_pgio_header. For the moment keeps nfs_read_header as a way to preallocate a single nfs_read_data with the nfs_pgio_header. The code doesn't need this, and would be prettier without, but given the amount of churn I am already introducing I didn't want to play with tuning new mempools. This also fixes bug in pnfs_ld_handle_read_error. In the case of desc->pg_bsize < PAGE_CACHE_SIZE, the pages list was empty, causing replay attempt to do nothing. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index d705da427e6d..d1a91dbe7654 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1333,7 +1333,9 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
1333 clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags); 1333 clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags);
1334 pnfs_return_layout(hdr->inode); 1334 pnfs_return_layout(hdr->inode);
1335 } 1335 }
1336 data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode, &hdr->pages); 1336 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
1337 data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
1338 &hdr->pages);
1337} 1339}
1338 1340
1339/* 1341/*
@@ -1348,7 +1350,6 @@ void pnfs_ld_read_done(struct nfs_read_data *data)
1348 hdr->mds_ops->rpc_call_done(&data->task, data); 1350 hdr->mds_ops->rpc_call_done(&data->task, data);
1349 } else 1351 } else
1350 pnfs_ld_handle_read_error(data); 1352 pnfs_ld_handle_read_error(data);
1351 put_lseg(hdr->lseg);
1352 hdr->mds_ops->rpc_release(data); 1353 hdr->mds_ops->rpc_release(data);
1353} 1354}
1354EXPORT_SYMBOL_GPL(pnfs_ld_read_done); 1355EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
@@ -1359,11 +1360,11 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
1359{ 1360{
1360 struct nfs_pgio_header *hdr = data->header; 1361 struct nfs_pgio_header *hdr = data->header;
1361 1362
1362 list_splice_tail_init(&hdr->pages, &desc->pg_list); 1363 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
1363 if (hdr->req && list_empty(&hdr->req->wb_list)) 1364 list_splice_tail_init(&hdr->pages, &desc->pg_list);
1364 nfs_list_add_request(hdr->req, &desc->pg_list); 1365 nfs_pageio_reset_read_mds(desc);
1365 nfs_pageio_reset_read_mds(desc); 1366 desc->pg_recoalesce = 1;
1366 desc->pg_recoalesce = 1; 1367 }
1367 nfs_readdata_release(data); 1368 nfs_readdata_release(data);
1368} 1369}
1369 1370
@@ -1381,18 +1382,13 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata,
1381 enum pnfs_try_status trypnfs; 1382 enum pnfs_try_status trypnfs;
1382 1383
1383 hdr->mds_ops = call_ops; 1384 hdr->mds_ops = call_ops;
1384 hdr->lseg = get_lseg(lseg);
1385 1385
1386 dprintk("%s: Reading ino:%lu %u@%llu\n", 1386 dprintk("%s: Reading ino:%lu %u@%llu\n",
1387 __func__, inode->i_ino, rdata->args.count, rdata->args.offset); 1387 __func__, inode->i_ino, rdata->args.count, rdata->args.offset);
1388 1388
1389 trypnfs = nfss->pnfs_curr_ld->read_pagelist(rdata); 1389 trypnfs = nfss->pnfs_curr_ld->read_pagelist(rdata);
1390 if (trypnfs == PNFS_NOT_ATTEMPTED) { 1390 if (trypnfs != PNFS_NOT_ATTEMPTED)
1391 put_lseg(hdr->lseg);
1392 hdr->lseg = NULL;
1393 } else {
1394 nfs_inc_stats(inode, NFSIOS_PNFS_READ); 1391 nfs_inc_stats(inode, NFSIOS_PNFS_READ);
1395 }
1396 dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs); 1392 dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs);
1397 return trypnfs; 1393 return trypnfs;
1398} 1394}
@@ -1408,7 +1404,7 @@ pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *hea
1408 while (!list_empty(head)) { 1404 while (!list_empty(head)) {
1409 enum pnfs_try_status trypnfs; 1405 enum pnfs_try_status trypnfs;
1410 1406
1411 data = list_entry(head->next, struct nfs_read_data, list); 1407 data = list_first_entry(head, struct nfs_read_data, list);
1412 list_del_init(&data->list); 1408 list_del_init(&data->list);
1413 1409
1414 trypnfs = pnfs_try_to_read_data(data, call_ops, lseg); 1410 trypnfs = pnfs_try_to_read_data(data, call_ops, lseg);
@@ -1418,20 +1414,41 @@ pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *hea
1418 put_lseg(lseg); 1414 put_lseg(lseg);
1419} 1415}
1420 1416
1417static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
1418{
1419 put_lseg(hdr->lseg);
1420 nfs_readhdr_free(hdr);
1421}
1422
1421int 1423int
1422pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) 1424pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
1423{ 1425{
1424 LIST_HEAD(head); 1426 struct nfs_read_header *rhdr;
1427 struct nfs_pgio_header *hdr;
1425 int ret; 1428 int ret;
1426 1429
1427 ret = nfs_generic_pagein(desc, &head); 1430 rhdr = nfs_readhdr_alloc();
1428 if (ret != 0) { 1431 if (!rhdr) {
1432 nfs_async_read_error(&desc->pg_list);
1433 ret = -ENOMEM;
1429 put_lseg(desc->pg_lseg); 1434 put_lseg(desc->pg_lseg);
1430 desc->pg_lseg = NULL; 1435 desc->pg_lseg = NULL;
1431 return ret; 1436 return ret;
1432 } 1437 }
1433 pnfs_do_multiple_reads(desc, &head); 1438 hdr = &rhdr->header;
1434 return 0; 1439 nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
1440 hdr->lseg = get_lseg(desc->pg_lseg);
1441 atomic_inc(&hdr->refcnt);
1442 ret = nfs_generic_pagein(desc, hdr);
1443 if (ret != 0) {
1444 put_lseg(desc->pg_lseg);
1445 desc->pg_lseg = NULL;
1446 set_bit(NFS_IOHDR_REDO, &hdr->flags);
1447 } else
1448 pnfs_do_multiple_reads(desc, &hdr->rpc_list);
1449 if (atomic_dec_and_test(&hdr->refcnt))
1450 nfs_read_completion(hdr);
1451 return ret;
1435} 1452}
1436EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages); 1453EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages);
1437 1454