You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
f2fs: avoid deadlock during evict after f2fs_gc
o Deadlock case #1 Thread 1: - writeback_sb_inodes - do_writepages - f2fs_write_data_pages - write_cache_pages - f2fs_write_data_page - f2fs_balance_fs - wait mutex_lock(gc_mutex) Thread 2: - f2fs_balance_fs - mutex_lock(gc_mutex) - f2fs_gc - f2fs_iget - wait iget_locked(inode->i_lock) Thread 3: - do_unlinkat - iput - lock(inode->i_lock) - evict - inode_wait_for_writeback o Deadlock case #2 Thread 1: - __writeback_single_inode : set I_SYNC - do_writepages - f2fs_write_data_page - f2fs_balance_fs - f2fs_gc - iput - evict - inode_wait_for_writeback(I_SYNC) In order to avoid this, even though iput is called with the zero-reference count, we need to stop the eviction procedure if the inode is on writeback. So this patch links f2fs_drop_inode which checks the I_SYNC flag. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
This commit is contained in:
+5
-2
@@ -577,6 +577,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
|
||||
{
|
||||
struct inode *inode = mapping->host;
|
||||
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
|
||||
bool locked = false;
|
||||
int ret;
|
||||
long excess_nrtw = 0, desired_nrtw;
|
||||
|
||||
@@ -590,10 +591,12 @@ static int f2fs_write_data_pages(struct address_space *mapping,
|
||||
wbc->nr_to_write = desired_nrtw;
|
||||
}
|
||||
|
||||
if (!S_ISDIR(inode->i_mode))
|
||||
if (!S_ISDIR(inode->i_mode)) {
|
||||
mutex_lock(&sbi->writepages);
|
||||
locked = true;
|
||||
}
|
||||
ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping);
|
||||
if (!S_ISDIR(inode->i_mode))
|
||||
if (locked)
|
||||
mutex_unlock(&sbi->writepages);
|
||||
f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user