OSDN Git Service

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[android-x86/kernel.git] / fs / f2fs / sysfs.c
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
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/proc_fs.h>
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
20 static struct proc_dir_entry *f2fs_proc_root;
21
22 /* Sysfs support for f2fs */
23 enum {
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 */
32 #endif
33         RESERVED_BLOCKS,        /* struct f2fs_sb_info */
34 };
35
36 struct 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
46 static 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);
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 *)&F2FS_OPTION(sbi).fault_info;
62 #endif
63         return NULL;
64 }
65
66 static ssize_t dirty_segments_show(struct f2fs_attr *a,
67                 struct f2fs_sb_info *sbi, char *buf)
68 {
69         return snprintf(buf, PAGE_SIZE, "%llu\n",
70                 (unsigned long long)(dirty_segments(sbi)));
71 }
72
73 static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
74                 struct f2fs_sb_info *sbi, char *buf)
75 {
76         struct super_block *sb = sbi->sb;
77
78         if (!sb->s_bdev->bd_part)
79                 return snprintf(buf, PAGE_SIZE, "0\n");
80
81         return snprintf(buf, PAGE_SIZE, "%llu\n",
82                 (unsigned long long)(sbi->kbytes_written +
83                         BD_PART_WRITTEN(sbi)));
84 }
85
86 static ssize_t features_show(struct f2fs_attr *a,
87                 struct f2fs_sb_info *sbi, char *buf)
88 {
89         struct super_block *sb = sbi->sb;
90         int len = 0;
91
92         if (!sb->s_bdev->bd_part)
93                 return snprintf(buf, PAGE_SIZE, "0\n");
94
95         if (f2fs_sb_has_encrypt(sb))
96                 len += snprintf(buf, PAGE_SIZE - len, "%s",
97                                                 "encryption");
98         if (f2fs_sb_has_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         if (f2fs_sb_has_flexible_inline_xattr(sb))
111                 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
112                                 len ? ", " : "", "flexible_inline_xattr");
113         if (f2fs_sb_has_quota_ino(sb))
114                 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
115                                 len ? ", " : "", "quota_ino");
116         if (f2fs_sb_has_inode_crtime(sb))
117                 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
118                                 len ? ", " : "", "inode_crtime");
119         if (f2fs_sb_has_lost_found(sb))
120                 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
121                                 len ? ", " : "", "lost_found");
122         len += snprintf(buf + len, PAGE_SIZE - len, "\n");
123         return len;
124 }
125
126 static ssize_t current_reserved_blocks_show(struct f2fs_attr *a,
127                                         struct f2fs_sb_info *sbi, char *buf)
128 {
129         return snprintf(buf, PAGE_SIZE, "%u\n", sbi->current_reserved_blocks);
130 }
131
132 static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
133                         struct f2fs_sb_info *sbi, char *buf)
134 {
135         unsigned char *ptr = NULL;
136         unsigned int *ui;
137
138         ptr = __struct_ptr(sbi, a->struct_type);
139         if (!ptr)
140                 return -EINVAL;
141
142         if (!strcmp(a->attr.name, "extension_list")) {
143                 __u8 (*extlist)[F2FS_EXTENSION_LEN] =
144                                         sbi->raw_super->extension_list;
145                 int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
146                 int hot_count = sbi->raw_super->hot_ext_count;
147                 int len = 0, i;
148
149                 len += snprintf(buf + len, PAGE_SIZE - len,
150                                                 "cold file extension:\n");
151                 for (i = 0; i < cold_count; i++)
152                         len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
153                                                                 extlist[i]);
154
155                 len += snprintf(buf + len, PAGE_SIZE - len,
156                                                 "hot file extension:\n");
157                 for (i = cold_count; i < cold_count + hot_count; i++)
158                         len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
159                                                                 extlist[i]);
160                 return len;
161         }
162
163         ui = (unsigned int *)(ptr + a->offset);
164
165         return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
166 }
167
168 static ssize_t __sbi_store(struct f2fs_attr *a,
169                         struct f2fs_sb_info *sbi,
170                         const char *buf, size_t count)
171 {
172         unsigned char *ptr;
173         unsigned long t;
174         unsigned int *ui;
175         ssize_t ret;
176
177         ptr = __struct_ptr(sbi, a->struct_type);
178         if (!ptr)
179                 return -EINVAL;
180
181         if (!strcmp(a->attr.name, "extension_list")) {
182                 const char *name = strim((char *)buf);
183                 bool set = true, hot;
184
185                 if (!strncmp(name, "[h]", 3))
186                         hot = true;
187                 else if (!strncmp(name, "[c]", 3))
188                         hot = false;
189                 else
190                         return -EINVAL;
191
192                 name += 3;
193
194                 if (*name == '!') {
195                         name++;
196                         set = false;
197                 }
198
199                 if (strlen(name) >= F2FS_EXTENSION_LEN)
200                         return -EINVAL;
201
202                 down_write(&sbi->sb_lock);
203
204                 ret = f2fs_update_extension_list(sbi, name, hot, set);
205                 if (ret)
206                         goto out;
207
208                 ret = f2fs_commit_super(sbi, false);
209                 if (ret)
210                         f2fs_update_extension_list(sbi, name, hot, !set);
211 out:
212                 up_write(&sbi->sb_lock);
213                 return ret ? ret : count;
214         }
215
216         ui = (unsigned int *)(ptr + a->offset);
217
218         ret = kstrtoul(skip_spaces(buf), 0, &t);
219         if (ret < 0)
220                 return ret;
221 #ifdef CONFIG_F2FS_FAULT_INJECTION
222         if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX))
223                 return -EINVAL;
224 #endif
225         if (a->struct_type == RESERVED_BLOCKS) {
226                 spin_lock(&sbi->stat_lock);
227                 if (t > (unsigned long)(sbi->user_block_count -
228                                 F2FS_OPTION(sbi).root_reserved_blocks)) {
229                         spin_unlock(&sbi->stat_lock);
230                         return -EINVAL;
231                 }
232                 *ui = t;
233                 sbi->current_reserved_blocks = min(sbi->reserved_blocks,
234                                 sbi->user_block_count - valid_user_blocks(sbi));
235                 spin_unlock(&sbi->stat_lock);
236                 return count;
237         }
238
239         if (!strcmp(a->attr.name, "discard_granularity")) {
240                 if (t == 0 || t > MAX_PLIST_NUM)
241                         return -EINVAL;
242                 if (t == *ui)
243                         return count;
244                 *ui = t;
245                 return count;
246         }
247
248         if (!strcmp(a->attr.name, "trim_sections"))
249                 return -EINVAL;
250
251         if (!strcmp(a->attr.name, "gc_urgent")) {
252                 if (t >= 1) {
253                         sbi->gc_mode = GC_URGENT;
254                         if (sbi->gc_thread) {
255                                 wake_up_interruptible_all(
256                                         &sbi->gc_thread->gc_wait_queue_head);
257                                 wake_up_discard_thread(sbi, true);
258                         }
259                 } else {
260                         sbi->gc_mode = GC_NORMAL;
261                 }
262                 return count;
263         }
264         if (!strcmp(a->attr.name, "gc_idle")) {
265                 if (t == GC_IDLE_CB)
266                         sbi->gc_mode = GC_IDLE_CB;
267                 else if (t == GC_IDLE_GREEDY)
268                         sbi->gc_mode = GC_IDLE_GREEDY;
269                 else
270                         sbi->gc_mode = GC_NORMAL;
271                 return count;
272         }
273
274         *ui = t;
275
276         if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
277                 f2fs_reset_iostat(sbi);
278         return count;
279 }
280
281 static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
282                         struct f2fs_sb_info *sbi,
283                         const char *buf, size_t count)
284 {
285         ssize_t ret;
286         bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") ||
287                                         a->struct_type == GC_THREAD);
288
289         if (gc_entry)
290                 down_read(&sbi->sb->s_umount);
291         ret = __sbi_store(a, sbi, buf, count);
292         if (gc_entry)
293                 up_read(&sbi->sb->s_umount);
294
295         return ret;
296 }
297
298 static ssize_t f2fs_attr_show(struct kobject *kobj,
299                                 struct attribute *attr, char *buf)
300 {
301         struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
302                                                                 s_kobj);
303         struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
304
305         return a->show ? a->show(a, sbi, buf) : 0;
306 }
307
308 static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr,
309                                                 const char *buf, size_t len)
310 {
311         struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
312                                                                         s_kobj);
313         struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
314
315         return a->store ? a->store(a, sbi, buf, len) : 0;
316 }
317
318 static void f2fs_sb_release(struct kobject *kobj)
319 {
320         struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
321                                                                 s_kobj);
322         complete(&sbi->s_kobj_unregister);
323 }
324
325 enum feat_id {
326         FEAT_CRYPTO = 0,
327         FEAT_BLKZONED,
328         FEAT_ATOMIC_WRITE,
329         FEAT_EXTRA_ATTR,
330         FEAT_PROJECT_QUOTA,
331         FEAT_INODE_CHECKSUM,
332         FEAT_FLEXIBLE_INLINE_XATTR,
333         FEAT_QUOTA_INO,
334         FEAT_INODE_CRTIME,
335         FEAT_LOST_FOUND,
336 };
337
338 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
339                 struct f2fs_sb_info *sbi, char *buf)
340 {
341         switch (a->id) {
342         case FEAT_CRYPTO:
343         case FEAT_BLKZONED:
344         case FEAT_ATOMIC_WRITE:
345         case FEAT_EXTRA_ATTR:
346         case FEAT_PROJECT_QUOTA:
347         case FEAT_INODE_CHECKSUM:
348         case FEAT_FLEXIBLE_INLINE_XATTR:
349         case FEAT_QUOTA_INO:
350         case FEAT_INODE_CRTIME:
351         case FEAT_LOST_FOUND:
352                 return snprintf(buf, PAGE_SIZE, "supported\n");
353         }
354         return 0;
355 }
356
357 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
358 static struct f2fs_attr f2fs_attr_##_name = {                   \
359         .attr = {.name = __stringify(_name), .mode = _mode },   \
360         .show   = _show,                                        \
361         .store  = _store,                                       \
362         .struct_type = _struct_type,                            \
363         .offset = _offset                                       \
364 }
365
366 #define F2FS_RW_ATTR(struct_type, struct_name, name, elname)    \
367         F2FS_ATTR_OFFSET(struct_type, name, 0644,               \
368                 f2fs_sbi_show, f2fs_sbi_store,                  \
369                 offsetof(struct struct_name, elname))
370
371 #define F2FS_GENERAL_RO_ATTR(name) \
372 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
373
374 #define F2FS_FEATURE_RO_ATTR(_name, _id)                        \
375 static struct f2fs_attr f2fs_attr_##_name = {                   \
376         .attr = {.name = __stringify(_name), .mode = 0444 },    \
377         .show   = f2fs_feature_show,                            \
378         .id     = _id,                                          \
379 }
380
381 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
382                                                         urgent_sleep_time);
383 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
384 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
385 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
386 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
387 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
388 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
389 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
390 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
391 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
392 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
393 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
394 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
395 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
396 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
397 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections);
398 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
399 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
400 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
401 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
402 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
403 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
404 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
405 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
406 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
407 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
408 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
409 #ifdef CONFIG_F2FS_FAULT_INJECTION
410 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
411 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
412 #endif
413 F2FS_GENERAL_RO_ATTR(dirty_segments);
414 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
415 F2FS_GENERAL_RO_ATTR(features);
416 F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
417
418 #ifdef CONFIG_F2FS_FS_ENCRYPTION
419 F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
420 #endif
421 #ifdef CONFIG_BLK_DEV_ZONED
422 F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED);
423 #endif
424 F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE);
425 F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR);
426 F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA);
427 F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
428 F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
429 F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
430 F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
431 F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
432
433 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
434 static struct attribute *f2fs_attrs[] = {
435         ATTR_LIST(gc_urgent_sleep_time),
436         ATTR_LIST(gc_min_sleep_time),
437         ATTR_LIST(gc_max_sleep_time),
438         ATTR_LIST(gc_no_gc_sleep_time),
439         ATTR_LIST(gc_idle),
440         ATTR_LIST(gc_urgent),
441         ATTR_LIST(reclaim_segments),
442         ATTR_LIST(max_small_discards),
443         ATTR_LIST(discard_granularity),
444         ATTR_LIST(batched_trim_sections),
445         ATTR_LIST(ipu_policy),
446         ATTR_LIST(min_ipu_util),
447         ATTR_LIST(min_fsync_blocks),
448         ATTR_LIST(min_hot_blocks),
449         ATTR_LIST(min_ssr_sections),
450         ATTR_LIST(max_victim_search),
451         ATTR_LIST(dir_level),
452         ATTR_LIST(ram_thresh),
453         ATTR_LIST(ra_nid_pages),
454         ATTR_LIST(dirty_nats_ratio),
455         ATTR_LIST(cp_interval),
456         ATTR_LIST(idle_interval),
457         ATTR_LIST(iostat_enable),
458         ATTR_LIST(readdir_ra),
459         ATTR_LIST(gc_pin_file_thresh),
460         ATTR_LIST(extension_list),
461 #ifdef CONFIG_F2FS_FAULT_INJECTION
462         ATTR_LIST(inject_rate),
463         ATTR_LIST(inject_type),
464 #endif
465         ATTR_LIST(dirty_segments),
466         ATTR_LIST(lifetime_write_kbytes),
467         ATTR_LIST(features),
468         ATTR_LIST(reserved_blocks),
469         ATTR_LIST(current_reserved_blocks),
470         NULL,
471 };
472
473 static struct attribute *f2fs_feat_attrs[] = {
474 #ifdef CONFIG_F2FS_FS_ENCRYPTION
475         ATTR_LIST(encryption),
476 #endif
477 #ifdef CONFIG_BLK_DEV_ZONED
478         ATTR_LIST(block_zoned),
479 #endif
480         ATTR_LIST(atomic_write),
481         ATTR_LIST(extra_attr),
482         ATTR_LIST(project_quota),
483         ATTR_LIST(inode_checksum),
484         ATTR_LIST(flexible_inline_xattr),
485         ATTR_LIST(quota_ino),
486         ATTR_LIST(inode_crtime),
487         ATTR_LIST(lost_found),
488         NULL,
489 };
490
491 static const struct sysfs_ops f2fs_attr_ops = {
492         .show   = f2fs_attr_show,
493         .store  = f2fs_attr_store,
494 };
495
496 static struct kobj_type f2fs_sb_ktype = {
497         .default_attrs  = f2fs_attrs,
498         .sysfs_ops      = &f2fs_attr_ops,
499         .release        = f2fs_sb_release,
500 };
501
502 static struct kobj_type f2fs_ktype = {
503         .sysfs_ops      = &f2fs_attr_ops,
504 };
505
506 static struct kset f2fs_kset = {
507         .kobj   = {.ktype = &f2fs_ktype},
508 };
509
510 static struct kobj_type f2fs_feat_ktype = {
511         .default_attrs  = f2fs_feat_attrs,
512         .sysfs_ops      = &f2fs_attr_ops,
513 };
514
515 static struct kobject f2fs_feat = {
516         .kset   = &f2fs_kset,
517 };
518
519 static int segment_info_seq_show(struct seq_file *seq, void *offset)
520 {
521         struct super_block *sb = seq->private;
522         struct f2fs_sb_info *sbi = F2FS_SB(sb);
523         unsigned int total_segs =
524                         le32_to_cpu(sbi->raw_super->segment_count_main);
525         int i;
526
527         seq_puts(seq, "format: segment_type|valid_blocks\n"
528                 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
529
530         for (i = 0; i < total_segs; i++) {
531                 struct seg_entry *se = get_seg_entry(sbi, i);
532
533                 if ((i % 10) == 0)
534                         seq_printf(seq, "%-10d", i);
535                 seq_printf(seq, "%d|%-3u", se->type,
536                                         get_valid_blocks(sbi, i, false));
537                 if ((i % 10) == 9 || i == (total_segs - 1))
538                         seq_putc(seq, '\n');
539                 else
540                         seq_putc(seq, ' ');
541         }
542
543         return 0;
544 }
545
546 static int segment_bits_seq_show(struct seq_file *seq, void *offset)
547 {
548         struct super_block *sb = seq->private;
549         struct f2fs_sb_info *sbi = F2FS_SB(sb);
550         unsigned int total_segs =
551                         le32_to_cpu(sbi->raw_super->segment_count_main);
552         int i, j;
553
554         seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n"
555                 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
556
557         for (i = 0; i < total_segs; i++) {
558                 struct seg_entry *se = get_seg_entry(sbi, i);
559
560                 seq_printf(seq, "%-10d", i);
561                 seq_printf(seq, "%d|%-3u|", se->type,
562                                         get_valid_blocks(sbi, i, false));
563                 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)
564                         seq_printf(seq, " %.2x", se->cur_valid_map[j]);
565                 seq_putc(seq, '\n');
566         }
567         return 0;
568 }
569
570 static int iostat_info_seq_show(struct seq_file *seq, void *offset)
571 {
572         struct super_block *sb = seq->private;
573         struct f2fs_sb_info *sbi = F2FS_SB(sb);
574         time64_t now = ktime_get_real_seconds();
575
576         if (!sbi->iostat_enable)
577                 return 0;
578
579         seq_printf(seq, "time:          %-16llu\n", now);
580
581         /* print app IOs */
582         seq_printf(seq, "app buffered:  %-16llu\n",
583                                 sbi->write_iostat[APP_BUFFERED_IO]);
584         seq_printf(seq, "app direct:    %-16llu\n",
585                                 sbi->write_iostat[APP_DIRECT_IO]);
586         seq_printf(seq, "app mapped:    %-16llu\n",
587                                 sbi->write_iostat[APP_MAPPED_IO]);
588
589         /* print fs IOs */
590         seq_printf(seq, "fs data:       %-16llu\n",
591                                 sbi->write_iostat[FS_DATA_IO]);
592         seq_printf(seq, "fs node:       %-16llu\n",
593                                 sbi->write_iostat[FS_NODE_IO]);
594         seq_printf(seq, "fs meta:       %-16llu\n",
595                                 sbi->write_iostat[FS_META_IO]);
596         seq_printf(seq, "fs gc data:    %-16llu\n",
597                                 sbi->write_iostat[FS_GC_DATA_IO]);
598         seq_printf(seq, "fs gc node:    %-16llu\n",
599                                 sbi->write_iostat[FS_GC_NODE_IO]);
600         seq_printf(seq, "fs cp data:    %-16llu\n",
601                                 sbi->write_iostat[FS_CP_DATA_IO]);
602         seq_printf(seq, "fs cp node:    %-16llu\n",
603                                 sbi->write_iostat[FS_CP_NODE_IO]);
604         seq_printf(seq, "fs cp meta:    %-16llu\n",
605                                 sbi->write_iostat[FS_CP_META_IO]);
606         seq_printf(seq, "fs discard:    %-16llu\n",
607                                 sbi->write_iostat[FS_DISCARD]);
608
609         return 0;
610 }
611
612 int __init f2fs_init_sysfs(void)
613 {
614         int ret;
615
616         kobject_set_name(&f2fs_kset.kobj, "f2fs");
617         f2fs_kset.kobj.parent = fs_kobj;
618         ret = kset_register(&f2fs_kset);
619         if (ret)
620                 return ret;
621
622         ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,
623                                    NULL, "features");
624         if (ret)
625                 kset_unregister(&f2fs_kset);
626         else
627                 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
628         return ret;
629 }
630
631 void f2fs_exit_sysfs(void)
632 {
633         kobject_put(&f2fs_feat);
634         kset_unregister(&f2fs_kset);
635         remove_proc_entry("fs/f2fs", NULL);
636         f2fs_proc_root = NULL;
637 }
638
639 int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
640 {
641         struct super_block *sb = sbi->sb;
642         int err;
643
644         sbi->s_kobj.kset = &f2fs_kset;
645         init_completion(&sbi->s_kobj_unregister);
646         err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
647                                 "%s", sb->s_id);
648         if (err)
649                 return err;
650
651         if (f2fs_proc_root)
652                 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
653
654         if (sbi->s_proc) {
655                 proc_create_single_data("segment_info", S_IRUGO, sbi->s_proc,
656                                 segment_info_seq_show, sb);
657                 proc_create_single_data("segment_bits", S_IRUGO, sbi->s_proc,
658                                 segment_bits_seq_show, sb);
659                 proc_create_single_data("iostat_info", S_IRUGO, sbi->s_proc,
660                                 iostat_info_seq_show, sb);
661         }
662         return 0;
663 }
664
665 void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
666 {
667         if (sbi->s_proc) {
668                 remove_proc_entry("iostat_info", sbi->s_proc);
669                 remove_proc_entry("segment_info", sbi->s_proc);
670                 remove_proc_entry("segment_bits", sbi->s_proc);
671                 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
672         }
673         kobject_del(&sbi->s_kobj);
674 }