1 /* 2 * Copyright (c) 2014 Red Hat, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include "xfs.h" 20 #include "xfs_shared.h" 21 #include "xfs_format.h" 22 #include "xfs_log_format.h" 23 #include "xfs_trans_resv.h" 24 #include "xfs_sysfs.h" 25 #include "xfs_log.h" 26 #include "xfs_log_priv.h" 27 #include "xfs_stats.h" 28 #include "xfs_mount.h" 29 30 struct xfs_sysfs_attr { 31 struct attribute attr; 32 ssize_t (*show)(struct kobject *kobject, char *buf); 33 ssize_t (*store)(struct kobject *kobject, const char *buf, 34 size_t count); 35 }; 36 37 static inline struct xfs_sysfs_attr * 38 to_attr(struct attribute *attr) 39 { 40 return container_of(attr, struct xfs_sysfs_attr, attr); 41 } 42 43 #define XFS_SYSFS_ATTR_RW(name) \ 44 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) 45 #define XFS_SYSFS_ATTR_RO(name) \ 46 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) 47 #define XFS_SYSFS_ATTR_WO(name) \ 48 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name) 49 50 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr 51 52 STATIC ssize_t 53 xfs_sysfs_object_show( 54 struct kobject *kobject, 55 struct attribute *attr, 56 char *buf) 57 { 58 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 59 60 return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0; 61 } 62 63 STATIC ssize_t 64 xfs_sysfs_object_store( 65 struct kobject *kobject, 66 struct attribute *attr, 67 const char *buf, 68 size_t count) 69 { 70 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 71 72 return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0; 73 } 74 75 static const struct sysfs_ops xfs_sysfs_ops = { 76 .show = xfs_sysfs_object_show, 77 .store = xfs_sysfs_object_store, 78 }; 79 80 /* 81 * xfs_mount kobject. The mp kobject also serves as the per-mount parent object 82 * that is identified by the fsname under sysfs. 83 */ 84 85 static inline struct xfs_mount * 86 to_mp(struct kobject *kobject) 87 { 88 struct xfs_kobj *kobj = to_kobj(kobject); 89 90 return container_of(kobj, struct xfs_mount, m_kobj); 91 } 92 93 static struct attribute *xfs_mp_attrs[] = { 94 NULL, 95 }; 96 97 struct kobj_type xfs_mp_ktype = { 98 .release = xfs_sysfs_release, 99 .sysfs_ops = &xfs_sysfs_ops, 100 .default_attrs = xfs_mp_attrs, 101 }; 102 103 #ifdef DEBUG 104 /* debug */ 105 106 STATIC ssize_t 107 bug_on_assert_store( 108 struct kobject *kobject, 109 const char *buf, 110 size_t count) 111 { 112 int ret; 113 int val; 114 115 ret = kstrtoint(buf, 0, &val); 116 if (ret) 117 return ret; 118 119 if (val == 1) 120 xfs_globals.bug_on_assert = true; 121 else if (val == 0) 122 xfs_globals.bug_on_assert = false; 123 else 124 return -EINVAL; 125 126 return count; 127 } 128 129 STATIC ssize_t 130 bug_on_assert_show( 131 struct kobject *kobject, 132 char *buf) 133 { 134 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bug_on_assert ? 1 : 0); 135 } 136 XFS_SYSFS_ATTR_RW(bug_on_assert); 137 138 STATIC ssize_t 139 log_recovery_delay_store( 140 struct kobject *kobject, 141 const char *buf, 142 size_t count) 143 { 144 int ret; 145 int val; 146 147 ret = kstrtoint(buf, 0, &val); 148 if (ret) 149 return ret; 150 151 if (val < 0 || val > 60) 152 return -EINVAL; 153 154 xfs_globals.log_recovery_delay = val; 155 156 return count; 157 } 158 159 STATIC ssize_t 160 log_recovery_delay_show( 161 struct kobject *kobject, 162 char *buf) 163 { 164 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); 165 } 166 XFS_SYSFS_ATTR_RW(log_recovery_delay); 167 168 STATIC ssize_t 169 mount_delay_store( 170 struct kobject *kobject, 171 const char *buf, 172 size_t count) 173 { 174 int ret; 175 int val; 176 177 ret = kstrtoint(buf, 0, &val); 178 if (ret) 179 return ret; 180 181 if (val < 0 || val > 60) 182 return -EINVAL; 183 184 xfs_globals.mount_delay = val; 185 186 return count; 187 } 188 189 STATIC ssize_t 190 mount_delay_show( 191 struct kobject *kobject, 192 char *buf) 193 { 194 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.mount_delay); 195 } 196 XFS_SYSFS_ATTR_RW(mount_delay); 197 198 static struct attribute *xfs_dbg_attrs[] = { 199 ATTR_LIST(bug_on_assert), 200 ATTR_LIST(log_recovery_delay), 201 ATTR_LIST(mount_delay), 202 NULL, 203 }; 204 205 struct kobj_type xfs_dbg_ktype = { 206 .release = xfs_sysfs_release, 207 .sysfs_ops = &xfs_sysfs_ops, 208 .default_attrs = xfs_dbg_attrs, 209 }; 210 211 #endif /* DEBUG */ 212 213 /* stats */ 214 215 static inline struct xstats * 216 to_xstats(struct kobject *kobject) 217 { 218 struct xfs_kobj *kobj = to_kobj(kobject); 219 220 return container_of(kobj, struct xstats, xs_kobj); 221 } 222 223 STATIC ssize_t 224 stats_show( 225 struct kobject *kobject, 226 char *buf) 227 { 228 struct xstats *stats = to_xstats(kobject); 229 230 return xfs_stats_format(stats->xs_stats, buf); 231 } 232 XFS_SYSFS_ATTR_RO(stats); 233 234 STATIC ssize_t 235 stats_clear_store( 236 struct kobject *kobject, 237 const char *buf, 238 size_t count) 239 { 240 int ret; 241 int val; 242 struct xstats *stats = to_xstats(kobject); 243 244 ret = kstrtoint(buf, 0, &val); 245 if (ret) 246 return ret; 247 248 if (val != 1) 249 return -EINVAL; 250 251 xfs_stats_clearall(stats->xs_stats); 252 return count; 253 } 254 XFS_SYSFS_ATTR_WO(stats_clear); 255 256 static struct attribute *xfs_stats_attrs[] = { 257 ATTR_LIST(stats), 258 ATTR_LIST(stats_clear), 259 NULL, 260 }; 261 262 struct kobj_type xfs_stats_ktype = { 263 .release = xfs_sysfs_release, 264 .sysfs_ops = &xfs_sysfs_ops, 265 .default_attrs = xfs_stats_attrs, 266 }; 267 268 /* xlog */ 269 270 static inline struct xlog * 271 to_xlog(struct kobject *kobject) 272 { 273 struct xfs_kobj *kobj = to_kobj(kobject); 274 275 return container_of(kobj, struct xlog, l_kobj); 276 } 277 278 STATIC ssize_t 279 log_head_lsn_show( 280 struct kobject *kobject, 281 char *buf) 282 { 283 int cycle; 284 int block; 285 struct xlog *log = to_xlog(kobject); 286 287 spin_lock(&log->l_icloglock); 288 cycle = log->l_curr_cycle; 289 block = log->l_curr_block; 290 spin_unlock(&log->l_icloglock); 291 292 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 293 } 294 XFS_SYSFS_ATTR_RO(log_head_lsn); 295 296 STATIC ssize_t 297 log_tail_lsn_show( 298 struct kobject *kobject, 299 char *buf) 300 { 301 int cycle; 302 int block; 303 struct xlog *log = to_xlog(kobject); 304 305 xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); 306 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 307 } 308 XFS_SYSFS_ATTR_RO(log_tail_lsn); 309 310 STATIC ssize_t 311 reserve_grant_head_show( 312 struct kobject *kobject, 313 char *buf) 314 315 { 316 int cycle; 317 int bytes; 318 struct xlog *log = to_xlog(kobject); 319 320 xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes); 321 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 322 } 323 XFS_SYSFS_ATTR_RO(reserve_grant_head); 324 325 STATIC ssize_t 326 write_grant_head_show( 327 struct kobject *kobject, 328 char *buf) 329 { 330 int cycle; 331 int bytes; 332 struct xlog *log = to_xlog(kobject); 333 334 xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes); 335 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 336 } 337 XFS_SYSFS_ATTR_RO(write_grant_head); 338 339 static struct attribute *xfs_log_attrs[] = { 340 ATTR_LIST(log_head_lsn), 341 ATTR_LIST(log_tail_lsn), 342 ATTR_LIST(reserve_grant_head), 343 ATTR_LIST(write_grant_head), 344 NULL, 345 }; 346 347 struct kobj_type xfs_log_ktype = { 348 .release = xfs_sysfs_release, 349 .sysfs_ops = &xfs_sysfs_ops, 350 .default_attrs = xfs_log_attrs, 351 }; 352 353 /* 354 * Metadata IO error configuration 355 * 356 * The sysfs structure here is: 357 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs> 358 * 359 * where <class> allows us to discriminate between data IO and metadata IO, 360 * and any other future type of IO (e.g. special inode or directory error 361 * handling) we care to support. 362 */ 363 static inline struct xfs_error_cfg * 364 to_error_cfg(struct kobject *kobject) 365 { 366 struct xfs_kobj *kobj = to_kobj(kobject); 367 return container_of(kobj, struct xfs_error_cfg, kobj); 368 } 369 370 static inline struct xfs_mount * 371 err_to_mp(struct kobject *kobject) 372 { 373 struct xfs_kobj *kobj = to_kobj(kobject); 374 return container_of(kobj, struct xfs_mount, m_error_kobj); 375 } 376 377 static ssize_t 378 max_retries_show( 379 struct kobject *kobject, 380 char *buf) 381 { 382 int retries; 383 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 384 385 if (cfg->max_retries == XFS_ERR_RETRY_FOREVER) 386 retries = -1; 387 else 388 retries = cfg->max_retries; 389 390 return snprintf(buf, PAGE_SIZE, "%d\n", retries); 391 } 392 393 static ssize_t 394 max_retries_store( 395 struct kobject *kobject, 396 const char *buf, 397 size_t count) 398 { 399 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 400 int ret; 401 int val; 402 403 ret = kstrtoint(buf, 0, &val); 404 if (ret) 405 return ret; 406 407 if (val < -1) 408 return -EINVAL; 409 410 if (val == -1) 411 cfg->max_retries = XFS_ERR_RETRY_FOREVER; 412 else 413 cfg->max_retries = val; 414 return count; 415 } 416 XFS_SYSFS_ATTR_RW(max_retries); 417 418 static ssize_t 419 retry_timeout_seconds_show( 420 struct kobject *kobject, 421 char *buf) 422 { 423 int timeout; 424 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 425 426 if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER) 427 timeout = -1; 428 else 429 timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC; 430 431 return snprintf(buf, PAGE_SIZE, "%d\n", timeout); 432 } 433 434 static ssize_t 435 retry_timeout_seconds_store( 436 struct kobject *kobject, 437 const char *buf, 438 size_t count) 439 { 440 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 441 int ret; 442 int val; 443 444 ret = kstrtoint(buf, 0, &val); 445 if (ret) 446 return ret; 447 448 /* 1 day timeout maximum, -1 means infinite */ 449 if (val < -1 || val > 86400) 450 return -EINVAL; 451 452 if (val == -1) 453 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER; 454 else { 455 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC); 456 ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX); 457 } 458 return count; 459 } 460 XFS_SYSFS_ATTR_RW(retry_timeout_seconds); 461 462 static ssize_t 463 fail_at_unmount_show( 464 struct kobject *kobject, 465 char *buf) 466 { 467 struct xfs_mount *mp = err_to_mp(kobject); 468 469 return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount); 470 } 471 472 static ssize_t 473 fail_at_unmount_store( 474 struct kobject *kobject, 475 const char *buf, 476 size_t count) 477 { 478 struct xfs_mount *mp = err_to_mp(kobject); 479 int ret; 480 int val; 481 482 ret = kstrtoint(buf, 0, &val); 483 if (ret) 484 return ret; 485 486 if (val < 0 || val > 1) 487 return -EINVAL; 488 489 mp->m_fail_unmount = val; 490 return count; 491 } 492 XFS_SYSFS_ATTR_RW(fail_at_unmount); 493 494 static struct attribute *xfs_error_attrs[] = { 495 ATTR_LIST(max_retries), 496 ATTR_LIST(retry_timeout_seconds), 497 NULL, 498 }; 499 500 501 static struct kobj_type xfs_error_cfg_ktype = { 502 .release = xfs_sysfs_release, 503 .sysfs_ops = &xfs_sysfs_ops, 504 .default_attrs = xfs_error_attrs, 505 }; 506 507 static struct kobj_type xfs_error_ktype = { 508 .release = xfs_sysfs_release, 509 .sysfs_ops = &xfs_sysfs_ops, 510 }; 511 512 /* 513 * Error initialization tables. These need to be ordered in the same 514 * order as the enums used to index the array. All class init tables need to 515 * define a "default" behaviour as the first entry, all other entries can be 516 * empty. 517 */ 518 struct xfs_error_init { 519 char *name; 520 int max_retries; 521 int retry_timeout; /* in seconds */ 522 }; 523 524 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = { 525 { .name = "default", 526 .max_retries = XFS_ERR_RETRY_FOREVER, 527 .retry_timeout = XFS_ERR_RETRY_FOREVER, 528 }, 529 { .name = "EIO", 530 .max_retries = XFS_ERR_RETRY_FOREVER, 531 .retry_timeout = XFS_ERR_RETRY_FOREVER, 532 }, 533 { .name = "ENOSPC", 534 .max_retries = XFS_ERR_RETRY_FOREVER, 535 .retry_timeout = XFS_ERR_RETRY_FOREVER, 536 }, 537 { .name = "ENODEV", 538 .max_retries = 0, /* We can't recover from devices disappearing */ 539 .retry_timeout = 0, 540 }, 541 }; 542 543 static int 544 xfs_error_sysfs_init_class( 545 struct xfs_mount *mp, 546 int class, 547 const char *parent_name, 548 struct xfs_kobj *parent_kobj, 549 const struct xfs_error_init init[]) 550 { 551 struct xfs_error_cfg *cfg; 552 int error; 553 int i; 554 555 ASSERT(class < XFS_ERR_CLASS_MAX); 556 557 error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype, 558 &mp->m_error_kobj, parent_name); 559 if (error) 560 return error; 561 562 for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) { 563 cfg = &mp->m_error_cfg[class][i]; 564 error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype, 565 parent_kobj, init[i].name); 566 if (error) 567 goto out_error; 568 569 cfg->max_retries = init[i].max_retries; 570 if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER) 571 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER; 572 else 573 cfg->retry_timeout = msecs_to_jiffies( 574 init[i].retry_timeout * MSEC_PER_SEC); 575 } 576 return 0; 577 578 out_error: 579 /* unwind the entries that succeeded */ 580 for (i--; i >= 0; i--) { 581 cfg = &mp->m_error_cfg[class][i]; 582 xfs_sysfs_del(&cfg->kobj); 583 } 584 xfs_sysfs_del(parent_kobj); 585 return error; 586 } 587 588 int 589 xfs_error_sysfs_init( 590 struct xfs_mount *mp) 591 { 592 int error; 593 594 /* .../xfs/<dev>/error/ */ 595 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype, 596 &mp->m_kobj, "error"); 597 if (error) 598 return error; 599 600 error = sysfs_create_file(&mp->m_error_kobj.kobject, 601 ATTR_LIST(fail_at_unmount)); 602 603 if (error) 604 goto out_error; 605 606 /* .../xfs/<dev>/error/metadata/ */ 607 error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA, 608 "metadata", &mp->m_error_meta_kobj, 609 xfs_error_meta_init); 610 if (error) 611 goto out_error; 612 613 return 0; 614 615 out_error: 616 xfs_sysfs_del(&mp->m_error_kobj); 617 return error; 618 } 619 620 void 621 xfs_error_sysfs_del( 622 struct xfs_mount *mp) 623 { 624 struct xfs_error_cfg *cfg; 625 int i, j; 626 627 for (i = 0; i < XFS_ERR_CLASS_MAX; i++) { 628 for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) { 629 cfg = &mp->m_error_cfg[i][j]; 630 631 xfs_sysfs_del(&cfg->kobj); 632 } 633 } 634 xfs_sysfs_del(&mp->m_error_meta_kobj); 635 xfs_sysfs_del(&mp->m_error_kobj); 636 } 637 638 struct xfs_error_cfg * 639 xfs_error_get_cfg( 640 struct xfs_mount *mp, 641 int error_class, 642 int error) 643 { 644 struct xfs_error_cfg *cfg; 645 646 if (error < 0) 647 error = -error; 648 649 switch (error) { 650 case EIO: 651 cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO]; 652 break; 653 case ENOSPC: 654 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC]; 655 break; 656 case ENODEV: 657 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV]; 658 break; 659 default: 660 cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT]; 661 break; 662 } 663 664 return cfg; 665 } 666