From 8a397e7c7c0d4ec02beddcb9c7f57605160a876b Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Wed, 1 Nov 2023 16:14:12 -0400 Subject: [PATCH] EX-7601 osc: walk chunk unaligned RPC correctly For decompression, the client must start looking for compressed chunks at a chunk aligned offset. Implement this in decompress_request. Signed-off-by: Patrick Farrell Change-Id: I3273135990ddf51e8b3c651734e19350e91f659c Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52933 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Artem Blagodarenko --- lustre/osc/osc_compress.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/lustre/osc/osc_compress.c b/lustre/osc/osc_compress.c index e2243d3..58bd390 100644 --- a/lustre/osc/osc_compress.c +++ b/lustre/osc/osc_compress.c @@ -309,6 +309,7 @@ out: int decompress_request(struct osc_brw_async_args *aa, int page_count) { struct brw_page **pga = aa->aa_ppga; + struct osc_async_page *oap = NULL; struct ll_compr_hdr *llch = NULL; struct cl_page *clpage; unsigned int src_size; @@ -336,7 +337,29 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count) buf_bits = chunk_bits + 1; pages_in_chunk = chunk_size / PAGE_SIZE; - for (i = 0; i < page_count; i+=pages_in_chunk) { + /* the RPC may not start on a chunk boundary, find the first chunk + * boundary, then start iterating by chunk_size at that point (in the + * next loop) + */ + for (i = 0; i < page_count; i++) { + oap = brw_page2oap(pga[i]); + + /* aligned to chunk size */ + if (!(oap->oap_obj_off & (chunk_size - 1))) + break; + } + + /* no chunk aligned pages in the RPC, no possibility of a compressed + * chunk + */ + if (i == page_count) + GOTO(out, rc = 0); + + CDEBUG(D_SEC, "starting decompression at page %d, offset %llu\n", + i, oap->oap_obj_off); + + /* i is the first chunk aligned page in the RPC */ + for (; i < page_count; i+=pages_in_chunk) { struct cl_page *cl_page = oap2cl_page(brw_page2oap(pga[i])); @@ -393,7 +416,8 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count) count++; } - CDEBUG(D_SEC, "Decompressed %i pages (%i chunks)\n", page_count, count); + CDEBUG(D_SEC, + "RPC is %d pages, decompressed %d chunks\n", page_count, count); out: if (src != NULL) sptlrpc_pool_put_pages(&src, buf_bits); -- 1.8.3.1