1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2014 Red Hat, Inc. 4 * All Rights Reserved. 5 */ 6 7 #include "xfs_platform.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_sysfs.h" 13 #include "xfs_log.h" 14 #include "xfs_log_priv.h" 15 #include "xfs_mount.h" 16 #include "xfs_zone_priv.h" 17 #include "xfs_zones.h" 18 #include "xfs_zone_alloc.h" 19 20 struct xfs_sysfs_attr { 21 struct attribute attr; 22 ssize_t (*show)(struct kobject *kobject, char *buf); 23 ssize_t (*store)(struct kobject *kobject, const char *buf, 24 size_t count); 25 }; 26 27 static inline struct xfs_sysfs_attr * 28 to_attr(struct attribute *attr) 29 { 30 return container_of(attr, struct xfs_sysfs_attr, attr); 31 } 32 33 #define XFS_SYSFS_ATTR_RW(name) \ 34 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) 35 #define XFS_SYSFS_ATTR_RO(name) \ 36 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) 37 #define XFS_SYSFS_ATTR_WO(name) \ 38 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name) 39 40 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr 41 42 STATIC ssize_t 43 xfs_sysfs_object_show( 44 struct kobject *kobject, 45 struct attribute *attr, 46 char *buf) 47 { 48 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 49 50 return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0; 51 } 52 53 STATIC ssize_t 54 xfs_sysfs_object_store( 55 struct kobject *kobject, 56 struct attribute *attr, 57 const char *buf, 58 size_t count) 59 { 60 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 61 62 return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0; 63 } 64 65 static const struct sysfs_ops xfs_sysfs_ops = { 66 .show = xfs_sysfs_object_show, 67 .store = xfs_sysfs_object_store, 68 }; 69 70 static struct attribute *xfs_mp_attrs[] = { 71 NULL, 72 }; 73 ATTRIBUTE_GROUPS(xfs_mp); 74 75 static const struct kobj_type xfs_mp_ktype = { 76 .release = xfs_sysfs_release, 77 .sysfs_ops = &xfs_sysfs_ops, 78 .default_groups = xfs_mp_groups, 79 }; 80 81 #ifdef DEBUG 82 /* debug */ 83 84 STATIC ssize_t 85 bug_on_assert_store( 86 struct kobject *kobject, 87 const char *buf, 88 size_t count) 89 { 90 int ret; 91 int val; 92 93 ret = kstrtoint(buf, 0, &val); 94 if (ret) 95 return ret; 96 97 if (val == 1) 98 xfs_globals.bug_on_assert = true; 99 else if (val == 0) 100 xfs_globals.bug_on_assert = false; 101 else 102 return -EINVAL; 103 104 return count; 105 } 106 107 STATIC ssize_t 108 bug_on_assert_show( 109 struct kobject *kobject, 110 char *buf) 111 { 112 return sysfs_emit(buf, "%d\n", xfs_globals.bug_on_assert); 113 } 114 XFS_SYSFS_ATTR_RW(bug_on_assert); 115 116 STATIC ssize_t 117 log_recovery_delay_store( 118 struct kobject *kobject, 119 const char *buf, 120 size_t count) 121 { 122 int ret; 123 int val; 124 125 ret = kstrtoint(buf, 0, &val); 126 if (ret) 127 return ret; 128 129 if (val < 0 || val > 60) 130 return -EINVAL; 131 132 xfs_globals.log_recovery_delay = val; 133 134 return count; 135 } 136 137 STATIC ssize_t 138 log_recovery_delay_show( 139 struct kobject *kobject, 140 char *buf) 141 { 142 return sysfs_emit(buf, "%d\n", xfs_globals.log_recovery_delay); 143 } 144 XFS_SYSFS_ATTR_RW(log_recovery_delay); 145 146 STATIC ssize_t 147 mount_delay_store( 148 struct kobject *kobject, 149 const char *buf, 150 size_t count) 151 { 152 int ret; 153 int val; 154 155 ret = kstrtoint(buf, 0, &val); 156 if (ret) 157 return ret; 158 159 if (val < 0 || val > 60) 160 return -EINVAL; 161 162 xfs_globals.mount_delay = val; 163 164 return count; 165 } 166 167 STATIC ssize_t 168 mount_delay_show( 169 struct kobject *kobject, 170 char *buf) 171 { 172 return sysfs_emit(buf, "%d\n", xfs_globals.mount_delay); 173 } 174 XFS_SYSFS_ATTR_RW(mount_delay); 175 176 static ssize_t 177 always_cow_store( 178 struct kobject *kobject, 179 const char *buf, 180 size_t count) 181 { 182 ssize_t ret; 183 184 ret = kstrtobool(buf, &xfs_globals.always_cow); 185 if (ret < 0) 186 return ret; 187 return count; 188 } 189 190 static ssize_t 191 always_cow_show( 192 struct kobject *kobject, 193 char *buf) 194 { 195 return sysfs_emit(buf, "%d\n", xfs_globals.always_cow); 196 } 197 XFS_SYSFS_ATTR_RW(always_cow); 198 199 /* 200 * Override how many threads the parallel work queue is allowed to create. 201 * This has to be a debug-only global (instead of an errortag) because one of 202 * the main users of parallel workqueues is mount time quotacheck. 203 */ 204 STATIC ssize_t 205 pwork_threads_store( 206 struct kobject *kobject, 207 const char *buf, 208 size_t count) 209 { 210 int ret; 211 int val; 212 213 ret = kstrtoint(buf, 0, &val); 214 if (ret) 215 return ret; 216 217 if (val < -1 || val > num_possible_cpus()) 218 return -EINVAL; 219 220 xfs_globals.pwork_threads = val; 221 222 return count; 223 } 224 225 STATIC ssize_t 226 pwork_threads_show( 227 struct kobject *kobject, 228 char *buf) 229 { 230 return sysfs_emit(buf, "%d\n", xfs_globals.pwork_threads); 231 } 232 XFS_SYSFS_ATTR_RW(pwork_threads); 233 234 /* 235 * The "LARP" (Logged extended Attribute Recovery Persistence) debugging knob 236 * sets the XFS_DA_OP_LOGGED flag on all xfs_attr_set operations performed on 237 * V5 filesystems. As a result, the intermediate progress of all setxattr and 238 * removexattr operations are tracked via the log and can be restarted during 239 * recovery. This is useful for testing xattr recovery prior to merging of the 240 * parent pointer feature which requires it to maintain consistency, and may be 241 * enabled for userspace xattrs in the future. 242 */ 243 static ssize_t 244 larp_store( 245 struct kobject *kobject, 246 const char *buf, 247 size_t count) 248 { 249 ssize_t ret; 250 251 ret = kstrtobool(buf, &xfs_globals.larp); 252 if (ret < 0) 253 return ret; 254 return count; 255 } 256 257 STATIC ssize_t 258 larp_show( 259 struct kobject *kobject, 260 char *buf) 261 { 262 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.larp); 263 } 264 XFS_SYSFS_ATTR_RW(larp); 265 266 STATIC ssize_t 267 bload_leaf_slack_store( 268 struct kobject *kobject, 269 const char *buf, 270 size_t count) 271 { 272 int ret; 273 int val; 274 275 ret = kstrtoint(buf, 0, &val); 276 if (ret) 277 return ret; 278 279 xfs_globals.bload_leaf_slack = val; 280 return count; 281 } 282 283 STATIC ssize_t 284 bload_leaf_slack_show( 285 struct kobject *kobject, 286 char *buf) 287 { 288 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bload_leaf_slack); 289 } 290 XFS_SYSFS_ATTR_RW(bload_leaf_slack); 291 292 STATIC ssize_t 293 bload_node_slack_store( 294 struct kobject *kobject, 295 const char *buf, 296 size_t count) 297 { 298 int ret; 299 int val; 300 301 ret = kstrtoint(buf, 0, &val); 302 if (ret) 303 return ret; 304 305 xfs_globals.bload_node_slack = val; 306 return count; 307 } 308 309 STATIC ssize_t 310 bload_node_slack_show( 311 struct kobject *kobject, 312 char *buf) 313 { 314 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bload_node_slack); 315 } 316 XFS_SYSFS_ATTR_RW(bload_node_slack); 317 318 static struct attribute *xfs_dbg_attrs[] = { 319 ATTR_LIST(bug_on_assert), 320 ATTR_LIST(log_recovery_delay), 321 ATTR_LIST(mount_delay), 322 ATTR_LIST(always_cow), 323 ATTR_LIST(pwork_threads), 324 ATTR_LIST(larp), 325 ATTR_LIST(bload_leaf_slack), 326 ATTR_LIST(bload_node_slack), 327 NULL, 328 }; 329 ATTRIBUTE_GROUPS(xfs_dbg); 330 331 const struct kobj_type xfs_dbg_ktype = { 332 .release = xfs_sysfs_release, 333 .sysfs_ops = &xfs_sysfs_ops, 334 .default_groups = xfs_dbg_groups, 335 }; 336 337 #endif /* DEBUG */ 338 339 /* stats */ 340 341 static inline struct xstats * 342 to_xstats(struct kobject *kobject) 343 { 344 struct xfs_kobj *kobj = to_kobj(kobject); 345 346 return container_of(kobj, struct xstats, xs_kobj); 347 } 348 349 STATIC ssize_t 350 stats_show( 351 struct kobject *kobject, 352 char *buf) 353 { 354 struct xstats *stats = to_xstats(kobject); 355 356 return xfs_stats_format(stats->xs_stats, buf); 357 } 358 XFS_SYSFS_ATTR_RO(stats); 359 360 STATIC ssize_t 361 stats_clear_store( 362 struct kobject *kobject, 363 const char *buf, 364 size_t count) 365 { 366 int ret; 367 int val; 368 struct xstats *stats = to_xstats(kobject); 369 370 ret = kstrtoint(buf, 0, &val); 371 if (ret) 372 return ret; 373 374 if (val != 1) 375 return -EINVAL; 376 377 xfs_stats_clearall(stats->xs_stats); 378 return count; 379 } 380 XFS_SYSFS_ATTR_WO(stats_clear); 381 382 static struct attribute *xfs_stats_attrs[] = { 383 ATTR_LIST(stats), 384 ATTR_LIST(stats_clear), 385 NULL, 386 }; 387 ATTRIBUTE_GROUPS(xfs_stats); 388 389 const struct kobj_type xfs_stats_ktype = { 390 .release = xfs_sysfs_release, 391 .sysfs_ops = &xfs_sysfs_ops, 392 .default_groups = xfs_stats_groups, 393 }; 394 395 static inline struct xfs_mount *csum_to_mp(struct kobject *kobj) 396 { 397 return container_of(to_kobj(kobj), struct xfs_mount, m_csum_kobj); 398 } 399 400 static bool 401 xfs_has_read_bounce( 402 struct xfs_mount *mp) 403 { 404 if (bdev_has_integrity_csum(mp->m_ddev_targp->bt_bdev)) 405 return true; 406 if (mp->m_rtdev_targp && 407 bdev_has_integrity_csum(mp->m_rtdev_targp->bt_bdev)) 408 return true; 409 return false; 410 } 411 412 static const char * const bounce_modes[] = { 413 [XFS_READ_BOUNCE_NEVER] = "never", 414 [XFS_READ_BOUNCE_ALWAYS] = "always", 415 [XFS_READ_BOUNCE_LAZY] = "lazy", 416 }; 417 418 static ssize_t 419 read_bounce_show( 420 struct kobject *kobj, 421 char *buf) 422 { 423 struct xfs_mount *mp = csum_to_mp(kobj); 424 425 return sysfs_emit(buf, "%s\n", 426 bounce_modes[READ_ONCE(mp->m_read_bounce)]); 427 } 428 429 static ssize_t 430 read_bounce_store( 431 struct kobject *kobj, 432 const char *buf, 433 size_t count) 434 { 435 struct xfs_mount *mp = csum_to_mp(kobj); 436 int ret; 437 438 if (!xfs_has_read_bounce(mp)) 439 return -EINVAL; 440 ret = sysfs_match_string(bounce_modes, buf); 441 if (ret < 0) 442 return ret; 443 WRITE_ONCE(mp->m_read_bounce, ret); 444 return count; 445 } 446 XFS_SYSFS_ATTR_RW(read_bounce); 447 448 static struct attribute *xfs_csum_attrs[] = { 449 ATTR_LIST(read_bounce), 450 NULL, 451 }; 452 ATTRIBUTE_GROUPS(xfs_csum); 453 454 static const struct kobj_type xfs_csum_ktype = { 455 .release = xfs_sysfs_release, 456 .sysfs_ops = &xfs_sysfs_ops, 457 .default_groups = xfs_csum_groups, 458 }; 459 460 /* xlog */ 461 462 static inline struct xlog * 463 to_xlog(struct kobject *kobject) 464 { 465 struct xfs_kobj *kobj = to_kobj(kobject); 466 467 return container_of(kobj, struct xlog, l_kobj); 468 } 469 470 STATIC ssize_t 471 log_head_lsn_show( 472 struct kobject *kobject, 473 char *buf) 474 { 475 int cycle; 476 int block; 477 struct xlog *log = to_xlog(kobject); 478 479 spin_lock(&log->l_icloglock); 480 cycle = log->l_curr_cycle; 481 block = log->l_curr_block; 482 spin_unlock(&log->l_icloglock); 483 484 return sysfs_emit(buf, "%d:%d\n", cycle, block); 485 } 486 XFS_SYSFS_ATTR_RO(log_head_lsn); 487 488 STATIC ssize_t 489 log_tail_lsn_show( 490 struct kobject *kobject, 491 char *buf) 492 { 493 int cycle; 494 int block; 495 struct xlog *log = to_xlog(kobject); 496 497 xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); 498 return sysfs_emit(buf, "%d:%d\n", cycle, block); 499 } 500 XFS_SYSFS_ATTR_RO(log_tail_lsn); 501 502 STATIC ssize_t 503 reserve_grant_head_bytes_show( 504 struct kobject *kobject, 505 char *buf) 506 { 507 return sysfs_emit(buf, "%lld\n", 508 atomic64_read(&to_xlog(kobject)->l_reserve_head.grant)); 509 } 510 XFS_SYSFS_ATTR_RO(reserve_grant_head_bytes); 511 512 STATIC ssize_t 513 write_grant_head_bytes_show( 514 struct kobject *kobject, 515 char *buf) 516 { 517 return sysfs_emit(buf, "%lld\n", 518 atomic64_read(&to_xlog(kobject)->l_write_head.grant)); 519 } 520 XFS_SYSFS_ATTR_RO(write_grant_head_bytes); 521 522 static struct attribute *xfs_log_attrs[] = { 523 ATTR_LIST(log_head_lsn), 524 ATTR_LIST(log_tail_lsn), 525 ATTR_LIST(reserve_grant_head_bytes), 526 ATTR_LIST(write_grant_head_bytes), 527 NULL, 528 }; 529 ATTRIBUTE_GROUPS(xfs_log); 530 531 const struct kobj_type xfs_log_ktype = { 532 .release = xfs_sysfs_release, 533 .sysfs_ops = &xfs_sysfs_ops, 534 .default_groups = xfs_log_groups, 535 }; 536 537 /* 538 * Metadata IO error configuration 539 * 540 * The sysfs structure here is: 541 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs> 542 * 543 * where <class> allows us to discriminate between data IO and metadata IO, 544 * and any other future type of IO (e.g. special inode or directory error 545 * handling) we care to support. 546 */ 547 static inline struct xfs_error_cfg * 548 to_error_cfg(struct kobject *kobject) 549 { 550 struct xfs_kobj *kobj = to_kobj(kobject); 551 return container_of(kobj, struct xfs_error_cfg, kobj); 552 } 553 554 static inline struct xfs_mount * 555 err_to_mp(struct kobject *kobject) 556 { 557 struct xfs_kobj *kobj = to_kobj(kobject); 558 return container_of(kobj, struct xfs_mount, m_error_kobj); 559 } 560 561 static ssize_t 562 max_retries_show( 563 struct kobject *kobject, 564 char *buf) 565 { 566 int retries; 567 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 568 569 if (cfg->max_retries == XFS_ERR_RETRY_FOREVER) 570 retries = -1; 571 else 572 retries = cfg->max_retries; 573 574 return sysfs_emit(buf, "%d\n", retries); 575 } 576 577 static ssize_t 578 max_retries_store( 579 struct kobject *kobject, 580 const char *buf, 581 size_t count) 582 { 583 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 584 int ret; 585 int val; 586 587 ret = kstrtoint(buf, 0, &val); 588 if (ret) 589 return ret; 590 591 if (val < -1) 592 return -EINVAL; 593 594 if (val == -1) 595 cfg->max_retries = XFS_ERR_RETRY_FOREVER; 596 else 597 cfg->max_retries = val; 598 return count; 599 } 600 XFS_SYSFS_ATTR_RW(max_retries); 601 602 static ssize_t 603 retry_timeout_seconds_show( 604 struct kobject *kobject, 605 char *buf) 606 { 607 int timeout; 608 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 609 610 if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER) 611 timeout = -1; 612 else 613 timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC; 614 615 return sysfs_emit(buf, "%d\n", timeout); 616 } 617 618 static ssize_t 619 retry_timeout_seconds_store( 620 struct kobject *kobject, 621 const char *buf, 622 size_t count) 623 { 624 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 625 int ret; 626 int val; 627 628 ret = kstrtoint(buf, 0, &val); 629 if (ret) 630 return ret; 631 632 /* 1 day timeout maximum, -1 means infinite */ 633 if (val < -1 || val > 86400) 634 return -EINVAL; 635 636 if (val == -1) 637 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER; 638 else { 639 cfg->retry_timeout = secs_to_jiffies(val); 640 ASSERT(secs_to_jiffies(val) < LONG_MAX); 641 } 642 return count; 643 } 644 XFS_SYSFS_ATTR_RW(retry_timeout_seconds); 645 646 static ssize_t 647 fail_at_unmount_show( 648 struct kobject *kobject, 649 char *buf) 650 { 651 struct xfs_mount *mp = err_to_mp(kobject); 652 653 return sysfs_emit(buf, "%d\n", mp->m_fail_unmount); 654 } 655 656 static ssize_t 657 fail_at_unmount_store( 658 struct kobject *kobject, 659 const char *buf, 660 size_t count) 661 { 662 struct xfs_mount *mp = err_to_mp(kobject); 663 int ret; 664 int val; 665 666 ret = kstrtoint(buf, 0, &val); 667 if (ret) 668 return ret; 669 670 if (val < 0 || val > 1) 671 return -EINVAL; 672 673 mp->m_fail_unmount = val; 674 return count; 675 } 676 XFS_SYSFS_ATTR_RW(fail_at_unmount); 677 678 static struct attribute *xfs_error_attrs[] = { 679 ATTR_LIST(max_retries), 680 ATTR_LIST(retry_timeout_seconds), 681 NULL, 682 }; 683 ATTRIBUTE_GROUPS(xfs_error); 684 685 static const struct kobj_type xfs_error_cfg_ktype = { 686 .release = xfs_sysfs_release, 687 .sysfs_ops = &xfs_sysfs_ops, 688 .default_groups = xfs_error_groups, 689 }; 690 691 static const struct kobj_type xfs_error_ktype = { 692 .release = xfs_sysfs_release, 693 .sysfs_ops = &xfs_sysfs_ops, 694 }; 695 696 /* 697 * Error initialization tables. These need to be ordered in the same 698 * order as the enums used to index the array. All class init tables need to 699 * define a "default" behaviour as the first entry, all other entries can be 700 * empty. 701 */ 702 struct xfs_error_init { 703 char *name; 704 int max_retries; 705 int retry_timeout; /* in seconds */ 706 }; 707 708 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = { 709 { .name = "default", 710 .max_retries = XFS_ERR_RETRY_FOREVER, 711 .retry_timeout = XFS_ERR_RETRY_FOREVER, 712 }, 713 { .name = "EIO", 714 .max_retries = XFS_ERR_RETRY_FOREVER, 715 .retry_timeout = XFS_ERR_RETRY_FOREVER, 716 }, 717 { .name = "ENOSPC", 718 .max_retries = XFS_ERR_RETRY_FOREVER, 719 .retry_timeout = XFS_ERR_RETRY_FOREVER, 720 }, 721 { .name = "ENODEV", 722 .max_retries = 0, /* We can't recover from devices disappearing */ 723 .retry_timeout = 0, 724 }, 725 }; 726 727 static int 728 xfs_error_sysfs_init_class( 729 struct xfs_mount *mp, 730 int class, 731 const char *parent_name, 732 struct xfs_kobj *parent_kobj, 733 const struct xfs_error_init init[]) 734 { 735 struct xfs_error_cfg *cfg; 736 int error; 737 int i; 738 739 ASSERT(class < XFS_ERR_CLASS_MAX); 740 741 error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype, 742 &mp->m_error_kobj, parent_name); 743 if (error) 744 return error; 745 746 for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) { 747 cfg = &mp->m_error_cfg[class][i]; 748 error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype, 749 parent_kobj, init[i].name); 750 if (error) 751 goto out_error; 752 753 cfg->max_retries = init[i].max_retries; 754 if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER) 755 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER; 756 else 757 cfg->retry_timeout = 758 secs_to_jiffies(init[i].retry_timeout); 759 } 760 return 0; 761 762 out_error: 763 /* unwind the entries that succeeded */ 764 for (i--; i >= 0; i--) { 765 cfg = &mp->m_error_cfg[class][i]; 766 xfs_sysfs_del(&cfg->kobj); 767 } 768 xfs_sysfs_del(parent_kobj); 769 return error; 770 } 771 772 static inline struct xfs_mount *zoned_to_mp(struct kobject *kobj) 773 { 774 return container_of(to_kobj(kobj), struct xfs_mount, m_zoned_kobj); 775 } 776 777 static ssize_t 778 max_open_zones_show( 779 struct kobject *kobj, 780 char *buf) 781 { 782 /* only report the open zones available for user data */ 783 return sysfs_emit(buf, "%u\n", 784 zoned_to_mp(kobj)->m_max_open_zones - XFS_OPEN_GC_ZONES); 785 } 786 XFS_SYSFS_ATTR_RO(max_open_zones); 787 788 static ssize_t 789 nr_open_zones_show( 790 struct kobject *kobj, 791 char *buf) 792 { 793 struct xfs_zone_info *zi = zoned_to_mp(kobj)->m_zone_info; 794 795 return sysfs_emit(buf, "%u\n", READ_ONCE(zi->zi_nr_open_zones)); 796 } 797 XFS_SYSFS_ATTR_RO(nr_open_zones); 798 799 static ssize_t 800 zonegc_low_space_store( 801 struct kobject *kobj, 802 const char *buf, 803 size_t count) 804 { 805 struct xfs_mount *mp = zoned_to_mp(kobj); 806 int ret; 807 unsigned int val; 808 809 ret = kstrtouint(buf, 0, &val); 810 if (ret) 811 return ret; 812 813 if (val > 100) 814 return -EINVAL; 815 816 if (mp->m_zonegc_low_space != val) { 817 mp->m_zonegc_low_space = val; 818 xfs_zone_gc_wakeup(mp); 819 } 820 821 return count; 822 } 823 824 static ssize_t 825 zonegc_low_space_show( 826 struct kobject *kobj, 827 char *buf) 828 { 829 return sysfs_emit(buf, "%u\n", 830 zoned_to_mp(kobj)->m_zonegc_low_space); 831 } 832 XFS_SYSFS_ATTR_RW(zonegc_low_space); 833 834 static struct attribute *xfs_zoned_attrs[] = { 835 ATTR_LIST(max_open_zones), 836 ATTR_LIST(nr_open_zones), 837 ATTR_LIST(zonegc_low_space), 838 NULL, 839 }; 840 ATTRIBUTE_GROUPS(xfs_zoned); 841 842 static const struct kobj_type xfs_zoned_ktype = { 843 .release = xfs_sysfs_release, 844 .sysfs_ops = &xfs_sysfs_ops, 845 .default_groups = xfs_zoned_groups, 846 }; 847 848 int 849 xfs_zoned_sysfs_init(struct xfs_mount *mp) 850 { 851 if (!IS_ENABLED(CONFIG_XFS_RT) || !xfs_has_zoned(mp)) 852 return 0; 853 854 return xfs_sysfs_init(&mp->m_zoned_kobj, &xfs_zoned_ktype, 855 &mp->m_kobj, "zoned"); 856 } 857 858 void 859 xfs_zoned_sysfs_del(struct xfs_mount *mp) 860 { 861 if (IS_ENABLED(CONFIG_XFS_RT) && xfs_has_zoned(mp)) 862 xfs_sysfs_del(&mp->m_zoned_kobj); 863 } 864 865 int 866 xfs_mount_sysfs_init( 867 struct xfs_mount *mp) 868 { 869 int error; 870 871 super_set_sysfs_name_id(mp->m_super); 872 873 /* .../xfs/<dev>/ */ 874 error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, 875 NULL, mp->m_super->s_id); 876 if (error) 877 return error; 878 879 /* .../xfs/<dev>/stats/ */ 880 error = xfs_sysfs_init(&mp->m_stats.xs_kobj, &xfs_stats_ktype, 881 &mp->m_kobj, "stats"); 882 if (error) 883 goto out_remove_fsdir; 884 885 /* .../xfs/<dev>/csum/ */ 886 error = xfs_sysfs_init(&mp->m_csum_kobj, &xfs_csum_ktype, &mp->m_kobj, 887 "csum"); 888 if (error) 889 goto out_remove_stats_dir; 890 891 /* .../xfs/<dev>/error/ */ 892 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype, 893 &mp->m_kobj, "error"); 894 if (error) 895 goto out_remove_csum_dir; 896 897 /* .../xfs/<dev>/error/fail_at_unmount */ 898 error = sysfs_create_file(&mp->m_error_kobj.kobject, 899 ATTR_LIST(fail_at_unmount)); 900 901 if (error) 902 goto out_remove_error_dir; 903 904 /* .../xfs/<dev>/error/metadata/ */ 905 error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA, 906 "metadata", &mp->m_error_meta_kobj, 907 xfs_error_meta_init); 908 if (error) 909 goto out_remove_error_dir; 910 911 return 0; 912 913 out_remove_error_dir: 914 xfs_sysfs_del(&mp->m_error_kobj); 915 out_remove_csum_dir: 916 xfs_sysfs_del(&mp->m_csum_kobj); 917 out_remove_stats_dir: 918 xfs_sysfs_del(&mp->m_stats.xs_kobj); 919 out_remove_fsdir: 920 xfs_sysfs_del(&mp->m_kobj); 921 return error; 922 } 923 924 void 925 xfs_mount_sysfs_del( 926 struct xfs_mount *mp) 927 { 928 struct xfs_error_cfg *cfg; 929 int i, j; 930 931 for (i = 0; i < XFS_ERR_CLASS_MAX; i++) { 932 for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) { 933 cfg = &mp->m_error_cfg[i][j]; 934 935 xfs_sysfs_del(&cfg->kobj); 936 } 937 } 938 xfs_sysfs_del(&mp->m_error_meta_kobj); 939 xfs_sysfs_del(&mp->m_error_kobj); 940 xfs_sysfs_del(&mp->m_csum_kobj); 941 xfs_sysfs_del(&mp->m_stats.xs_kobj); 942 xfs_sysfs_del(&mp->m_kobj); 943 } 944 945 struct xfs_error_cfg * 946 xfs_error_get_cfg( 947 struct xfs_mount *mp, 948 int error_class, 949 int error) 950 { 951 struct xfs_error_cfg *cfg; 952 953 if (error < 0) 954 error = -error; 955 956 switch (error) { 957 case EIO: 958 cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO]; 959 break; 960 case ENOSPC: 961 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC]; 962 break; 963 case ENODEV: 964 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV]; 965 break; 966 default: 967 cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT]; 968 break; 969 } 970 971 return cfg; 972 } 973