hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
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,42 @@
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;
469
+ } else if (t == 3) {
470
+ sbi->gc_mode = GC_URGENT_MID;
471
+ if (sbi->gc_thread) {
472
+ sbi->gc_thread->gc_wake = 1;
473
+ wake_up_interruptible_all(
474
+ &sbi->gc_thread->gc_wait_queue_head);
475
+ }
363476 } else {
364
- sbi->gc_mode = GC_NORMAL;
477
+ return -EINVAL;
365478 }
366479 return count;
367480 }
368481 if (!strcmp(a->attr.name, "gc_idle")) {
369
- if (t == GC_IDLE_CB)
482
+ if (t == GC_IDLE_CB) {
370483 sbi->gc_mode = GC_IDLE_CB;
371
- else if (t == GC_IDLE_GREEDY)
484
+ } else if (t == GC_IDLE_GREEDY) {
372485 sbi->gc_mode = GC_IDLE_GREEDY;
373
- else
486
+ } else if (t == GC_IDLE_AT) {
487
+ if (!sbi->am.atgc_enabled)
488
+ return -EINVAL;
489
+ sbi->gc_mode = GC_IDLE_AT;
490
+ } else {
374491 sbi->gc_mode = GC_NORMAL;
492
+ }
375493 return count;
376494 }
377495
....@@ -385,9 +503,83 @@
385503 if (!strcmp(a->attr.name, "iostat_period_ms")) {
386504 if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)
387505 return -EINVAL;
388
- spin_lock(&sbi->iostat_lock);
506
+ spin_lock_irq(&sbi->iostat_lock);
389507 sbi->iostat_period_ms = (unsigned int)t;
390
- spin_unlock(&sbi->iostat_lock);
508
+ spin_unlock_irq(&sbi->iostat_lock);
509
+ return count;
510
+ }
511
+
512
+#ifdef CONFIG_F2FS_FS_COMPRESSION
513
+ if (!strcmp(a->attr.name, "compr_written_block") ||
514
+ !strcmp(a->attr.name, "compr_saved_block")) {
515
+ if (t != 0)
516
+ return -EINVAL;
517
+ sbi->compr_written_block = 0;
518
+ sbi->compr_saved_block = 0;
519
+ return count;
520
+ }
521
+
522
+ if (!strcmp(a->attr.name, "compr_new_inode")) {
523
+ if (t != 0)
524
+ return -EINVAL;
525
+ sbi->compr_new_inode = 0;
526
+ return count;
527
+ }
528
+#endif
529
+
530
+ if (!strcmp(a->attr.name, "atgc_candidate_ratio")) {
531
+ if (t > 100)
532
+ return -EINVAL;
533
+ sbi->am.candidate_ratio = t;
534
+ return count;
535
+ }
536
+
537
+ if (!strcmp(a->attr.name, "atgc_age_weight")) {
538
+ if (t > 100)
539
+ return -EINVAL;
540
+ sbi->am.age_weight = t;
541
+ return count;
542
+ }
543
+
544
+ if (!strcmp(a->attr.name, "gc_segment_mode")) {
545
+ if (t < MAX_GC_MODE)
546
+ sbi->gc_segment_mode = t;
547
+ else
548
+ return -EINVAL;
549
+ return count;
550
+ }
551
+
552
+ if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
553
+ if (t != 0)
554
+ return -EINVAL;
555
+ sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0;
556
+ return count;
557
+ }
558
+
559
+ if (!strcmp(a->attr.name, "hot_data_age_threshold")) {
560
+ if (t == 0 || t >= sbi->warm_data_age_threshold)
561
+ return -EINVAL;
562
+ if (t == *ui)
563
+ return count;
564
+ *ui = (unsigned int)t;
565
+ return count;
566
+ }
567
+
568
+ if (!strcmp(a->attr.name, "warm_data_age_threshold")) {
569
+ if (t == 0 || t <= sbi->hot_data_age_threshold)
570
+ return -EINVAL;
571
+ if (t == *ui)
572
+ return count;
573
+ *ui = (unsigned int)t;
574
+ return count;
575
+ }
576
+
577
+ if (!strcmp(a->attr.name, "last_age_weight")) {
578
+ if (t > 100)
579
+ return -EINVAL;
580
+ if (t == *ui)
581
+ return count;
582
+ *ui = (unsigned int)t;
391583 return count;
392584 }
393585
....@@ -442,46 +634,49 @@
442634 complete(&sbi->s_kobj_unregister);
443635 }
444636
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
-
637
+/*
638
+ * Note that there are three feature list entries:
639
+ * 1) /sys/fs/f2fs/features
640
+ * : shows runtime features supported by in-kernel f2fs along with Kconfig.
641
+ * - ref. F2FS_FEATURE_RO_ATTR()
642
+ *
643
+ * 2) /sys/fs/f2fs/$s_id/features <deprecated>
644
+ * : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This
645
+ * won't add new feature anymore, and thus, users should check entries in 3)
646
+ * instead of this 2).
647
+ *
648
+ * 3) /sys/fs/f2fs/$s_id/feature_list
649
+ * : shows on-disk features enabled by mkfs.f2fs per instance, which follows
650
+ * sysfs entry rule where each entry should expose single value.
651
+ * This list covers old feature list provided by 2) and beyond. Therefore,
652
+ * please add new on-disk feature in this list only.
653
+ * - ref. F2FS_SB_FEATURE_RO_ATTR()
654
+ */
463655 static ssize_t f2fs_feature_show(struct f2fs_attr *a,
464656 struct f2fs_sb_info *sbi, char *buf)
465657 {
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:
658
+ return sprintf(buf, "supported\n");
659
+}
660
+
661
+#define F2FS_FEATURE_RO_ATTR(_name) \
662
+static struct f2fs_attr f2fs_attr_##_name = { \
663
+ .attr = {.name = __stringify(_name), .mode = 0444 }, \
664
+ .show = f2fs_feature_show, \
665
+}
666
+
667
+static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
668
+ struct f2fs_sb_info *sbi, char *buf)
669
+{
670
+ if (F2FS_HAS_FEATURE(sbi, a->id))
482671 return sprintf(buf, "supported\n");
483
- }
484
- return 0;
672
+ return sprintf(buf, "unsupported\n");
673
+}
674
+
675
+#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \
676
+static struct f2fs_attr f2fs_attr_sb_##_name = { \
677
+ .attr = {.name = __stringify(_name), .mode = 0444 }, \
678
+ .show = f2fs_sb_feature_show, \
679
+ .id = F2FS_FEATURE_##_feat, \
485680 }
486681
487682 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \
....@@ -501,13 +696,6 @@
501696 #define F2FS_GENERAL_RO_ATTR(name) \
502697 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
503698
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
-
511699 #define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
512700 static struct f2fs_attr f2fs_attr_##_name = { \
513701 .attr = {.name = __stringify(_name), .mode = 0444 }, \
....@@ -524,7 +712,6 @@
524712 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
525713 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
526714 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);
528715 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
529716 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
530717 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
....@@ -551,6 +738,7 @@
551738 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
552739 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms);
553740 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
741
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_io_bytes, max_io_bytes);
554742 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
555743 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
556744 #ifdef CONFIG_F2FS_FAULT_INJECTION
....@@ -559,14 +747,18 @@
559747 #endif
560748 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
561749 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag);
750
+F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio);
562751 F2FS_GENERAL_RO_ATTR(dirty_segments);
563752 F2FS_GENERAL_RO_ATTR(free_segments);
753
+F2FS_GENERAL_RO_ATTR(ovp_segments);
564754 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
565755 F2FS_GENERAL_RO_ATTR(features);
566756 F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
567757 F2FS_GENERAL_RO_ATTR(unusable);
568758 F2FS_GENERAL_RO_ATTR(encoding);
569759 F2FS_GENERAL_RO_ATTR(mounted_time_sec);
760
+F2FS_GENERAL_RO_ATTR(main_blkaddr);
761
+F2FS_GENERAL_RO_ATTR(pending_discard);
570762 #ifdef CONFIG_F2FS_STAT_FS
571763 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count);
572764 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count);
....@@ -578,28 +770,52 @@
578770 #endif
579771
580772 #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);
773
+F2FS_FEATURE_RO_ATTR(encryption);
774
+F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2);
775
+#ifdef CONFIG_UNICODE
776
+F2FS_FEATURE_RO_ATTR(encrypted_casefold);
583777 #endif
778
+#endif /* CONFIG_FS_ENCRYPTION */
584779 #ifdef CONFIG_BLK_DEV_ZONED
585
-F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED);
780
+F2FS_FEATURE_RO_ATTR(block_zoned);
586781 #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);
782
+F2FS_FEATURE_RO_ATTR(atomic_write);
783
+F2FS_FEATURE_RO_ATTR(extra_attr);
784
+F2FS_FEATURE_RO_ATTR(project_quota);
785
+F2FS_FEATURE_RO_ATTR(inode_checksum);
786
+F2FS_FEATURE_RO_ATTR(flexible_inline_xattr);
787
+F2FS_FEATURE_RO_ATTR(quota_ino);
788
+F2FS_FEATURE_RO_ATTR(inode_crtime);
789
+F2FS_FEATURE_RO_ATTR(lost_found);
595790 #ifdef CONFIG_FS_VERITY
596
-F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
791
+F2FS_FEATURE_RO_ATTR(verity);
597792 #endif
598
-F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
599
-F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD);
793
+F2FS_FEATURE_RO_ATTR(sb_checksum);
794
+#ifdef CONFIG_UNICODE
795
+F2FS_FEATURE_RO_ATTR(casefold);
796
+#endif
797
+F2FS_FEATURE_RO_ATTR(readonly);
600798 #ifdef CONFIG_F2FS_FS_COMPRESSION
601
-F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION);
799
+F2FS_FEATURE_RO_ATTR(compression);
800
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
801
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
802
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
602803 #endif
804
+F2FS_FEATURE_RO_ATTR(pin_file);
805
+
806
+/* For ATGC */
807
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio);
808
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count);
809
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight);
810
+F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold);
811
+
812
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode);
813
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs);
814
+
815
+/* For block age extent cache */
816
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, hot_data_age_threshold, hot_data_age_threshold);
817
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, warm_data_age_threshold, warm_data_age_threshold);
818
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, last_age_weight, last_age_weight);
603819
604820 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
605821 static struct attribute *f2fs_attrs[] = {
....@@ -613,6 +829,7 @@
613829 ATTR_LIST(main_blkaddr),
614830 ATTR_LIST(max_small_discards),
615831 ATTR_LIST(discard_granularity),
832
+ ATTR_LIST(pending_discard),
616833 ATTR_LIST(batched_trim_sections),
617834 ATTR_LIST(ipu_policy),
618835 ATTR_LIST(min_ipu_util),
....@@ -634,6 +851,7 @@
634851 ATTR_LIST(iostat_enable),
635852 ATTR_LIST(iostat_period_ms),
636853 ATTR_LIST(readdir_ra),
854
+ ATTR_LIST(max_io_bytes),
637855 ATTR_LIST(gc_pin_file_thresh),
638856 ATTR_LIST(extension_list),
639857 #ifdef CONFIG_F2FS_FAULT_INJECTION
....@@ -642,8 +860,10 @@
642860 #endif
643861 ATTR_LIST(data_io_flag),
644862 ATTR_LIST(node_io_flag),
863
+ ATTR_LIST(ckpt_thread_ioprio),
645864 ATTR_LIST(dirty_segments),
646865 ATTR_LIST(free_segments),
866
+ ATTR_LIST(ovp_segments),
647867 ATTR_LIST(unusable),
648868 ATTR_LIST(lifetime_write_kbytes),
649869 ATTR_LIST(features),
....@@ -660,14 +880,33 @@
660880 ATTR_LIST(moved_blocks_background),
661881 ATTR_LIST(avg_vblocks),
662882 #endif
883
+#ifdef CONFIG_F2FS_FS_COMPRESSION
884
+ ATTR_LIST(compr_written_block),
885
+ ATTR_LIST(compr_saved_block),
886
+ ATTR_LIST(compr_new_inode),
887
+#endif
888
+ /* For ATGC */
889
+ ATTR_LIST(atgc_candidate_ratio),
890
+ ATTR_LIST(atgc_candidate_count),
891
+ ATTR_LIST(atgc_age_weight),
892
+ ATTR_LIST(atgc_age_threshold),
893
+ ATTR_LIST(gc_segment_mode),
894
+ ATTR_LIST(gc_reclaimed_segments),
895
+ ATTR_LIST(hot_data_age_threshold),
896
+ ATTR_LIST(warm_data_age_threshold),
897
+ ATTR_LIST(last_age_weight),
663898 NULL,
664899 };
900
+ATTRIBUTE_GROUPS(f2fs);
665901
666902 static struct attribute *f2fs_feat_attrs[] = {
667903 #ifdef CONFIG_FS_ENCRYPTION
668904 ATTR_LIST(encryption),
669905 ATTR_LIST(test_dummy_encryption_v2),
906
+#ifdef CONFIG_UNICODE
907
+ ATTR_LIST(encrypted_casefold),
670908 #endif
909
+#endif /* CONFIG_FS_ENCRYPTION */
671910 #ifdef CONFIG_BLK_DEV_ZONED
672911 ATTR_LIST(block_zoned),
673912 #endif
....@@ -683,12 +922,58 @@
683922 ATTR_LIST(verity),
684923 #endif
685924 ATTR_LIST(sb_checksum),
925
+#ifdef CONFIG_UNICODE
686926 ATTR_LIST(casefold),
927
+#endif
928
+ ATTR_LIST(readonly),
687929 #ifdef CONFIG_F2FS_FS_COMPRESSION
688930 ATTR_LIST(compression),
689931 #endif
932
+ ATTR_LIST(pin_file),
690933 NULL,
691934 };
935
+ATTRIBUTE_GROUPS(f2fs_feat);
936
+
937
+F2FS_GENERAL_RO_ATTR(sb_status);
938
+static struct attribute *f2fs_stat_attrs[] = {
939
+ ATTR_LIST(sb_status),
940
+ NULL,
941
+};
942
+ATTRIBUTE_GROUPS(f2fs_stat);
943
+
944
+F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT);
945
+F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED);
946
+F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR);
947
+F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA);
948
+F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM);
949
+F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
950
+F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO);
951
+F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME);
952
+F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND);
953
+F2FS_SB_FEATURE_RO_ATTR(verity, VERITY);
954
+F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM);
955
+F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD);
956
+F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION);
957
+F2FS_SB_FEATURE_RO_ATTR(readonly, RO);
958
+
959
+static struct attribute *f2fs_sb_feat_attrs[] = {
960
+ ATTR_LIST(sb_encryption),
961
+ ATTR_LIST(sb_block_zoned),
962
+ ATTR_LIST(sb_extra_attr),
963
+ ATTR_LIST(sb_project_quota),
964
+ ATTR_LIST(sb_inode_checksum),
965
+ ATTR_LIST(sb_flexible_inline_xattr),
966
+ ATTR_LIST(sb_quota_ino),
967
+ ATTR_LIST(sb_inode_crtime),
968
+ ATTR_LIST(sb_lost_found),
969
+ ATTR_LIST(sb_verity),
970
+ ATTR_LIST(sb_sb_checksum),
971
+ ATTR_LIST(sb_casefold),
972
+ ATTR_LIST(sb_compression),
973
+ ATTR_LIST(sb_readonly),
974
+ NULL,
975
+};
976
+ATTRIBUTE_GROUPS(f2fs_sb_feat);
692977
693978 static const struct sysfs_ops f2fs_attr_ops = {
694979 .show = f2fs_attr_show,
....@@ -696,7 +981,7 @@
696981 };
697982
698983 static struct kobj_type f2fs_sb_ktype = {
699
- .default_attrs = f2fs_attrs,
984
+ .default_groups = f2fs_groups,
700985 .sysfs_ops = &f2fs_attr_ops,
701986 .release = f2fs_sb_release,
702987 };
....@@ -706,16 +991,81 @@
706991 };
707992
708993 static struct kset f2fs_kset = {
709
- .kobj = {.ktype = &f2fs_ktype},
994
+ .kobj = {.ktype = &f2fs_ktype},
710995 };
711996
712997 static struct kobj_type f2fs_feat_ktype = {
713
- .default_attrs = f2fs_feat_attrs,
998
+ .default_groups = f2fs_feat_groups,
714999 .sysfs_ops = &f2fs_attr_ops,
7151000 };
7161001
7171002 static struct kobject f2fs_feat = {
7181003 .kset = &f2fs_kset,
1004
+};
1005
+
1006
+static ssize_t f2fs_stat_attr_show(struct kobject *kobj,
1007
+ struct attribute *attr, char *buf)
1008
+{
1009
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1010
+ s_stat_kobj);
1011
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1012
+
1013
+ return a->show ? a->show(a, sbi, buf) : 0;
1014
+}
1015
+
1016
+static ssize_t f2fs_stat_attr_store(struct kobject *kobj, struct attribute *attr,
1017
+ const char *buf, size_t len)
1018
+{
1019
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1020
+ s_stat_kobj);
1021
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1022
+
1023
+ return a->store ? a->store(a, sbi, buf, len) : 0;
1024
+}
1025
+
1026
+static void f2fs_stat_kobj_release(struct kobject *kobj)
1027
+{
1028
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1029
+ s_stat_kobj);
1030
+ complete(&sbi->s_stat_kobj_unregister);
1031
+}
1032
+
1033
+static const struct sysfs_ops f2fs_stat_attr_ops = {
1034
+ .show = f2fs_stat_attr_show,
1035
+ .store = f2fs_stat_attr_store,
1036
+};
1037
+
1038
+static struct kobj_type f2fs_stat_ktype = {
1039
+ .default_groups = f2fs_stat_groups,
1040
+ .sysfs_ops = &f2fs_stat_attr_ops,
1041
+ .release = f2fs_stat_kobj_release,
1042
+};
1043
+
1044
+static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj,
1045
+ struct attribute *attr, char *buf)
1046
+{
1047
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1048
+ s_feature_list_kobj);
1049
+ struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr);
1050
+
1051
+ return a->show ? a->show(a, sbi, buf) : 0;
1052
+}
1053
+
1054
+static void f2fs_feature_list_kobj_release(struct kobject *kobj)
1055
+{
1056
+ struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info,
1057
+ s_feature_list_kobj);
1058
+ complete(&sbi->s_feature_list_kobj_unregister);
1059
+}
1060
+
1061
+static const struct sysfs_ops f2fs_feature_list_attr_ops = {
1062
+ .show = f2fs_sb_feat_attr_show,
1063
+};
1064
+
1065
+static struct kobj_type f2fs_feature_list_ktype = {
1066
+ .default_groups = f2fs_sb_feat_groups,
1067
+ .sysfs_ops = &f2fs_feature_list_attr_ops,
1068
+ .release = f2fs_feature_list_kobj_release,
7191069 };
7201070
7211071 static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
....@@ -924,11 +1274,23 @@
9241274 init_completion(&sbi->s_kobj_unregister);
9251275 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
9261276 "%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
- }
1277
+ if (err)
1278
+ goto put_sb_kobj;
1279
+
1280
+ sbi->s_stat_kobj.kset = &f2fs_kset;
1281
+ init_completion(&sbi->s_stat_kobj_unregister);
1282
+ err = kobject_init_and_add(&sbi->s_stat_kobj, &f2fs_stat_ktype,
1283
+ &sbi->s_kobj, "stat");
1284
+ if (err)
1285
+ goto put_stat_kobj;
1286
+
1287
+ sbi->s_feature_list_kobj.kset = &f2fs_kset;
1288
+ init_completion(&sbi->s_feature_list_kobj_unregister);
1289
+ err = kobject_init_and_add(&sbi->s_feature_list_kobj,
1290
+ &f2fs_feature_list_ktype,
1291
+ &sbi->s_kobj, "feature_list");
1292
+ if (err)
1293
+ goto put_feature_list_kobj;
9321294
9331295 if (f2fs_proc_root)
9341296 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
....@@ -944,6 +1306,16 @@
9441306 victim_bits_seq_show, sb);
9451307 }
9461308 return 0;
1309
+put_feature_list_kobj:
1310
+ kobject_put(&sbi->s_feature_list_kobj);
1311
+ wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1312
+put_stat_kobj:
1313
+ kobject_put(&sbi->s_stat_kobj);
1314
+ wait_for_completion(&sbi->s_stat_kobj_unregister);
1315
+put_sb_kobj:
1316
+ kobject_put(&sbi->s_kobj);
1317
+ wait_for_completion(&sbi->s_kobj_unregister);
1318
+ return err;
9471319 }
9481320
9491321 void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
....@@ -955,6 +1327,14 @@
9551327 remove_proc_entry("victim_bits", sbi->s_proc);
9561328 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
9571329 }
1330
+
1331
+ kobject_del(&sbi->s_stat_kobj);
1332
+ kobject_put(&sbi->s_stat_kobj);
1333
+ wait_for_completion(&sbi->s_stat_kobj_unregister);
1334
+ kobject_del(&sbi->s_feature_list_kobj);
1335
+ kobject_put(&sbi->s_feature_list_kobj);
1336
+ wait_for_completion(&sbi->s_feature_list_kobj_unregister);
1337
+
9581338 kobject_del(&sbi->s_kobj);
9591339 kobject_put(&sbi->s_kobj);
9601340 wait_for_completion(&sbi->s_kobj_unregister);