From 35017d0973bb1fcc2a4f47d7cecdea75f5f0e69b Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Wed, 14 Jun 2023 19:33:43 +0300 Subject: [PATCH] LU-16898 osd-ldiskfs: do not return dr_error from past RPC dr_error was cleared in osd_init_iobuf() only before handling new read/write RPCs, so a later non-read/write RPC handled by that thread would return the stale dr_error value from the last read/write RPC. Always clear dr_error in osd_trans_stop->osd_fini_iobuf() after it is checked, so that it cannot affect later RPCs. Change-Id: Idbeab67edc66b58e9869b67640693c7f1dd9d6f2 Signed-off-by: Andrew Perepechko HPE-bug-id: LUS-11682 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51320 Reviewed-by: Alexander Zarochentsev Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger Tested-by: Maloo Tested-by: jenkins --- lustre/osd-ldiskfs/osd_handler.c | 4 +++- lustre/osd-ldiskfs/osd_io.c | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 7fe6533..51f3dbd 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2228,10 +2228,12 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt, */ wait_event(iobuf->dr_wait, atomic_read(&iobuf->dr_numreqs) == 0); - osd_fini_iobuf(osd, iobuf); + if (!rc) rc = iobuf->dr_error; + osd_fini_iobuf(osd, iobuf); + if (unlikely(remove_agents != 0)) osd_process_scheduled_agent_removals(env, osd); diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 74ca2d9..04314ed 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -195,6 +195,8 @@ void osd_fini_iobuf(struct osd_device *d, struct osd_iobuf *iobuf) lprocfs_oh_tally_log2_pcpu(&h->bs_hist[BRW_R_IO_TIME+rw], ktime_to_ms(iobuf->dr_elapsed)); } + + iobuf->dr_error = 0; } @@ -511,17 +513,18 @@ out: * parallel and wait for IO completion once transaction is stopped * see osd_trans_stop() for more details -bzzz */ - if (iobuf->dr_rw == 0 || fault_inject) { + if (iobuf->dr_rw == 0 || fault_inject) wait_event(iobuf->dr_wait, atomic_read(&iobuf->dr_numreqs) == 0); - osd_fini_iobuf(osd, iobuf); - } if (rc == 0) rc = iobuf->dr_error; else osd_bio_fini(bio); + if (iobuf->dr_rw == 0 || fault_inject) + osd_fini_iobuf(osd, iobuf); + /* Write only now */ if (rc == 0 && iobuf->dr_rw) osd_mark_page_io_done(iobuf, inode, -- 1.8.3.1