diff options
author | Chao Yu <yuchao0@huawei.com> | 2018-05-07 20:28:54 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2018-05-31 11:31:51 -0700 |
commit | 2ef79ecb5e906d87475d3e0c49b22425499a89f3 (patch) | |
tree | 266179c3b3bd4d98a621ce4652729bdb716e1d2f /fs/f2fs/segment.c | |
parent | 5b0e95398e2bcc18e871758221cc712be4a0a39a (diff) | |
download | linux-2ef79ecb5e906d87475d3e0c49b22425499a89f3.tar.gz linux-2ef79ecb5e906d87475d3e0c49b22425499a89f3.tar.bz2 linux-2ef79ecb5e906d87475d3e0c49b22425499a89f3.zip |
f2fs: avoid stucking GC due to atomic write
f2fs doesn't allow abuse on atomic write class interface, so except
limiting in-mem pages' total memory usage capacity, we need to limit
atomic-write usage as well when filesystem is seriously fragmented,
otherwise we may run into infinite loop during foreground GC because
target blocks in victim segment are belong to atomic opened file for
long time.
Now, we will detect failure due to atomic write in foreground GC, if
the count exceeds threshold, we will drop all atomic written data in
cache, by this, I expect it can keep our system running safely to
prevent Dos attack.
In addition, his patch adds to show GC skip information in debugfs,
now it just shows count of skipped caused by atomic write.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r-- | fs/f2fs/segment.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 55cba4fc3a04..cc2d8f86d1ae 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -273,7 +273,7 @@ next: return err; } -void drop_inmem_pages_all(struct f2fs_sb_info *sbi) +void drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure) { struct list_head *head = &sbi->inode_list[ATOMIC_FILE]; struct inode *inode; @@ -289,9 +289,17 @@ next: spin_unlock(&sbi->inode_lock[ATOMIC_FILE]); if (inode) { + if (gc_failure) { + if (fi->i_gc_failures[GC_FAILURE_ATOMIC]) + goto drop; + goto skip; + } +drop: + set_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST); drop_inmem_pages(inode); iput(inode); } +skip: congestion_wait(BLK_RW_ASYNC, HZ/50); cond_resched(); goto next; @@ -311,6 +319,7 @@ void drop_inmem_pages(struct inode *inode) mutex_unlock(&fi->inmem_lock); clear_inode_flag(inode, FI_ATOMIC_FILE); + fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0; stat_dec_atomic_write(inode); } |