mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 21:01:29 +00:00
f2fs: add reclaiming control by sysfs
This patch adds a control method in sysfs to reclaim prefree segments. Signed-off-by: Changman Lee <cm224.lee@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
This commit is contained in:
parent
4660f9c0fe
commit
ea91e9b043
@ -164,6 +164,12 @@ Files in /sys/fs/f2fs/<devname>
|
|||||||
gc_idle = 1 will select the Cost Benefit approach
|
gc_idle = 1 will select the Cost Benefit approach
|
||||||
& setting gc_idle = 2 will select the greedy aproach.
|
& 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
|
USAGE
|
||||||
================================================================================
|
================================================================================
|
||||||
|
@ -69,24 +69,40 @@ static match_table_t f2fs_tokens = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Sysfs support for f2fs */
|
/* Sysfs support for f2fs */
|
||||||
|
enum {
|
||||||
|
GC_THREAD, /* struct f2fs_gc_thread */
|
||||||
|
SM_INFO, /* struct f2fs_sm_info */
|
||||||
|
};
|
||||||
|
|
||||||
struct f2fs_attr {
|
struct f2fs_attr {
|
||||||
struct attribute attr;
|
struct attribute attr;
|
||||||
ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
|
ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
|
||||||
ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
|
ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
|
||||||
const char *, size_t);
|
const char *, size_t);
|
||||||
|
int struct_type;
|
||||||
int offset;
|
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,
|
static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
|
||||||
struct f2fs_sb_info *sbi, char *buf)
|
struct f2fs_sb_info *sbi, char *buf)
|
||||||
{
|
{
|
||||||
struct f2fs_gc_kthread *gc_kth = sbi->gc_thread;
|
unsigned char *ptr = NULL;
|
||||||
unsigned int *ui;
|
unsigned int *ui;
|
||||||
|
|
||||||
if (!gc_kth)
|
ptr = __struct_ptr(sbi, a->struct_type);
|
||||||
|
if (!ptr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ui = (unsigned int *)(((char *)gc_kth) + a->offset);
|
ui = (unsigned int *)(ptr + a->offset);
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
|
return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
|
||||||
}
|
}
|
||||||
@ -95,15 +111,16 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
|
|||||||
struct f2fs_sb_info *sbi,
|
struct f2fs_sb_info *sbi,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct f2fs_gc_kthread *gc_kth = sbi->gc_thread;
|
unsigned char *ptr;
|
||||||
unsigned long t;
|
unsigned long t;
|
||||||
unsigned int *ui;
|
unsigned int *ui;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (!gc_kth)
|
ptr = __struct_ptr(sbi, a->struct_type);
|
||||||
|
if (!ptr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ui = (unsigned int *)(((char *)gc_kth) + a->offset);
|
ui = (unsigned int *)(ptr + a->offset);
|
||||||
|
|
||||||
ret = kstrtoul(skip_spaces(buf), 0, &t);
|
ret = kstrtoul(skip_spaces(buf), 0, &t);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -139,21 +156,25 @@ static void f2fs_sb_release(struct kobject *kobj)
|
|||||||
complete(&sbi->s_kobj_unregister);
|
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 = { \
|
static struct f2fs_attr f2fs_attr_##_name = { \
|
||||||
.attr = {.name = __stringify(_name), .mode = _mode }, \
|
.attr = {.name = __stringify(_name), .mode = _mode }, \
|
||||||
.show = _show, \
|
.show = _show, \
|
||||||
.store = _store, \
|
.store = _store, \
|
||||||
.offset = offsetof(struct f2fs_gc_kthread, _elname), \
|
.struct_type = _struct_type, \
|
||||||
|
.offset = _offset \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define F2FS_RW_ATTR(name, elname) \
|
#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
|
||||||
F2FS_ATTR_OFFSET(name, 0644, f2fs_sbi_show, f2fs_sbi_store, 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_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
|
||||||
F2FS_RW_ATTR(gc_max_sleep_time, max_sleep_time);
|
F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
|
||||||
F2FS_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);
|
F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, 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_idle, gc_idle);
|
||||||
|
F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
|
||||||
|
|
||||||
#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
|
#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
|
||||||
static struct attribute *f2fs_attrs[] = {
|
static struct attribute *f2fs_attrs[] = {
|
||||||
@ -161,6 +182,7 @@ static struct attribute *f2fs_attrs[] = {
|
|||||||
ATTR_LIST(gc_max_sleep_time),
|
ATTR_LIST(gc_max_sleep_time),
|
||||||
ATTR_LIST(gc_no_gc_sleep_time),
|
ATTR_LIST(gc_no_gc_sleep_time),
|
||||||
ATTR_LIST(gc_idle),
|
ATTR_LIST(gc_idle),
|
||||||
|
ATTR_LIST(reclaim_segments),
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user