diff options
author | Sahitya Tummala <stummala@codeaurora.org> | 2019-11-13 16:01:03 +0530 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-04 19:18:18 +0100 |
commit | ce7269497052f463cb3c74f1388d352c37d24b80 (patch) | |
tree | 631053a644a39c02f8250e5aabe450b7bc47a3ae /fs/f2fs/f2fs.h | |
parent | ddf426dbe3162d61d35497dc5ac8034778009481 (diff) | |
download | linux-stable-ce7269497052f463cb3c74f1388d352c37d24b80.tar.gz linux-stable-ce7269497052f463cb3c74f1388d352c37d24b80.tar.bz2 linux-stable-ce7269497052f463cb3c74f1388d352c37d24b80.zip |
f2fs: Fix deadlock in f2fs_gc() context during atomic files handling
[ Upstream commit 677017d196ba2a4cfff13626b951cc9a206b8c7c ]
The FS got stuck in the below stack when the storage is almost
full/dirty condition (when FG_GC is being done).
schedule_timeout
io_schedule_timeout
congestion_wait
f2fs_drop_inmem_pages_all
f2fs_gc
f2fs_balance_fs
__write_node_page
f2fs_fsync_node_pages
f2fs_do_sync_file
f2fs_ioctl
The root cause for this issue is there is a potential infinite loop
in f2fs_drop_inmem_pages_all() for the case where gc_failure is true
and when there an inode whose i_gc_failures[GC_FAILURE_ATOMIC] is
not set. Fix this by keeping track of the total atomic files
currently opened and using that to exit from this condition.
Fix-suggested-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/f2fs/f2fs.h')
-rw-r--r-- | fs/f2fs/f2fs.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f078cd20dab8..9046432b87c2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1289,6 +1289,7 @@ struct f2fs_sb_info { unsigned int gc_mode; /* current GC state */ unsigned int next_victim_seg[2]; /* next segment in victim section */ /* for skip statistic */ + unsigned int atomic_files; /* # of opened atomic file */ unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */ unsigned long long skipped_gc_rwsem; /* FG_GC only */ |