Messages in this thread Patch in this message | | | From | Jia-Ju Bai <> | Subject | [PATCH v2] fs: jfs: fix a possible data race in metapage_writepage() | Date | Tue, 5 May 2020 21:53:13 +0800 |
| |
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 <baijiaju1990@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
| |