Commit c521a6ab authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: fix to limit gc_pin_file_threshold

type of f2fs_inode.i_gc_failures, f2fs_inode_info.i_gc_failures, and
f2fs_sb_info.gc_pin_file_threshold is __le16, unsigned int, and u64,
so it will cause truncation during comparison and persistence.

Unifying variable of these three variables to unsigned short, and
add an upper boundary limitation for gc_pin_file_threshold.
Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 968c4f72
...@@ -331,7 +331,7 @@ Date: January 2018 ...@@ -331,7 +331,7 @@ Date: January 2018
Contact: Jaegeuk Kim <jaegeuk@kernel.org> Contact: Jaegeuk Kim <jaegeuk@kernel.org>
Description: This indicates how many GC can be failed for the pinned Description: This indicates how many GC can be failed for the pinned
file. If it exceeds this, F2FS doesn't guarantee its pinning file. If it exceeds this, F2FS doesn't guarantee its pinning
state. 2048 trials is set by default. state. 2048 trials is set by default, and 65535 as maximum.
What: /sys/fs/f2fs/<disk>/extension_list What: /sys/fs/f2fs/<disk>/extension_list
Date: February 2018 Date: February 2018
......
...@@ -813,7 +813,7 @@ struct f2fs_inode_info { ...@@ -813,7 +813,7 @@ struct f2fs_inode_info {
unsigned char i_dir_level; /* use for dentry level for large dir */ unsigned char i_dir_level; /* use for dentry level for large dir */
union { union {
unsigned int i_current_depth; /* only for directory depth */ unsigned int i_current_depth; /* only for directory depth */
unsigned int i_gc_failures; /* for gc failure statistic */ unsigned short i_gc_failures; /* for gc failure statistic */
}; };
unsigned int i_pino; /* parent inode number */ unsigned int i_pino; /* parent inode number */
umode_t i_acl_mode; /* keep file acl mode temporarily */ umode_t i_acl_mode; /* keep file acl mode temporarily */
...@@ -1673,7 +1673,7 @@ struct f2fs_sb_info { ...@@ -1673,7 +1673,7 @@ struct f2fs_sb_info {
unsigned long long skipped_gc_rwsem; /* FG_GC only */ unsigned long long skipped_gc_rwsem; /* FG_GC only */
/* threshold for gc trials on pinned files */ /* threshold for gc trials on pinned files */
u64 gc_pin_file_threshold; unsigned short gc_pin_file_threshold;
struct f2fs_rwsem pin_sem; struct f2fs_rwsem pin_sem;
/* maximum # of trials to find a victim segment for SSR and GC */ /* maximum # of trials to find a victim segment for SSR and GC */
......
...@@ -3215,16 +3215,17 @@ int f2fs_pin_file_control(struct inode *inode, bool inc) ...@@ -3215,16 +3215,17 @@ int f2fs_pin_file_control(struct inode *inode, bool inc)
struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_inode_info *fi = F2FS_I(inode);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
/* Use i_gc_failures for normal file as a risk signal. */ if (fi->i_gc_failures >= sbi->gc_pin_file_threshold) {
if (inc)
f2fs_i_gc_failures_write(inode, fi->i_gc_failures + 1);
if (fi->i_gc_failures > sbi->gc_pin_file_threshold) {
f2fs_warn(sbi, "%s: Enable GC = ino %lx after %x GC trials", f2fs_warn(sbi, "%s: Enable GC = ino %lx after %x GC trials",
__func__, inode->i_ino, fi->i_gc_failures); __func__, inode->i_ino, fi->i_gc_failures);
clear_inode_flag(inode, FI_PIN_FILE); clear_inode_flag(inode, FI_PIN_FILE);
return -EAGAIN; return -EAGAIN;
} }
/* Use i_gc_failures for normal file as a risk signal. */
if (inc)
f2fs_i_gc_failures_write(inode, fi->i_gc_failures + 1);
return 0; return 0;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ #define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */
#define DEF_GC_FAILED_PINNED_FILES 2048 #define DEF_GC_FAILED_PINNED_FILES 2048
#define MAX_GC_FAILED_PINNED_FILES USHRT_MAX
/* Search max. number of dirty segments to select a victim segment */ /* Search max. number of dirty segments to select a victim segment */
#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */ #define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
......
...@@ -675,6 +675,13 @@ static ssize_t __sbi_store(struct f2fs_attr *a, ...@@ -675,6 +675,13 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
return count; return count;
} }
if (!strcmp(a->attr.name, "gc_pin_file_threshold")) {
if (t > MAX_GC_FAILED_PINNED_FILES)
return -EINVAL;
sbi->gc_pin_file_threshold = t;
return count;
}
if (!strcmp(a->attr.name, "gc_reclaimed_segments")) { if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
if (t != 0) if (t != 0)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment