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 15#include "f2fs.h" 16#include "segment.h" 17#include "gc.h" 18#include <trace/events/f2fs.h> 19 20static struct proc_dir_entry *f2fs_proc_root; 21 22/* Sysfs support for f2fs */ 23enum { 24 GC_THREAD, /* struct f2fs_gc_thread */ 25 SM_INFO, /* struct f2fs_sm_info */ 26 DCC_INFO, /* struct discard_cmd_control */ 27 NM_INFO, /* struct f2fs_nm_info */ 28 F2FS_SBI, /* struct f2fs_sb_info */ 29#ifdef CONFIG_F2FS_STAT_FS 30 STAT_INFO, /* struct f2fs_stat_info */ 31#endif 32#ifdef CONFIG_F2FS_FAULT_INJECTION 33 FAULT_INFO_RATE, /* struct f2fs_fault_info */ 34 FAULT_INFO_TYPE, /* struct f2fs_fault_info */ 35#endif 36 RESERVED_BLOCKS, /* struct f2fs_sb_info */ 37#ifdef CONFIG_F2FS_GRADING_SSR 38 F2FS_HOT_COLD_PARAMS, /* struct f2fs_hot_cold_params */ 39#endif 40}; 41 42struct f2fs_attr { 43 struct attribute attr; 44 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); 45 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, 46 const char *, size_t); 47 int struct_type; 48 int offset; 49 int id; 50}; 51 52static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 53 struct f2fs_sb_info *sbi, char *buf); 54 55static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) 56{ 57 if (struct_type == GC_THREAD) 58 return (unsigned char *)sbi->gc_thread; 59 else if (struct_type == SM_INFO) 60 return (unsigned char *)SM_I(sbi); 61 else if (struct_type == DCC_INFO) 62 return (unsigned char *)SM_I(sbi)->dcc_info; 63 else if (struct_type == NM_INFO) 64 return (unsigned char *)NM_I(sbi); 65 else if (struct_type == F2FS_SBI || struct_type == RESERVED_BLOCKS) 66 return (unsigned char *)sbi; 67#ifdef CONFIG_F2FS_GRADING_SSR 68 else if (struct_type == F2FS_HOT_COLD_PARAMS) 69 return (unsigned char *)&sbi->hot_cold_params; 70#endif 71#ifdef CONFIG_F2FS_FAULT_INJECTION 72 else if (struct_type == FAULT_INFO_RATE || 73 struct_type == FAULT_INFO_TYPE) 74 return (unsigned char *)&F2FS_OPTION(sbi).fault_info; 75#endif 76#ifdef CONFIG_F2FS_STAT_FS 77 else if (struct_type == STAT_INFO) 78 return (unsigned char *)F2FS_STAT(sbi); 79#endif 80 return NULL; 81} 82 83static ssize_t dirty_segments_show(struct f2fs_attr *a, 84 struct f2fs_sb_info *sbi, char *buf) 85{ 86 return sprintf(buf, "%llu\n", 87 (unsigned long long)(dirty_segments(sbi))); 88} 89 90static ssize_t free_segments_show(struct f2fs_attr *a, 91 struct f2fs_sb_info *sbi, char *buf) 92{ 93 return sprintf(buf, "%llu\n", 94 (unsigned long long)(free_segments(sbi))); 95} 96 97static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, 98 struct f2fs_sb_info *sbi, char *buf) 99{ 100 struct super_block *sb = sbi->sb; 101 102 if (!sb->s_bdev->bd_part) 103 return sprintf(buf, "0\n"); 104 105 return sprintf(buf, "%llu\n", 106 (unsigned long long)(sbi->kbytes_written + 107 BD_PART_WRITTEN(sbi))); 108} 109 110static ssize_t features_show(struct f2fs_attr *a, 111 struct f2fs_sb_info *sbi, char *buf) 112{ 113 struct super_block *sb = sbi->sb; 114 int len = 0; 115 116 if (!sb->s_bdev->bd_part) 117 return sprintf(buf, "0\n"); 118 119 if (f2fs_sb_has_encrypt(sbi)) 120 len += scnprintf(buf, PAGE_SIZE - len, "%s", 121 "encryption"); 122 if (f2fs_sb_has_blkzoned(sbi)) 123 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 124 len ? ", " : "", "blkzoned"); 125 if (f2fs_sb_has_extra_attr(sbi)) 126 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 127 len ? ", " : "", "extra_attr"); 128 if (f2fs_sb_has_project_quota(sbi)) 129 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 130 len ? ", " : "", "projquota"); 131 if (f2fs_sb_has_inode_chksum(sbi)) 132 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 133 len ? ", " : "", "inode_checksum"); 134 if (f2fs_sb_has_flexible_inline_xattr(sbi)) 135 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 136 len ? ", " : "", "flexible_inline_xattr"); 137 if (f2fs_sb_has_quota_ino(sbi)) 138 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 139 len ? ", " : "", "quota_ino"); 140 if (f2fs_sb_has_inode_crtime(sbi)) 141 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 142 len ? ", " : "", "inode_crtime"); 143 if (f2fs_sb_has_lost_found(sbi)) 144 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 145 len ? ", " : "", "lost_found"); 146 if (f2fs_sb_has_verity(sbi)) 147 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 148 len ? ", " : "", "verity"); 149 if (f2fs_sb_has_sb_chksum(sbi)) 150 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 151 len ? ", " : "", "sb_checksum"); 152 if (f2fs_sb_has_casefold(sbi)) 153 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 154 len ? ", " : "", "casefold"); 155 if (f2fs_sb_has_compression(sbi)) 156 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 157 len ? ", " : "", "compression"); 158 len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", 159 len ? ", " : "", "pin_file"); 160 len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); 161 return len; 162} 163 164static ssize_t current_reserved_blocks_show(struct f2fs_attr *a, 165 struct f2fs_sb_info *sbi, char *buf) 166{ 167 return sprintf(buf, "%u\n", sbi->current_reserved_blocks); 168} 169 170static ssize_t unusable_show(struct f2fs_attr *a, 171 struct f2fs_sb_info *sbi, char *buf) 172{ 173 block_t unusable; 174 175 if (test_opt(sbi, DISABLE_CHECKPOINT)) 176 unusable = sbi->unusable_block_count; 177 else 178 unusable = f2fs_get_unusable_blocks(sbi); 179 return sprintf(buf, "%llu\n", (unsigned long long)unusable); 180} 181 182static ssize_t encoding_show(struct f2fs_attr *a, 183 struct f2fs_sb_info *sbi, char *buf) 184{ 185#ifdef CONFIG_UNICODE 186 struct super_block *sb = sbi->sb; 187 188 if (f2fs_sb_has_casefold(sbi)) 189 return snprintf(buf, PAGE_SIZE, "%s (%d.%d.%d)\n", 190 sb->s_encoding->charset, 191 (sb->s_encoding->version >> 16) & 0xff, 192 (sb->s_encoding->version >> 8) & 0xff, 193 sb->s_encoding->version & 0xff); 194#endif 195 return sprintf(buf, "(none)"); 196} 197 198static ssize_t mounted_time_sec_show(struct f2fs_attr *a, 199 struct f2fs_sb_info *sbi, char *buf) 200{ 201 return sprintf(buf, "%llu", SIT_I(sbi)->mounted_time); 202} 203 204#ifdef CONFIG_F2FS_STAT_FS 205static ssize_t moved_blocks_foreground_show(struct f2fs_attr *a, 206 struct f2fs_sb_info *sbi, char *buf) 207{ 208 struct f2fs_stat_info *si = F2FS_STAT(sbi); 209 210 return sprintf(buf, "%llu\n", 211 (unsigned long long)(si->tot_blks - 212 (si->bg_data_blks + si->bg_node_blks))); 213} 214 215static ssize_t moved_blocks_background_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->bg_data_blks + si->bg_node_blks)); 222} 223 224static ssize_t avg_vblocks_show(struct f2fs_attr *a, 225 struct f2fs_sb_info *sbi, char *buf) 226{ 227 struct f2fs_stat_info *si = F2FS_STAT(sbi); 228 229 si->dirty_count = dirty_segments(sbi); 230 f2fs_update_sit_info(sbi); 231 return sprintf(buf, "%llu\n", (unsigned long long)(si->avg_vblocks)); 232} 233#endif 234 235static ssize_t main_blkaddr_show(struct f2fs_attr *a, 236 struct f2fs_sb_info *sbi, char *buf) 237{ 238 return snprintf(buf, PAGE_SIZE, "%llu\n", 239 (unsigned long long)MAIN_BLKADDR(sbi)); 240} 241 242static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 243 struct f2fs_sb_info *sbi, char *buf) 244{ 245 unsigned char *ptr = NULL; 246 unsigned int *ui; 247 248 ptr = __struct_ptr(sbi, a->struct_type); 249 if (!ptr) 250 return -EINVAL; 251 252 if (!strcmp(a->attr.name, "extension_list")) { 253 __u8 (*extlist)[F2FS_EXTENSION_LEN] = 254 sbi->raw_super->extension_list; 255 int cold_count = le32_to_cpu(sbi->raw_super->extension_count); 256 int hot_count = sbi->raw_super->hot_ext_count; 257 int len = 0, i; 258 259 len += scnprintf(buf + len, PAGE_SIZE - len, 260 "cold file extension:\n"); 261 for (i = 0; i < cold_count; i++) 262 len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", 263 extlist[i]); 264 265 len += scnprintf(buf + len, PAGE_SIZE - len, 266 "hot file extension:\n"); 267 for (i = cold_count; i < cold_count + hot_count; i++) 268 len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", 269 extlist[i]); 270 return len; 271 } 272 273 ui = (unsigned int *)(ptr + a->offset); 274 275 return sprintf(buf, "%u\n", *ui); 276} 277 278static ssize_t __sbi_store(struct f2fs_attr *a, 279 struct f2fs_sb_info *sbi, 280 const char *buf, size_t count) 281{ 282 unsigned char *ptr; 283 unsigned long t; 284 unsigned int *ui; 285 ssize_t ret; 286 287 ptr = __struct_ptr(sbi, a->struct_type); 288 if (!ptr) 289 return -EINVAL; 290 291 if (!strcmp(a->attr.name, "extension_list")) { 292 const char *name = strim((char *)buf); 293 bool set = true, hot; 294 295 if (!strncmp(name, "[h]", 3)) 296 hot = true; 297 else if (!strncmp(name, "[c]", 3)) 298 hot = false; 299 else 300 return -EINVAL; 301 302 name += 3; 303 304 if (*name == '!') { 305 name++; 306 set = false; 307 } 308 309 if (strlen(name) >= F2FS_EXTENSION_LEN) 310 return -EINVAL; 311 312 down_write(&sbi->sb_lock); 313 314 ret = f2fs_update_extension_list(sbi, name, hot, set); 315 if (ret) 316 goto out; 317 318 ret = f2fs_commit_super(sbi, false); 319 if (ret) 320 f2fs_update_extension_list(sbi, name, hot, !set); 321out: 322 up_write(&sbi->sb_lock); 323 return ret ? ret : count; 324 } 325 326 ui = (unsigned int *)(ptr + a->offset); 327 328 ret = kstrtoul(skip_spaces(buf), 0, &t); 329 if (ret < 0) 330 return ret; 331#ifdef CONFIG_F2FS_FAULT_INJECTION 332 if (a->struct_type == FAULT_INFO_TYPE) { 333 if (f2fs_build_fault_attr(sbi, 0, t)) 334 return -EINVAL; 335 return count; 336 } 337 if (a->struct_type == FAULT_INFO_RATE) { 338 if (f2fs_build_fault_attr(sbi, t, 0)) 339 return -EINVAL; 340 return count; 341 } 342#endif 343 if (a->struct_type == RESERVED_BLOCKS) { 344 spin_lock(&sbi->stat_lock); 345 if (t > (unsigned long)(sbi->user_block_count - 346 F2FS_OPTION(sbi).root_reserved_blocks - 347 sbi->blocks_per_seg * 348 SM_I(sbi)->additional_reserved_segments)) { 349 spin_unlock(&sbi->stat_lock); 350 return -EINVAL; 351 } 352 *ui = t; 353 sbi->current_reserved_blocks = min(sbi->reserved_blocks, 354 sbi->user_block_count - valid_user_blocks(sbi)); 355 spin_unlock(&sbi->stat_lock); 356 return count; 357 } 358 359 if (!strcmp(a->attr.name, "discard_granularity")) { 360 if (t == 0 || t > MAX_PLIST_NUM) 361 return -EINVAL; 362 if (t == *ui) 363 return count; 364 *ui = t; 365 return count; 366 } 367 368 if (!strcmp(a->attr.name, "migration_granularity")) { 369 if (t == 0 || t > sbi->segs_per_sec) 370 return -EINVAL; 371 } 372 373 if (!strcmp(a->attr.name, "trim_sections")) 374 return -EINVAL; 375 376 if (!strcmp(a->attr.name, "gc_urgent")) { 377 if (t == 0) { 378 sbi->gc_mode = GC_NORMAL; 379 } else if (t == 1) { 380 sbi->gc_mode = GC_URGENT_HIGH; 381 if (sbi->gc_thread) { 382 sbi->gc_thread->gc_wake = 1; 383 wake_up_interruptible_all( 384 &sbi->gc_thread->gc_wait_queue_head); 385 wake_up_discard_thread(sbi, true); 386 } 387 } else if (t == 2) { 388 sbi->gc_mode = GC_URGENT_LOW; 389 } else { 390 return -EINVAL; 391 } 392 return count; 393 } 394 if (!strcmp(a->attr.name, "gc_idle")) { 395 if (t == GC_IDLE_CB) { 396 sbi->gc_mode = GC_IDLE_CB; 397 } else if (t == GC_IDLE_GREEDY) { 398 sbi->gc_mode = GC_IDLE_GREEDY; 399 } else if (t == GC_IDLE_AT) { 400 if (!sbi->am.atgc_enabled) 401 return -EINVAL; 402 sbi->gc_mode = GC_IDLE_AT; 403 } else { 404 sbi->gc_mode = GC_NORMAL; 405 } 406 return count; 407 } 408 409 if (!strcmp(a->attr.name, "iostat_enable")) { 410 sbi->iostat_enable = !!t; 411 if (!sbi->iostat_enable) 412 f2fs_reset_iostat(sbi); 413 return count; 414 } 415 416 if (!strcmp(a->attr.name, "iostat_period_ms")) { 417 if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS) 418 return -EINVAL; 419 spin_lock_irq(&sbi->iostat_lock); 420 sbi->iostat_period_ms = (unsigned int)t; 421 spin_unlock_irq(&sbi->iostat_lock); 422 return count; 423 } 424 425 *ui = (unsigned int)t; 426 427 return count; 428} 429 430static ssize_t f2fs_sbi_store(struct f2fs_attr *a, 431 struct f2fs_sb_info *sbi, 432 const char *buf, size_t count) 433{ 434 ssize_t ret; 435 bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") || 436 a->struct_type == GC_THREAD); 437 438 if (gc_entry) { 439 if (!down_read_trylock(&sbi->sb->s_umount)) 440 return -EAGAIN; 441 } 442 ret = __sbi_store(a, sbi, buf, count); 443 if (gc_entry) 444 up_read(&sbi->sb->s_umount); 445 446 return ret; 447} 448 449static ssize_t f2fs_attr_show(struct kobject *kobj, 450 struct attribute *attr, char *buf) 451{ 452 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 453 s_kobj); 454 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 455 456 return a->show ? a->show(a, sbi, buf) : 0; 457} 458 459static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr, 460 const char *buf, size_t len) 461{ 462 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 463 s_kobj); 464 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 465 466 return a->store ? a->store(a, sbi, buf, len) : 0; 467} 468 469static void f2fs_sb_release(struct kobject *kobj) 470{ 471 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 472 s_kobj); 473 complete(&sbi->s_kobj_unregister); 474} 475 476enum feat_id { 477 FEAT_CRYPTO = 0, 478 FEAT_BLKZONED, 479 FEAT_ATOMIC_WRITE, 480 FEAT_EXTRA_ATTR, 481 FEAT_PROJECT_QUOTA, 482 FEAT_INODE_CHECKSUM, 483 FEAT_FLEXIBLE_INLINE_XATTR, 484 FEAT_QUOTA_INO, 485 FEAT_INODE_CRTIME, 486 FEAT_LOST_FOUND, 487 FEAT_VERITY, 488 FEAT_SB_CHECKSUM, 489 FEAT_CASEFOLD, 490 FEAT_COMPRESSION, 491 FEAT_TEST_DUMMY_ENCRYPTION_V2, 492}; 493 494static ssize_t f2fs_feature_show(struct f2fs_attr *a, 495 struct f2fs_sb_info *sbi, char *buf) 496{ 497 switch (a->id) { 498 case FEAT_CRYPTO: 499 case FEAT_BLKZONED: 500 case FEAT_ATOMIC_WRITE: 501 case FEAT_EXTRA_ATTR: 502 case FEAT_PROJECT_QUOTA: 503 case FEAT_INODE_CHECKSUM: 504 case FEAT_FLEXIBLE_INLINE_XATTR: 505 case FEAT_QUOTA_INO: 506 case FEAT_INODE_CRTIME: 507 case FEAT_LOST_FOUND: 508 case FEAT_VERITY: 509 case FEAT_SB_CHECKSUM: 510 case FEAT_CASEFOLD: 511 case FEAT_COMPRESSION: 512 case FEAT_TEST_DUMMY_ENCRYPTION_V2: 513 return sprintf(buf, "supported\n"); 514 } 515 return 0; 516} 517 518#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ 519static struct f2fs_attr f2fs_attr_##_name = { \ 520 .attr = {.name = __stringify(_name), .mode = _mode }, \ 521 .show = _show, \ 522 .store = _store, \ 523 .struct_type = _struct_type, \ 524 .offset = _offset \ 525} 526 527#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ 528 F2FS_ATTR_OFFSET(struct_type, name, 0644, \ 529 f2fs_sbi_show, f2fs_sbi_store, \ 530 offsetof(struct struct_name, elname)) 531 532#define F2FS_GENERAL_RO_ATTR(name) \ 533static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) 534 535#define F2FS_FEATURE_RO_ATTR(_name, _id) \ 536static struct f2fs_attr f2fs_attr_##_name = { \ 537 .attr = {.name = __stringify(_name), .mode = 0444 }, \ 538 .show = f2fs_feature_show, \ 539 .id = _id, \ 540} 541 542#define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \ 543static struct f2fs_attr f2fs_attr_##_name = { \ 544 .attr = {.name = __stringify(_name), .mode = 0444 }, \ 545 .show = f2fs_sbi_show, \ 546 .struct_type = _struct_type, \ 547 .offset = offsetof(struct _struct_name, _elname), \ 548} 549 550F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time, 551 urgent_sleep_time); 552F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); 553F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); 554F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); 555F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode); 556F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode); 557F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 558F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); 559F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity); 560F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_type, discard_type); 561F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); 562F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); 563F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 564F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); 565F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); 566F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_seq_blocks, min_seq_blocks); 567F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); 568F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections); 569F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); 570F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); 571F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); 572F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); 573F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, migration_granularity, migration_granularity); 574F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); 575F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); 576F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); 577F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, discard_idle_interval, 578 interval_time[DISCARD_TIME]); 579F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle_interval, interval_time[GC_TIME]); 580F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, 581 umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]); 582F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable); 583F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms); 584F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra); 585F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold); 586F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list); 587#ifdef CONFIG_F2FS_GRADING_SSR 588F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 589 hc_hot_data_lower_limit, hot_data_lower_limit); 590F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 591 hc_hot_data_waterline, hot_data_waterline); 592F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 593 hc_warm_data_lower_limit, warm_data_lower_limit); 594F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 595 hc_warm_data_waterline, warm_data_waterline); 596F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 597 hc_hot_node_lower_limit, hot_node_lower_limit); 598F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 599 hc_hot_node_waterline, hot_node_waterline); 600F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 601 hc_warm_node_lower_limit, warm_node_lower_limit); 602F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 603 hc_warm_node_waterline, warm_node_waterline); 604F2FS_RW_ATTR(F2FS_HOT_COLD_PARAMS, f2fs_hot_cold_params, 605 hc_enable, enable); 606#endif 607#ifdef CONFIG_F2FS_FAULT_INJECTION 608F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); 609F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); 610#endif 611F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag); 612F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag); 613F2FS_GENERAL_RO_ATTR(dirty_segments); 614F2FS_GENERAL_RO_ATTR(free_segments); 615F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); 616F2FS_GENERAL_RO_ATTR(features); 617F2FS_GENERAL_RO_ATTR(current_reserved_blocks); 618F2FS_GENERAL_RO_ATTR(unusable); 619F2FS_GENERAL_RO_ATTR(encoding); 620F2FS_GENERAL_RO_ATTR(mounted_time_sec); 621F2FS_GENERAL_RO_ATTR(main_blkaddr); 622#ifdef CONFIG_F2FS_STAT_FS 623F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count); 624F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count); 625F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_foreground_calls, call_count); 626F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_background_calls, bg_gc); 627F2FS_GENERAL_RO_ATTR(moved_blocks_background); 628F2FS_GENERAL_RO_ATTR(moved_blocks_foreground); 629F2FS_GENERAL_RO_ATTR(avg_vblocks); 630#endif 631 632#ifdef CONFIG_FS_ENCRYPTION 633F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); 634F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2); 635#endif 636#ifdef CONFIG_BLK_DEV_ZONED 637F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); 638#endif 639F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); 640F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); 641F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); 642F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); 643F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); 644F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); 645F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); 646F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); 647#ifdef CONFIG_FS_VERITY 648F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); 649#endif 650F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); 651#ifdef CONFIG_UNICODE 652F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); 653#endif 654#ifdef CONFIG_F2FS_FS_COMPRESSION 655F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION); 656#endif 657 658#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 659static struct attribute *f2fs_attrs[] = { 660 ATTR_LIST(gc_urgent_sleep_time), 661 ATTR_LIST(gc_min_sleep_time), 662 ATTR_LIST(gc_max_sleep_time), 663 ATTR_LIST(gc_no_gc_sleep_time), 664 ATTR_LIST(gc_idle), 665 ATTR_LIST(gc_urgent), 666 ATTR_LIST(reclaim_segments), 667 ATTR_LIST(main_blkaddr), 668 ATTR_LIST(max_small_discards), 669 ATTR_LIST(discard_granularity), 670 ATTR_LIST(discard_type), 671 ATTR_LIST(batched_trim_sections), 672 ATTR_LIST(ipu_policy), 673 ATTR_LIST(min_ipu_util), 674 ATTR_LIST(min_fsync_blocks), 675 ATTR_LIST(min_seq_blocks), 676 ATTR_LIST(min_hot_blocks), 677 ATTR_LIST(min_ssr_sections), 678 ATTR_LIST(max_victim_search), 679 ATTR_LIST(migration_granularity), 680 ATTR_LIST(dir_level), 681 ATTR_LIST(ram_thresh), 682 ATTR_LIST(ra_nid_pages), 683 ATTR_LIST(dirty_nats_ratio), 684 ATTR_LIST(cp_interval), 685 ATTR_LIST(idle_interval), 686 ATTR_LIST(discard_idle_interval), 687 ATTR_LIST(gc_idle_interval), 688 ATTR_LIST(umount_discard_timeout), 689 ATTR_LIST(iostat_enable), 690 ATTR_LIST(iostat_period_ms), 691 ATTR_LIST(readdir_ra), 692 ATTR_LIST(gc_pin_file_thresh), 693 ATTR_LIST(extension_list), 694#ifdef CONFIG_F2FS_FAULT_INJECTION 695 ATTR_LIST(inject_rate), 696 ATTR_LIST(inject_type), 697#endif 698 ATTR_LIST(data_io_flag), 699 ATTR_LIST(node_io_flag), 700 ATTR_LIST(dirty_segments), 701 ATTR_LIST(free_segments), 702 ATTR_LIST(unusable), 703 ATTR_LIST(lifetime_write_kbytes), 704 ATTR_LIST(features), 705 ATTR_LIST(reserved_blocks), 706 ATTR_LIST(current_reserved_blocks), 707 ATTR_LIST(encoding), 708 ATTR_LIST(mounted_time_sec), 709#ifdef CONFIG_F2FS_STAT_FS 710 ATTR_LIST(cp_foreground_calls), 711 ATTR_LIST(cp_background_calls), 712 ATTR_LIST(gc_foreground_calls), 713 ATTR_LIST(gc_background_calls), 714 ATTR_LIST(moved_blocks_foreground), 715 ATTR_LIST(moved_blocks_background), 716 ATTR_LIST(avg_vblocks), 717#endif 718#ifdef CONFIG_F2FS_GRADING_SSR 719 ATTR_LIST(hc_hot_data_lower_limit), 720 ATTR_LIST(hc_hot_data_waterline), 721 ATTR_LIST(hc_warm_data_lower_limit), 722 ATTR_LIST(hc_warm_data_waterline), 723 ATTR_LIST(hc_hot_node_lower_limit), 724 ATTR_LIST(hc_hot_node_waterline), 725 ATTR_LIST(hc_warm_node_lower_limit), 726 ATTR_LIST(hc_warm_node_waterline), 727 ATTR_LIST(hc_enable), 728#endif 729 NULL, 730}; 731ATTRIBUTE_GROUPS(f2fs); 732 733static struct attribute *f2fs_feat_attrs[] = { 734#ifdef CONFIG_FS_ENCRYPTION 735 ATTR_LIST(encryption), 736 ATTR_LIST(test_dummy_encryption_v2), 737#endif 738#ifdef CONFIG_BLK_DEV_ZONED 739 ATTR_LIST(block_zoned), 740#endif 741 ATTR_LIST(atomic_write), 742 ATTR_LIST(extra_attr), 743 ATTR_LIST(project_quota), 744 ATTR_LIST(inode_checksum), 745 ATTR_LIST(flexible_inline_xattr), 746 ATTR_LIST(quota_ino), 747 ATTR_LIST(inode_crtime), 748 ATTR_LIST(lost_found), 749#ifdef CONFIG_FS_VERITY 750 ATTR_LIST(verity), 751#endif 752 ATTR_LIST(sb_checksum), 753#ifdef CONFIG_UNICODE 754 ATTR_LIST(casefold), 755#endif 756#ifdef CONFIG_F2FS_FS_COMPRESSION 757 ATTR_LIST(compression), 758#endif 759 NULL, 760}; 761ATTRIBUTE_GROUPS(f2fs_feat); 762 763static const struct sysfs_ops f2fs_attr_ops = { 764 .show = f2fs_attr_show, 765 .store = f2fs_attr_store, 766}; 767 768static struct kobj_type f2fs_sb_ktype = { 769 .default_groups = f2fs_groups, 770 .sysfs_ops = &f2fs_attr_ops, 771 .release = f2fs_sb_release, 772}; 773 774static struct kobj_type f2fs_ktype = { 775 .sysfs_ops = &f2fs_attr_ops, 776}; 777 778static struct kset f2fs_kset = { 779 .kobj = {.ktype = &f2fs_ktype}, 780}; 781 782static struct kobj_type f2fs_feat_ktype = { 783 .default_groups = f2fs_feat_groups, 784 .sysfs_ops = &f2fs_attr_ops, 785}; 786 787static struct kobject f2fs_feat = { 788 .kset = &f2fs_kset, 789}; 790 791static int __maybe_unused segment_info_seq_show(struct seq_file *seq, 792 void *offset) 793{ 794 struct super_block *sb = seq->private; 795 struct f2fs_sb_info *sbi = F2FS_SB(sb); 796 unsigned int total_segs = 797 le32_to_cpu(sbi->raw_super->segment_count_main); 798 int i; 799 800 seq_puts(seq, "format: segment_type|valid_blocks\n" 801 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 802 803 for (i = 0; i < total_segs; i++) { 804 struct seg_entry *se = get_seg_entry(sbi, i); 805 806 if ((i % 10) == 0) 807 seq_printf(seq, "%-10d", i); 808 seq_printf(seq, "%d|%-3u", se->type, se->valid_blocks); 809 if ((i % 10) == 9 || i == (total_segs - 1)) 810 seq_putc(seq, '\n'); 811 else 812 seq_putc(seq, ' '); 813 } 814 815 return 0; 816} 817 818static int __maybe_unused segment_bits_seq_show(struct seq_file *seq, 819 void *offset) 820{ 821 struct super_block *sb = seq->private; 822 struct f2fs_sb_info *sbi = F2FS_SB(sb); 823 unsigned int total_segs = 824 le32_to_cpu(sbi->raw_super->segment_count_main); 825 int i, j; 826 827 seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n" 828 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 829 830 for (i = 0; i < total_segs; i++) { 831 struct seg_entry *se = get_seg_entry(sbi, i); 832 833 seq_printf(seq, "%-10d", i); 834 seq_printf(seq, "%d|%-3u|", se->type, se->valid_blocks); 835 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) 836 seq_printf(seq, " %.2x", se->cur_valid_map[j]); 837 seq_putc(seq, '\n'); 838 } 839 return 0; 840} 841 842void f2fs_record_iostat(struct f2fs_sb_info *sbi) 843{ 844 unsigned long long iostat_diff[NR_IO_TYPE]; 845 int i; 846 847 if (time_is_after_jiffies(sbi->iostat_next_period)) 848 return; 849 850 /* Need double check under the lock */ 851 spin_lock(&sbi->iostat_lock); 852 if (time_is_after_jiffies(sbi->iostat_next_period)) { 853 spin_unlock(&sbi->iostat_lock); 854 return; 855 } 856 sbi->iostat_next_period = jiffies + 857 msecs_to_jiffies(sbi->iostat_period_ms); 858 859 for (i = 0; i < NR_IO_TYPE; i++) { 860 iostat_diff[i] = sbi->rw_iostat[i] - 861 sbi->prev_rw_iostat[i]; 862 sbi->prev_rw_iostat[i] = sbi->rw_iostat[i]; 863 } 864 spin_unlock(&sbi->iostat_lock); 865 866 trace_f2fs_iostat(sbi, iostat_diff); 867} 868 869static int __maybe_unused iostat_info_seq_show(struct seq_file *seq, 870 void *offset) 871{ 872 struct super_block *sb = seq->private; 873 struct f2fs_sb_info *sbi = F2FS_SB(sb); 874 time64_t now = ktime_get_real_seconds(); 875 876 if (!sbi->iostat_enable) 877 return 0; 878 879 seq_printf(seq, "time: %-16llu\n", now); 880 881 /* print app write IOs */ 882 seq_puts(seq, "[WRITE]\n"); 883 seq_printf(seq, "app buffered: %-16llu\n", 884 sbi->rw_iostat[APP_BUFFERED_IO]); 885 seq_printf(seq, "app direct: %-16llu\n", 886 sbi->rw_iostat[APP_DIRECT_IO]); 887 seq_printf(seq, "app mapped: %-16llu\n", 888 sbi->rw_iostat[APP_MAPPED_IO]); 889 890 /* print fs write IOs */ 891 seq_printf(seq, "fs data: %-16llu\n", 892 sbi->rw_iostat[FS_DATA_IO]); 893 seq_printf(seq, "fs node: %-16llu\n", 894 sbi->rw_iostat[FS_NODE_IO]); 895 seq_printf(seq, "fs meta: %-16llu\n", 896 sbi->rw_iostat[FS_META_IO]); 897 seq_printf(seq, "fs gc data: %-16llu\n", 898 sbi->rw_iostat[FS_GC_DATA_IO]); 899 seq_printf(seq, "fs gc node: %-16llu\n", 900 sbi->rw_iostat[FS_GC_NODE_IO]); 901 seq_printf(seq, "fs cp data: %-16llu\n", 902 sbi->rw_iostat[FS_CP_DATA_IO]); 903 seq_printf(seq, "fs cp node: %-16llu\n", 904 sbi->rw_iostat[FS_CP_NODE_IO]); 905 seq_printf(seq, "fs cp meta: %-16llu\n", 906 sbi->rw_iostat[FS_CP_META_IO]); 907 908 /* print app read IOs */ 909 seq_puts(seq, "[READ]\n"); 910 seq_printf(seq, "app buffered: %-16llu\n", 911 sbi->rw_iostat[APP_BUFFERED_READ_IO]); 912 seq_printf(seq, "app direct: %-16llu\n", 913 sbi->rw_iostat[APP_DIRECT_READ_IO]); 914 seq_printf(seq, "app mapped: %-16llu\n", 915 sbi->rw_iostat[APP_MAPPED_READ_IO]); 916 917 /* print fs read IOs */ 918 seq_printf(seq, "fs data: %-16llu\n", 919 sbi->rw_iostat[FS_DATA_READ_IO]); 920 seq_printf(seq, "fs gc data: %-16llu\n", 921 sbi->rw_iostat[FS_GDATA_READ_IO]); 922 seq_printf(seq, "fs compr_data: %-16llu\n", 923 sbi->rw_iostat[FS_CDATA_READ_IO]); 924 seq_printf(seq, "fs node: %-16llu\n", 925 sbi->rw_iostat[FS_NODE_READ_IO]); 926 seq_printf(seq, "fs meta: %-16llu\n", 927 sbi->rw_iostat[FS_META_READ_IO]); 928 929 /* print other IOs */ 930 seq_puts(seq, "[OTHER]\n"); 931 seq_printf(seq, "fs discard: %-16llu\n", 932 sbi->rw_iostat[FS_DISCARD]); 933 934 return 0; 935} 936 937static int __maybe_unused victim_bits_seq_show(struct seq_file *seq, 938 void *offset) 939{ 940 struct super_block *sb = seq->private; 941 struct f2fs_sb_info *sbi = F2FS_SB(sb); 942 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 943 int i; 944 945 seq_puts(seq, "format: victim_secmap bitmaps\n"); 946 947 for (i = 0; i < MAIN_SECS(sbi); i++) { 948 if ((i % 10) == 0) 949 seq_printf(seq, "%-10d", i); 950 seq_printf(seq, "%d", test_bit(i, dirty_i->victim_secmap) ? 1 : 0); 951 if ((i % 10) == 9 || i == (MAIN_SECS(sbi) - 1)) 952 seq_putc(seq, '\n'); 953 else 954 seq_putc(seq, ' '); 955 } 956 return 0; 957} 958 959static int undiscard_info_seq_show(struct seq_file *seq, void *offset) 960{ 961 struct super_block *sb = seq->private; 962 struct f2fs_sb_info *sbi = F2FS_SB(sb); 963 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 964 struct sit_info *sit_i = SIT_I(sbi); 965 unsigned int total_segs = le32_to_cpu(sbi->raw_super->segment_count_main); 966 unsigned int total = 0; 967 unsigned int i, j; 968 unsigned int max_blocks = sbi->blocks_per_seg; 969 unsigned long *dmap = SIT_I(sbi)->tmp_map; 970 971 if (!f2fs_realtime_discard_enable(sbi)) 972 goto out; 973 974 for (i = 0; i < total_segs; i++) { 975 struct seg_entry *se = get_seg_entry(sbi, i); 976 unsigned int entries = SIT_VBLOCK_MAP_SIZE / 977 sizeof(unsigned long); 978 unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map; 979 unsigned long *discard_map = (unsigned long *)se->discard_map; 980 int start = 0, end = -1; 981 982 down_write(&sit_i->sentry_lock); 983 if (se->valid_blocks == max_blocks) { 984 up_write(&sit_i->sentry_lock); 985 continue; 986 } 987 988 if (se->valid_blocks == 0) { 989 mutex_lock(&dirty_i->seglist_lock); 990 if (test_bit((int)i, dirty_i->dirty_segmap[PRE])) 991 total += 512; 992 mutex_unlock(&dirty_i->seglist_lock); 993 } else { 994 for (j = 0; j < entries; j++) 995 dmap[j] = ~ckpt_map[j] & ~discard_map[j]; 996 while (1) { 997 start = (int)find_rev_next_bit(dmap, 998 (unsigned long)max_blocks, 999 (unsigned long)(end + 1)); 1000 1001 if ((unsigned int)start >= max_blocks) 1002 break; 1003 1004 end = (int)find_rev_next_zero_bit(dmap, 1005 (unsigned long)max_blocks, 1006 (unsigned long)(start + 1)); 1007 total += (unsigned int)(end - start); 1008 } 1009 } 1010 1011 up_write(&sit_i->sentry_lock); 1012 } 1013 1014out: 1015 seq_printf(seq, "total undiscard:%u K\n", total * 4); 1016 return 0; 1017} 1018 1019int __init f2fs_init_sysfs(void) 1020{ 1021 int ret; 1022 1023 kobject_set_name(&f2fs_kset.kobj, "f2fs"); 1024 f2fs_kset.kobj.parent = fs_kobj; 1025 ret = kset_register(&f2fs_kset); 1026 if (ret) 1027 return ret; 1028 1029 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype, 1030 NULL, "features"); 1031 if (ret) { 1032 kobject_put(&f2fs_feat); 1033 kset_unregister(&f2fs_kset); 1034 } else { 1035 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); 1036 } 1037 return ret; 1038} 1039 1040void f2fs_exit_sysfs(void) 1041{ 1042 kobject_put(&f2fs_feat); 1043 kset_unregister(&f2fs_kset); 1044 remove_proc_entry("fs/f2fs", NULL); 1045 f2fs_proc_root = NULL; 1046} 1047 1048int f2fs_register_sysfs(struct f2fs_sb_info *sbi) 1049{ 1050 struct super_block *sb = sbi->sb; 1051 int err; 1052 1053 sbi->s_kobj.kset = &f2fs_kset; 1054 init_completion(&sbi->s_kobj_unregister); 1055 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL, 1056 "%s", sb->s_id); 1057 if (err) { 1058 kobject_put(&sbi->s_kobj); 1059 wait_for_completion(&sbi->s_kobj_unregister); 1060 return err; 1061 } 1062 1063 if (f2fs_proc_root) 1064 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 1065 1066 if (sbi->s_proc) { 1067 proc_create_single_data("segment_info", S_IRUGO, sbi->s_proc, 1068 segment_info_seq_show, sb); 1069 proc_create_single_data("segment_bits", S_IRUGO, sbi->s_proc, 1070 segment_bits_seq_show, sb); 1071 proc_create_single_data("iostat_info", S_IRUGO, sbi->s_proc, 1072 iostat_info_seq_show, sb); 1073 proc_create_single_data("victim_bits", S_IRUGO, sbi->s_proc, 1074 victim_bits_seq_show, sb); 1075 proc_create_single_data("undiscard_info", S_IRUGO, sbi->s_proc, 1076 undiscard_info_seq_show, sb); 1077 1078 } 1079 return 0; 1080} 1081 1082void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) 1083{ 1084 if (sbi->s_proc) { 1085 remove_proc_entry("iostat_info", sbi->s_proc); 1086 remove_proc_entry("segment_info", sbi->s_proc); 1087 remove_proc_entry("segment_bits", sbi->s_proc); 1088 remove_proc_entry("victim_bits", sbi->s_proc); 1089 remove_proc_entry("undiscard_info", sbi->s_proc); 1090 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); 1091 } 1092 kobject_del(&sbi->s_kobj); 1093 kobject_put(&sbi->s_kobj); 1094 wait_for_completion(&sbi->s_kobj_unregister); 1095} 1096