aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/pnfs.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index ce46a417e500..ee60c42b72b3 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1433,33 +1433,37 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1433 struct nfs_page *req) 1433 struct nfs_page *req)
1434{ 1434{
1435 unsigned int size; 1435 unsigned int size;
1436 u64 end; 1436 u64 seg_end, req_start, seg_left;
1437 1437
1438 size = nfs_generic_pg_test(pgio, prev, req); 1438 size = nfs_generic_pg_test(pgio, prev, req);
1439 if (!size) 1439 if (!size)
1440 return 0; 1440 return 0;
1441 1441
1442 /* 1442 /*
1443 * Test if a nfs_page is fully contained in the pnfs_layout_range. 1443 * 'size' contains the number of bytes left in the current page (up
1444 * Note that this test makes several assumptions: 1444 * to the original size asked for in @req->wb_bytes).
1445 * - that the previous nfs_page in the struct nfs_pageio_descriptor 1445 *
1446 * is known to lie within the range. 1446 * Calculate how many bytes are left in the layout segment
1447 * - that the nfs_page being tested is known to be contiguous with the 1447 * and if there are less bytes than 'size', return that instead.
1448 * previous nfs_page.
1449 * - Layout ranges are page aligned, so we only have to test the
1450 * start offset of the request.
1451 * 1448 *
1452 * Please also note that 'end_offset' is actually the offset of the 1449 * Please also note that 'end_offset' is actually the offset of the
1453 * first byte that lies outside the pnfs_layout_range. FIXME? 1450 * first byte that lies outside the pnfs_layout_range. FIXME?
1454 * 1451 *
1455 */ 1452 */
1456 if (pgio->pg_lseg) { 1453 if (pgio->pg_lseg) {
1457 end = end_offset(pgio->pg_lseg->pls_range.offset, 1454 seg_end = end_offset(pgio->pg_lseg->pls_range.offset,
1458 pgio->pg_lseg->pls_range.length); 1455 pgio->pg_lseg->pls_range.length);
1459 WARN_ON_ONCE(req_offset(req) > end); 1456 req_start = req_offset(req);
1460 if (req_offset(req) >= end) 1457 WARN_ON_ONCE(req_start > seg_end);
1458 /* start of request is past the last byte of this segment */
1459 if (req_start >= seg_end)
1461 return 0; 1460 return 0;
1462 size = min((unsigned int)(end - req_offset(req)), size); 1461
1462 /* adjust 'size' iff there are fewer bytes left in the
1463 * segment than what nfs_generic_pg_test returned */
1464 seg_left = seg_end - req_start;
1465 if (seg_left < size)
1466 size = (unsigned int)seg_left;
1463 } 1467 }
1464 1468
1465 return size; 1469 return size;