1 /* 2 * f2fs sysfs interface 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * Copyright (c) 2017 Chao Yu <chao@kernel.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 #include <linux/proc_fs.h> 13 #include <linux/f2fs_fs.h> 14 #include <linux/seq_file.h> 15 16 #include "f2fs.h" 17 #include "segment.h" 18 #include "gc.h" 19 20 static struct proc_dir_entry *f2fs_proc_root; 21 22 /* Sysfs support for f2fs */ 23 enum { 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_FAULT_INJECTION 30 FAULT_INFO_RATE, /* struct f2fs_fault_info */ 31 FAULT_INFO_TYPE, /* struct f2fs_fault_info */ 32 #endif 33 RESERVED_BLOCKS, /* struct f2fs_sb_info */ 34 }; 35 36 struct f2fs_attr { 37 struct attribute attr; 38 ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); 39 ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, 40 const char *, size_t); 41 int struct_type; 42 int offset; 43 int id; 44 }; 45 46 static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) 47 { 48 if (struct_type == GC_THREAD) 49 return (unsigned char *)sbi->gc_thread; 50 else if (struct_type == SM_INFO) 51 return (unsigned char *)SM_I(sbi); 52 else if (struct_type == DCC_INFO) 53 return (unsigned char *)SM_I(sbi)->dcc_info; 54 else if (struct_type == NM_INFO) 55 return (unsigned char *)NM_I(sbi); 56 else if (struct_type == F2FS_SBI || struct_type == RESERVED_BLOCKS) 57 return (unsigned char *)sbi; 58 #ifdef CONFIG_F2FS_FAULT_INJECTION 59 else if (struct_type == FAULT_INFO_RATE || 60 struct_type == FAULT_INFO_TYPE) 61 return (unsigned char *)&F2FS_OPTION(sbi).fault_info; 62 #endif 63 return NULL; 64 } 65 66 static ssize_t dirty_segments_show(struct f2fs_attr *a, 67 struct f2fs_sb_info *sbi, char *buf) 68 { 69 return snprintf(buf, PAGE_SIZE, "%llu\n", 70 (unsigned long long)(dirty_segments(sbi))); 71 } 72 73 static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, 74 struct f2fs_sb_info *sbi, char *buf) 75 { 76 struct super_block *sb = sbi->sb; 77 78 if (!sb->s_bdev->bd_part) 79 return snprintf(buf, PAGE_SIZE, "0\n"); 80 81 return snprintf(buf, PAGE_SIZE, "%llu\n", 82 (unsigned long long)(sbi->kbytes_written + 83 BD_PART_WRITTEN(sbi))); 84 } 85 86 static ssize_t features_show(struct f2fs_attr *a, 87 struct f2fs_sb_info *sbi, char *buf) 88 { 89 struct super_block *sb = sbi->sb; 90 int len = 0; 91 92 if (!sb->s_bdev->bd_part) 93 return snprintf(buf, PAGE_SIZE, "0\n"); 94 95 if (f2fs_sb_has_encrypt(sb)) 96 len += snprintf(buf, PAGE_SIZE - len, "%s", 97 "encryption"); 98 if (f2fs_sb_has_blkzoned(sb)) 99 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 100 len ? ", " : "", "blkzoned"); 101 if (f2fs_sb_has_extra_attr(sb)) 102 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 103 len ? ", " : "", "extra_attr"); 104 if (f2fs_sb_has_project_quota(sb)) 105 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 106 len ? ", " : "", "projquota"); 107 if (f2fs_sb_has_inode_chksum(sb)) 108 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 109 len ? ", " : "", "inode_checksum"); 110 if (f2fs_sb_has_flexible_inline_xattr(sb)) 111 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 112 len ? ", " : "", "flexible_inline_xattr"); 113 if (f2fs_sb_has_quota_ino(sb)) 114 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 115 len ? ", " : "", "quota_ino"); 116 if (f2fs_sb_has_inode_crtime(sb)) 117 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 118 len ? ", " : "", "inode_crtime"); 119 if (f2fs_sb_has_lost_found(sb)) 120 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 121 len ? ", " : "", "lost_found"); 122 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 123 return len; 124 } 125 126 static ssize_t current_reserved_blocks_show(struct f2fs_attr *a, 127 struct f2fs_sb_info *sbi, char *buf) 128 { 129 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->current_reserved_blocks); 130 } 131 132 static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 133 struct f2fs_sb_info *sbi, char *buf) 134 { 135 unsigned char *ptr = NULL; 136 unsigned int *ui; 137 138 ptr = __struct_ptr(sbi, a->struct_type); 139 if (!ptr) 140 return -EINVAL; 141 142 if (!strcmp(a->attr.name, "extension_list")) { 143 __u8 (*extlist)[F2FS_EXTENSION_LEN] = 144 sbi->raw_super->extension_list; 145 int cold_count = le32_to_cpu(sbi->raw_super->extension_count); 146 int hot_count = sbi->raw_super->hot_ext_count; 147 int len = 0, i; 148 149 len += snprintf(buf + len, PAGE_SIZE - len, 150 "cold file extension:\n"); 151 for (i = 0; i < cold_count; i++) 152 len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", 153 extlist[i]); 154 155 len += snprintf(buf + len, PAGE_SIZE - len, 156 "hot file extension:\n"); 157 for (i = cold_count; i < cold_count + hot_count; i++) 158 len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", 159 extlist[i]); 160 return len; 161 } 162 163 ui = (unsigned int *)(ptr + a->offset); 164 165 return snprintf(buf, PAGE_SIZE, "%u\n", *ui); 166 } 167 168 static ssize_t __sbi_store(struct f2fs_attr *a, 169 struct f2fs_sb_info *sbi, 170 const char *buf, size_t count) 171 { 172 unsigned char *ptr; 173 unsigned long t; 174 unsigned int *ui; 175 ssize_t ret; 176 177 ptr = __struct_ptr(sbi, a->struct_type); 178 if (!ptr) 179 return -EINVAL; 180 181 if (!strcmp(a->attr.name, "extension_list")) { 182 const char *name = strim((char *)buf); 183 bool set = true, hot; 184 185 if (!strncmp(name, "[h]", 3)) 186 hot = true; 187 else if (!strncmp(name, "[c]", 3)) 188 hot = false; 189 else 190 return -EINVAL; 191 192 name += 3; 193 194 if (*name == '!') { 195 name++; 196 set = false; 197 } 198 199 if (strlen(name) >= F2FS_EXTENSION_LEN) 200 return -EINVAL; 201 202 down_write(&sbi->sb_lock); 203 204 ret = f2fs_update_extension_list(sbi, name, hot, set); 205 if (ret) 206 goto out; 207 208 ret = f2fs_commit_super(sbi, false); 209 if (ret) 210 f2fs_update_extension_list(sbi, name, hot, !set); 211 out: 212 up_write(&sbi->sb_lock); 213 return ret ? ret : count; 214 } 215 216 ui = (unsigned int *)(ptr + a->offset); 217 218 ret = kstrtoul(skip_spaces(buf), 0, &t); 219 if (ret < 0) 220 return ret; 221 #ifdef CONFIG_F2FS_FAULT_INJECTION 222 if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX)) 223 return -EINVAL; 224 #endif 225 if (a->struct_type == RESERVED_BLOCKS) { 226 spin_lock(&sbi->stat_lock); 227 if (t > (unsigned long)(sbi->user_block_count - 228 F2FS_OPTION(sbi).root_reserved_blocks)) { 229 spin_unlock(&sbi->stat_lock); 230 return -EINVAL; 231 } 232 *ui = t; 233 sbi->current_reserved_blocks = min(sbi->reserved_blocks, 234 sbi->user_block_count - valid_user_blocks(sbi)); 235 spin_unlock(&sbi->stat_lock); 236 return count; 237 } 238 239 if (!strcmp(a->attr.name, "discard_granularity")) { 240 if (t == 0 || t > MAX_PLIST_NUM) 241 return -EINVAL; 242 if (t == *ui) 243 return count; 244 *ui = t; 245 return count; 246 } 247 248 if (!strcmp(a->attr.name, "trim_sections")) 249 return -EINVAL; 250 251 if (!strcmp(a->attr.name, "gc_urgent")) { 252 if (t >= 1) { 253 sbi->gc_mode = GC_URGENT; 254 if (sbi->gc_thread) { 255 wake_up_interruptible_all( 256 &sbi->gc_thread->gc_wait_queue_head); 257 wake_up_discard_thread(sbi, true); 258 } 259 } else { 260 sbi->gc_mode = GC_NORMAL; 261 } 262 return count; 263 } 264 if (!strcmp(a->attr.name, "gc_idle")) { 265 if (t == GC_IDLE_CB) 266 sbi->gc_mode = GC_IDLE_CB; 267 else if (t == GC_IDLE_GREEDY) 268 sbi->gc_mode = GC_IDLE_GREEDY; 269 else 270 sbi->gc_mode = GC_NORMAL; 271 return count; 272 } 273 274 *ui = t; 275 276 if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0) 277 f2fs_reset_iostat(sbi); 278 return count; 279 } 280 281 static ssize_t f2fs_sbi_store(struct f2fs_attr *a, 282 struct f2fs_sb_info *sbi, 283 const char *buf, size_t count) 284 { 285 ssize_t ret; 286 bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") || 287 a->struct_type == GC_THREAD); 288 289 if (gc_entry) 290 down_read(&sbi->sb->s_umount); 291 ret = __sbi_store(a, sbi, buf, count); 292 if (gc_entry) 293 up_read(&sbi->sb->s_umount); 294 295 return ret; 296 } 297 298 static ssize_t f2fs_attr_show(struct kobject *kobj, 299 struct attribute *attr, char *buf) 300 { 301 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 302 s_kobj); 303 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 304 305 return a->show ? a->show(a, sbi, buf) : 0; 306 } 307 308 static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr, 309 const char *buf, size_t len) 310 { 311 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 312 s_kobj); 313 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 314 315 return a->store ? a->store(a, sbi, buf, len) : 0; 316 } 317 318 static void f2fs_sb_release(struct kobject *kobj) 319 { 320 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 321 s_kobj); 322 complete(&sbi->s_kobj_unregister); 323 } 324 325 enum feat_id { 326 FEAT_CRYPTO = 0, 327 FEAT_BLKZONED, 328 FEAT_ATOMIC_WRITE, 329 FEAT_EXTRA_ATTR, 330 FEAT_PROJECT_QUOTA, 331 FEAT_INODE_CHECKSUM, 332 FEAT_FLEXIBLE_INLINE_XATTR, 333 FEAT_QUOTA_INO, 334 FEAT_INODE_CRTIME, 335 FEAT_LOST_FOUND, 336 }; 337 338 static ssize_t f2fs_feature_show(struct f2fs_attr *a, 339 struct f2fs_sb_info *sbi, char *buf) 340 { 341 switch (a->id) { 342 case FEAT_CRYPTO: 343 case FEAT_BLKZONED: 344 case FEAT_ATOMIC_WRITE: 345 case FEAT_EXTRA_ATTR: 346 case FEAT_PROJECT_QUOTA: 347 case FEAT_INODE_CHECKSUM: 348 case FEAT_FLEXIBLE_INLINE_XATTR: 349 case FEAT_QUOTA_INO: 350 case FEAT_INODE_CRTIME: 351 case FEAT_LOST_FOUND: 352 return snprintf(buf, PAGE_SIZE, "supported\n"); 353 } 354 return 0; 355 } 356 357 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ 358 static struct f2fs_attr f2fs_attr_##_name = { \ 359 .attr = {.name = __stringify(_name), .mode = _mode }, \ 360 .show = _show, \ 361 .store = _store, \ 362 .struct_type = _struct_type, \ 363 .offset = _offset \ 364 } 365 366 #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ 367 F2FS_ATTR_OFFSET(struct_type, name, 0644, \ 368 f2fs_sbi_show, f2fs_sbi_store, \ 369 offsetof(struct struct_name, elname)) 370 371 #define F2FS_GENERAL_RO_ATTR(name) \ 372 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) 373 374 #define F2FS_FEATURE_RO_ATTR(_name, _id) \ 375 static struct f2fs_attr f2fs_attr_##_name = { \ 376 .attr = {.name = __stringify(_name), .mode = 0444 }, \ 377 .show = f2fs_feature_show, \ 378 .id = _id, \ 379 } 380 381 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time, 382 urgent_sleep_time); 383 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); 384 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); 385 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); 386 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode); 387 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode); 388 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 389 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); 390 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity); 391 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); 392 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); 393 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 394 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); 395 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); 396 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); 397 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections); 398 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); 399 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); 400 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); 401 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); 402 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); 403 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); 404 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); 405 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable); 406 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra); 407 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold); 408 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list); 409 #ifdef CONFIG_F2FS_FAULT_INJECTION 410 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); 411 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); 412 #endif 413 F2FS_GENERAL_RO_ATTR(dirty_segments); 414 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); 415 F2FS_GENERAL_RO_ATTR(features); 416 F2FS_GENERAL_RO_ATTR(current_reserved_blocks); 417 418 #ifdef CONFIG_F2FS_FS_ENCRYPTION 419 F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); 420 #endif 421 #ifdef CONFIG_BLK_DEV_ZONED 422 F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); 423 #endif 424 F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); 425 F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); 426 F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); 427 F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); 428 F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); 429 F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); 430 F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); 431 F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); 432 433 #define ATTR_LIST(name) (&f2fs_attr_##name.attr) 434 static struct attribute *f2fs_attrs[] = { 435 ATTR_LIST(gc_urgent_sleep_time), 436 ATTR_LIST(gc_min_sleep_time), 437 ATTR_LIST(gc_max_sleep_time), 438 ATTR_LIST(gc_no_gc_sleep_time), 439 ATTR_LIST(gc_idle), 440 ATTR_LIST(gc_urgent), 441 ATTR_LIST(reclaim_segments), 442 ATTR_LIST(max_small_discards), 443 ATTR_LIST(discard_granularity), 444 ATTR_LIST(batched_trim_sections), 445 ATTR_LIST(ipu_policy), 446 ATTR_LIST(min_ipu_util), 447 ATTR_LIST(min_fsync_blocks), 448 ATTR_LIST(min_hot_blocks), 449 ATTR_LIST(min_ssr_sections), 450 ATTR_LIST(max_victim_search), 451 ATTR_LIST(dir_level), 452 ATTR_LIST(ram_thresh), 453 ATTR_LIST(ra_nid_pages), 454 ATTR_LIST(dirty_nats_ratio), 455 ATTR_LIST(cp_interval), 456 ATTR_LIST(idle_interval), 457 ATTR_LIST(iostat_enable), 458 ATTR_LIST(readdir_ra), 459 ATTR_LIST(gc_pin_file_thresh), 460 ATTR_LIST(extension_list), 461 #ifdef CONFIG_F2FS_FAULT_INJECTION 462 ATTR_LIST(inject_rate), 463 ATTR_LIST(inject_type), 464 #endif 465 ATTR_LIST(dirty_segments), 466 ATTR_LIST(lifetime_write_kbytes), 467 ATTR_LIST(features), 468 ATTR_LIST(reserved_blocks), 469 ATTR_LIST(current_reserved_blocks), 470 NULL, 471 }; 472 473 static struct attribute *f2fs_feat_attrs[] = { 474 #ifdef CONFIG_F2FS_FS_ENCRYPTION 475 ATTR_LIST(encryption), 476 #endif 477 #ifdef CONFIG_BLK_DEV_ZONED 478 ATTR_LIST(block_zoned), 479 #endif 480 ATTR_LIST(atomic_write), 481 ATTR_LIST(extra_attr), 482 ATTR_LIST(project_quota), 483 ATTR_LIST(inode_checksum), 484 ATTR_LIST(flexible_inline_xattr), 485 ATTR_LIST(quota_ino), 486 ATTR_LIST(inode_crtime), 487 ATTR_LIST(lost_found), 488 NULL, 489 }; 490 491 static const struct sysfs_ops f2fs_attr_ops = { 492 .show = f2fs_attr_show, 493 .store = f2fs_attr_store, 494 }; 495 496 static struct kobj_type f2fs_sb_ktype = { 497 .default_attrs = f2fs_attrs, 498 .sysfs_ops = &f2fs_attr_ops, 499 .release = f2fs_sb_release, 500 }; 501 502 static struct kobj_type f2fs_ktype = { 503 .sysfs_ops = &f2fs_attr_ops, 504 }; 505 506 static struct kset f2fs_kset = { 507 .kobj = {.ktype = &f2fs_ktype}, 508 }; 509 510 static struct kobj_type f2fs_feat_ktype = { 511 .default_attrs = f2fs_feat_attrs, 512 .sysfs_ops = &f2fs_attr_ops, 513 }; 514 515 static struct kobject f2fs_feat = { 516 .kset = &f2fs_kset, 517 }; 518 519 static int segment_info_seq_show(struct seq_file *seq, void *offset) 520 { 521 struct super_block *sb = seq->private; 522 struct f2fs_sb_info *sbi = F2FS_SB(sb); 523 unsigned int total_segs = 524 le32_to_cpu(sbi->raw_super->segment_count_main); 525 int i; 526 527 seq_puts(seq, "format: segment_type|valid_blocks\n" 528 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 529 530 for (i = 0; i < total_segs; i++) { 531 struct seg_entry *se = get_seg_entry(sbi, i); 532 533 if ((i % 10) == 0) 534 seq_printf(seq, "%-10d", i); 535 seq_printf(seq, "%d|%-3u", se->type, 536 get_valid_blocks(sbi, i, false)); 537 if ((i % 10) == 9 || i == (total_segs - 1)) 538 seq_putc(seq, '\n'); 539 else 540 seq_putc(seq, ' '); 541 } 542 543 return 0; 544 } 545 546 static int segment_bits_seq_show(struct seq_file *seq, void *offset) 547 { 548 struct super_block *sb = seq->private; 549 struct f2fs_sb_info *sbi = F2FS_SB(sb); 550 unsigned int total_segs = 551 le32_to_cpu(sbi->raw_super->segment_count_main); 552 int i, j; 553 554 seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n" 555 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 556 557 for (i = 0; i < total_segs; i++) { 558 struct seg_entry *se = get_seg_entry(sbi, i); 559 560 seq_printf(seq, "%-10d", i); 561 seq_printf(seq, "%d|%-3u|", se->type, 562 get_valid_blocks(sbi, i, false)); 563 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) 564 seq_printf(seq, " %.2x", se->cur_valid_map[j]); 565 seq_putc(seq, '\n'); 566 } 567 return 0; 568 } 569 570 static int iostat_info_seq_show(struct seq_file *seq, void *offset) 571 { 572 struct super_block *sb = seq->private; 573 struct f2fs_sb_info *sbi = F2FS_SB(sb); 574 time64_t now = ktime_get_real_seconds(); 575 576 if (!sbi->iostat_enable) 577 return 0; 578 579 seq_printf(seq, "time: %-16llu\n", now); 580 581 /* print app IOs */ 582 seq_printf(seq, "app buffered: %-16llu\n", 583 sbi->write_iostat[APP_BUFFERED_IO]); 584 seq_printf(seq, "app direct: %-16llu\n", 585 sbi->write_iostat[APP_DIRECT_IO]); 586 seq_printf(seq, "app mapped: %-16llu\n", 587 sbi->write_iostat[APP_MAPPED_IO]); 588 589 /* print fs IOs */ 590 seq_printf(seq, "fs data: %-16llu\n", 591 sbi->write_iostat[FS_DATA_IO]); 592 seq_printf(seq, "fs node: %-16llu\n", 593 sbi->write_iostat[FS_NODE_IO]); 594 seq_printf(seq, "fs meta: %-16llu\n", 595 sbi->write_iostat[FS_META_IO]); 596 seq_printf(seq, "fs gc data: %-16llu\n", 597 sbi->write_iostat[FS_GC_DATA_IO]); 598 seq_printf(seq, "fs gc node: %-16llu\n", 599 sbi->write_iostat[FS_GC_NODE_IO]); 600 seq_printf(seq, "fs cp data: %-16llu\n", 601 sbi->write_iostat[FS_CP_DATA_IO]); 602 seq_printf(seq, "fs cp node: %-16llu\n", 603 sbi->write_iostat[FS_CP_NODE_IO]); 604 seq_printf(seq, "fs cp meta: %-16llu\n", 605 sbi->write_iostat[FS_CP_META_IO]); 606 seq_printf(seq, "fs discard: %-16llu\n", 607 sbi->write_iostat[FS_DISCARD]); 608 609 return 0; 610 } 611 612 int __init f2fs_init_sysfs(void) 613 { 614 int ret; 615 616 kobject_set_name(&f2fs_kset.kobj, "f2fs"); 617 f2fs_kset.kobj.parent = fs_kobj; 618 ret = kset_register(&f2fs_kset); 619 if (ret) 620 return ret; 621 622 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype, 623 NULL, "features"); 624 if (ret) 625 kset_unregister(&f2fs_kset); 626 else 627 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); 628 return ret; 629 } 630 631 void f2fs_exit_sysfs(void) 632 { 633 kobject_put(&f2fs_feat); 634 kset_unregister(&f2fs_kset); 635 remove_proc_entry("fs/f2fs", NULL); 636 f2fs_proc_root = NULL; 637 } 638 639 int f2fs_register_sysfs(struct f2fs_sb_info *sbi) 640 { 641 struct super_block *sb = sbi->sb; 642 int err; 643 644 sbi->s_kobj.kset = &f2fs_kset; 645 init_completion(&sbi->s_kobj_unregister); 646 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL, 647 "%s", sb->s_id); 648 if (err) 649 return err; 650 651 if (f2fs_proc_root) 652 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 653 654 if (sbi->s_proc) { 655 proc_create_single_data("segment_info", S_IRUGO, sbi->s_proc, 656 segment_info_seq_show, sb); 657 proc_create_single_data("segment_bits", S_IRUGO, sbi->s_proc, 658 segment_bits_seq_show, sb); 659 proc_create_single_data("iostat_info", S_IRUGO, sbi->s_proc, 660 iostat_info_seq_show, sb); 661 } 662 return 0; 663 } 664 665 void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) 666 { 667 if (sbi->s_proc) { 668 remove_proc_entry("iostat_info", sbi->s_proc); 669 remove_proc_entry("segment_info", sbi->s_proc); 670 remove_proc_entry("segment_bits", sbi->s_proc); 671 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); 672 } 673 kobject_del(&sbi->s_kobj); 674 } 675