Loading Documentation/filesystems/f2fs.txt +6 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,12 @@ Files in /sys/fs/f2fs/<devname> gc_idle = 1 will select the Cost Benefit approach & setting gc_idle = 2 will select the greedy aproach. reclaim_segments This parameter controls the number of prefree segments to be reclaimed. If the number of prefree segments is larger than this number, f2fs tries to conduct checkpoint to reclaim the prefree segments to free segments. By default, 100 segments, 200MB. ================================================================================ USAGE ================================================================================ Loading fs/f2fs/super.c +36 −14 Original line number Diff line number Diff line Loading @@ -69,24 +69,40 @@ static match_table_t f2fs_tokens = { }; /* Sysfs support for f2fs */ enum { GC_THREAD, /* struct f2fs_gc_thread */ SM_INFO, /* struct f2fs_sm_info */ }; struct f2fs_attr { struct attribute attr; ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, const char *, size_t); int struct_type; int offset; }; static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) { if (struct_type == GC_THREAD) return (unsigned char *)sbi->gc_thread; else if (struct_type == SM_INFO) return (unsigned char *)SM_I(sbi); return NULL; } static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; unsigned char *ptr = NULL; unsigned int *ui; if (!gc_kth) ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) return -EINVAL; ui = (unsigned int *)(((char *)gc_kth) + a->offset); ui = (unsigned int *)(ptr + a->offset); return snprintf(buf, PAGE_SIZE, "%u\n", *ui); } Loading @@ -95,15 +111,16 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a, struct f2fs_sb_info *sbi, const char *buf, size_t count) { struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; unsigned char *ptr; unsigned long t; unsigned int *ui; ssize_t ret; if (!gc_kth) ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) return -EINVAL; ui = (unsigned int *)(((char *)gc_kth) + a->offset); ui = (unsigned int *)(ptr + a->offset); ret = kstrtoul(skip_spaces(buf), 0, &t); if (ret < 0) Loading Loading @@ -139,21 +156,25 @@ static void f2fs_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } #define F2FS_ATTR_OFFSET(_name, _mode, _show, _store, _elname) \ #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ .offset = offsetof(struct f2fs_gc_kthread, _elname), \ .struct_type = _struct_type, \ .offset = _offset \ } #define F2FS_RW_ATTR(name, elname) \ F2FS_ATTR_OFFSET(name, 0644, f2fs_sbi_show, f2fs_sbi_store, elname) #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0644, \ f2fs_sbi_show, f2fs_sbi_store, \ offsetof(struct struct_name, elname)) F2FS_RW_ATTR(gc_min_sleep_time, min_sleep_time); F2FS_RW_ATTR(gc_max_sleep_time, max_sleep_time); F2FS_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(gc_idle, gc_idle); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { Loading @@ -161,6 +182,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(gc_max_sleep_time), ATTR_LIST(gc_no_gc_sleep_time), ATTR_LIST(gc_idle), ATTR_LIST(reclaim_segments), NULL, }; Loading Loading
Documentation/filesystems/f2fs.txt +6 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,12 @@ Files in /sys/fs/f2fs/<devname> gc_idle = 1 will select the Cost Benefit approach & setting gc_idle = 2 will select the greedy aproach. reclaim_segments This parameter controls the number of prefree segments to be reclaimed. If the number of prefree segments is larger than this number, f2fs tries to conduct checkpoint to reclaim the prefree segments to free segments. By default, 100 segments, 200MB. ================================================================================ USAGE ================================================================================ Loading
fs/f2fs/super.c +36 −14 Original line number Diff line number Diff line Loading @@ -69,24 +69,40 @@ static match_table_t f2fs_tokens = { }; /* Sysfs support for f2fs */ enum { GC_THREAD, /* struct f2fs_gc_thread */ SM_INFO, /* struct f2fs_sm_info */ }; struct f2fs_attr { struct attribute attr; ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, const char *, size_t); int struct_type; int offset; }; static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) { if (struct_type == GC_THREAD) return (unsigned char *)sbi->gc_thread; else if (struct_type == SM_INFO) return (unsigned char *)SM_I(sbi); return NULL; } static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; unsigned char *ptr = NULL; unsigned int *ui; if (!gc_kth) ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) return -EINVAL; ui = (unsigned int *)(((char *)gc_kth) + a->offset); ui = (unsigned int *)(ptr + a->offset); return snprintf(buf, PAGE_SIZE, "%u\n", *ui); } Loading @@ -95,15 +111,16 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a, struct f2fs_sb_info *sbi, const char *buf, size_t count) { struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; unsigned char *ptr; unsigned long t; unsigned int *ui; ssize_t ret; if (!gc_kth) ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) return -EINVAL; ui = (unsigned int *)(((char *)gc_kth) + a->offset); ui = (unsigned int *)(ptr + a->offset); ret = kstrtoul(skip_spaces(buf), 0, &t); if (ret < 0) Loading Loading @@ -139,21 +156,25 @@ static void f2fs_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } #define F2FS_ATTR_OFFSET(_name, _mode, _show, _store, _elname) \ #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ .offset = offsetof(struct f2fs_gc_kthread, _elname), \ .struct_type = _struct_type, \ .offset = _offset \ } #define F2FS_RW_ATTR(name, elname) \ F2FS_ATTR_OFFSET(name, 0644, f2fs_sbi_show, f2fs_sbi_store, elname) #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0644, \ f2fs_sbi_show, f2fs_sbi_store, \ offsetof(struct struct_name, elname)) F2FS_RW_ATTR(gc_min_sleep_time, min_sleep_time); F2FS_RW_ATTR(gc_max_sleep_time, max_sleep_time); F2FS_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(gc_idle, gc_idle); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { Loading @@ -161,6 +182,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(gc_max_sleep_time), ATTR_LIST(gc_no_gc_sleep_time), ATTR_LIST(gc_idle), ATTR_LIST(reclaim_segments), NULL, }; Loading