4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 * Copyright (c) 2017 Chao Yu <chao@kernel.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 #include <linux/proc_fs.h>
13 #include <linux/f2fs_fs.h>
14 #include <linux/seq_file.h>
20 static struct proc_dir_entry
*f2fs_proc_root
;
22 /* Sysfs support for f2fs */
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 */
29 #ifdef CONFIG_F2FS_FAULT_INJECTION
30 FAULT_INFO_RATE
, /* struct f2fs_fault_info */
31 FAULT_INFO_TYPE
, /* struct f2fs_fault_info */
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);
46 static unsigned char *__struct_ptr(struct f2fs_sb_info
*sbi
, int struct_type
)
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
);
52 else if (struct_type
== DCC_INFO
)
53 return (unsigned char *)SM_I(sbi
)->dcc_info
;
54 else if (struct_type
== NM_INFO
)
55 return (unsigned char *)NM_I(sbi
);
56 else if (struct_type
== F2FS_SBI
|| struct_type
== RESERVED_BLOCKS
)
57 return (unsigned char *)sbi
;
58 #ifdef CONFIG_F2FS_FAULT_INJECTION
59 else if (struct_type
== FAULT_INFO_RATE
||
60 struct_type
== FAULT_INFO_TYPE
)
61 return (unsigned char *)&sbi
->fault_info
;
66 static ssize_t
dirty_segments_show(struct f2fs_attr
*a
,
67 struct f2fs_sb_info
*sbi
, char *buf
)
69 return snprintf(buf
, PAGE_SIZE
, "%llu\n",
70 (unsigned long long)(dirty_segments(sbi
)));
73 static ssize_t
lifetime_write_kbytes_show(struct f2fs_attr
*a
,
74 struct f2fs_sb_info
*sbi
, char *buf
)
76 struct super_block
*sb
= sbi
->sb
;
78 if (!sb
->s_bdev
->bd_part
)
79 return snprintf(buf
, PAGE_SIZE
, "0\n");
81 return snprintf(buf
, PAGE_SIZE
, "%llu\n",
82 (unsigned long long)(sbi
->kbytes_written
+
83 BD_PART_WRITTEN(sbi
)));
86 static ssize_t
features_show(struct f2fs_attr
*a
,
87 struct f2fs_sb_info
*sbi
, char *buf
)
89 struct super_block
*sb
= sbi
->sb
;
92 if (!sb
->s_bdev
->bd_part
)
93 return snprintf(buf
, PAGE_SIZE
, "0\n");
95 if (f2fs_sb_has_crypto(sb
))
96 len
+= snprintf(buf
, PAGE_SIZE
- len
, "%s",
98 if (f2fs_sb_mounted_blkzoned(sb
))
99 len
+= snprintf(buf
+ len
, PAGE_SIZE
- len
, "%s%s",
100 len
? ", " : "", "blkzoned");
101 if (f2fs_sb_has_extra_attr(sb
))
102 len
+= snprintf(buf
+ len
, PAGE_SIZE
- len
, "%s%s",
103 len
? ", " : "", "extra_attr");
104 if (f2fs_sb_has_project_quota(sb
))
105 len
+= snprintf(buf
+ len
, PAGE_SIZE
- len
, "%s%s",
106 len
? ", " : "", "projquota");
107 if (f2fs_sb_has_inode_chksum(sb
))
108 len
+= snprintf(buf
+ len
, PAGE_SIZE
- len
, "%s%s",
109 len
? ", " : "", "inode_checksum");
110 len
+= snprintf(buf
+ len
, PAGE_SIZE
- len
, "\n");
114 static ssize_t
f2fs_sbi_show(struct f2fs_attr
*a
,
115 struct f2fs_sb_info
*sbi
, char *buf
)
117 unsigned char *ptr
= NULL
;
120 ptr
= __struct_ptr(sbi
, a
->struct_type
);
124 ui
= (unsigned int *)(ptr
+ a
->offset
);
126 return snprintf(buf
, PAGE_SIZE
, "%u\n", *ui
);
129 static ssize_t
f2fs_sbi_store(struct f2fs_attr
*a
,
130 struct f2fs_sb_info
*sbi
,
131 const char *buf
, size_t count
)
138 ptr
= __struct_ptr(sbi
, a
->struct_type
);
142 ui
= (unsigned int *)(ptr
+ a
->offset
);
144 ret
= kstrtoul(skip_spaces(buf
), 0, &t
);
147 #ifdef CONFIG_F2FS_FAULT_INJECTION
148 if (a
->struct_type
== FAULT_INFO_TYPE
&& t
>= (1 << FAULT_MAX
))
151 if (a
->struct_type
== RESERVED_BLOCKS
) {
152 spin_lock(&sbi
->stat_lock
);
153 if ((unsigned long)sbi
->total_valid_block_count
+ t
>
154 (unsigned long)sbi
->user_block_count
) {
155 spin_unlock(&sbi
->stat_lock
);
159 spin_unlock(&sbi
->stat_lock
);
163 if (!strcmp(a
->attr
.name
, "discard_granularity")) {
164 if (t
== 0 || t
> MAX_PLIST_NUM
)
174 if (!strcmp(a
->attr
.name
, "iostat_enable") && *ui
== 0)
175 f2fs_reset_iostat(sbi
);
176 if (!strcmp(a
->attr
.name
, "gc_urgent") && t
== 1 && sbi
->gc_thread
) {
177 sbi
->gc_thread
->gc_wake
= 1;
178 wake_up_interruptible_all(&sbi
->gc_thread
->gc_wait_queue_head
);
179 wake_up_discard_thread(sbi
, true);
185 static ssize_t
f2fs_attr_show(struct kobject
*kobj
,
186 struct attribute
*attr
, char *buf
)
188 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
190 struct f2fs_attr
*a
= container_of(attr
, struct f2fs_attr
, attr
);
192 return a
->show
? a
->show(a
, sbi
, buf
) : 0;
195 static ssize_t
f2fs_attr_store(struct kobject
*kobj
, struct attribute
*attr
,
196 const char *buf
, size_t len
)
198 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
200 struct f2fs_attr
*a
= container_of(attr
, struct f2fs_attr
, attr
);
202 return a
->store
? a
->store(a
, sbi
, buf
, len
) : 0;
205 static void f2fs_sb_release(struct kobject
*kobj
)
207 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
209 complete(&sbi
->s_kobj_unregister
);
221 static ssize_t
f2fs_feature_show(struct f2fs_attr
*a
,
222 struct f2fs_sb_info
*sbi
, char *buf
)
227 case FEAT_ATOMIC_WRITE
:
228 case FEAT_EXTRA_ATTR
:
229 case FEAT_PROJECT_QUOTA
:
230 case FEAT_INODE_CHECKSUM
:
231 return snprintf(buf
, PAGE_SIZE
, "supported\n");
236 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
237 static struct f2fs_attr f2fs_attr_##_name = { \
238 .attr = {.name = __stringify(_name), .mode = _mode }, \
241 .struct_type = _struct_type, \
245 #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
246 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
247 f2fs_sbi_show, f2fs_sbi_store, \
248 offsetof(struct struct_name, elname))
250 #define F2FS_GENERAL_RO_ATTR(name) \
251 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
253 #define F2FS_FEATURE_RO_ATTR(_name, _id) \
254 static struct f2fs_attr f2fs_attr_##_name = { \
255 .attr = {.name = __stringify(_name), .mode = 0444 }, \
256 .show = f2fs_feature_show, \
260 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_urgent_sleep_time
,
262 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_min_sleep_time
, min_sleep_time
);
263 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_max_sleep_time
, max_sleep_time
);
264 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_no_gc_sleep_time
, no_gc_sleep_time
);
265 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_idle
, gc_idle
);
266 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_urgent
, gc_urgent
);
267 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, reclaim_segments
, rec_prefree_segments
);
268 F2FS_RW_ATTR(DCC_INFO
, discard_cmd_control
, max_small_discards
, max_discards
);
269 F2FS_RW_ATTR(DCC_INFO
, discard_cmd_control
, discard_granularity
, discard_granularity
);
270 F2FS_RW_ATTR(RESERVED_BLOCKS
, f2fs_sb_info
, reserved_blocks
, reserved_blocks
);
271 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, batched_trim_sections
, trim_sections
);
272 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, ipu_policy
, ipu_policy
);
273 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_ipu_util
, min_ipu_util
);
274 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_fsync_blocks
, min_fsync_blocks
);
275 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_hot_blocks
, min_hot_blocks
);
276 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, ram_thresh
, ram_thresh
);
277 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, ra_nid_pages
, ra_nid_pages
);
278 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, dirty_nats_ratio
, dirty_nats_ratio
);
279 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, max_victim_search
, max_victim_search
);
280 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, dir_level
, dir_level
);
281 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, cp_interval
, interval_time
[CP_TIME
]);
282 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, idle_interval
, interval_time
[REQ_TIME
]);
283 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, iostat_enable
, iostat_enable
);
284 #ifdef CONFIG_F2FS_FAULT_INJECTION
285 F2FS_RW_ATTR(FAULT_INFO_RATE
, f2fs_fault_info
, inject_rate
, inject_rate
);
286 F2FS_RW_ATTR(FAULT_INFO_TYPE
, f2fs_fault_info
, inject_type
, inject_type
);
288 F2FS_GENERAL_RO_ATTR(dirty_segments
);
289 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes
);
290 F2FS_GENERAL_RO_ATTR(features
);
292 #ifdef CONFIG_F2FS_FS_ENCRYPTION
293 F2FS_FEATURE_RO_ATTR(encryption
, FEAT_CRYPTO
);
295 #ifdef CONFIG_BLK_DEV_ZONED
296 F2FS_FEATURE_RO_ATTR(block_zoned
, FEAT_BLKZONED
);
298 F2FS_FEATURE_RO_ATTR(atomic_write
, FEAT_ATOMIC_WRITE
);
299 F2FS_FEATURE_RO_ATTR(extra_attr
, FEAT_EXTRA_ATTR
);
300 F2FS_FEATURE_RO_ATTR(project_quota
, FEAT_PROJECT_QUOTA
);
301 F2FS_FEATURE_RO_ATTR(inode_checksum
, FEAT_INODE_CHECKSUM
);
303 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
304 static struct attribute
*f2fs_attrs
[] = {
305 ATTR_LIST(gc_urgent_sleep_time
),
306 ATTR_LIST(gc_min_sleep_time
),
307 ATTR_LIST(gc_max_sleep_time
),
308 ATTR_LIST(gc_no_gc_sleep_time
),
310 ATTR_LIST(gc_urgent
),
311 ATTR_LIST(reclaim_segments
),
312 ATTR_LIST(max_small_discards
),
313 ATTR_LIST(discard_granularity
),
314 ATTR_LIST(batched_trim_sections
),
315 ATTR_LIST(ipu_policy
),
316 ATTR_LIST(min_ipu_util
),
317 ATTR_LIST(min_fsync_blocks
),
318 ATTR_LIST(min_hot_blocks
),
319 ATTR_LIST(max_victim_search
),
320 ATTR_LIST(dir_level
),
321 ATTR_LIST(ram_thresh
),
322 ATTR_LIST(ra_nid_pages
),
323 ATTR_LIST(dirty_nats_ratio
),
324 ATTR_LIST(cp_interval
),
325 ATTR_LIST(idle_interval
),
326 ATTR_LIST(iostat_enable
),
327 #ifdef CONFIG_F2FS_FAULT_INJECTION
328 ATTR_LIST(inject_rate
),
329 ATTR_LIST(inject_type
),
331 ATTR_LIST(dirty_segments
),
332 ATTR_LIST(lifetime_write_kbytes
),
334 ATTR_LIST(reserved_blocks
),
338 static struct attribute
*f2fs_feat_attrs
[] = {
339 #ifdef CONFIG_F2FS_FS_ENCRYPTION
340 ATTR_LIST(encryption
),
342 #ifdef CONFIG_BLK_DEV_ZONED
343 ATTR_LIST(block_zoned
),
345 ATTR_LIST(atomic_write
),
346 ATTR_LIST(extra_attr
),
347 ATTR_LIST(project_quota
),
348 ATTR_LIST(inode_checksum
),
352 static const struct sysfs_ops f2fs_attr_ops
= {
353 .show
= f2fs_attr_show
,
354 .store
= f2fs_attr_store
,
357 static struct kobj_type f2fs_sb_ktype
= {
358 .default_attrs
= f2fs_attrs
,
359 .sysfs_ops
= &f2fs_attr_ops
,
360 .release
= f2fs_sb_release
,
363 static struct kobj_type f2fs_ktype
= {
364 .sysfs_ops
= &f2fs_attr_ops
,
367 static struct kset f2fs_kset
= {
368 .kobj
= {.ktype
= &f2fs_ktype
},
371 static struct kobj_type f2fs_feat_ktype
= {
372 .default_attrs
= f2fs_feat_attrs
,
373 .sysfs_ops
= &f2fs_attr_ops
,
376 static struct kobject f2fs_feat
= {
380 static int segment_info_seq_show(struct seq_file
*seq
, void *offset
)
382 struct super_block
*sb
= seq
->private;
383 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
384 unsigned int total_segs
=
385 le32_to_cpu(sbi
->raw_super
->segment_count_main
);
388 seq_puts(seq
, "format: segment_type|valid_blocks\n"
389 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
391 for (i
= 0; i
< total_segs
; i
++) {
392 struct seg_entry
*se
= get_seg_entry(sbi
, i
);
395 seq_printf(seq
, "%-10d", i
);
396 seq_printf(seq
, "%d|%-3u", se
->type
,
397 get_valid_blocks(sbi
, i
, false));
398 if ((i
% 10) == 9 || i
== (total_segs
- 1))
407 static int segment_bits_seq_show(struct seq_file
*seq
, void *offset
)
409 struct super_block
*sb
= seq
->private;
410 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
411 unsigned int total_segs
=
412 le32_to_cpu(sbi
->raw_super
->segment_count_main
);
415 seq_puts(seq
, "format: segment_type|valid_blocks|bitmaps\n"
416 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
418 for (i
= 0; i
< total_segs
; i
++) {
419 struct seg_entry
*se
= get_seg_entry(sbi
, i
);
421 seq_printf(seq
, "%-10d", i
);
422 seq_printf(seq
, "%d|%-3u|", se
->type
,
423 get_valid_blocks(sbi
, i
, false));
424 for (j
= 0; j
< SIT_VBLOCK_MAP_SIZE
; j
++)
425 seq_printf(seq
, " %.2x", se
->cur_valid_map
[j
]);
431 static int iostat_info_seq_show(struct seq_file
*seq
, void *offset
)
433 struct super_block
*sb
= seq
->private;
434 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
435 time64_t now
= ktime_get_real_seconds();
437 if (!sbi
->iostat_enable
)
440 seq_printf(seq
, "time: %-16llu\n", now
);
443 seq_printf(seq
, "app buffered: %-16llu\n",
444 sbi
->write_iostat
[APP_BUFFERED_IO
]);
445 seq_printf(seq
, "app direct: %-16llu\n",
446 sbi
->write_iostat
[APP_DIRECT_IO
]);
447 seq_printf(seq
, "app mapped: %-16llu\n",
448 sbi
->write_iostat
[APP_MAPPED_IO
]);
451 seq_printf(seq
, "fs data: %-16llu\n",
452 sbi
->write_iostat
[FS_DATA_IO
]);
453 seq_printf(seq
, "fs node: %-16llu\n",
454 sbi
->write_iostat
[FS_NODE_IO
]);
455 seq_printf(seq
, "fs meta: %-16llu\n",
456 sbi
->write_iostat
[FS_META_IO
]);
457 seq_printf(seq
, "fs gc data: %-16llu\n",
458 sbi
->write_iostat
[FS_GC_DATA_IO
]);
459 seq_printf(seq
, "fs gc node: %-16llu\n",
460 sbi
->write_iostat
[FS_GC_NODE_IO
]);
461 seq_printf(seq
, "fs cp data: %-16llu\n",
462 sbi
->write_iostat
[FS_CP_DATA_IO
]);
463 seq_printf(seq
, "fs cp node: %-16llu\n",
464 sbi
->write_iostat
[FS_CP_NODE_IO
]);
465 seq_printf(seq
, "fs cp meta: %-16llu\n",
466 sbi
->write_iostat
[FS_CP_META_IO
]);
467 seq_printf(seq
, "fs discard: %-16llu\n",
468 sbi
->write_iostat
[FS_DISCARD
]);
473 #define F2FS_PROC_FILE_DEF(_name) \
474 static int _name##_open_fs(struct inode *inode, struct file *file) \
476 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \
479 static const struct file_operations f2fs_seq_##_name##_fops = { \
480 .open = _name##_open_fs, \
482 .llseek = seq_lseek, \
483 .release = single_release, \
486 F2FS_PROC_FILE_DEF(segment_info
);
487 F2FS_PROC_FILE_DEF(segment_bits
);
488 F2FS_PROC_FILE_DEF(iostat_info
);
490 int __init
f2fs_init_sysfs(void)
494 kobject_set_name(&f2fs_kset
.kobj
, "f2fs");
495 f2fs_kset
.kobj
.parent
= fs_kobj
;
496 ret
= kset_register(&f2fs_kset
);
500 ret
= kobject_init_and_add(&f2fs_feat
, &f2fs_feat_ktype
,
503 kset_unregister(&f2fs_kset
);
505 f2fs_proc_root
= proc_mkdir("fs/f2fs", NULL
);
509 void f2fs_exit_sysfs(void)
511 kobject_put(&f2fs_feat
);
512 kset_unregister(&f2fs_kset
);
513 remove_proc_entry("fs/f2fs", NULL
);
514 f2fs_proc_root
= NULL
;
517 int f2fs_register_sysfs(struct f2fs_sb_info
*sbi
)
519 struct super_block
*sb
= sbi
->sb
;
522 sbi
->s_kobj
.kset
= &f2fs_kset
;
523 init_completion(&sbi
->s_kobj_unregister
);
524 err
= kobject_init_and_add(&sbi
->s_kobj
, &f2fs_sb_ktype
, NULL
,
530 sbi
->s_proc
= proc_mkdir(sb
->s_id
, f2fs_proc_root
);
533 proc_create_data("segment_info", S_IRUGO
, sbi
->s_proc
,
534 &f2fs_seq_segment_info_fops
, sb
);
535 proc_create_data("segment_bits", S_IRUGO
, sbi
->s_proc
,
536 &f2fs_seq_segment_bits_fops
, sb
);
537 proc_create_data("iostat_info", S_IRUGO
, sbi
->s_proc
,
538 &f2fs_seq_iostat_info_fops
, sb
);
543 void f2fs_unregister_sysfs(struct f2fs_sb_info
*sbi
)
546 remove_proc_entry("iostat_info", sbi
->s_proc
);
547 remove_proc_entry("segment_info", sbi
->s_proc
);
548 remove_proc_entry("segment_bits", sbi
->s_proc
);
549 remove_proc_entry(sbi
->sb
->s_id
, f2fs_proc_root
);
551 kobject_del(&sbi
->s_kobj
);