From c53f5fc6a1c6a1832217ebb76450120d18e42267 Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Wed, 13 Dec 2023 18:33:16 -0500 Subject: [PATCH] EX-7601 ofd: add checks to io_lnb_to_tx_lnb We should always be able to find the remote niobuf in the local io range, if we can't, there's a bug. So assert on this. We should also never have page level overlapping remote IOs, at least until we have unaligned DIO. (We can remove this check when we combine the features.) Test-Parameters: trivial Signed-off-by: Patrick Farrell Change-Id: I325d4a37d25c116e42621964e90b225b71fd8f1f Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/53450 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/target/tgt_handler.c | 47 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index fcd7174..959ba58 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -2305,13 +2305,16 @@ int range_to_page_count(loff_t offset, ssize_t len) return end_page - start_page + 1; } -void io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb, - struct niobuf_remote *rnb, int niocount, int npages_local) +int io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb, + struct niobuf_remote *rnb, int niocount, int npages_local) { + int prev_lnb_index = -1; int lnb_index = 0; int tx_lnb_pg = 0; int i; + ENTRY; + /* for each io in the remote niobuf, we find the offset of the * starting page in the lnb, then we point the tx lnbs at the matching * pages in the io lnb, so we can do transfer from just those pages @@ -2337,6 +2340,33 @@ void io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb, break; lnb_index++; } + /* this indicates remote ios overlapped at the page level, + * which is impossible until we have unaligned DIO + */ + if (lnb_index == prev_lnb_index) { + CDEBUG(D_ERROR, + "lnbs overlap at page level: lnb %d, at %llu page offset %d, rnb %d, rnb offset %llu, prev lnb at %llu, page offset %d\n", + lnb_index, io_lnb[lnb_index].lnb_file_offset, + io_lnb[lnb_index].lnb_page_offset, i, + rnb[i].rnb_offset, + io_lnb[prev_lnb_index].lnb_file_offset, + io_lnb[prev_lnb_index].lnb_page_offset); + RETURN(-EINVAL); + } + prev_lnb_index = lnb_index; + /* this means we didn't find the remote IO, which should be + * impossible + */ + if (lnb_index == npages_local) { + CDEBUG(D_ERROR, + "hit end of local pages, remote IO not found!\n"); + CDEBUG(D_ERROR, + "npages_local %d, last offset %llu, rnb %d, rnb offset %llu\n", + npages_local, + io_lnb[lnb_index - 1].lnb_file_offset, i, + rnb[i].rnb_offset); + LBUG(); + } npages_remote = range_to_page_count(rnb[i].rnb_offset, rnb[i].rnb_len); CDEBUG(D_SEC, "nio %d npages_remote %d, lnb_index %d\n", i, @@ -2358,6 +2388,7 @@ void io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb, } LASSERT(len == 0); } + RETURN(0); } int tgt_brw_read(struct tgt_session_info *tsi) @@ -2572,8 +2603,10 @@ int tgt_brw_read(struct tgt_session_info *tsi) if (npages_local != npages_remote) { LASSERT(compr_type != LL_COMPR_TYPE_NONE); local_tx_nb = tbc->tbc_lnb2; - io_lnb_to_tx_lnb(local_io_nb, local_tx_nb, remote_nb, - niocount, npages_local); + rc = io_lnb_to_tx_lnb(local_io_nb, local_tx_nb, remote_nb, + niocount, npages_local); + if (rc) + GOTO(out_commitrw, rc); } npages_read = npages_remote; @@ -3047,8 +3080,10 @@ int tgt_brw_write(struct tgt_session_info *tsi) if (npages_local != npages_remote) { LASSERT(compr_type != LL_COMPR_TYPE_NONE); local_tx_nb = tbc->tbc_lnb2; - io_lnb_to_tx_lnb(local_write_nb, local_tx_nb, remote_nb, - niocount, npages_local); + rc = io_lnb_to_tx_lnb(local_write_nb, local_tx_nb, remote_nb, + niocount, npages_local); + if (rc) + GOTO(out_commitrw, rc); } if (body->oa.o_valid & OBD_MD_FLFLAGS && -- 1.8.3.1