Skip to content

Commit

Permalink
f2fs: fix to limit gc_pin_file_threshold
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
chaseyu authored and Jaegeuk Kim committed May 9, 2024
1 parent 968c4f7 commit c521a6a
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Documentation/ABI/testing/sysfs-fs-f2fs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ Date: January 2018
Contact: Jaegeuk Kim <jaegeuk@kernel.org>
Description: This indicates how many GC can be failed for the pinned
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
Date: February 2018
Expand Down
4 changes: 2 additions & 2 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ struct f2fs_inode_info {
unsigned char i_dir_level; /* use for dentry level for large dir */
union {
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 */
umode_t i_acl_mode; /* keep file acl mode temporarily */
Expand Down Expand Up @@ -1673,7 +1673,7 @@ struct f2fs_sb_info {
unsigned long long skipped_gc_rwsem; /* FG_GC only */

/* threshold for gc trials on pinned files */
u64 gc_pin_file_threshold;
unsigned short gc_pin_file_threshold;
struct f2fs_rwsem pin_sem;

/* maximum # of trials to find a victim segment for SSR and GC */
Expand Down
11 changes: 6 additions & 5 deletions fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -3215,16 +3215,17 @@ int f2fs_pin_file_control(struct inode *inode, bool inc)
struct f2fs_inode_info *fi = F2FS_I(inode);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);

/* Use i_gc_failures for normal file as a risk signal. */
if (inc)
f2fs_i_gc_failures_write(inode, fi->i_gc_failures + 1);

if (fi->i_gc_failures > sbi->gc_pin_file_threshold) {
if (fi->i_gc_failures >= sbi->gc_pin_file_threshold) {
f2fs_warn(sbi, "%s: Enable GC = ino %lx after %x GC trials",
__func__, inode->i_ino, fi->i_gc_failures);
clear_inode_flag(inode, FI_PIN_FILE);
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;
}

Expand Down
1 change: 1 addition & 0 deletions fs/f2fs/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */

#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 */
#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
Expand Down
7 changes: 7 additions & 0 deletions fs/f2fs/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,13 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
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 (t != 0)
return -EINVAL;
Expand Down

0 comments on commit c521a6a

Please sign in to comment.