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