1
2
3
4
5
6
7
8
9#include <linux/compiler.h>
10#include <linux/proc_fs.h>
11#include <linux/f2fs_fs.h>
12#include <linux/seq_file.h>
13#include <linux/unicode.h>
14#include <linux/ioprio.h>
15#include <linux/sysfs.h>
16
17#include "f2fs.h"
18#include "segment.h"
19#include "gc.h"
20#include "iostat.h"
21#include <trace/events/f2fs.h>
22
23static struct proc_dir_entry *f2fs_proc_root;
24
25
26enum {
27 GC_THREAD,
28 SM_INFO,
29 DCC_INFO,
30 NM_INFO,
31 F2FS_SBI,
32#ifdef CONFIG_F2FS_STAT_FS
33 STAT_INFO,
34#endif
35#ifdef CONFIG_F2FS_FAULT_INJECTION
36 FAULT_INFO_RATE,
37 FAULT_INFO_TYPE,
38#endif
39 RESERVED_BLOCKS,
40 CPRC_INFO,
41 ATGC_INFO,
42};
43
44struct f2fs_attr {
45 struct attribute attr;
46 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
47 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *,
48 const char *, size_t);
49 int struct_type;
50 int offset;
51 int id;
52};
53
54static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
55 struct f2fs_sb_info *sbi, char *buf);
56
57static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
58{
59 if (struct_type == GC_THREAD)
60 return (unsigned char *)sbi->gc_thread;
61 else if (struct_type == SM_INFO)
62 return (unsigned char *)SM_I(sbi);
63 else if (struct_type == DCC_INFO)
64 return (unsigned char *)SM_I(sbi)->dcc_info;
65 else if (struct_type == NM_INFO)
66 return (unsigned char *)NM_I(sbi);
67 else if (struct_type == F2FS_SBI || struct_type == RESERVED_BLOCKS)
68 return (unsigned char *)sbi;
69#ifdef CONFIG_F2FS_FAULT_INJECTION
70 else if (struct_type == FAULT_INFO_RATE ||
71 struct_type == FAULT_INFO_TYPE)
72 return (unsigned char *)&F2FS_OPTION(sbi).fault_info;
73#endif
74#ifdef CONFIG_F2FS_STAT_FS
75 else if (struct_type == STAT_INFO)
76 return (unsigned char *)F2FS_STAT(sbi);
77#endif
78 else if (struct_type == CPRC_INFO)
79 return (unsigned char *)&sbi->cprc_info;
80 else if (struct_type == ATGC_INFO)
81 return (unsigned char *)&sbi->am;
82 return NULL;
83}
84
85static ssize_t dirty_segments_show(struct f2fs_attr *a,
86 struct f2fs_sb_info *sbi, char *buf)
87{
88 return sprintf(buf, "%llu\n",
89 (unsigned long long)(dirty_segments(sbi)));
90}
91
92static ssize_t free_segments_show(struct f2fs_attr *a,
93 struct f2fs_sb_info *sbi, char *buf)
94{
95 return sprintf(buf, "%llu\n",
96 (unsigned long long)(free_segments(sbi)));
97}
98
99static ssize_t ovp_segments_show(struct f2fs_attr *a,
100 struct f2fs_sb_info *sbi, char *buf)
101{
102 return sprintf(buf, "%llu\n",
103 (unsigned long long)(overprovision_segments(sbi)));
104}
105
106static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
107 struct f2fs_sb_info *sbi, char *buf)
108{
109 return sprintf(buf, "%llu\n",
110 (unsigned long long)(sbi->kbytes_written +
111 ((f2fs_get_sectors_written(sbi) -
112 sbi->sectors_written_start) >> 1)));
113}
114
115static ssize_t sb_status_show(struct f2fs_attr *a,
116 struct f2fs_sb_info *sbi, char *buf)
117{
118 return sprintf(buf, "%lx\n", sbi->s_flag);
119}
120
121static ssize_t features_show(struct f2fs_attr *a,
122 struct f2fs_sb_info *sbi, char *buf)
123{
124 int len = 0;
125
126 if (f2fs_sb_has_encrypt(sbi))
127 len += scnprintf(buf, PAGE_SIZE - len, "%s",
128 "encryption");
129 if (f2fs_sb_has_blkzoned(sbi))
130 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
131 len ? ", " : "", "blkzoned");
132 if (f2fs_sb_has_extra_attr(sbi))
133 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
134 len ? ", " : "", "extra_attr");
135 if (f2fs_sb_has_project_quota(sbi))
136 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
137 len ? ", " : "", "projquota");
138 if (f2fs_sb_has_inode_chksum(sbi))
139 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
140 len ? ", " : "", "inode_checksum");
141 if (f2fs_sb_has_flexible_inline_xattr(sbi))
142 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
143 len ? ", " : "", "flexible_inline_xattr");
144 if (f2fs_sb_has_quota_ino(sbi))
145 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
146 len ? ", " : "", "quota_ino");
147 if (f2fs_sb_has_inode_crtime(sbi))
148 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
149 len ? ", " : "", "inode_crtime");
150 if (f2fs_sb_has_lost_found(sbi))
151 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
152 len ? ", " : "", "lost_found");
153 if (f2fs_sb_has_verity(sbi))
154 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
155 len ? ", " : "", "verity");
156 if (f2fs_sb_has_sb_chksum(sbi))
157 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
158 len ? ", " : "", "sb_checksum");
159 if (f2fs_sb_has_casefold(sbi))
160 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
161 len ? ", " : "", "casefold");
162 if (f2fs_sb_has_readonly(sbi))
163 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
164 len ? ", " : "", "readonly");
165 if (f2fs_sb_has_compression(sbi))
166 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
167 len ? ", " : "", "compression");
168 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
169 len ? ", " : "", "pin_file");
170 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
171 return len;
172}
173
174static ssize_t current_reserved_blocks_show(struct f2fs_attr *a,
175 struct f2fs_sb_info *sbi, char *buf)
176{
177 return sprintf(buf, "%u\n", sbi->current_reserved_blocks);
178}
179
180static ssize_t unusable_show(struct f2fs_attr *a,
181 struct f2fs_sb_info *sbi, char *buf)
182{
183 block_t unusable;
184
185 if (test_opt(sbi, DISABLE_CHECKPOINT))
186 unusable = sbi->unusable_block_count;
187 else
188 unusable = f2fs_get_unusable_blocks(sbi);
189 return sprintf(buf, "%llu\n", (unsigned long long)unusable);
190}
191
192static ssize_t encoding_show(struct f2fs_attr *a,
193 struct f2fs_sb_info *sbi, char *buf)
194{
195#ifdef CONFIG_UNICODE
196 struct super_block *sb = sbi->sb;
197
198 if (f2fs_sb_has_casefold(sbi))
199 return snprintf(buf, PAGE_SIZE, "%s (%d.%d.%d)\n",
200 sb->s_encoding->charset,
201 (sb->s_encoding->version >> 16) & 0xff,
202 (sb->s_encoding->version >> 8) & 0xff,
203 sb->s_encoding->version & 0xff);
204#endif
205 return sprintf(buf, "(none)");
206}
207
208static ssize_t mounted_time_sec_show(struct f2fs_attr *a,
209 struct f2fs_sb_info *sbi, char *buf)
210{
211 return sprintf(buf, "%llu", SIT_I(sbi)->mounted_time);
212}
213
214#ifdef CONFIG_F2FS_STAT_FS
215static ssize_t moved_blocks_foreground_show(struct f2fs_attr *a,
216 struct f2fs_sb_info *sbi, char *buf)
217{
218 struct f2fs_stat_info *si = F2FS_STAT(sbi);
219
220 return sprintf(buf, "%llu\n",
221 (unsigned long long)(si->tot_blks -
222 (si->bg_data_blks + si->bg_node_blks)));
223}
224
225static ssize_t moved_blocks_background_show(struct f2fs_attr *a,
226 struct f2fs_sb_info *sbi, char *buf)
227{
228 struct f2fs_stat_info *si = F2FS_STAT(sbi);
229
230 return sprintf(buf, "%llu\n",
231 (unsigned long long)(si->bg_data_blks + si->bg_node_blks));
232}
233
234static ssize_t avg_vblocks_show(struct f2fs_attr *a,
235 struct f2fs_sb_info *sbi, char *buf)
236{
237 struct f2fs_stat_info *si = F2FS_STAT(sbi);
238
239 si->dirty_count = dirty_segments(sbi);
240 f2fs_update_sit_info(sbi);
241 return sprintf(buf, "%llu\n", (unsigned long long)(si->avg_vblocks));
242}
243#endif
244
245static ssize_t main_blkaddr_show(struct f2fs_attr *a,
246 struct f2fs_sb_info *sbi, char *buf)
247{
248 return snprintf(buf, PAGE_SIZE, "%llu\n",
249 (unsigned long long)MAIN_BLKADDR(sbi));
250}
251
252static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
253 struct f2fs_sb_info *sbi, char *buf)
254{
255 unsigned char *ptr = NULL;
256 unsigned int *ui;
257
258 ptr = __struct_ptr(sbi, a->struct_type);
259 if (!ptr)
260 return -EINVAL;
261
262 if (!strcmp(a->attr.name, "extension_list")) {
263 __u8 (*extlist)[F2FS_EXTENSION_LEN] =
264 sbi->raw_super->extension_list;
265 int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
266 int hot_count = sbi->raw_super->hot_ext_count;
267 int len = 0, i;
268
269 len += scnprintf(buf + len, PAGE_SIZE - len,
270 "cold file extension:\n");
271 for (i = 0; i < cold_count; i++)
272 len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n",
273 extlist[i]);
274
275 len += scnprintf(buf + len, PAGE_SIZE - len,
276 "hot file extension:\n");
277 for (i = cold_count; i < cold_count + hot_count; i++)
278 len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n",
279 extlist[i]);
280 return len;
281 }
282
283 if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
284 struct ckpt_req_control *cprc = &sbi->cprc_info;
285 int len = 0;
286 int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio);
287 int data = IOPRIO_PRIO_DATA(cprc->ckpt_thread_ioprio);
288
289 if (class == IOPRIO_CLASS_RT)
290 len += scnprintf(buf + len, PAGE_SIZE - len, "rt,");
291 else if (class == IOPRIO_CLASS_BE)
292 len += scnprintf(buf + len, PAGE_SIZE - len, "be,");
293 else
294 return -EINVAL;
295
296 len += scnprintf(buf + len, PAGE_SIZE - len, "%d\n", data);
297 return len;
298 }
299
300#ifdef CONFIG_F2FS_FS_COMPRESSION
301 if (!strcmp(a->attr.name, "compr_written_block"))
302 return sysfs_emit(buf, "%llu\n", sbi->compr_written_block);
303
304 if (!strcmp(a->attr.name, "compr_saved_block"))
305 return sysfs_emit(buf, "%llu\n", sbi->compr_saved_block);
306
307 if (!strcmp(a->attr.name, "compr_new_inode"))
308 return sysfs_emit(buf, "%u\n", sbi->compr_new_inode);
309#endif
310
311 if (!strcmp(a->attr.name, "gc_segment_mode"))
312 return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode);
313
314 if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
315 return sysfs_emit(buf, "%u\n",
316 sbi->gc_reclaimed_segs[sbi->gc_segment_mode]);
317 }
318
319 ui = (unsigned int *)(ptr + a->offset);
320
321 return sprintf(buf, "%u\n", *ui);
322}
323
324static ssize_t __sbi_store(struct f2fs_attr *a,
325 struct f2fs_sb_info *sbi,
326 const char *buf, size_t count)
327{
328 unsigned char *ptr;
329 unsigned long t;
330 unsigned int *ui;
331 ssize_t ret;
332
333 ptr = __struct_ptr(sbi, a->struct_type);
334 if (!ptr)
335 return -EINVAL;
336
337 if (!strcmp(a->attr.name, "extension_list")) {
338 const char *name = strim((char *)buf);
339 bool set = true, hot;
340
341 if (!strncmp(name, "[h]", 3))
342 hot = true;
343 else if (!strncmp(name, "[c]", 3))
344 hot = false;
345 else
346 return -EINVAL;
347
348 name += 3;
349
350 if (*name == '!') {
351 name++;
352 set = false;
353 }
354
355 if (!strlen(name) || strlen(name) >= F2FS_EXTENSION_LEN)
356 return -EINVAL;
357
358 down_write(&sbi->sb_lock);
359
360 ret = f2fs_update_extension_list(sbi, name, hot, set);
361 if (ret)
362 goto out;
363
364 ret = f2fs_commit_super(sbi, false);
365 if (ret)
366 f2fs_update_extension_list(sbi, name, hot, !set);
367out:
368 up_write(&sbi->sb_lock);
369 return ret ? ret : count;
370 }
371
372 if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
373 const char *name = strim((char *)buf);
374 struct ckpt_req_control *cprc = &sbi->cprc_info;
375 int class;
376 long data;
377 int ret;
378
379 if (!strncmp(name, "rt,", 3))
380 class = IOPRIO_CLASS_RT;
381 else if (!strncmp(name, "be,", 3))
382 class = IOPRIO_CLASS_BE;
383 else
384 return -EINVAL;
385
386 name += 3;
387 ret = kstrtol(name, 10, &data);
388 if (ret)
389 return ret;
390 if (data >= IOPRIO_NR_LEVELS || data < 0)
391 return -EINVAL;
392
393 cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, data);
394 if (test_opt(sbi, MERGE_CHECKPOINT)) {
395 ret = set_task_ioprio(cprc->f2fs_issue_ckpt,
396 cprc->ckpt_thread_ioprio);
397 if (ret)
398 return ret;
399 }
400
401 return count;
402 }
403
404 ui = (unsigned int *)(ptr + a->offset);
405
406 ret = kstrtoul(skip_spaces(buf), 0, &t);
407 if (ret < 0)
408 return ret;
409#ifdef CONFIG_F2FS_FAULT_INJECTION
410 if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX))
411 return -EINVAL;
412 if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX)
413 return -EINVAL;
414#endif
415 if (a->struct_type == RESERVED_BLOCKS) {
416 spin_lock(&sbi->stat_lock);
417 if (t > (unsigned long)(sbi->user_block_count -
418 F2FS_OPTION(sbi).root_reserved_blocks)) {
419 spin_unlock(&sbi->stat_lock);
420 return -EINVAL;
421 }
422 *ui = t;
423 sbi->current_reserved_blocks = min(sbi->reserved_blocks,
424 sbi->user_block_count - valid_user_blocks(sbi));
425 spin_unlock(&sbi->stat_lock);
426 return count;
427 }
428
429 if (!strcmp(a->attr.name, "discard_granularity")) {
430 if (t == 0 || t > MAX_PLIST_NUM)
431 return -EINVAL;
432 if (!f2fs_block_unit_discard(sbi))
433 return -EINVAL;
434 if (t == *ui)
435 return count;
436 *ui = t;
437 return count;
438 }
439
440 if (!strcmp(a->attr.name, "migration_granularity")) {
441 if (t == 0 || t > sbi->segs_per_sec)
442 return -EINVAL;
443 }
444
445 if (!strcmp(a->attr.name, "trim_sections"))
446 return -EINVAL;
447
448 if (!strcmp(a->attr.name, "gc_urgent")) {
449 if (t == 0) {
450 sbi->gc_mode = GC_NORMAL;
451 } else if (t == 1) {
452 sbi->gc_mode = GC_URGENT_HIGH;
453 if (sbi->gc_thread) {
454 sbi->gc_thread->gc_wake = 1;
455 wake_up_interruptible_all(
456 &sbi->gc_thread->gc_wait_queue_head);
457 wake_up_discard_thread(sbi, true);
458 }
459 } else if (t == 2) {
460 sbi->gc_mode = GC_URGENT_LOW;
461 } else {
462 return -EINVAL;
463 }
464 return count;
465 }
466 if (!strcmp(a->attr.name, "gc_idle")) {
467 if (t == GC_IDLE_CB) {
468 sbi->gc_mode = GC_IDLE_CB;
469 } else if (t == GC_IDLE_GREEDY) {
470 sbi->gc_mode = GC_IDLE_GREEDY;
471 } else if (t == GC_IDLE_AT) {
472 if (!sbi->am.atgc_enabled)
473 return -EINVAL;
474 sbi->gc_mode = GC_AT;
475 } else {
476 sbi->gc_mode = GC_NORMAL;
477 }
478 return count;
479 }
480
481#ifdef CONFIG_F2FS_IOSTAT
482 if (!strcmp(a->attr.name, "iostat_enable")) {
483 sbi->iostat_enable = !!t;
484 if (!sbi->iostat_enable)
485 f2fs_reset_iostat(sbi);
486 return count;
487 }
488
489 if (!strcmp(a->attr.name, "iostat_period_ms")) {
490 if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)
491 return -EINVAL;
492 spin_lock(&sbi->iostat_lock);
493 sbi->iostat_period_ms = (unsigned int)t;
494 spin_unlock(&sbi->iostat_lock);
495 return count;
496 }
497#endif
498
499#ifdef CONFIG_F2FS_FS_COMPRESSION
500 if (!strcmp(a->attr.name, "compr_written_block") ||
501 !strcmp(a->attr.name, "compr_saved_block")) {
502 if (t != 0)
503 return -EINVAL;
504 sbi->compr_written_block = 0;
505 sbi->compr_saved_block = 0;
506 return count;
507 }
508
509 if (!strcmp(a->attr.name, "compr_new_inode")) {
510 if (t != 0)
511 return -EINVAL;
512 sbi->compr_new_inode = 0;
513 return count;
514 }
515#endif
516
517 if (!strcmp(a->attr.name, "atgc_candidate_ratio")) {
518 if (t > 100)
519 return -EINVAL;
520 sbi->am.candidate_ratio = t;
521 return count;
522 }
523
524 if (!strcmp(a->attr.name, "atgc_age_weight")) {
525 if (t > 100)
526 return -EINVAL;
527 sbi->am.age_weight = t;
528 return count;
529 }
530
531 if (!strcmp(a->attr.name, "gc_segment_mode")) {
532 if (t < MAX_GC_MODE)
533 sbi->gc_segment_mode = t;
534 else
535 return -EINVAL;
536 return count;
537 }
538
539 if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
540 if (t != 0)
541 return -EINVAL;
542 sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0;
543 return count;
544 }
545
546 if (!strcmp(a->attr.name, "seq_file_ra_mul")) {
547 if (t >= MIN_RA_MUL && t <= MAX_RA_MUL)
548 sbi->seq_file_ra_mul = t;
549 else
550 return -EINVAL;
551 return count;
552 }
553
554 *ui = (unsigned int)t;
555
556 return count;
557}
558
559static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
560 struct f2fs_sb_info *sbi,
561 const char *buf, size_t count)
562{
563 ssize_t ret;
564 bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") ||
565 a->struct_type == GC_THREAD);
566
567 if (gc_entry) {
568 if (!down_read_trylock(&sbi->sb->s_umount))
569 return -EAGAIN;
570 }
571 ret = __sbi_store(a, sbi, buf, count);
572 if (gc_entry)
573 up_read(&sbi->sb->s_umount);
574
575 return ret;
576}
577
578static ssize_t f2fs_attr_show(struct kobject *kobj,
579 struct attribute *attr, char *buf)
580{
581 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
582 s_kobj);
583 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
584
585 return a->show ? a->show(a, sbi, buf) : 0;
586}
587
588static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr,
589 const char *buf, size_t len)
590{
591 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
592 s_kobj);
593 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
594
595 return a->store ? a->store(a, sbi, buf, len) : 0;
596}
597
598static void f2fs_sb_release(struct kobject *kobj)
599{
600 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
601 s_kobj);
602 complete(&sbi->s_kobj_unregister);
603}
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623static ssize_t f2fs_feature_show(struct f2fs_attr *a,
624 struct f2fs_sb_info *sbi, char *buf)
625{
626 return sprintf(buf, "supported\n");
627}
628
629#define F2FS_FEATURE_RO_ATTR(_name) \
630static struct f2fs_attr f2fs_attr_##_name = { \
631 .attr = {.name = __stringify(_name), .mode = 0444 }, \
632 .show = f2fs_feature_show, \
633}
634
635static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
636 struct f2fs_sb_info *sbi, char *buf)
637{
638 if (F2FS_HAS_FEATURE(sbi, a->id))
639 return sprintf(buf, "supported\n");
640 return sprintf(buf, "unsupported\n");
641}
642
643#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \
644static struct f2fs_attr f2fs_attr_sb_##_name = { \
645 .attr = {.name = __stringify(_name), .mode = 0444 }, \
646 .show = f2fs_sb_feature_show, \
647 .id = F2FS_FEATURE_##_feat, \
648}
649
650#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
651static struct f2fs_attr f2fs_attr_##_name = { \
652 .attr = {.name = __stringify(_name), .mode = _mode }, \
653 .show = _show, \
654 .store = _store, \
655 .struct_type = _struct_type, \
656 .offset = _offset \
657}
658
659#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \
660 F2FS_ATTR_OFFSET(struct_type, name, 0644, \
661 f2fs_sbi_show, f2fs_sbi_store, \
662 offsetof(struct struct_name, elname))
663
664#define F2FS_GENERAL_RO_ATTR(name) \
665static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
666
667#define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
668static struct f2fs_attr f2fs_attr_##_name = { \
669 .attr = {.name = __stringify(_name), .mode = 0444 }, \
670 .show = f2fs_sbi_show, \
671 .struct_type = _struct_type, \
672 .offset = offsetof(struct _struct_name, _elname), \
673}
674
675F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
676 urgent_sleep_time);
677F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
678F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
679F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
680F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
681F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
682F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
683F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
684F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
685F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
686F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
687F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
688F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
689F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
690F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_seq_blocks, min_seq_blocks);
691F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
692F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections);
693F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
694F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
695F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
696F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
697F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, migration_granularity, migration_granularity);
698F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
699F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
700F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
701F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, discard_idle_interval,
702 interval_time[DISCARD_TIME]);
703F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle_interval, interval_time[GC_TIME]);
704F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info,
705 umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
706#ifdef CONFIG_F2FS_IOSTAT
707F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
708F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms);
709#endif
710F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
711F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_io_bytes, max_io_bytes);
712F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
713F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
714#ifdef CONFIG_F2FS_FAULT_INJECTION
715F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
716F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
717#endif
718F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
719F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag);
720F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio);
721F2FS_GENERAL_RO_ATTR(dirty_segments);
722F2FS_GENERAL_RO_ATTR(free_segments);
723F2FS_GENERAL_RO_ATTR(ovp_segments);
724F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
725F2FS_GENERAL_RO_ATTR(features);
726F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
727F2FS_GENERAL_RO_ATTR(unusable);
728F2FS_GENERAL_RO_ATTR(encoding);
729F2FS_GENERAL_RO_ATTR(mounted_time_sec);
730F2FS_GENERAL_RO_ATTR(main_blkaddr);
731#ifdef CONFIG_F2FS_STAT_FS
732F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count);
733F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count);
734F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_foreground_calls, call_count);
735F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_background_calls, bg_gc);
736F2FS_GENERAL_RO_ATTR(moved_blocks_background);
737F2FS_GENERAL_RO_ATTR(moved_blocks_foreground);
738F2FS_GENERAL_RO_ATTR(avg_vblocks);
739#endif
740
741#ifdef CONFIG_FS_ENCRYPTION
742F2FS_FEATURE_RO_ATTR(encryption);
743F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2);
744#ifdef CONFIG_UNICODE
745F2FS_FEATURE_RO_ATTR(encrypted_casefold);
746#endif
747#endif
748#ifdef CONFIG_BLK_DEV_ZONED
749F2FS_FEATURE_RO_ATTR(block_zoned);
750#endif
751F2FS_FEATURE_RO_ATTR(atomic_write);
752F2FS_FEATURE_RO_ATTR(extra_attr);
753F2FS_FEATURE_RO_ATTR(project_quota);
754F2FS_FEATURE_RO_ATTR(inode_checksum);
755F2FS_FEATURE_RO_ATTR(flexible_inline_xattr);
756F2FS_FEATURE_RO_ATTR(quota_ino);
757F2FS_FEATURE_RO_ATTR(inode_crtime);
758F2FS_FEATURE_RO_ATTR(lost_found);
759#ifdef CONFIG_FS_VERITY
760F2FS_FEATURE_RO_ATTR(verity);
761#endif
762F2FS_FEATURE_RO_ATTR(sb_checksum);
763#ifdef CONFIG_UNICODE
764F2FS_FEATURE_RO_ATTR(casefold);
765#endif
766F2FS_FEATURE_RO_ATTR(readonly);
767#ifdef CONFIG_F2FS_FS_COMPRESSION
768F2FS_FEATURE_RO_ATTR(compression);
769F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
770F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
771F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
772#endif
773F2FS_FEATURE_RO_ATTR(pin_file);
774
775
776F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio);
777F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count);
778F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight);
779F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold);
780
781F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, seq_file_ra_mul, seq_file_ra_mul);
782F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode);
783F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs);
784
785#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
786static struct attribute *f2fs_attrs[] = {
787 ATTR_LIST(gc_urgent_sleep_time),
788 ATTR_LIST(gc_min_sleep_time),
789 ATTR_LIST(gc_max_sleep_time),
790 ATTR_LIST(gc_no_gc_sleep_time),
791 ATTR_LIST(gc_idle),
792 ATTR_LIST(gc_urgent),
793 ATTR_LIST(reclaim_segments),
794 ATTR_LIST(main_blkaddr),
795 ATTR_LIST(max_small_discards),
796 ATTR_LIST(discard_granularity),
797 ATTR_LIST(batched_trim_sections),
798 ATTR_LIST(ipu_policy),
799 ATTR_LIST(min_ipu_util),
800 ATTR_LIST(min_fsync_blocks),
801 ATTR_LIST(min_seq_blocks),
802 ATTR_LIST(min_hot_blocks),
803 ATTR_LIST(min_ssr_sections),
804 ATTR_LIST(max_victim_search),
805 ATTR_LIST(migration_granularity),
806 ATTR_LIST(dir_level),
807 ATTR_LIST(ram_thresh),
808 ATTR_LIST(ra_nid_pages),
809 ATTR_LIST(dirty_nats_ratio),
810 ATTR_LIST(cp_interval),
811 ATTR_LIST(idle_interval),
812 ATTR_LIST(discard_idle_interval),
813 ATTR_LIST(gc_idle_interval),
814 ATTR_LIST(umount_discard_timeout),
815#ifdef CONFIG_F2FS_IOSTAT
816 ATTR_LIST(iostat_enable),
817 ATTR_LIST(iostat_period_ms),
818#endif
819 ATTR_LIST(readdir_ra),
820 ATTR_LIST(max_io_bytes),
821 ATTR_LIST(gc_pin_file_thresh),
822 ATTR_LIST(extension_list),
823#ifdef CONFIG_F2FS_FAULT_INJECTION
824 ATTR_LIST(inject_rate),
825 ATTR_LIST(inject_type),
826#endif
827 ATTR_LIST(data_io_flag),
828 ATTR_LIST(node_io_flag),
829 ATTR_LIST(ckpt_thread_ioprio),
830 ATTR_LIST(dirty_segments),
831 ATTR_LIST(free_segments),
832 ATTR_LIST(ovp_segments),
833 ATTR_LIST(unusable),
834 ATTR_LIST(lifetime_write_kbytes),
835 ATTR_LIST(features),
836 ATTR_LIST(reserved_blocks),
837 ATTR_LIST(current_reserved_blocks),
838 ATTR_LIST(encoding),
839 ATTR_LIST(mounted_time_sec),
840#ifdef CONFIG_F2FS_STAT_FS
841 ATTR_LIST(cp_foreground_calls),
842 ATTR_LIST(cp_background_calls),
843 ATTR_LIST(gc_foreground_calls),
844 ATTR_LIST(gc_background_calls),
845 ATTR_LIST(moved_blocks_foreground),
846 ATTR_LIST(moved_blocks_background),
847 ATTR_LIST(avg_vblocks),
848#endif
849#ifdef CONFIG_F2FS_FS_COMPRESSION
850 ATTR_LIST(compr_written_block),
851 ATTR_LIST(compr_saved_block),
852 ATTR_LIST(compr_new_inode),
853#endif
854
855 ATTR_LIST(atgc_candidate_ratio),
856 ATTR_LIST(atgc_candidate_count),
857 ATTR_LIST(atgc_age_weight),
858 ATTR_LIST(atgc_age_threshold),
859 ATTR_LIST(seq_file_ra_mul),
860 ATTR_LIST(gc_segment_mode),
861 ATTR_LIST(gc_reclaimed_segments),
862 NULL,
863};
864ATTRIBUTE_GROUPS(f2fs);
865
866static struct attribute *f2fs_feat_attrs[] = {
867#ifdef CONFIG_FS_ENCRYPTION
868 ATTR_LIST(encryption),
869 ATTR_LIST(test_dummy_encryption_v2),
870#ifdef CONFIG_UNICODE
871 ATTR_LIST(encrypted_casefold),
872#endif
873#endif
874#ifdef CONFIG_BLK_DEV_ZONED
875 ATTR_LIST(block_zoned),
876#endif
877 ATTR_LIST(atomic_write),
878 ATTR_LIST(extra_attr),
879 ATTR_LIST(project_quota),
880 ATTR_LIST(inode_checksum),
881 ATTR_LIST(flexible_inline_xattr),
882 ATTR_LIST(quota_ino),
883 ATTR_LIST(inode_crtime),
884 ATTR_LIST(lost_found),
885#ifdef CONFIG_FS_VERITY
886 ATTR_LIST(verity),
887#endif
888 ATTR_LIST(sb_checksum),
889#ifdef CONFIG_UNICODE
890 ATTR_LIST(casefold),
891#endif
892 ATTR_LIST(readonly),
893#ifdef CONFIG_F2FS_FS_COMPRESSION
894 ATTR_LIST(compression),
895#endif
896 ATTR_LIST(pin_file),
897 NULL,
898};
899ATTRIBUTE_GROUPS(f2fs_feat);
900
901F2FS_GENERAL_RO_ATTR(sb_status);
902static struct attribute *f2fs_stat_attrs[] = {
903 ATTR_LIST(sb_status),
904 NULL,
905};
906ATTRIBUTE_GROUPS(f2fs_stat);
907
908F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT);
909F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED);
910F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR);
911F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA);
912F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM);
913F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
914F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO);
915F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME);
916F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND);
917F2FS_SB_FEATURE_RO_ATTR(verity, VERITY);
918F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM);
919F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);
920F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);
921F2FS_SB_FEATURE_RO_ATTR(readonly, RO);
922
923static struct attribute *f2fs_sb_feat_attrs[] = {
924 ATTR_LIST(sb_encryption),
925 ATTR_LIST(sb_block_zoned),
926 ATTR_LIST(sb_extra_attr),
927 ATTR_LIST(sb_project_quota),
928 ATTR_LIST(sb_inode_checksum),
929 ATTR_LIST(sb_flexible_inline_xattr),
930 ATTR_LIST(sb_quota_ino),
931 ATTR_LIST(sb_inode_crtime),
932 ATTR_LIST(sb_lost_found),
933 ATTR_LIST(sb_verity),
934 ATTR_LIST(sb_sb_checksum),
935 ATTR_LIST(sb_casefold),
936 ATTR_LIST(sb_compression),
937 ATTR_LIST(sb_readonly),
938 NULL,
939};
940ATTRIBUTE_GROUPS(f2fs_sb_feat);
941
942static const struct sysfs_ops f2fs_attr_ops = {
943 .show = f2fs_attr_show,
944 .store = f2fs_attr_store,
945};
946
947static struct kobj_type f2fs_sb_ktype = {
948 .default_groups = f2fs_groups,
949 .sysfs_ops = &f2fs_attr_ops,
950 .release = f2fs_sb_release,
951};
952
953static struct kobj_type f2fs_ktype = {
954 .sysfs_ops = &f2fs_attr_ops,
955};
956
957static struct kset f2fs_kset = {
958 .kobj = {.ktype = &f2fs_ktype},
959};
960
961static struct kobj_type f2fs_feat_ktype = {
962 .default_groups = f2fs_feat_groups,
963 .sysfs_ops = &f2fs_attr_ops,
964};
965
966static struct kobject f2fs_feat = {
967 .kset = &f2fs_kset,
968};
969
970static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
971 struct attribute *attr, char *buf)
972{
973 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
974 s_stat_kobj);
975 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
976
977 return a->show ? a->show(a, sbi, buf) : 0;
978}
979
980static ssize_t f2fs_stat_attr_store(struct kobject *kobj, struct attribute *attr,
981 const char *buf, size_t len)
982{
983 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
984 s_stat_kobj);
985 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
986
987 return a->store ? a->store(a, sbi, buf, len) : 0;
988}
989
990static void f2fs_stat_kobj_release(struct kobject *kobj)
991{
992 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
993 s_stat_kobj);
994 complete(&sbi->s_stat_kobj_unregister);
995}
996
997static const struct sysfs_ops f2fs_stat_attr_ops = {
998 .show = f2fs_stat_attr_show,
999 .store = f2fs_stat_attr_store,
1000};
1001
1002static struct kobj_type f2fs_stat_ktype = {
1003 .default_groups = f2fs_stat_groups,
1004 .sysfs_ops = &f2fs_stat_attr_ops,
1005 .release = f2fs_stat_kobj_release,
1006};
1007
1008static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj,
1009 struct attribute *attr, char *buf)
1010{
1011 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1012 s_feature_list_kobj);
1013 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1014
1015 return a->show ? a->show(a, sbi, buf) : 0;
1016}
1017
1018static void f2fs_feature_list_kobj_release(struct kobject *kobj)
1019{
1020 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1021 s_feature_list_kobj);
1022 complete(&sbi->s_feature_list_kobj_unregister);
1023}
1024
1025static const struct sysfs_ops f2fs_feature_list_attr_ops = {
1026 .show = f2fs_sb_feat_attr_show,
1027};
1028
1029static struct kobj_type f2fs_feature_list_ktype = {
1030 .default_groups = f2fs_sb_feat_groups,
1031 .sysfs_ops = &f2fs_feature_list_attr_ops,
1032 .release = f2fs_feature_list_kobj_release,
1033};
1034
1035static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
1036 void *offset)
1037{
1038 struct super_block *sb = seq->private;
1039 struct f2fs_sb_info *sbi = F2FS_SB(sb);
1040 unsigned int total_segs =
1041 le32_to_cpu(sbi->raw_super->segment_count_main);
1042 int i;
1043
1044 seq_puts(seq, "format: segment_type|valid_blocks\n"
1045 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
1046
1047 for (i = 0; i < total_segs; i++) {
1048 struct seg_entry *se = get_seg_entry(sbi, i);
1049
1050 if ((i % 10) == 0)
1051 seq_printf(seq, "%-10d", i);
1052 seq_printf(seq, "%d|%-3u", se->type, se->valid_blocks);
1053 if ((i % 10) == 9 || i == (total_segs - 1))
1054 seq_putc(seq, '\n');
1055 else
1056 seq_putc(seq, ' ');
1057 }
1058
1059 return 0;
1060}
1061
1062static int __maybe_unused segment_bits_seq_show(struct seq_file *seq,
1063 void *offset)
1064{
1065 struct super_block *sb = seq->private;
1066 struct f2fs_sb_info *sbi = F2FS_SB(sb);
1067 unsigned int total_segs =
1068 le32_to_cpu(sbi->raw_super->segment_count_main);
1069 int i, j;
1070
1071 seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n"
1072 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
1073
1074 for (i = 0; i < total_segs; i++) {
1075 struct seg_entry *se = get_seg_entry(sbi, i);
1076
1077 seq_printf(seq, "%-10d", i);
1078 seq_printf(seq, "%d|%-3u|", se->type, se->valid_blocks);
1079 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)
1080 seq_printf(seq, " %.2x", se->cur_valid_map[j]);
1081 seq_putc(seq, '\n');
1082 }
1083 return 0;
1084}
1085
1086static int __maybe_unused victim_bits_seq_show(struct seq_file *seq,
1087 void *offset)
1088{
1089 struct super_block *sb = seq->private;
1090 struct f2fs_sb_info *sbi = F2FS_SB(sb);
1091 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
1092 int i;
1093
1094 seq_puts(seq, "format: victim_secmap bitmaps\n");
1095
1096 for (i = 0; i < MAIN_SECS(sbi); i++) {
1097 if ((i % 10) == 0)
1098 seq_printf(seq, "%-10d", i);
1099 seq_printf(seq, "%d", test_bit(i, dirty_i->victim_secmap) ? 1 : 0);
1100 if ((i % 10) == 9 || i == (MAIN_SECS(sbi) - 1))
1101 seq_putc(seq, '\n');
1102 else
1103 seq_putc(seq, ' ');
1104 }
1105 return 0;
1106}
1107
1108int __init f2fs_init_sysfs(void)
1109{
1110 int ret;
1111
1112 kobject_set_name(&f2fs_kset.kobj, "f2fs");
1113 f2fs_kset.kobj.parent = fs_kobj;
1114 ret = kset_register(&f2fs_kset);
1115 if (ret)
1116 return ret;
1117
1118 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,
1119 NULL, "features");
1120 if (ret) {
1121 kobject_put(&f2fs_feat);
1122 kset_unregister(&f2fs_kset);
1123 } else {
1124 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
1125 }
1126 return ret;
1127}
1128
1129void f2fs_exit_sysfs(void)
1130{
1131 kobject_put(&f2fs_feat);
1132 kset_unregister(&f2fs_kset);
1133 remove_proc_entry("fs/f2fs", NULL);
1134 f2fs_proc_root = NULL;
1135}
1136
1137int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
1138{
1139 struct super_block *sb = sbi->sb;
1140 int err;
1141
1142 sbi->s_kobj.kset = &f2fs_kset;
1143 init_completion(&sbi->s_kobj_unregister);
1144 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
1145 "%s", sb->s_id);
1146 if (err)
1147 goto put_sb_kobj;
1148
1149 sbi->s_stat_kobj.kset = &f2fs_kset;
1150 init_completion(&sbi->s_stat_kobj_unregister);
1151 err = kobject_init_and_add(&sbi->s_stat_kobj, &f2fs_stat_ktype,
1152 &sbi->s_kobj, "stat");
1153 if (err)
1154 goto put_stat_kobj;
1155
1156 sbi->s_feature_list_kobj.kset = &f2fs_kset;
1157 init_completion(&sbi->s_feature_list_kobj_unregister);
1158 err = kobject_init_and_add(&sbi->s_feature_list_kobj,
1159 &f2fs_feature_list_ktype,
1160 &sbi->s_kobj, "feature_list");
1161 if (err)
1162 goto put_feature_list_kobj;
1163
1164 if (f2fs_proc_root)
1165 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
1166
1167 if (sbi->s_proc) {
1168 proc_create_single_data("segment_info", 0444, sbi->s_proc,
1169 segment_info_seq_show, sb);
1170 proc_create_single_data("segment_bits", 0444, sbi->s_proc,
1171 segment_bits_seq_show, sb);
1172#ifdef CONFIG_F2FS_IOSTAT
1173 proc_create_single_data("iostat_info", 0444, sbi->s_proc,
1174 iostat_info_seq_show, sb);
1175#endif
1176 proc_create_single_data("victim_bits", 0444, sbi->s_proc,
1177 victim_bits_seq_show, sb);
1178 }
1179 return 0;
1180put_feature_list_kobj:
1181 kobject_put(&sbi->s_feature_list_kobj);
1182 wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1183put_stat_kobj:
1184 kobject_put(&sbi->s_stat_kobj);
1185 wait_for_completion(&sbi->s_stat_kobj_unregister);
1186put_sb_kobj:
1187 kobject_put(&sbi->s_kobj);
1188 wait_for_completion(&sbi->s_kobj_unregister);
1189 return err;
1190}
1191
1192void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
1193{
1194 if (sbi->s_proc) {
1195#ifdef CONFIG_F2FS_IOSTAT
1196 remove_proc_entry("iostat_info", sbi->s_proc);
1197#endif
1198 remove_proc_entry("segment_info", sbi->s_proc);
1199 remove_proc_entry("segment_bits", sbi->s_proc);
1200 remove_proc_entry("victim_bits", sbi->s_proc);
1201 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
1202 }
1203
1204 kobject_del(&sbi->s_stat_kobj);
1205 kobject_put(&sbi->s_stat_kobj);
1206 wait_for_completion(&sbi->s_stat_kobj_unregister);
1207 kobject_del(&sbi->s_feature_list_kobj);
1208 kobject_put(&sbi->s_feature_list_kobj);
1209 wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1210
1211 kobject_del(&sbi->s_kobj);
1212 kobject_put(&sbi->s_kobj);
1213 wait_for_completion(&sbi->s_kobj_unregister);
1214}
1215