[PATCH] jfs: Read returns only when the bio is done
From: Edward Adam Davis
Date: Sat Apr 18 2026 - 05:06:54 EST
Fixed the sequencing of setting the DONE flag and waking up the ioevent.
The ioevent wakeup must occur after the DONE flag has been set, and while
under the protection of the jfsLCacheLock. This ensures that when the
thread associated with wait_event() resumes execution (e.g., in lbmRead/
Write/IOWait, etc.), it will strictly avoid accessing any content related
to the bio, simultaneously, this guarantees the stable and proper shutdown
of subsequent log I/O operations.
Fixes: b15e4310633f ("jfs: Set the lbmDone flag at the end of lbmIODone")
Reported-by: syzbot+ecf51a7ccb6b1394e90c@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=ecf51a7ccb6b1394e90c
Tested-by: syzbot+ecf51a7ccb6b1394e90c@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Edward Adam Davis <eadavis@xxxxxx>
---
fs/jfs/jfs_logmgr.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 306165e61438..f795f19d24bb 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -1984,7 +1984,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
submit_bio(bio);
}
- wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD));
+ wait_event(bp->l_ioevent, (bp->l_flag & lbmDONE));
return 0;
}
@@ -2192,9 +2192,6 @@ static void lbmIODone(struct bio *bio)
if (bp->l_flag & lbmREAD) {
bp->l_flag &= ~lbmREAD;
- /* wakeup I/O initiator */
- LCACHE_WAKEUP(&bp->l_ioevent);
-
goto out;
}
@@ -2217,10 +2214,8 @@ static void lbmIODone(struct bio *bio)
log = bp->l_log;
log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor;
- if (bp->l_flag & lbmDIRECT) {
- LCACHE_WAKEUP(&bp->l_ioevent);
+ if (bp->l_flag & lbmDIRECT)
goto out;
- }
tail = log->wqueue;
@@ -2271,8 +2266,7 @@ static void lbmIODone(struct bio *bio)
* leave buffer for i/o initiator to dispose
*/
if (bp->l_flag & lbmSYNC) {
- /* wakeup I/O initiator */
- LCACHE_WAKEUP(&bp->l_ioevent);
+ goto out;
}
/*
@@ -2298,6 +2292,8 @@ static void lbmIODone(struct bio *bio)
out:
bp->l_flag |= lbmDONE;
+ /* wakeup I/O initiator */
+ LCACHE_WAKEUP(&bp->l_ioevent);
LCACHE_UNLOCK(flags);
}
--
2.43.0