The functions metapage_writepage() and lmPostGC() can be concurrently executed in the following call contexts:
Thread1: metapage_writepage() Thread2: lbmIODone() lmPostGC() In metapage_writepage(): if (mp->log && !(mp->log->cflag & logGC_PAGEOUT)) In lmPostGC(): spin_lock_irqsave(&log->gclock, flags); ... log->cflag &= ~logGC_PAGEOUT ... spin_unlock_irqrestore(&log->gclock, flags); The memory addresses of mp->log->cflag and log->cflag can be identical, and thus a data race can occur. This data race is found by our concurrency fuzzer. Thus use the spin lock "mp->log->gclock" for the assignment of the data structure member "log->cflag" to a local variable in this function implementation. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- v2: * Change the description. Thank Markus Elfring for good advice. --- fs/jfs/jfs_metapage.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index a2f5338a5ea1..026c11b2572d 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -351,6 +351,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) unsigned long bio_offset = 0; int offset; int bad_blocks = 0; + uint cflag; page_start = (sector_t)page->index << (PAGE_SHIFT - inode->i_blkbits); @@ -370,8 +371,14 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) * Make sure this page isn't blocked indefinitely. * If the journal isn't undergoing I/O, push it */ - if (mp->log && !(mp->log->cflag & logGC_PAGEOUT)) - jfs_flush_journal(mp->log, 0); + + if (mp->log) { + spin_lock_irq(&mp->log->gclock); + cflag = mp->log->cflag; + spin_unlock_irq(&mp->log->gclock); + if (!(cflag & logGC_PAGEOUT)) + jfs_flush_journal(mp->log, 0); + } continue; } -- 2.17.1