aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/f2fs.txt6
-rw-r--r--fs/f2fs/super.c50
2 files changed, 42 insertions, 14 deletions
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index 3cd27bed6349..4c647c280dcc 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -164,6 +164,12 @@ Files in /sys/fs/f2fs/<devname>
164 gc_idle = 1 will select the Cost Benefit approach 164 gc_idle = 1 will select the Cost Benefit approach
165 & setting gc_idle = 2 will select the greedy aproach. 165 & setting gc_idle = 2 will select the greedy aproach.
166 166
167 reclaim_segments This parameter controls the number of prefree
168 segments to be reclaimed. If the number of prefree
169 segments is larger than this number, f2fs tries to
170 conduct checkpoint to reclaim the prefree segments
171 to free segments. By default, 100 segments, 200MB.
172
167================================================================================ 173================================================================================
168USAGE 174USAGE
169================================================================================ 175================================================================================
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 9a094596fd21..e42351cbe166 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -69,24 +69,40 @@ static match_table_t f2fs_tokens = {
69}; 69};
70 70
71/* Sysfs support for f2fs */ 71/* Sysfs support for f2fs */
72enum {
73 GC_THREAD, /* struct f2fs_gc_thread */
74 SM_INFO, /* struct f2fs_sm_info */
75};
76
72struct f2fs_attr { 77struct f2fs_attr {
73 struct attribute attr; 78 struct attribute attr;
74 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); 79 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
75 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, 80 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
76 const char *, size_t); 81 const char *, size_t);
82 int struct_type;
77 int offset; 83 int offset;
78}; 84};
79 85
86static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
87{
88 if (struct_type == GC_THREAD)
89 return (unsigned char *)sbi->gc_thread;
90 else if (struct_type == SM_INFO)
91 return (unsigned char *)SM_I(sbi);
92 return NULL;
93}
94
80static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 95static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
81 struct f2fs_sb_info *sbi, char *buf) 96 struct f2fs_sb_info *sbi, char *buf)
82{ 97{
83 struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; 98 unsigned char *ptr = NULL;
84 unsigned int *ui; 99 unsigned int *ui;
85 100
86 if (!gc_kth) 101 ptr = __struct_ptr(sbi, a->struct_type);
102 if (!ptr)
87 return -EINVAL; 103 return -EINVAL;
88 104
89 ui = (unsigned int *)(((char *)gc_kth) + a->offset); 105 ui = (unsigned int *)(ptr + a->offset);
90 106
91 return snprintf(buf, PAGE_SIZE, "%u\n", *ui); 107 return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
92} 108}
@@ -95,15 +111,16 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
95 struct f2fs_sb_info *sbi, 111 struct f2fs_sb_info *sbi,
96 const char *buf, size_t count) 112 const char *buf, size_t count)
97{ 113{
98 struct f2fs_gc_kthread *gc_kth = sbi->gc_thread; 114 unsigned char *ptr;
99 unsigned long t; 115 unsigned long t;
100 unsigned int *ui; 116 unsigned int *ui;
101 ssize_t ret; 117 ssize_t ret;
102 118
103 if (!gc_kth) 119 ptr = __struct_ptr(sbi, a->struct_type);
120 if (!ptr)
104 return -EINVAL; 121 return -EINVAL;
105 122
106 ui = (unsigned int *)(((char *)gc_kth) + a->offset); 123 ui = (unsigned int *)(ptr + a->offset);
107 124
108 ret = kstrtoul(skip_spaces(buf), 0, &t); 125 ret = kstrtoul(skip_spaces(buf), 0, &t);
109 if (ret < 0) 126 if (ret < 0)
@@ -139,21 +156,25 @@ static void f2fs_sb_release(struct kobject *kobj)
139 complete(&sbi->s_kobj_unregister); 156 complete(&sbi->s_kobj_unregister);
140} 157}
141 158
142#define F2FS_ATTR_OFFSET(_name, _mode, _show, _store, _elname) \ 159#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
143static struct f2fs_attr f2fs_attr_##_name = { \ 160static struct f2fs_attr f2fs_attr_##_name = { \
144 .attr = {.name = __stringify(_name), .mode = _mode }, \ 161 .attr = {.name = __stringify(_name), .mode = _mode }, \
145 .show = _show, \ 162 .show = _show, \
146 .store = _store, \ 163 .store = _store, \
147 .offset = offsetof(struct f2fs_gc_kthread, _elname), \ 164 .struct_type = _struct_type, \
165 .offset = _offset \
148} 166}
149 167
150#define F2FS_RW_ATTR(name, elname) \ 168#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
151 F2FS_ATTR_OFFSET(name, 0644, f2fs_sbi_show, f2fs_sbi_store, elname) 169 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
170 f2fs_sbi_show, f2fs_sbi_store, \
171 offsetof(struct struct_name, elname))
152 172
153F2FS_RW_ATTR(gc_min_sleep_time, min_sleep_time); 173F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
154F2FS_RW_ATTR(gc_max_sleep_time, max_sleep_time); 174F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
155F2FS_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time); 175F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
156F2FS_RW_ATTR(gc_idle, gc_idle); 176F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
177F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
157 178
158#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 179#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
159static struct attribute *f2fs_attrs[] = { 180static struct attribute *f2fs_attrs[] = {
@@ -161,6 +182,7 @@ static struct attribute *f2fs_attrs[] = {
161 ATTR_LIST(gc_max_sleep_time), 182 ATTR_LIST(gc_max_sleep_time),
162 ATTR_LIST(gc_no_gc_sleep_time), 183 ATTR_LIST(gc_no_gc_sleep_time),
163 ATTR_LIST(gc_idle), 184 ATTR_LIST(gc_idle),
185 ATTR_LIST(reclaim_segments),
164 NULL, 186 NULL,
165}; 187};
166 188