Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfs: chain calls to pg_test

Now that pg_test can change the size of the request (by returning a non-zero
size smaller than the request), pg_test functions that call other
pg_test functions must return the minimum of the result - or 0 if any fail.

Also clean up the logic of some pg_test functions so that all checks are
for contitions where coalescing is not possible.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

authored by

Weston Andros Adamson and committed by
Trond Myklebust
0f9c429e 6094f838

+30 -21
+14 -13
fs/nfs/nfs4filelayout.c
··· 928 928 filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 929 929 struct nfs_page *req) 930 930 { 931 + unsigned int size; 931 932 u64 p_stripe, r_stripe; 932 933 u32 stripe_unit; 933 934 934 - if (!pnfs_generic_pg_test(pgio, prev, req) || 935 - !nfs_generic_pg_test(pgio, prev, req)) 935 + /* calls nfs_generic_pg_test */ 936 + size = pnfs_generic_pg_test(pgio, prev, req); 937 + if (!size) 936 938 return 0; 937 939 938 - if (!prev) 939 - return req->wb_bytes; 940 + if (prev) { 941 + p_stripe = (u64)req_offset(prev); 942 + r_stripe = (u64)req_offset(req); 943 + stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit; 940 944 941 - p_stripe = (u64)req_offset(prev); 942 - r_stripe = (u64)req_offset(req); 943 - stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit; 945 + do_div(p_stripe, stripe_unit); 946 + do_div(r_stripe, stripe_unit); 944 947 945 - do_div(p_stripe, stripe_unit); 946 - do_div(r_stripe, stripe_unit); 947 - 948 - if (p_stripe == r_stripe) 949 - return req->wb_bytes; 950 - return 0; 948 + if (p_stripe != r_stripe) 949 + return 0; 950 + } 951 + return min(size, req->wb_bytes); 951 952 } 952 953 953 954 static void
+6 -3
fs/nfs/objlayout/objio_osd.c
··· 571 571 static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio, 572 572 struct nfs_page *prev, struct nfs_page *req) 573 573 { 574 - if (!pnfs_generic_pg_test(pgio, prev, req) || 575 - pgio->pg_count + req->wb_bytes > 574 + unsigned int size; 575 + 576 + size = pnfs_generic_pg_test(pgio, prev, req); 577 + 578 + if (!size || pgio->pg_count + req->wb_bytes > 576 579 (unsigned long)pgio->pg_layout_private) 577 580 return 0; 578 581 579 - return req->wb_bytes; 582 + return min(size, req->wb_bytes); 580 583 } 581 584 582 585 static void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+10 -5
fs/nfs/pnfs.c
··· 1442 1442 pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 1443 1443 struct nfs_page *req) 1444 1444 { 1445 - if (pgio->pg_lseg == NULL) 1446 - return nfs_generic_pg_test(pgio, prev, req); 1445 + unsigned int size; 1446 + 1447 + size = nfs_generic_pg_test(pgio, prev, req); 1448 + 1449 + if (!size) 1450 + return 0; 1447 1451 1448 1452 /* 1449 1453 * Test if a nfs_page is fully contained in the pnfs_layout_range. ··· 1463 1459 * first byte that lies outside the pnfs_layout_range. FIXME? 1464 1460 * 1465 1461 */ 1466 - if (req_offset(req) < end_offset(pgio->pg_lseg->pls_range.offset, 1462 + if (req_offset(req) >= end_offset(pgio->pg_lseg->pls_range.offset, 1467 1463 pgio->pg_lseg->pls_range.length)) 1468 - return req->wb_bytes; 1469 - return 0; 1464 + return 0; 1465 + 1466 + return min(size, req->wb_bytes); 1470 1467 } 1471 1468 EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); 1472 1469