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
lifetime_write_kbytes_show(struct f2fs_attr
*a
,
67 struct f2fs_sb_info
*sbi
, char *buf
)
69 struct super_block
*sb
= sbi
->sb
;
71 if (!sb
->s_bdev
->bd_part
)
72 return snprintf(buf
, PAGE_SIZE
, "0\n");
74 return snprintf(buf
, PAGE_SIZE
, "%llu\n",
75 (unsigned long long)(sbi
->kbytes_written
+
76 BD_PART_WRITTEN(sbi
)));
79 static ssize_t
features_show(struct f2fs_attr
*a
,
80 struct f2fs_sb_info
*sbi
, char *buf
)
82 struct super_block
*sb
= sbi
->sb
;
85 if (!sb
->s_bdev
->bd_part
)
86 return snprintf(buf
, PAGE_SIZE
, "0\n");
88 if (f2fs_sb_has_crypto(sb
))
89 len
+= snprintf(buf
, PAGE_SIZE
- len
, "%s",
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");
107 static ssize_t
f2fs_sbi_show(struct f2fs_attr
*a
,
108 struct f2fs_sb_info
*sbi
, char *buf
)
110 unsigned char *ptr
= NULL
;
113 ptr
= __struct_ptr(sbi
, a
->struct_type
);
117 ui
= (unsigned int *)(ptr
+ a
->offset
);
119 return snprintf(buf
, PAGE_SIZE
, "%u\n", *ui
);
122 static ssize_t
f2fs_sbi_store(struct f2fs_attr
*a
,
123 struct f2fs_sb_info
*sbi
,
124 const char *buf
, size_t count
)
131 ptr
= __struct_ptr(sbi
, a
->struct_type
);
135 ui
= (unsigned int *)(ptr
+ a
->offset
);
137 ret
= kstrtoul(skip_spaces(buf
), 0, &t
);
140 #ifdef CONFIG_F2FS_FAULT_INJECTION
141 if (a
->struct_type
== FAULT_INFO_TYPE
&& t
>= (1 << FAULT_MAX
))
144 if (a
->struct_type
== RESERVED_BLOCKS
) {
145 spin_lock(&sbi
->stat_lock
);
146 if ((unsigned long)sbi
->total_valid_block_count
+ t
>
147 (unsigned long)sbi
->user_block_count
) {
148 spin_unlock(&sbi
->stat_lock
);
152 spin_unlock(&sbi
->stat_lock
);
156 if (!strcmp(a
->attr
.name
, "discard_granularity")) {
157 struct discard_cmd_control
*dcc
= SM_I(sbi
)->dcc_info
;
160 if (t
== 0 || t
> MAX_PLIST_NUM
)
165 mutex_lock(&dcc
->cmd_lock
);
166 for (i
= 0; i
< MAX_PLIST_NUM
; i
++) {
168 dcc
->pend_list_tag
[i
] |= P_ACTIVE
;
170 dcc
->pend_list_tag
[i
] &= (~P_ACTIVE
);
172 mutex_unlock(&dcc
->cmd_lock
);
180 if (!strcmp(a
->attr
.name
, "iostat_enable") && *ui
== 0)
181 f2fs_reset_iostat(sbi
);
182 if (!strcmp(a
->attr
.name
, "gc_urgent") && t
== 1 && sbi
->gc_thread
) {
183 sbi
->gc_thread
->gc_wake
= 1;
184 wake_up_interruptible_all(&sbi
->gc_thread
->gc_wait_queue_head
);
185 wake_up_discard_thread(sbi
, true);
191 static ssize_t
f2fs_attr_show(struct kobject
*kobj
,
192 struct attribute
*attr
, char *buf
)
194 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
196 struct f2fs_attr
*a
= container_of(attr
, struct f2fs_attr
, attr
);
198 return a
->show
? a
->show(a
, sbi
, buf
) : 0;
201 static ssize_t
f2fs_attr_store(struct kobject
*kobj
, struct attribute
*attr
,
202 const char *buf
, size_t len
)
204 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
206 struct f2fs_attr
*a
= container_of(attr
, struct f2fs_attr
, attr
);
208 return a
->store
? a
->store(a
, sbi
, buf
, len
) : 0;
211 static void f2fs_sb_release(struct kobject
*kobj
)
213 struct f2fs_sb_info
*sbi
= container_of(kobj
, struct f2fs_sb_info
,
215 complete(&sbi
->s_kobj_unregister
);
227 static ssize_t
f2fs_feature_show(struct f2fs_attr
*a
,
228 struct f2fs_sb_info
*sbi
, char *buf
)
233 case FEAT_ATOMIC_WRITE
:
234 case FEAT_EXTRA_ATTR
:
235 case FEAT_PROJECT_QUOTA
:
236 case FEAT_INODE_CHECKSUM
:
237 return snprintf(buf
, PAGE_SIZE
, "supported\n");
242 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
243 static struct f2fs_attr f2fs_attr_##_name = { \
244 .attr = {.name = __stringify(_name), .mode = _mode }, \
247 .struct_type = _struct_type, \
251 #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
252 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
253 f2fs_sbi_show, f2fs_sbi_store, \
254 offsetof(struct struct_name, elname))
256 #define F2FS_GENERAL_RO_ATTR(name) \
257 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
259 #define F2FS_FEATURE_RO_ATTR(_name, _id) \
260 static struct f2fs_attr f2fs_attr_##_name = { \
261 .attr = {.name = __stringify(_name), .mode = 0444 }, \
262 .show = f2fs_feature_show, \
266 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_urgent_sleep_time
,
268 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_min_sleep_time
, min_sleep_time
);
269 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_max_sleep_time
, max_sleep_time
);
270 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_no_gc_sleep_time
, no_gc_sleep_time
);
271 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_idle
, gc_idle
);
272 F2FS_RW_ATTR(GC_THREAD
, f2fs_gc_kthread
, gc_urgent
, gc_urgent
);
273 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, reclaim_segments
, rec_prefree_segments
);
274 F2FS_RW_ATTR(DCC_INFO
, discard_cmd_control
, max_small_discards
, max_discards
);
275 F2FS_RW_ATTR(DCC_INFO
, discard_cmd_control
, discard_granularity
, discard_granularity
);
276 F2FS_RW_ATTR(RESERVED_BLOCKS
, f2fs_sb_info
, reserved_blocks
, reserved_blocks
);
277 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, batched_trim_sections
, trim_sections
);
278 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, ipu_policy
, ipu_policy
);
279 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_ipu_util
, min_ipu_util
);
280 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_fsync_blocks
, min_fsync_blocks
);
281 F2FS_RW_ATTR(SM_INFO
, f2fs_sm_info
, min_hot_blocks
, min_hot_blocks
);
282 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, ram_thresh
, ram_thresh
);
283 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, ra_nid_pages
, ra_nid_pages
);
284 F2FS_RW_ATTR(NM_INFO
, f2fs_nm_info
, dirty_nats_ratio
, dirty_nats_ratio
);
285 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, max_victim_search
, max_victim_search
);
286 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, dir_level
, dir_level
);
287 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, cp_interval
, interval_time
[CP_TIME
]);
288 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, idle_interval
, interval_time
[REQ_TIME
]);
289 F2FS_RW_ATTR(F2FS_SBI
, f2fs_sb_info
, iostat_enable
, iostat_enable
);
290 #ifdef CONFIG_F2FS_FAULT_INJECTION
291 F2FS_RW_ATTR(FAULT_INFO_RATE
, f2fs_fault_info
, inject_rate
, inject_rate
);
292 F2FS_RW_ATTR(FAULT_INFO_TYPE
, f2fs_fault_info
, inject_type
, inject_type
);
294 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes
);
295 F2FS_GENERAL_RO_ATTR(features
);
297 #ifdef CONFIG_F2FS_FS_ENCRYPTION
298 F2FS_FEATURE_RO_ATTR(encryption
, FEAT_CRYPTO
);
300 #ifdef CONFIG_BLK_DEV_ZONED
301 F2FS_FEATURE_RO_ATTR(block_zoned
, FEAT_BLKZONED
);
303 F2FS_FEATURE_RO_ATTR(atomic_write
, FEAT_ATOMIC_WRITE
);
304 F2FS_FEATURE_RO_ATTR(extra_attr
, FEAT_EXTRA_ATTR
);
305 F2FS_FEATURE_RO_ATTR(project_quota
, FEAT_PROJECT_QUOTA
);
306 F2FS_FEATURE_RO_ATTR(inode_checksum
, FEAT_INODE_CHECKSUM
);
308 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
309 static struct attribute
*f2fs_attrs
[] = {
310 ATTR_LIST(gc_urgent_sleep_time
),
311 ATTR_LIST(gc_min_sleep_time
),
312 ATTR_LIST(gc_max_sleep_time
),
313 ATTR_LIST(gc_no_gc_sleep_time
),
315 ATTR_LIST(gc_urgent
),
316 ATTR_LIST(reclaim_segments
),
317 ATTR_LIST(max_small_discards
),
318 ATTR_LIST(discard_granularity
),
319 ATTR_LIST(batched_trim_sections
),
320 ATTR_LIST(ipu_policy
),
321 ATTR_LIST(min_ipu_util
),
322 ATTR_LIST(min_fsync_blocks
),
323 ATTR_LIST(min_hot_blocks
),
324 ATTR_LIST(max_victim_search
),
325 ATTR_LIST(dir_level
),
326 ATTR_LIST(ram_thresh
),
327 ATTR_LIST(ra_nid_pages
),
328 ATTR_LIST(dirty_nats_ratio
),
329 ATTR_LIST(cp_interval
),
330 ATTR_LIST(idle_interval
),
331 ATTR_LIST(iostat_enable
),
332 #ifdef CONFIG_F2FS_FAULT_INJECTION
333 ATTR_LIST(inject_rate
),
334 ATTR_LIST(inject_type
),
336 ATTR_LIST(lifetime_write_kbytes
),
338 ATTR_LIST(reserved_blocks
),
342 static struct attribute
*f2fs_feat_attrs
[] = {
343 #ifdef CONFIG_F2FS_FS_ENCRYPTION
344 ATTR_LIST(encryption
),
346 #ifdef CONFIG_BLK_DEV_ZONED
347 ATTR_LIST(block_zoned
),
349 ATTR_LIST(atomic_write
),
350 ATTR_LIST(extra_attr
),
351 ATTR_LIST(project_quota
),
352 ATTR_LIST(inode_checksum
),
356 static const struct sysfs_ops f2fs_attr_ops
= {
357 .show
= f2fs_attr_show
,
358 .store
= f2fs_attr_store
,
361 static struct kobj_type f2fs_sb_ktype
= {
362 .default_attrs
= f2fs_attrs
,
363 .sysfs_ops
= &f2fs_attr_ops
,
364 .release
= f2fs_sb_release
,
367 static struct kobj_type f2fs_ktype
= {
368 .sysfs_ops
= &f2fs_attr_ops
,
371 static struct kset f2fs_kset
= {
372 .kobj
= {.ktype
= &f2fs_ktype
},
375 static struct kobj_type f2fs_feat_ktype
= {
376 .default_attrs
= f2fs_feat_attrs
,
377 .sysfs_ops
= &f2fs_attr_ops
,
380 static struct kobject f2fs_feat
= {
384 static int segment_info_seq_show(struct seq_file
*seq
, void *offset
)
386 struct super_block
*sb
= seq
->private;
387 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
388 unsigned int total_segs
=
389 le32_to_cpu(sbi
->raw_super
->segment_count_main
);
392 seq_puts(seq
, "format: segment_type|valid_blocks\n"
393 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
395 for (i
= 0; i
< total_segs
; i
++) {
396 struct seg_entry
*se
= get_seg_entry(sbi
, i
);
399 seq_printf(seq
, "%-10d", i
);
400 seq_printf(seq
, "%d|%-3u", se
->type
,
401 get_valid_blocks(sbi
, i
, false));
402 if ((i
% 10) == 9 || i
== (total_segs
- 1))
411 static int segment_bits_seq_show(struct seq_file
*seq
, void *offset
)
413 struct super_block
*sb
= seq
->private;
414 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
415 unsigned int total_segs
=
416 le32_to_cpu(sbi
->raw_super
->segment_count_main
);
419 seq_puts(seq
, "format: segment_type|valid_blocks|bitmaps\n"
420 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
422 for (i
= 0; i
< total_segs
; i
++) {
423 struct seg_entry
*se
= get_seg_entry(sbi
, i
);
425 seq_printf(seq
, "%-10d", i
);
426 seq_printf(seq
, "%d|%-3u|", se
->type
,
427 get_valid_blocks(sbi
, i
, false));
428 for (j
= 0; j
< SIT_VBLOCK_MAP_SIZE
; j
++)
429 seq_printf(seq
, " %.2x", se
->cur_valid_map
[j
]);
435 static int iostat_info_seq_show(struct seq_file
*seq
, void *offset
)
437 struct super_block
*sb
= seq
->private;
438 struct f2fs_sb_info
*sbi
= F2FS_SB(sb
);
439 time64_t now
= ktime_get_real_seconds();
441 if (!sbi
->iostat_enable
)
444 seq_printf(seq
, "time: %-16llu\n", now
);
447 seq_printf(seq
, "app buffered: %-16llu\n",
448 sbi
->write_iostat
[APP_BUFFERED_IO
]);
449 seq_printf(seq
, "app direct: %-16llu\n",
450 sbi
->write_iostat
[APP_DIRECT_IO
]);
451 seq_printf(seq
, "app mapped: %-16llu\n",
452 sbi
->write_iostat
[APP_MAPPED_IO
]);
455 seq_printf(seq
, "fs data: %-16llu\n",
456 sbi
->write_iostat
[FS_DATA_IO
]);
457 seq_printf(seq
, "fs node: %-16llu\n",
458 sbi
->write_iostat
[FS_NODE_IO
]);
459 seq_printf(seq
, "fs meta: %-16llu\n",
460 sbi
->write_iostat
[FS_META_IO
]);
461 seq_printf(seq
, "fs gc data: %-16llu\n",
462 sbi
->write_iostat
[FS_GC_DATA_IO
]);
463 seq_printf(seq
, "fs gc node: %-16llu\n",
464 sbi
->write_iostat
[FS_GC_NODE_IO
]);
465 seq_printf(seq
, "fs cp data: %-16llu\n",
466 sbi
->write_iostat
[FS_CP_DATA_IO
]);
467 seq_printf(seq
, "fs cp node: %-16llu\n",
468 sbi
->write_iostat
[FS_CP_NODE_IO
]);
469 seq_printf(seq
, "fs cp meta: %-16llu\n",
470 sbi
->write_iostat
[FS_CP_META_IO
]);
471 seq_printf(seq
, "fs discard: %-16llu\n",
472 sbi
->write_iostat
[FS_DISCARD
]);
477 #define F2FS_PROC_FILE_DEF(_name) \
478 static int _name##_open_fs(struct inode *inode, struct file *file) \
480 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \
483 static const struct file_operations f2fs_seq_##_name##_fops = { \
484 .open = _name##_open_fs, \
486 .llseek = seq_lseek, \
487 .release = single_release, \
490 F2FS_PROC_FILE_DEF(segment_info
);
491 F2FS_PROC_FILE_DEF(segment_bits
);
492 F2FS_PROC_FILE_DEF(iostat_info
);
494 int __init
f2fs_init_sysfs(void)
498 kobject_set_name(&f2fs_kset
.kobj
, "f2fs");
499 f2fs_kset
.kobj
.parent
= fs_kobj
;
500 ret
= kset_register(&f2fs_kset
);
504 ret
= kobject_init_and_add(&f2fs_feat
, &f2fs_feat_ktype
,
507 kset_unregister(&f2fs_kset
);
509 f2fs_proc_root
= proc_mkdir("fs/f2fs", NULL
);
513 void f2fs_exit_sysfs(void)
515 kobject_put(&f2fs_feat
);
516 kset_unregister(&f2fs_kset
);
517 remove_proc_entry("fs/f2fs", NULL
);
518 f2fs_proc_root
= NULL
;
521 int f2fs_register_sysfs(struct f2fs_sb_info
*sbi
)
523 struct super_block
*sb
= sbi
->sb
;
526 sbi
->s_kobj
.kset
= &f2fs_kset
;
527 init_completion(&sbi
->s_kobj_unregister
);
528 err
= kobject_init_and_add(&sbi
->s_kobj
, &f2fs_sb_ktype
, NULL
,
534 sbi
->s_proc
= proc_mkdir(sb
->s_id
, f2fs_proc_root
);
537 proc_create_data("segment_info", S_IRUGO
, sbi
->s_proc
,
538 &f2fs_seq_segment_info_fops
, sb
);
539 proc_create_data("segment_bits", S_IRUGO
, sbi
->s_proc
,
540 &f2fs_seq_segment_bits_fops
, sb
);
541 proc_create_data("iostat_info", S_IRUGO
, sbi
->s_proc
,
542 &f2fs_seq_iostat_info_fops
, sb
);
547 void f2fs_unregister_sysfs(struct f2fs_sb_info
*sbi
)
550 remove_proc_entry("iostat_info", sbi
->s_proc
);
551 remove_proc_entry("segment_info", sbi
->s_proc
);
552 remove_proc_entry("segment_bits", sbi
->s_proc
);
553 remove_proc_entry(sbi
->sb
->s_id
, f2fs_proc_root
);
555 kobject_del(&sbi
->s_kobj
);