linux/fs/f2fs/sysfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * f2fs sysfs interface
   4 *
   5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   6 *             http://www.samsung.com/
   7 * Copyright (c) 2017 Chao Yu <chao@kernel.org>
   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/* Sysfs support for f2fs */
  26enum {
  27        GC_THREAD,      /* struct f2fs_gc_thread */
  28        SM_INFO,        /* struct f2fs_sm_info */
  29        DCC_INFO,       /* struct discard_cmd_control */
  30        NM_INFO,        /* struct f2fs_nm_info */
  31        F2FS_SBI,       /* struct f2fs_sb_info */
  32#ifdef CONFIG_F2FS_STAT_FS
  33        STAT_INFO,      /* struct f2fs_stat_info */
  34#endif
  35#ifdef CONFIG_F2FS_FAULT_INJECTION
  36        FAULT_INFO_RATE,        /* struct f2fs_fault_info */
  37        FAULT_INFO_TYPE,        /* struct f2fs_fault_info */
  38#endif
  39        RESERVED_BLOCKS,        /* struct f2fs_sb_info */
  40        CPRC_INFO,      /* struct ckpt_req_control */
  41        ATGC_INFO,      /* struct atgc_management */
  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 * Note that there are three feature list entries:
 607 * 1) /sys/fs/f2fs/features
 608 *   : shows runtime features supported by in-kernel f2fs along with Kconfig.
 609 *     - ref. F2FS_FEATURE_RO_ATTR()
 610 *
 611 * 2) /sys/fs/f2fs/$s_id/features <deprecated>
 612 *   : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This
 613 *     won't add new feature anymore, and thus, users should check entries in 3)
 614 *     instead of this 2).
 615 *
 616 * 3) /sys/fs/f2fs/$s_id/feature_list
 617 *   : shows on-disk features enabled by mkfs.f2fs per instance, which follows
 618 *     sysfs entry rule where each entry should expose single value.
 619 *     This list covers old feature list provided by 2) and beyond. Therefore,
 620 *     please add new on-disk feature in this list only.
 621 *     - ref. F2FS_SB_FEATURE_RO_ATTR()
 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 /* CONFIG_FS_ENCRYPTION */
 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/* For ATGC */
 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        /* For ATGC */
 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 /* CONFIG_FS_ENCRYPTION */
 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