Whamcloud - gitweb
LU-16898 osd-ldiskfs: do not return dr_error from past RPC 20/51320/7
authorAndrew Perepechko <andrew.perepechko@hpe.com>
Wed, 14 Jun 2023 16:33:43 +0000 (19:33 +0300)
committerOleg Drokin <green@whamcloud.com>
Sat, 8 Jul 2023 22:36:12 +0000 (22:36 +0000)
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 <andrew.perepechko@hpe.com>
HPE-bug-id: LUS-11682
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51320
Reviewed-by: Alexander Zarochentsev <alexander.zarochentsev@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_io.c

index 7fe6533..51f3dbd 100644 (file)
@@ -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);
 
index 74ca2d9..04314ed 100644 (file)
@@ -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,