sysfs.c (f75f6ff2eaa626d32dd3225e3008f807741ad1c5) sysfs.c (d9872a698c393e0d1abca86bf05b62712cbfc581)
1/*
2 * f2fs sysfs interface
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 * Copyright (c) 2017 Chao Yu <chao@kernel.org>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 4 unchanged lines hidden (view full) ---

13#include <linux/f2fs_fs.h>
14#include <linux/seq_file.h>
15
16#include "f2fs.h"
17#include "segment.h"
18#include "gc.h"
19
20static struct proc_dir_entry *f2fs_proc_root;
1/*
2 * f2fs sysfs interface
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 * Copyright (c) 2017 Chao Yu <chao@kernel.org>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 4 unchanged lines hidden (view full) ---

13#include <linux/f2fs_fs.h>
14#include <linux/seq_file.h>
15
16#include "f2fs.h"
17#include "segment.h"
18#include "gc.h"
19
20static struct proc_dir_entry *f2fs_proc_root;
21static struct kset *f2fs_kset;
22
23/* Sysfs support for f2fs */
24enum {
25 GC_THREAD, /* struct f2fs_gc_thread */
26 SM_INFO, /* struct f2fs_sm_info */
27 DCC_INFO, /* struct discard_cmd_control */
28 NM_INFO, /* struct f2fs_nm_info */
29 F2FS_SBI, /* struct f2fs_sb_info */

--- 6 unchanged lines hidden (view full) ---

36
37struct f2fs_attr {
38 struct attribute attr;
39 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
40 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
41 const char *, size_t);
42 int struct_type;
43 int offset;
21
22/* Sysfs support for f2fs */
23enum {
24 GC_THREAD, /* struct f2fs_gc_thread */
25 SM_INFO, /* struct f2fs_sm_info */
26 DCC_INFO, /* struct discard_cmd_control */
27 NM_INFO, /* struct f2fs_nm_info */
28 F2FS_SBI, /* struct f2fs_sb_info */

--- 6 unchanged lines hidden (view full) ---

35
36struct f2fs_attr {
37 struct attribute attr;
38 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
39 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
40 const char *, size_t);
41 int struct_type;
42 int offset;
43 int id;
44};
45
46static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
47{
48 if (struct_type == GC_THREAD)
49 return (unsigned char *)sbi->gc_thread;
50 else if (struct_type == SM_INFO)
51 return (unsigned char *)SM_I(sbi);

--- 19 unchanged lines hidden (view full) ---

71 if (!sb->s_bdev->bd_part)
72 return snprintf(buf, PAGE_SIZE, "0\n");
73
74 return snprintf(buf, PAGE_SIZE, "%llu\n",
75 (unsigned long long)(sbi->kbytes_written +
76 BD_PART_WRITTEN(sbi)));
77}
78
44};
45
46static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
47{
48 if (struct_type == GC_THREAD)
49 return (unsigned char *)sbi->gc_thread;
50 else if (struct_type == SM_INFO)
51 return (unsigned char *)SM_I(sbi);

--- 19 unchanged lines hidden (view full) ---

71 if (!sb->s_bdev->bd_part)
72 return snprintf(buf, PAGE_SIZE, "0\n");
73
74 return snprintf(buf, PAGE_SIZE, "%llu\n",
75 (unsigned long long)(sbi->kbytes_written +
76 BD_PART_WRITTEN(sbi)));
77}
78
79static ssize_t features_show(struct f2fs_attr *a,
80 struct f2fs_sb_info *sbi, char *buf)
81{
82 struct super_block *sb = sbi->sb;
83 int len = 0;
84
85 if (!sb->s_bdev->bd_part)
86 return snprintf(buf, PAGE_SIZE, "0\n");
87
88 if (f2fs_sb_has_crypto(sb))
89 len += snprintf(buf, PAGE_SIZE - len, "%s",
90 "encryption");
91 if (f2fs_sb_mounted_blkzoned(sb))
92 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
93 len ? ", " : "", "blkzoned");
94 if (f2fs_sb_has_extra_attr(sb))
95 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
96 len ? ", " : "", "extra_attr");
97 if (f2fs_sb_has_project_quota(sb))
98 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
99 len ? ", " : "", "projquota");
100 if (f2fs_sb_has_inode_chksum(sb))
101 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
102 len ? ", " : "", "inode_checksum");
103 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
104 return len;
105}
106
79static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
80 struct f2fs_sb_info *sbi, char *buf)
81{
82 unsigned char *ptr = NULL;
83 unsigned int *ui;
84
85 ptr = __struct_ptr(sbi, a->struct_type);
86 if (!ptr)

--- 33 unchanged lines hidden (view full) ---

120 spin_unlock(&sbi->stat_lock);
121 return -EINVAL;
122 }
123 *ui = t;
124 spin_unlock(&sbi->stat_lock);
125 return count;
126 }
127 *ui = t;
107static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
108 struct f2fs_sb_info *sbi, char *buf)
109{
110 unsigned char *ptr = NULL;
111 unsigned int *ui;
112
113 ptr = __struct_ptr(sbi, a->struct_type);
114 if (!ptr)

--- 33 unchanged lines hidden (view full) ---

148 spin_unlock(&sbi->stat_lock);
149 return -EINVAL;
150 }
151 *ui = t;
152 spin_unlock(&sbi->stat_lock);
153 return count;
154 }
155 *ui = t;
156
157 if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
158 f2fs_reset_iostat(sbi);
159 if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
160 sbi->gc_thread->gc_wake = 1;
161 wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
162 }
163
128 return count;
129}
130
131static ssize_t f2fs_attr_show(struct kobject *kobj,
132 struct attribute *attr, char *buf)
133{
134 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
135 s_kobj);

