forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/fs/f2fs/sysfs.c
....@@ -11,6 +11,8 @@
1111 #include <linux/f2fs_fs.h>
1212 #include <linux/seq_file.h>
1313 #include <linux/unicode.h>
14
+#include <linux/ioprio.h>
15
+#include <linux/sysfs.h>
1416
1517 #include "f2fs.h"
1618 #include "segment.h"
....@@ -27,13 +29,15 @@
2729 NM_INFO, /* struct f2fs_nm_info */
2830 F2FS_SBI, /* struct f2fs_sb_info */
2931 #ifdef CONFIG_F2FS_STAT_FS
30
- STAT_INFO, /* struct f2fs_stat_info */
32
+ STAT_INFO, /* struct f2fs_stat_info */
3133 #endif
3234 #ifdef CONFIG_F2FS_FAULT_INJECTION
3335 FAULT_INFO_RATE, /* struct f2fs_fault_info */
3436 FAULT_INFO_TYPE, /* struct f2fs_fault_info */
3537 #endif
3638 RESERVED_BLOCKS, /* struct f2fs_sb_info */
39
+ CPRC_INFO, /* struct ckpt_req_control */
40
+ ATGC_INFO, /* struct atgc_management */
3741 };
3842
3943 struct f2fs_attr {
....@@ -70,6 +74,10 @@
7074 else if (struct_type == STAT_INFO)
7175 return (unsigned char *)F2FS_STAT(sbi);
7276 #endif
77
+ else if (struct_type == CPRC_INFO)
78
+ return (unsigned char *)&sbi->cprc_info;
79
+ else if (struct_type == ATGC_INFO)
80
+ return (unsigned char *)&sbi->am;
7381 return NULL;
7482 }
7583
....@@ -87,27 +95,41 @@
8795 (unsigned long long)(free_segments(sbi)));
8896 }
8997
98
+static ssize_t ovp_segments_show(struct f2fs_attr *a,
99
+ struct f2fs_sb_info *sbi, char *buf)
100
+{
101
+ return sprintf(buf, "%llu\n",
102
+ (unsigned long long)(overprovision_segments(sbi)));
103
+}
104
+
90105 static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
91106 struct f2fs_sb_info *sbi, char *buf)
92107 {
93
- struct super_block *sb = sbi->sb;
94
-
95
- if (!sb->s_bdev->bd_part)
96
- return sprintf(buf, "0\n");
97
-
98108 return sprintf(buf, "%llu\n",
99109 (unsigned long long)(sbi->kbytes_written +
100
- BD_PART_WRITTEN(sbi)));
110
+ ((f2fs_get_sectors_written(sbi) -
111
+ sbi->sectors_written_start) >> 1)));
112
+}
113
+
114
+static ssize_t sb_status_show(struct f2fs_attr *a,
115
+ struct f2fs_sb_info *sbi, char *buf)
116
+{
117
+ return sprintf(buf, "%lx\n", sbi->s_flag);
118
+}
119
+
120
+static ssize_t pending_discard_show(struct f2fs_attr *a,
121
+ struct f2fs_sb_info *sbi, char *buf)
122
+{
123
+ if (!SM_I(sbi)->dcc_info)
124
+ return -EINVAL;
125
+ return sprintf(buf, "%llu\n", (unsigned long long)atomic_read(
126
+ &SM_I(sbi)->dcc_info->discard_cmd_cnt));
101127 }
102128
103129 static ssize_t features_show(struct f2fs_attr *a,
104130 struct f2fs_sb_info *sbi, char *buf)
105131 {
106
- struct super_block *sb = sbi->sb;
107132 int len = 0;
108
-
109
- if (!sb->s_bdev->bd_part)
110
- return sprintf(buf, "0\n");
111133
112134 if (f2fs_sb_has_encrypt(sbi))
113135 len += scnprintf(buf, PAGE_SIZE - len, "%s",
....@@ -145,6 +167,9 @@
145167 if (f2fs_sb_has_casefold(sbi))
146168 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
147169 len ? ", " : "", "casefold");
170
+ if (f2fs_sb_has_readonly(sbi))
171
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
172
+ len ? ", " : "", "readonly");
148173 if (f2fs_sb_has_compression(sbi))
149174 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s",
150175 len ? ", " : "", "compression");
....@@ -225,6 +250,13 @@
225250 }
226251 #endif
227252
253
+static ssize_t main_blkaddr_show(struct f2fs_attr *a,
254
+ struct f2fs_sb_info *sbi, char *buf)
255
+{
256
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
257
+ (unsigned long long)MAIN_BLKADDR(sbi));
258
+}
259
+
228260 static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
229261 struct f2fs_sb_info *sbi, char *buf)
230262 {
....@@ -254,6 +286,42 @@
254286 len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n",
255287 extlist[i]);
256288 return len;
289
+ }
290
+
291
+ if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
292
+ struct ckpt_req_control *cprc = &sbi->cprc_info;
293
+ int len = 0;
294
+ int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio);
295
+ int data = IOPRIO_PRIO_DATA(cprc->ckpt_thread_ioprio);
296
+
297
+ if (class == IOPRIO_CLASS_RT)
298
+ len += scnprintf(buf + len, PAGE_SIZE - len, "rt,");
299
+ else if (class == IOPRIO_CLASS_BE)
300
+ len += scnprintf(buf + len, PAGE_SIZE - len, "be,");
301
+ else
302
+ return -EINVAL;
303
+
304
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d\n", data);
305
+ return len;
306
+ }
307
+
308
+#ifdef CONFIG_F2FS_FS_COMPRESSION
309
+ if (!strcmp(a->attr.name, "compr_written_block"))
310
+ return sysfs_emit(buf, "%llu\n", sbi->compr_written_block);
311
+
312
+ if (!strcmp(a->attr.name, "compr_saved_block"))
313
+ return sysfs_emit(buf, "%llu\n", sbi->compr_saved_block);
314
+
315
+ if (!strcmp(a->attr.name, "compr_new_inode"))
316
+ return sysfs_emit(buf, "%u\n", sbi->compr_new_inode);
317
+#endif
318
+
319
+ if (!strcmp(a->attr.name, "gc_segment_mode"))
320
+ return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode);
321
+
322
+ if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
323
+ return sysfs_emit(buf, "%u\n",
324
+ sbi->gc_reclaimed_segs[sbi->gc_segment_mode]);
257325 }
258326
259327 ui = (unsigned int *)(ptr + a->offset);
....@@ -295,7 +363,7 @@
295363 if (strlen(name) >= F2FS_EXTENSION_LEN)
296364 return -EINVAL;
297365
298
- down_write(&sbi->sb_lock);
366
+ f2fs_down_write(&sbi->sb_lock);
299367
300368 ret = f2fs_update_extension_list(sbi, name, hot, set);
301369 if (ret)
....@@ -305,8 +373,40 @@
305373 if (ret)
306374 f2fs_update_extension_list(sbi, name, hot, !set);
307375 out:
308
- up_write(&sbi->sb_lock);
376
+ f2fs_up_write(&sbi->sb_lock);
309377 return ret ? ret : count;
378
+ }
379
+
380
+ if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
381
+ const char *name = strim((char *)buf);
382
+ struct ckpt_req_control *cprc = &sbi->cprc_info;
383
+ int class;
384
+ long data;
385
+ int ret;
386
+
387
+ if (!strncmp(name, "rt,", 3))
388
+ class = IOPRIO_CLASS_RT;
389
+ else if (!strncmp(name, "be,", 3))
390
+ class = IOPRIO_CLASS_BE;
391
+ else
392
+ return -EINVAL;
393
+
394
+ name += 3;
395
+ ret = kstrtol(name, 10, &data);
396
+ if (ret)
397
+ return ret;
398
+ if (data >= IOPRIO_BE_NR || data < 0)
399
+ return -EINVAL;
400
+
401
+ cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, data);
402
+ if (test_opt(sbi, MERGE_CHECKPOINT)) {
403
+ ret = set_task_ioprio(cprc->f2fs_issue_ckpt,
404
+ cprc->ckpt_thread_ioprio);
405
+ if (ret)
406
+ return ret;
407
+ }
408
+
409
+ return count;
310410 }
311411
312412 ui = (unsigned int *)(ptr + a->offset);
....@@ -323,7 +423,9 @@
323423 if (a->struct_type == RESERVED_BLOCKS) {
324424 spin_lock(&sbi->stat_lock);
325425 if (t > (unsigned long)(sbi->user_block_count -
326
- F2FS_OPTION(sbi).root_reserved_blocks)) {
426
+ F2FS_OPTION(sbi).root_reserved_blocks -
427
+ sbi->blocks_per_seg *
428
+ SM_I(sbi)->additional_reserved_segments)) {
327429 spin_unlock(&sbi->stat_lock);
328430 return -EINVAL;
329431 }
....@@ -352,26 +454,35 @@
352454 return -EINVAL;
353455
354456 if (!strcmp(a->attr.name, "gc_urgent")) {
355
- if (t >= 1) {
356
- sbi->gc_mode = GC_URGENT;
457
+ if (t == 0) {
458
+ sbi->gc_mode = GC_NORMAL;
459
+ } else if (t == 1) {
460
+ sbi->gc_mode = GC_URGENT_HIGH;
357461 if (sbi->gc_thread) {
358462 sbi->gc_thread->gc_wake = 1;
359463 wake_up_interruptible_all(
360464 &sbi->gc_thread->gc_wait_queue_head);
361465 wake_up_discard_thread(sbi, true);
362466 }
467
+ } else if (t == 2) {
468
+ sbi->gc_mode = GC_URGENT_LOW;
363469 } else {
364
- sbi->gc_mode = GC_NORMAL;
470
+ return -EINVAL;
365471 }
366472 return count;
367473 }
368474 if (!strcmp(a->attr.name, "gc_idle")) {
369
- if (t == GC_IDLE_CB)
475
+ if (t == GC_IDLE_CB) {
370476 sbi->gc_mode = GC_IDLE_CB;
371
- else if (t == GC_IDLE_GREEDY)
477
+ } else if (t == GC_IDLE_GREEDY) {
372478 sbi->gc_mode = GC_IDLE_GREEDY;
373
- else
479
+ } else if (t == GC_IDLE_AT) {
480
+ if (!sbi->am.atgc_enabled)
481
+ return -EINVAL;
482
+ sbi->gc_mode = GC_IDLE_AT;
483
+ } else {
374484 sbi->gc_mode = GC_NORMAL;
485
+ }
375486 return count;
376487 }
377488
....@@ -388,6 +499,80 @@
388499 spin_lock(&sbi->iostat_lock);
389500 sbi->iostat_period_ms = (unsigned int)t;
390501 spin_unlock(&sbi->iostat_lock);
502
+ return count;
503
+ }
504
+
505
+#ifdef CONFIG_F2FS_FS_COMPRESSION
506
+ if (!strcmp(a->attr.name, "compr_written_block") ||
507
+ !strcmp(a->attr.name, "compr_saved_block")) {
508
+ if (t != 0)
509
+ return -EINVAL;
510
+ sbi->compr_written_block = 0;
511
+ sbi->compr_saved_block = 0;
512
+ return count;
513
+ }
514
+
515
+ if (!strcmp(a->attr.name, "compr_new_inode")) {
516
+ if (t != 0)
517
+ return -EINVAL;
518
+ sbi->compr_new_inode = 0;
519
+ return count;
520
+ }
521
+#endif
522
+
523
+ if (!strcmp(a->attr.name, "atgc_candidate_ratio")) {
524
+ if (t > 100)
525
+ return -EINVAL;
526
+ sbi->am.candidate_ratio = t;
527
+ return count;
528
+ }
529
+
530
+ if (!strcmp(a->attr.name, "atgc_age_weight")) {
531
+ if (t > 100)
532
+ return -EINVAL;
533
+ sbi->am.age_weight = t;
534
+ return count;
535
+ }
536
+
537
+ if (!strcmp(a->attr.name, "gc_segment_mode")) {
538
+ if (t < MAX_GC_MODE)
539
+ sbi->gc_segment_mode = t;
540
+ else
541
+ return -EINVAL;
542
+ return count;
543
+ }
544
+
545
+ if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
546
+ if (t != 0)
547
+ return -EINVAL;
548
+ sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0;
549
+ return count;
550
+ }
551
+
552
+ if (!strcmp(a->attr.name, "hot_data_age_threshold")) {
553
+ if (t == 0 || t >= sbi->warm_data_age_threshold)
554
+ return -EINVAL;
555
+ if (t == *ui)
556
+ return count;
557
+ *ui = (unsigned int)t;
558
+ return count;
559
+ }
560
+
561
+ if (!strcmp(a->attr.name, "warm_data_age_threshold")) {
562
+ if (t == 0 || t <= sbi->hot_data_age_threshold)
563
+ return -EINVAL;
564
+ if (t == *ui)
565
+ return count;
566
+ *ui = (unsigned int)t;
567
+ return count;
568
+ }
569
+
570
+ if (!strcmp(a->attr.name, "last_age_weight")) {
571
+ if (t > 100)
572
+ return -EINVAL;
573
+ if (t == *ui)
574
+ return count;
575
+ *ui = (unsigned int)t;
391576 return count;
392577 }
393578
....@@ -442,46 +627,49 @@
442627 complete(&sbi->s_kobj_unregister);
443628 }
444629
445
-enum feat_id {
446
- FEAT_CRYPTO = 0,
447
- FEAT_BLKZONED,
448
- FEAT_ATOMIC_WRITE,
449
- FEAT_EXTRA_ATTR,
450
- FEAT_PROJECT_QUOTA,
451
- FEAT_INODE_CHECKSUM,
452
- FEAT_FLEXIBLE_INLINE_XATTR,
453
- FEAT_QUOTA_INO,
454
- FEAT_INODE_CRTIME,
455
- FEAT_LOST_FOUND,
456
- FEAT_VERITY,
457
- FEAT_SB_CHECKSUM,
458
- FEAT_CASEFOLD,
459
- FEAT_COMPRESSION,
460
- FEAT_TEST_DUMMY_ENCRYPTION_V2,
461
-};
462
-
630
+/*
631
+ * Note that there are three feature list entries:
632
+ * 1) /sys/fs/f2fs/features
633
+ * : shows runtime features supported by in-kernel f2fs along with Kconfig.
634
+ * - ref. F2FS_FEATURE_RO_ATTR()
635
+ *
636
+ * 2) /sys/fs/f2fs/$s_id/features <deprecated>
637
+ * : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This
638
+ * won't add new feature anymore, and thus, users should check entries in 3)
639
+ * instead of this 2).
640
+ *
641
+ * 3) /sys/fs/f2fs/$s_id/feature_list
642
+ * : shows on-disk features enabled by mkfs.f2fs per instance, which follows
643
+ * sysfs entry rule where each entry should expose single value.
644
+ * This list covers old feature list provided by 2) and beyond. Therefore,
645
+ * please add new on-disk feature in this list only.
646
+ * - ref. F2FS_SB_FEATURE_RO_ATTR()
647
+ */
463648 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
464649 struct f2fs_sb_info *sbi, char *buf)
465650 {
466
- switch (a->id) {
467
- case FEAT_CRYPTO:
468
- case FEAT_BLKZONED:
469
- case FEAT_ATOMIC_WRITE:
470
- case FEAT_EXTRA_ATTR:
471
- case FEAT_PROJECT_QUOTA:
472
- case FEAT_INODE_CHECKSUM:
473
- case FEAT_FLEXIBLE_INLINE_XATTR:
474
- case FEAT_QUOTA_INO:
475
- case FEAT_INODE_CRTIME:
476
- case FEAT_LOST_FOUND:
477
- case FEAT_VERITY:
478
- case FEAT_SB_CHECKSUM:
479
- case FEAT_CASEFOLD:
480
- case FEAT_COMPRESSION:
481
- case FEAT_TEST_DUMMY_ENCRYPTION_V2:
651
+ return sprintf(buf, "supported\n");
652
+}
653
+
654
+#define F2FS_FEATURE_RO_ATTR(_name) \
655
+static struct f2fs_attr f2fs_attr_##_name = { \
656
+ .attr = {.name = __stringify(_name), .mode = 0444 }, \
657
+ .show = f2fs_feature_show, \
658
+}
659
+
660
+static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
661
+ struct f2fs_sb_info *sbi, char *buf)
662
+{
663
+ if (F2FS_HAS_FEATURE(sbi, a->id))
482664 return sprintf(buf, "supported\n");
483
- }
484
- return 0;
665
+ return sprintf(buf, "unsupported\n");
666
+}
667
+
668
+#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \
669
+static struct f2fs_attr f2fs_attr_sb_##_name = { \
670
+ .attr = {.name = __stringify(_name), .mode = 0444 }, \
671
+ .show = f2fs_sb_feature_show, \
672
+ .id = F2FS_FEATURE_##_feat, \
485673 }
486674
487675 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
....@@ -501,13 +689,6 @@
501689 #define F2FS_GENERAL_RO_ATTR(name) \
502690 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
503691
504
-#define F2FS_FEATURE_RO_ATTR(_name, _id) \
505
-static struct f2fs_attr f2fs_attr_##_name = { \
506
- .attr = {.name = __stringify(_name), .mode = 0444 }, \
507
- .show = f2fs_feature_show, \
508
- .id = _id, \
509
-}
510
-
511692 #define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
512693 static struct f2fs_attr f2fs_attr_##_name = { \
513694 .attr = {.name = __stringify(_name), .mode = 0444 }, \
....@@ -524,7 +705,6 @@
524705 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
525706 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
526707 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
527
-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, main_blkaddr, main_blkaddr);
528708 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
529709 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
530710 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
....@@ -551,6 +731,7 @@
551731 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
552732 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms);
553733 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
734
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_io_bytes, max_io_bytes);
554735 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
555736 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
556737 #ifdef CONFIG_F2FS_FAULT_INJECTION
....@@ -559,14 +740,18 @@
559740 #endif
560741 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
561742 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag);
743
+F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio);
562744 F2FS_GENERAL_RO_ATTR(dirty_segments);
563745 F2FS_GENERAL_RO_ATTR(free_segments);
746
+F2FS_GENERAL_RO_ATTR(ovp_segments);
564747 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
565748 F2FS_GENERAL_RO_ATTR(features);
566749 F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
567750 F2FS_GENERAL_RO_ATTR(unusable);
568751 F2FS_GENERAL_RO_ATTR(encoding);
569752 F2FS_GENERAL_RO_ATTR(mounted_time_sec);
753
+F2FS_GENERAL_RO_ATTR(main_blkaddr);
754
+F2FS_GENERAL_RO_ATTR(pending_discard);
570755 #ifdef CONFIG_F2FS_STAT_FS
571756 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count);
572757 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count);
....@@ -578,28 +763,52 @@
578763 #endif
579764
580765 #ifdef CONFIG_FS_ENCRYPTION
581
-F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
582
-F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2);
766
+F2FS_FEATURE_RO_ATTR(encryption);
767
+F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2);
768
+#ifdef CONFIG_UNICODE
769
+F2FS_FEATURE_RO_ATTR(encrypted_casefold);
583770 #endif
771
+#endif /* CONFIG_FS_ENCRYPTION */
584772 #ifdef CONFIG_BLK_DEV_ZONED
585
-F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED);
773
+F2FS_FEATURE_RO_ATTR(block_zoned);
586774 #endif
587
-F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE);
588
-F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR);
589
-F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA);
590
-F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
591
-F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
592
-F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
593
-F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
594
-F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
775
+F2FS_FEATURE_RO_ATTR(atomic_write);
776
+F2FS_FEATURE_RO_ATTR(extra_attr);
777
+F2FS_FEATURE_RO_ATTR(project_quota);
778
+F2FS_FEATURE_RO_ATTR(inode_checksum);
779
+F2FS_FEATURE_RO_ATTR(flexible_inline_xattr);
780
+F2FS_FEATURE_RO_ATTR(quota_ino);
781
+F2FS_FEATURE_RO_ATTR(inode_crtime);
782
+F2FS_FEATURE_RO_ATTR(lost_found);
595783 #ifdef CONFIG_FS_VERITY
596
-F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
784
+F2FS_FEATURE_RO_ATTR(verity);
597785 #endif
598
-F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
599
-F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD);
786
+F2FS_FEATURE_RO_ATTR(sb_checksum);
787
+#ifdef CONFIG_UNICODE
788
+F2FS_FEATURE_RO_ATTR(casefold);
789
+#endif
790
+F2FS_FEATURE_RO_ATTR(readonly);
600791 #ifdef CONFIG_F2FS_FS_COMPRESSION
601
-F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION);
792
+F2FS_FEATURE_RO_ATTR(compression);
793
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
794
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
795
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
602796 #endif
797
+F2FS_FEATURE_RO_ATTR(pin_file);
798
+
799
+/* For ATGC */
800
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio);
801
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count);
802
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight);
803
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold);
804
+
805
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode);
806
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs);
807
+
808
+/* For block age extent cache */
809
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, hot_data_age_threshold, hot_data_age_threshold);
810
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, warm_data_age_threshold, warm_data_age_threshold);
811
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, last_age_weight, last_age_weight);
603812
604813 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
605814 static struct attribute *f2fs_attrs[] = {
....@@ -613,6 +822,7 @@
613822 ATTR_LIST(main_blkaddr),
614823 ATTR_LIST(max_small_discards),
615824 ATTR_LIST(discard_granularity),
825
+ ATTR_LIST(pending_discard),
616826 ATTR_LIST(batched_trim_sections),
617827 ATTR_LIST(ipu_policy),
618828 ATTR_LIST(min_ipu_util),
....@@ -634,6 +844,7 @@
634844 ATTR_LIST(iostat_enable),
635845 ATTR_LIST(iostat_period_ms),
636846 ATTR_LIST(readdir_ra),
847
+ ATTR_LIST(max_io_bytes),
637848 ATTR_LIST(gc_pin_file_thresh),
638849 ATTR_LIST(extension_list),
639850 #ifdef CONFIG_F2FS_FAULT_INJECTION
....@@ -642,8 +853,10 @@
642853 #endif
643854 ATTR_LIST(data_io_flag),
644855 ATTR_LIST(node_io_flag),
856
+ ATTR_LIST(ckpt_thread_ioprio),
645857 ATTR_LIST(dirty_segments),
646858 ATTR_LIST(free_segments),
859
+ ATTR_LIST(ovp_segments),
647860 ATTR_LIST(unusable),
648861 ATTR_LIST(lifetime_write_kbytes),
649862 ATTR_LIST(features),
....@@ -660,14 +873,33 @@
660873 ATTR_LIST(moved_blocks_background),
661874 ATTR_LIST(avg_vblocks),
662875 #endif
876
+#ifdef CONFIG_F2FS_FS_COMPRESSION
877
+ ATTR_LIST(compr_written_block),
878
+ ATTR_LIST(compr_saved_block),
879
+ ATTR_LIST(compr_new_inode),
880
+#endif
881
+ /* For ATGC */
882
+ ATTR_LIST(atgc_candidate_ratio),
883
+ ATTR_LIST(atgc_candidate_count),
884
+ ATTR_LIST(atgc_age_weight),
885
+ ATTR_LIST(atgc_age_threshold),
886
+ ATTR_LIST(gc_segment_mode),
887
+ ATTR_LIST(gc_reclaimed_segments),
888
+ ATTR_LIST(hot_data_age_threshold),
889
+ ATTR_LIST(warm_data_age_threshold),
890
+ ATTR_LIST(last_age_weight),
663891 NULL,
664892 };
893
+ATTRIBUTE_GROUPS(f2fs);
665894
666895 static struct attribute *f2fs_feat_attrs[] = {
667896 #ifdef CONFIG_FS_ENCRYPTION
668897 ATTR_LIST(encryption),
669898 ATTR_LIST(test_dummy_encryption_v2),
899
+#ifdef CONFIG_UNICODE
900
+ ATTR_LIST(encrypted_casefold),
670901 #endif
902
+#endif /* CONFIG_FS_ENCRYPTION */
671903 #ifdef CONFIG_BLK_DEV_ZONED
672904 ATTR_LIST(block_zoned),
673905 #endif
....@@ -683,12 +915,58 @@
683915 ATTR_LIST(verity),
684916 #endif
685917 ATTR_LIST(sb_checksum),
918
+#ifdef CONFIG_UNICODE
686919 ATTR_LIST(casefold),
920
+#endif
921
+ ATTR_LIST(readonly),
687922 #ifdef CONFIG_F2FS_FS_COMPRESSION
688923 ATTR_LIST(compression),
689924 #endif
925
+ ATTR_LIST(pin_file),
690926 NULL,
691927 };
928
+ATTRIBUTE_GROUPS(f2fs_feat);
929
+
930
+F2FS_GENERAL_RO_ATTR(sb_status);
931
+static struct attribute *f2fs_stat_attrs[] = {
932
+ ATTR_LIST(sb_status),
933
+ NULL,
934
+};
935
+ATTRIBUTE_GROUPS(f2fs_stat);
936
+
937
+F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT);
938
+F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED);
939
+F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR);
940
+F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA);
941
+F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM);
942
+F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
943
+F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO);
944
+F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME);
945
+F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND);
946
+F2FS_SB_FEATURE_RO_ATTR(verity, VERITY);
947
+F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM);
948
+F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);
949
+F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);
950
+F2FS_SB_FEATURE_RO_ATTR(readonly, RO);
951
+
952
+static struct attribute *f2fs_sb_feat_attrs[] = {
953
+ ATTR_LIST(sb_encryption),
954
+ ATTR_LIST(sb_block_zoned),
955
+ ATTR_LIST(sb_extra_attr),
956
+ ATTR_LIST(sb_project_quota),
957
+ ATTR_LIST(sb_inode_checksum),
958
+ ATTR_LIST(sb_flexible_inline_xattr),
959
+ ATTR_LIST(sb_quota_ino),
960
+ ATTR_LIST(sb_inode_crtime),
961
+ ATTR_LIST(sb_lost_found),
962
+ ATTR_LIST(sb_verity),
963
+ ATTR_LIST(sb_sb_checksum),
964
+ ATTR_LIST(sb_casefold),
965
+ ATTR_LIST(sb_compression),
966
+ ATTR_LIST(sb_readonly),
967
+ NULL,
968
+};
969
+ATTRIBUTE_GROUPS(f2fs_sb_feat);
692970
693971 static const struct sysfs_ops f2fs_attr_ops = {
694972 .show = f2fs_attr_show,
....@@ -696,7 +974,7 @@
696974 };
697975
698976 static struct kobj_type f2fs_sb_ktype = {
699
- .default_attrs = f2fs_attrs,
977
+ .default_groups = f2fs_groups,
700978 .sysfs_ops = &f2fs_attr_ops,
701979 .release = f2fs_sb_release,
702980 };
....@@ -706,16 +984,81 @@
706984 };
707985
708986 static struct kset f2fs_kset = {
709
- .kobj = {.ktype = &f2fs_ktype},
987
+ .kobj = {.ktype = &f2fs_ktype},
710988 };
711989
712990 static struct kobj_type f2fs_feat_ktype = {
713
- .default_attrs = f2fs_feat_attrs,
991
+ .default_groups = f2fs_feat_groups,
714992 .sysfs_ops = &f2fs_attr_ops,
715993 };
716994
717995 static struct kobject f2fs_feat = {
718996 .kset = &f2fs_kset,
997
+};
998
+
999
+static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
1000
+ struct attribute *attr, char *buf)
1001
+{
1002
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1003
+ s_stat_kobj);
1004
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1005
+
1006
+ return a->show ? a->show(a, sbi, buf) : 0;
1007
+}
1008
+
1009
+static ssize_t f2fs_stat_attr_store(struct kobject *kobj, struct attribute *attr,
1010
+ const char *buf, size_t len)
1011
+{
1012
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1013
+ s_stat_kobj);
1014
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1015
+
1016
+ return a->store ? a->store(a, sbi, buf, len) : 0;
1017
+}
1018
+
1019
+static void f2fs_stat_kobj_release(struct kobject *kobj)
1020
+{
1021
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1022
+ s_stat_kobj);
1023
+ complete(&sbi->s_stat_kobj_unregister);
1024
+}
1025
+
1026
+static const struct sysfs_ops f2fs_stat_attr_ops = {
1027
+ .show = f2fs_stat_attr_show,
1028
+ .store = f2fs_stat_attr_store,
1029
+};
1030
+
1031
+static struct kobj_type f2fs_stat_ktype = {
1032
+ .default_groups = f2fs_stat_groups,
1033
+ .sysfs_ops = &f2fs_stat_attr_ops,
1034
+ .release = f2fs_stat_kobj_release,
1035
+};
1036
+
1037
+static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj,
1038
+ struct attribute *attr, char *buf)
1039
+{
1040
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1041
+ s_feature_list_kobj);
1042
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1043
+
1044
+ return a->show ? a->show(a, sbi, buf) : 0;
1045
+}
1046
+
1047
+static void f2fs_feature_list_kobj_release(struct kobject *kobj)
1048
+{
1049
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1050
+ s_feature_list_kobj);
1051
+ complete(&sbi->s_feature_list_kobj_unregister);
1052
+}
1053
+
1054
+static const struct sysfs_ops f2fs_feature_list_attr_ops = {
1055
+ .show = f2fs_sb_feat_attr_show,
1056
+};
1057
+
1058
+static struct kobj_type f2fs_feature_list_ktype = {
1059
+ .default_groups = f2fs_sb_feat_groups,
1060
+ .sysfs_ops = &f2fs_feature_list_attr_ops,
1061
+ .release = f2fs_feature_list_kobj_release,
7191062 };
7201063
7211064 static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
....@@ -924,11 +1267,23 @@
9241267 init_completion(&sbi->s_kobj_unregister);
9251268 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
9261269 "%s", sb->s_id);
927
- if (err) {
928
- kobject_put(&sbi->s_kobj);
929
- wait_for_completion(&sbi->s_kobj_unregister);
930
- return err;
931
- }
1270
+ if (err)
1271
+ goto put_sb_kobj;
1272
+
1273
+ sbi->s_stat_kobj.kset = &f2fs_kset;
1274
+ init_completion(&sbi->s_stat_kobj_unregister);
1275
+ err = kobject_init_and_add(&sbi->s_stat_kobj, &f2fs_stat_ktype,
1276
+ &sbi->s_kobj, "stat");
1277
+ if (err)
1278
+ goto put_stat_kobj;
1279
+
1280
+ sbi->s_feature_list_kobj.kset = &f2fs_kset;
1281
+ init_completion(&sbi->s_feature_list_kobj_unregister);
1282
+ err = kobject_init_and_add(&sbi->s_feature_list_kobj,
1283
+ &f2fs_feature_list_ktype,
1284
+ &sbi->s_kobj, "feature_list");
1285
+ if (err)
1286
+ goto put_feature_list_kobj;
9321287
9331288 if (f2fs_proc_root)
9341289 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
....@@ -944,6 +1299,16 @@
9441299 victim_bits_seq_show, sb);
9451300 }
9461301 return 0;
1302
+put_feature_list_kobj:
1303
+ kobject_put(&sbi->s_feature_list_kobj);
1304
+ wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1305
+put_stat_kobj:
1306
+ kobject_put(&sbi->s_stat_kobj);
1307
+ wait_for_completion(&sbi->s_stat_kobj_unregister);
1308
+put_sb_kobj:
1309
+ kobject_put(&sbi->s_kobj);
1310
+ wait_for_completion(&sbi->s_kobj_unregister);
1311
+ return err;
9471312 }
9481313
9491314 void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
....@@ -955,6 +1320,14 @@
9551320 remove_proc_entry("victim_bits", sbi->s_proc);
9561321 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
9571322 }
1323
+
1324
+ kobject_del(&sbi->s_stat_kobj);
1325
+ kobject_put(&sbi->s_stat_kobj);
1326
+ wait_for_completion(&sbi->s_stat_kobj_unregister);
1327
+ kobject_del(&sbi->s_feature_list_kobj);
1328
+ kobject_put(&sbi->s_feature_list_kobj);
1329
+ wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1330
+
9581331 kobject_del(&sbi->s_kobj);
9591332 kobject_put(&sbi->s_kobj);
9601333 wait_for_completion(&sbi->s_kobj_unregister);