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 *)&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_crypto(sb)) 96 len += snprintf(buf, PAGE_SIZE - len, "%s", 97 "encryption"); 98 if (f2fs_sb_mounted_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 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 120 return len; 121 } 122 123 static ssize_t current_reserved_blocks_show(struct f2fs_attr *a, 124 struct f2fs_sb_info *sbi, char *buf) 125 { 126 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->current_reserved_blocks); 127 } 128 129 static ssize_t f2fs_sbi_show(struct f2fs_attr *a, 130 struct f2fs_sb_info *sbi, char *buf) 131 { 132 unsigned char *ptr = NULL; 133 unsigned int *ui; 134 135 ptr = __struct_ptr(sbi, a->struct_type); 136 if (!ptr) 137 return -EINVAL; 138 139 ui = (unsigned int *)(ptr + a->offset); 140 141 return snprintf(buf, PAGE_SIZE, "%u\n", *ui); 142 } 143 144 static ssize_t f2fs_sbi_store(struct f2fs_attr *a, 145 struct f2fs_sb_info *sbi, 146 const char *buf, size_t count) 147 { 148 unsigned char *ptr; 149 unsigned long t; 150 unsigned int *ui; 151 ssize_t ret; 152 153 ptr = __struct_ptr(sbi, a->struct_type); 154 if (!ptr) 155 return -EINVAL; 156 157 ui = (unsigned int *)(ptr + a->offset); 158 159 ret = kstrtoul(skip_spaces(buf), 0, &t); 160 if (ret < 0) 161 return ret; 162 #ifdef CONFIG_F2FS_FAULT_INJECTION 163 if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX)) 164 return -EINVAL; 165 #endif 166 if (a->struct_type == RESERVED_BLOCKS) { 167 spin_lock(&sbi->stat_lock); 168 if (t > (unsigned long)(sbi->user_block_count - 169 sbi->root_reserved_blocks)) { 170 spin_unlock(&sbi->stat_lock); 171 return -EINVAL; 172 } 173 *ui = t; 174 sbi->current_reserved_blocks = min(sbi->reserved_blocks, 175 sbi->user_block_count - valid_user_blocks(sbi)); 176 spin_unlock(&sbi->stat_lock); 177 return count; 178 } 179 180 if (!strcmp(a->attr.name, "discard_granularity")) { 181 if (t == 0 || t > MAX_PLIST_NUM) 182 return -EINVAL; 183 if (t == *ui) 184 return count; 185 *ui = t; 186 return count; 187 } 188 189 *ui = t; 190 191 if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0) 192 f2fs_reset_iostat(sbi); 193 if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) { 194 sbi->gc_thread->gc_wake = 1; 195 wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head); 196 wake_up_discard_thread(sbi, true); 197 } 198 199 return count; 200 } 201 202 static ssize_t f2fs_attr_show(struct kobject *kobj, 203 struct attribute *attr, char *buf) 204 { 205 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 206 s_kobj); 207 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 208 209 return a->show ? a->show(a, sbi, buf) : 0; 210 } 211 212 static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr, 213 const char *buf, size_t len) 214 { 215 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 216 s_kobj); 217 struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); 218 219 return a->store ? a->store(a, sbi, buf, len) : 0; 220 } 221 222 static void f2fs_sb_release(struct kobject *kobj) 223 { 224 struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, 225 s_kobj); 226 complete(&sbi->s_kobj_unregister); 227 } 228 229 enum feat_id { 230 FEAT_CRYPTO = 0, 231 FEAT_BLKZONED, 232 FEAT_ATOMIC_WRITE, 233 FEAT_EXTRA_ATTR, 234 FEAT_PROJECT_QUOTA, 235 FEAT_INODE_CHECKSUM, 236 FEAT_FLEXIBLE_INLINE_XATTR, 237 FEAT_QUOTA_INO, 238 FEAT_INODE_CRTIME, 239 }; 240 241 static ssize_t f2fs_feature_show(struct f2fs_attr *a, 242 struct f2fs_sb_info *sbi, char *buf) 243 { 244 switch (a->id) { 245 case FEAT_CRYPTO: 246 case FEAT_BLKZONED: 247 case FEAT_ATOMIC_WRITE: 248 case FEAT_EXTRA_ATTR: 249 case FEAT_PROJECT_QUOTA: 250 case FEAT_INODE_CHECKSUM: 251 case FEAT_FLEXIBLE_INLINE_XATTR: 252 case FEAT_QUOTA_INO: 253 case FEAT_INODE_CRTIME: 254 return snprintf(buf, PAGE_SIZE, "supported\n"); 255 } 256 return 0; 257 } 258 259 #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ 260 static struct f2fs_attr f2fs_attr_##_name = { \ 261 .attr = {.name = __stringify(_name), .mode = _mode }, \ 262 .show = _show, \ 263 .store = _store, \ 264 .struct_type = _struct_type, \ 265 .offset = _offset \ 266 } 267 268 #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ 269 F2FS_ATTR_OFFSET(struct_type, name, 0644, \ 270 f2fs_sbi_show, f2fs_sbi_store, \ 271 offsetof(struct struct_name, elname)) 272 273 #define F2FS_GENERAL_RO_ATTR(name) \ 274 static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) 275 276 #define F2FS_FEATURE_RO_ATTR(_name, _id) \ 277 static struct f2fs_attr f2fs_attr_##_name = { \ 278 .attr = {.name = __stringify(_name), .mode = 0444 }, \ 279 .show = f2fs_feature_show, \ 280 .id = _id, \ 281 } 282 283 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time, 284 urgent_sleep_time); 285 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); 286 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); 287 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); 288 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); 289 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent); 290 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); 291 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); 292 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity); 293 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); 294 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); 295 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); 296 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); 297 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); 298 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); 299 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections); 300 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); 301 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); 302 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); 303 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); 304 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); 305 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); 306 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); 307 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable); 308 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra); 309 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold); 310 #ifdef CONFIG_F2FS_FAULT_INJECTION 311 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); 312 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); 313 #endif 314 F2FS_GENERAL_RO_ATTR(dirty_segments); 315 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); 316 F2FS_GENERAL_RO_ATTR(features); 317 F2FS_GENERAL_RO_ATTR(current_reserved_blocks); 318 319 #ifdef CONFIG_F2FS_FS_ENCRYPTION 320 F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); 321 #endif 322 #ifdef CONFIG_BLK_DEV_ZONED 323 F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); 324 #endif 325 F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); 326 F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); 327 F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); 328 F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); 329 F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); 330 F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); 331 F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); 332 333 #define ATTR_LIST(name) (&f2fs_attr_##name.attr) 334 static struct attribute *f2fs_attrs[] = { 335 ATTR_LIST(gc_urgent_sleep_time), 336 ATTR_LIST(gc_min_sleep_time), 337 ATTR_LIST(gc_max_sleep_time), 338 ATTR_LIST(gc_no_gc_sleep_time), 339 ATTR_LIST(gc_idle), 340 ATTR_LIST(gc_urgent), 341 ATTR_LIST(reclaim_segments), 342 ATTR_LIST(max_small_discards), 343 ATTR_LIST(discard_granularity), 344 ATTR_LIST(batched_trim_sections), 345 ATTR_LIST(ipu_policy), 346 ATTR_LIST(min_ipu_util), 347 ATTR_LIST(min_fsync_blocks), 348 ATTR_LIST(min_hot_blocks), 349 ATTR_LIST(min_ssr_sections), 350 ATTR_LIST(max_victim_search), 351 ATTR_LIST(dir_level), 352 ATTR_LIST(ram_thresh), 353 ATTR_LIST(ra_nid_pages), 354 ATTR_LIST(dirty_nats_ratio), 355 ATTR_LIST(cp_interval), 356 ATTR_LIST(idle_interval), 357 ATTR_LIST(iostat_enable), 358 ATTR_LIST(readdir_ra), 359 ATTR_LIST(gc_pin_file_thresh), 360 #ifdef CONFIG_F2FS_FAULT_INJECTION 361 ATTR_LIST(inject_rate), 362 ATTR_LIST(inject_type), 363 #endif 364 ATTR_LIST(dirty_segments), 365 ATTR_LIST(lifetime_write_kbytes), 366 ATTR_LIST(features), 367 ATTR_LIST(reserved_blocks), 368 ATTR_LIST(current_reserved_blocks), 369 NULL, 370 }; 371 372 static struct attribute *f2fs_feat_attrs[] = { 373 #ifdef CONFIG_F2FS_FS_ENCRYPTION 374 ATTR_LIST(encryption), 375 #endif 376 #ifdef CONFIG_BLK_DEV_ZONED 377 ATTR_LIST(block_zoned), 378 #endif 379 ATTR_LIST(atomic_write), 380 ATTR_LIST(extra_attr), 381 ATTR_LIST(project_quota), 382 ATTR_LIST(inode_checksum), 383 ATTR_LIST(flexible_inline_xattr), 384 ATTR_LIST(quota_ino), 385 ATTR_LIST(inode_crtime), 386 NULL, 387 }; 388 389 static const struct sysfs_ops f2fs_attr_ops = { 390 .show = f2fs_attr_show, 391 .store = f2fs_attr_store, 392 }; 393 394 static struct kobj_type f2fs_sb_ktype = { 395 .default_attrs = f2fs_attrs, 396 .sysfs_ops = &f2fs_attr_ops, 397 .release = f2fs_sb_release, 398 }; 399 400 static struct kobj_type f2fs_ktype = { 401 .sysfs_ops = &f2fs_attr_ops, 402 }; 403 404 static struct kset f2fs_kset = { 405 .kobj = {.ktype = &f2fs_ktype}, 406 }; 407 408 static struct kobj_type f2fs_feat_ktype = { 409 .default_attrs = f2fs_feat_attrs, 410 .sysfs_ops = &f2fs_attr_ops, 411 }; 412 413 static struct kobject f2fs_feat = { 414 .kset = &f2fs_kset, 415 }; 416 417 static int segment_info_seq_show(struct seq_file *seq, void *offset) 418 { 419 struct super_block *sb = seq->private; 420 struct f2fs_sb_info *sbi = F2FS_SB(sb); 421 unsigned int total_segs = 422 le32_to_cpu(sbi->raw_super->segment_count_main); 423 int i; 424 425 seq_puts(seq, "format: segment_type|valid_blocks\n" 426 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 427 428 for (i = 0; i < total_segs; i++) { 429 struct seg_entry *se = get_seg_entry(sbi, i); 430 431 if ((i % 10) == 0) 432 seq_printf(seq, "%-10d", i); 433 seq_printf(seq, "%d|%-3u", se->type, 434 get_valid_blocks(sbi, i, false)); 435 if ((i % 10) == 9 || i == (total_segs - 1)) 436 seq_putc(seq, '\n'); 437 else 438 seq_putc(seq, ' '); 439 } 440 441 return 0; 442 } 443 444 static int segment_bits_seq_show(struct seq_file *seq, void *offset) 445 { 446 struct super_block *sb = seq->private; 447 struct f2fs_sb_info *sbi = F2FS_SB(sb); 448 unsigned int total_segs = 449 le32_to_cpu(sbi->raw_super->segment_count_main); 450 int i, j; 451 452 seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n" 453 "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); 454 455 for (i = 0; i < total_segs; i++) { 456 struct seg_entry *se = get_seg_entry(sbi, i); 457 458 seq_printf(seq, "%-10d", i); 459 seq_printf(seq, "%d|%-3u|", se->type, 460 get_valid_blocks(sbi, i, false)); 461 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) 462 seq_printf(seq, " %.2x", se->cur_valid_map[j]); 463 seq_putc(seq, '\n'); 464 } 465 return 0; 466 } 467 468 static int iostat_info_seq_show(struct seq_file *seq, void *offset) 469 { 470 struct super_block *sb = seq->private; 471 struct f2fs_sb_info *sbi = F2FS_SB(sb); 472 time64_t now = ktime_get_real_seconds(); 473 474 if (!sbi->iostat_enable) 475 return 0; 476 477 seq_printf(seq, "time: %-16llu\n", now); 478 479 /* print app IOs */ 480 seq_printf(seq, "app buffered: %-16llu\n", 481 sbi->write_iostat[APP_BUFFERED_IO]); 482 seq_printf(seq, "app direct: %-16llu\n", 483 sbi->write_iostat[APP_DIRECT_IO]); 484 seq_printf(seq, "app mapped: %-16llu\n", 485 sbi->write_iostat[APP_MAPPED_IO]); 486 487 /* print fs IOs */ 488 seq_printf(seq, "fs data: %-16llu\n", 489 sbi->write_iostat[FS_DATA_IO]); 490 seq_printf(seq, "fs node: %-16llu\n", 491 sbi->write_iostat[FS_NODE_IO]); 492 seq_printf(seq, "fs meta: %-16llu\n", 493 sbi->write_iostat[FS_META_IO]); 494 seq_printf(seq, "fs gc data: %-16llu\n", 495 sbi->write_iostat[FS_GC_DATA_IO]); 496 seq_printf(seq, "fs gc node: %-16llu\n", 497 sbi->write_iostat[FS_GC_NODE_IO]); 498 seq_printf(seq, "fs cp data: %-16llu\n", 499 sbi->write_iostat[FS_CP_DATA_IO]); 500 seq_printf(seq, "fs cp node: %-16llu\n", 501 sbi->write_iostat[FS_CP_NODE_IO]); 502 seq_printf(seq, "fs cp meta: %-16llu\n", 503 sbi->write_iostat[FS_CP_META_IO]); 504 seq_printf(seq, "fs discard: %-16llu\n", 505 sbi->write_iostat[FS_DISCARD]); 506 507 return 0; 508 } 509 510 #define F2FS_PROC_FILE_DEF(_name) \ 511 static int _name##_open_fs(struct inode *inode, struct file *file) \ 512 { \ 513 return single_open(file, _name##_seq_show, PDE_DATA(inode)); \ 514 } \ 515 \ 516 static const struct file_operations f2fs_seq_##_name##_fops = { \ 517 .open = _name##_open_fs, \ 518 .read = seq_read, \ 519 .llseek = seq_lseek, \ 520 .release = single_release, \ 521 }; 522 523 F2FS_PROC_FILE_DEF(segment_info); 524 F2FS_PROC_FILE_DEF(segment_bits); 525 F2FS_PROC_FILE_DEF(iostat_info); 526 527 int __init f2fs_init_sysfs(void) 528 { 529 int ret; 530 531 kobject_set_name(&f2fs_kset.kobj, "f2fs"); 532 f2fs_kset.kobj.parent = fs_kobj; 533 ret = kset_register(&f2fs_kset); 534 if (ret) 535 return ret; 536 537 ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype, 538 NULL, "features"); 539 if (ret) 540 kset_unregister(&f2fs_kset); 541 else 542 f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); 543 return ret; 544 } 545 546 void f2fs_exit_sysfs(void) 547 { 548 kobject_put(&f2fs_feat); 549 kset_unregister(&f2fs_kset); 550 remove_proc_entry("fs/f2fs", NULL); 551 f2fs_proc_root = NULL; 552 } 553 554 int f2fs_register_sysfs(struct f2fs_sb_info *sbi) 555 { 556 struct super_block *sb = sbi->sb; 557 int err; 558 559 sbi->s_kobj.kset = &f2fs_kset; 560 init_completion(&sbi->s_kobj_unregister); 561 err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL, 562 "%s", sb->s_id); 563 if (err) 564 return err; 565 566 if (f2fs_proc_root) 567 sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); 568 569 if (sbi->s_proc) { 570 proc_create_data("segment_info", S_IRUGO, sbi->s_proc, 571 &f2fs_seq_segment_info_fops, sb); 572 proc_create_data("segment_bits", S_IRUGO, sbi->s_proc, 573 &f2fs_seq_segment_bits_fops, sb); 574 proc_create_data("iostat_info", S_IRUGO, sbi->s_proc, 575 &f2fs_seq_iostat_info_fops, sb); 576 } 577 return 0; 578 } 579 580 void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) 581 { 582 if (sbi->s_proc) { 583 remove_proc_entry("iostat_info", sbi->s_proc); 584 remove_proc_entry("segment_info", sbi->s_proc); 585 remove_proc_entry("segment_bits", sbi->s_proc); 586 remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); 587 } 588 kobject_del(&sbi->s_kobj); 589 } 590