--- 14 unchanged lines hidden (view full) ---

150
151static void f2fs_sb_release(struct kobject *kobj)
152{
153 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
154 s_kobj);
155 complete(&sbi->s_kobj_unregister);
156}
157
164 return count;
165}
166
167static ssize_t f2fs_attr_show(struct kobject *kobj,
168 struct attribute *attr, char *buf)
169{
170 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
171 s_kobj);

--- 14 unchanged lines hidden (view full) ---

186
187static void f2fs_sb_release(struct kobject *kobj)
188{
189 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
190 s_kobj);
191 complete(&sbi->s_kobj_unregister);
192}
193
194enum feat_id {
195 FEAT_CRYPTO = 0,
196 FEAT_BLKZONED,
197 FEAT_ATOMIC_WRITE,
198 FEAT_EXTRA_ATTR,
199 FEAT_PROJECT_QUOTA,
200 FEAT_INODE_CHECKSUM,
201};
202
203static ssize_t f2fs_feature_show(struct f2fs_attr *a,
204 struct f2fs_sb_info *sbi, char *buf)
205{
206 switch (a->id) {
207 case FEAT_CRYPTO:
208 case FEAT_BLKZONED:
209 case FEAT_ATOMIC_WRITE:
210 case FEAT_EXTRA_ATTR:
211 case FEAT_PROJECT_QUOTA:
212 case FEAT_INODE_CHECKSUM:
213 return snprintf(buf, PAGE_SIZE, "supported\n");
214 }
215 return 0;
216}
217
158#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
159static struct f2fs_attr f2fs_attr_##_name = { \
160 .attr = {.name = __stringify(_name), .mode = _mode }, \
161 .show = _show, \
162 .store = _store, \
163 .struct_type = _struct_type, \
164 .offset = _offset \
165}
166
167#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
168 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
169 f2fs_sbi_show, f2fs_sbi_store, \
170 offsetof(struct struct_name, elname))
171
172#define F2FS_GENERAL_RO_ATTR(name) \
173static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
174
218#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
219static struct f2fs_attr f2fs_attr_##_name = { \
220 .attr = {.name = __stringify(_name), .mode = _mode }, \
221 .show = _show, \
222 .store = _store, \
223 .struct_type = _struct_type, \
224 .offset = _offset \
225}
226
227#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
228 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
229 f2fs_sbi_show, f2fs_sbi_store, \
230 offsetof(struct struct_name, elname))
231
232#define F2FS_GENERAL_RO_ATTR(name) \
233static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
234
235#define F2FS_FEATURE_RO_ATTR(_name, _id) \
236static struct f2fs_attr f2fs_attr_##_name = { \
237 .attr = {.name = __stringify(_name), .mode = 0444 }, \
238 .show = f2fs_feature_show, \
239 .id = _id, \
240}
241
242F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
243 urgent_sleep_time);
175F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
176F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
177F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
178F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
244F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
245F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
246F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
247F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
248F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
179F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
180F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
181F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
182F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
183F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
184F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
185F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
186F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
187F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
188F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
189F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
190F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
191F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
192F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
193F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
249F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
250F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
251F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
252F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
253F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
254F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
255F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
256F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
257F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
258F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
259F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
260F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
261F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
262F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
263F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
264F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
194#ifdef CONFIG_F2FS_FAULT_INJECTION
195F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
196F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
197#endif
198F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
265#ifdef CONFIG_F2FS_FAULT_INJECTION
266F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
267F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
268#endif
269F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
270F2FS_GENERAL_RO_ATTR(features);
199
271
272#ifdef CONFIG_F2FS_FS_ENCRYPTION
273F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
274#endif
275#ifdef CONFIG_BLK_DEV_ZONED
276F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED);
277#endif
278F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE);
279F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR);
280F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA);
281F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
282
200#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
201static struct attribute *f2fs_attrs[] = {
283#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
284static struct attribute *f2fs_attrs[] = {
285 ATTR_LIST(gc_urgent_sleep_time),
202 ATTR_LIST(gc_min_sleep_time),
203 ATTR_LIST(gc_max_sleep_time),
204 ATTR_LIST(gc_no_gc_sleep_time),
205 ATTR_LIST(gc_idle),
286 ATTR_LIST(gc_min_sleep_time),
287 ATTR_LIST(gc_max_sleep_time),
288 ATTR_LIST(gc_no_gc_sleep_time),
289 ATTR_LIST(gc_idle),
290 ATTR_LIST(gc_urgent),
206 ATTR_LIST(reclaim_segments),
207 ATTR_LIST(max_small_discards),
208 ATTR_LIST(batched_trim_sections),
209 ATTR_LIST(ipu_policy),
210 ATTR_LIST(min_ipu_util),
211 ATTR_LIST(min_fsync_blocks),
212 ATTR_LIST(min_hot_blocks),
213 ATTR_LIST(max_victim_search),
214 ATTR_LIST(dir_level),
215 ATTR_LIST(ram_thresh),
216 ATTR_LIST(ra_nid_pages),
217 ATTR_LIST(dirty_nats_ratio),
218 ATTR_LIST(cp_interval),
219 ATTR_LIST(idle_interval),
291 ATTR_LIST(reclaim_segments),
292 ATTR_LIST(max_small_discards),
293 ATTR_LIST(batched_trim_sections),
294 ATTR_LIST(ipu_policy),
295 ATTR_LIST(min_ipu_util),
296 ATTR_LIST(min_fsync_blocks),
297 ATTR_LIST(min_hot_blocks),
298 ATTR_LIST(max_victim_search),
299 ATTR_LIST(dir_level),
300 ATTR_LIST(ram_thresh),
301 ATTR_LIST(ra_nid_pages),
302 ATTR_LIST(dirty_nats_ratio),
303 ATTR_LIST(cp_interval),
304 ATTR_LIST(idle_interval),
305 ATTR_LIST(iostat_enable),
220#ifdef CONFIG_F2FS_FAULT_INJECTION
221 ATTR_LIST(inject_rate),
222 ATTR_LIST(inject_type),
223#endif
224 ATTR_LIST(lifetime_write_kbytes),
306#ifdef CONFIG_F2FS_FAULT_INJECTION
307 ATTR_LIST(inject_rate),
308 ATTR_LIST(inject_type),
309#endif
310 ATTR_LIST(lifetime_write_kbytes),
311 ATTR_LIST(features),
225 ATTR_LIST(reserved_blocks),
226 NULL,
227};
228
312 ATTR_LIST(reserved_blocks),
313 NULL,
314};
315
316static struct attribute *f2fs_feat_attrs[] = {
317#ifdef CONFIG_F2FS_FS_ENCRYPTION
318 ATTR_LIST(encryption),
319#endif
320#ifdef CONFIG_BLK_DEV_ZONED
321 ATTR_LIST(block_zoned),
322#endif
323 ATTR_LIST(atomic_write),
324 ATTR_LIST(extra_attr),
325 ATTR_LIST(project_quota),
326 ATTR_LIST(inode_checksum),
327 NULL,
328};
329
229static const struct sysfs_ops f2fs_attr_ops = {
230 .show = f2fs_attr_show,
231 .store = f2fs_attr_store,
232};
233
330static const struct sysfs_ops f2fs_attr_ops = {
331 .show = f2fs_attr_show,
332 .store = f2fs_attr_store,
333};
334
234static struct kobj_type f2fs_ktype = {
335static struct kobj_type f2fs_sb_ktype = {
235 .default_attrs = f2fs_attrs,
236 .sysfs_ops = &f2fs_attr_ops,
237 .release = f2fs_sb_release,
238};
239
336 .default_attrs = f2fs_attrs,
337 .sysfs_ops = &f2fs_attr_ops,
338 .release = f2fs_sb_release,
339};
340
341static struct kobj_type f2fs_ktype = {
342 .sysfs_ops = &f2fs_attr_ops,
343};
344
345static struct kset f2fs_kset = {
346 .kobj = {.ktype = &f2fs_ktype},
347};
348
349static struct kobj_type f2fs_feat_ktype = {
350 .default_attrs = f2fs_feat_attrs,
351 .sysfs_ops = &f2fs_attr_ops,
352};
353
354static struct kobject f2fs_feat = {
355 .kset = &f2fs_kset,
356};
357
240static int segment_info_seq_show(struct seq_file *seq, void *offset)
241{
242 struct super_block *sb = seq->private;
243 struct f2fs_sb_info *sbi = F2FS_SB(sb);
244 unsigned int total_segs =
245 le32_to_cpu(sbi->raw_super->segment_count_main);
246 int i;
247

--- 35 unchanged lines hidden (view full) ---

283 get_valid_blocks(sbi, i, false));
284 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)
285 seq_printf(seq, " %.2x", se->cur_valid_map[j]);
286 seq_putc(seq, '\n');
287 }
288 return 0;
289}
290
358static int segment_info_seq_show(struct seq_file *seq, void *offset)
359{
360 struct super_block *sb = seq->private;
361 struct f2fs_sb_info *sbi = F2FS_SB(sb);
362 unsigned int total_segs =
363 le32_to_cpu(sbi->raw_super->segment_count_main);
364 int i;
365

--- 35 unchanged lines hidden (view full) ---

401 get_valid_blocks(sbi, i, false));
402 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)
403 seq_printf(seq, " %.2x", se->cur_valid_map[j]);
404 seq_putc(seq, '\n');
405 }
406 return 0;
407}
408
409static int iostat_info_seq_show(struct seq_file *seq, void *offset)
410{
411 struct super_block *sb = seq->private;
412 struct f2fs_sb_info *sbi = F2FS_SB(sb);
413 time64_t now = ktime_get_real_seconds();
414
415 if (!sbi->iostat_enable)
416 return 0;
417
418 seq_printf(seq, "time: %-16llu\n", now);
419
420 /* print app IOs */
421 seq_printf(seq, "app buffered: %-16llu\n",
422 sbi->write_iostat[APP_BUFFERED_IO]);
423 seq_printf(seq, "app direct: %-16llu\n",
424 sbi->write_iostat[APP_DIRECT_IO]);
425 seq_printf(seq, "app mapped: %-16llu\n",
426 sbi->write_iostat[APP_MAPPED_IO]);
427
428 /* print fs IOs */
429 seq_printf(seq, "fs data: %-16llu\n",
430 sbi->write_iostat[FS_DATA_IO]);
431 seq_printf(seq, "fs node: %-16llu\n",
432 sbi->write_iostat[FS_NODE_IO]);
433 seq_printf(seq, "fs meta: %-16llu\n",
434 sbi->write_iostat[FS_META_IO]);
435 seq_printf(seq, "fs gc data: %-16llu\n",
436 sbi->write_iostat[FS_GC_DATA_IO]);
437 seq_printf(seq, "fs gc node: %-16llu\n",
438 sbi->write_iostat[FS_GC_NODE_IO]);
439 seq_printf(seq, "fs cp data: %-16llu\n",
440 sbi->write_iostat[FS_CP_DATA_IO]);
441 seq_printf(seq, "fs cp node: %-16llu\n",
442 sbi->write_iostat[FS_CP_NODE_IO]);
443 seq_printf(seq, "fs cp meta: %-16llu\n",
444 sbi->write_iostat[FS_CP_META_IO]);
445 seq_printf(seq, "fs discard: %-16llu\n",
446 sbi->write_iostat[FS_DISCARD]);
447
448 return 0;
449}
450
291#define F2FS_PROC_FILE_DEF(_name) \
292static int _name##_open_fs(struct inode *inode, struct file *file) \
293{ \
294 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \
295} \
296 \
297static const struct file_operations f2fs_seq_##_name##_fops = { \
298 .open = _name##_open_fs, \
299 .read = seq_read, \
300 .llseek = seq_lseek, \
301 .release = single_release, \
302};
303
304F2FS_PROC_FILE_DEF(segment_info);
305F2FS_PROC_FILE_DEF(segment_bits);
451#define F2FS_PROC_FILE_DEF(_name) \
452static int _name##_open_fs(struct inode *inode, struct file *file) \
453{ \
454 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \
455} \
456 \
457static const struct file_operations f2fs_seq_##_name##_fops = { \
458 .open = _name##_open_fs, \
459 .read = seq_read, \
460 .llseek = seq_lseek, \
461 .release = single_release, \
462};
463
464F2FS_PROC_FILE_DEF(segment_info);
465F2FS_PROC_FILE_DEF(segment_bits);
466F2FS_PROC_FILE_DEF(iostat_info);
306
467
307int __init f2fs_register_sysfs(void)
468int __init f2fs_init_sysfs(void)
308{
469{
309 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
470 int ret;
310
471
311 f2fs_kset = kset_create_and_add("f2fs", NULL, fs_kobj);
312 if (!f2fs_kset)
313 return -ENOMEM;
314 return 0;
472 kobject_set_name(&f2fs_kset.kobj, "f2fs");
473 f2fs_kset.kobj.parent = fs_kobj;
474 ret = kset_register(&f2fs_kset);
475 if (ret)
476 return ret;
477
478 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,
479 NULL, "features");
480 if (ret)
481 kset_unregister(&f2fs_kset);
482 else
483 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
484 return ret;
315}
316
485}
486
317void f2fs_unregister_sysfs(void)
487void f2fs_exit_sysfs(void)
318{
488{
319 kset_unregister(f2fs_kset);
489 kobject_put(&f2fs_feat);
490 kset_unregister(&f2fs_kset);
320 remove_proc_entry("fs/f2fs", NULL);
491 remove_proc_entry("fs/f2fs", NULL);
492 f2fs_proc_root = NULL;
321}
322
493}
494
323int f2fs_init_sysfs(struct f2fs_sb_info *sbi)
495int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
324{
325 struct super_block *sb = sbi->sb;
326 int err;
327
496{
497 struct super_block *sb = sbi->sb;
498 int err;
499
500 sbi->s_kobj.kset = &f2fs_kset;
501 init_completion(&sbi->s_kobj_unregister);
502 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
503 "%s", sb->s_id);
504 if (err)
505 return err;
506
328 if (f2fs_proc_root)
329 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
330
331 if (sbi->s_proc) {
332 proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
333 &f2fs_seq_segment_info_fops, sb);
334 proc_create_data("segment_bits", S_IRUGO, sbi->s_proc,
335 &f2fs_seq_segment_bits_fops, sb);
507 if (f2fs_proc_root)
508 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
509
510 if (sbi->s_proc) {
511 proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
512 &f2fs_seq_segment_info_fops, sb);
513 proc_create_data("segment_bits", S_IRUGO, sbi->s_proc,
514 &f2fs_seq_segment_bits_fops, sb);
515 proc_create_data("iostat_info", S_IRUGO, sbi->s_proc,
516 &f2fs_seq_iostat_info_fops, sb);
336 }
517 }
337
338 sbi->s_kobj.kset = f2fs_kset;
339 init_completion(&sbi->s_kobj_unregister);
340 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,
341 "%s", sb->s_id);
342 if (err)
343 goto err_out;
344 return 0;
518 return 0;
345err_out:
346 if (sbi->s_proc) {
347 remove_proc_entry("segment_info", sbi->s_proc);
348 remove_proc_entry("segment_bits", sbi->s_proc);
349 remove_proc_entry(sb->s_id, f2fs_proc_root);
350 }
351 return err;
352}
353
519}
520
354void f2fs_exit_sysfs(struct f2fs_sb_info *sbi)
521void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
355{
522{
356 kobject_del(&sbi->s_kobj);
357 kobject_put(&sbi->s_kobj);
358 wait_for_completion(&sbi->s_kobj_unregister);
359
360 if (sbi->s_proc) {
523 if (sbi->s_proc) {
524 remove_proc_entry("iostat_info", sbi->s_proc);
361 remove_proc_entry("segment_info", sbi->s_proc);
362 remove_proc_entry("segment_bits", sbi->s_proc);
363 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
364 }
525 remove_proc_entry("segment_info", sbi->s_proc);
526 remove_proc_entry("segment_bits", sbi->s_proc);
527 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
528 }
529 kobject_del(&sbi->s_kobj);
365}
530}