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: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
968c4f72b2
commit
c521a6ab4a
@ -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 {
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
#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 @@ out:
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user