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 #ifdef DEBUG 94 95 STATIC ssize_t 96 fail_writes_store( 97 struct kobject *kobject, 98 const char *buf, 99 size_t count) 100 { 101 struct xfs_mount *mp = to_mp(kobject); 102 int ret; 103 int val; 104 105 ret = kstrtoint(buf, 0, &val); 106 if (ret) 107 return ret; 108 109 if (val == 1) 110 mp->m_fail_writes = true; 111 else if (val == 0) 112 mp->m_fail_writes = false; 113 else 114 return -EINVAL; 115 116 return count; 117 } 118 119 STATIC ssize_t 120 fail_writes_show( 121 struct kobject *kobject, 122 char *buf) 123 { 124 struct xfs_mount *mp = to_mp(kobject); 125 126 return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_writes ? 1 : 0); 127 } 128 XFS_SYSFS_ATTR_RW(fail_writes); 129 130 #endif /* DEBUG */ 131 132 static struct attribute *xfs_mp_attrs[] = { 133 #ifdef DEBUG 134 ATTR_LIST(fail_writes), 135 #endif 136 NULL, 137 }; 138 139 struct kobj_type xfs_mp_ktype = { 140 .release = xfs_sysfs_release, 141 .sysfs_ops = &xfs_sysfs_ops, 142 .default_attrs = xfs_mp_attrs, 143 }; 144 145 #ifdef DEBUG 146 /* debug */ 147 148 STATIC ssize_t 149 log_recovery_delay_store( 150 struct kobject *kobject, 151 const char *buf, 152 size_t count) 153 { 154 int ret; 155 int val; 156 157 ret = kstrtoint(buf, 0, &val); 158 if (ret) 159 return ret; 160 161 if (val < 0 || val > 60) 162 return -EINVAL; 163 164 xfs_globals.log_recovery_delay = val; 165 166 return count; 167 } 168 169 STATIC ssize_t 170 log_recovery_delay_show( 171 struct kobject *kobject, 172 char *buf) 173 { 174 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); 175 } 176 XFS_SYSFS_ATTR_RW(log_recovery_delay); 177 178 static struct attribute *xfs_dbg_attrs[] = { 179 ATTR_LIST(log_recovery_delay), 180 NULL, 181 }; 182 183 struct kobj_type xfs_dbg_ktype = { 184 .release = xfs_sysfs_release, 185 .sysfs_ops = &xfs_sysfs_ops, 186 .default_attrs = xfs_dbg_attrs, 187 }; 188 189 #endif /* DEBUG */ 190 191 /* stats */ 192 193 static inline struct xstats * 194 to_xstats(struct kobject *kobject) 195 { 196 struct xfs_kobj *kobj = to_kobj(kobject); 197 198 return container_of(kobj, struct xstats, xs_kobj); 199 } 200 201 STATIC ssize_t 202 stats_show( 203 struct kobject *kobject, 204 char *buf) 205 { 206 struct xstats *stats = to_xstats(kobject); 207 208 return xfs_stats_format(stats->xs_stats, buf); 209 } 210 XFS_SYSFS_ATTR_RO(stats); 211 212 STATIC ssize_t 213 stats_clear_store( 214 struct kobject *kobject, 215 const char *buf, 216 size_t count) 217 { 218 int ret; 219 int val; 220 struct xstats *stats = to_xstats(kobject); 221 222 ret = kstrtoint(buf, 0, &val); 223 if (ret) 224 return ret; 225 226 if (val != 1) 227 return -EINVAL; 228 229 xfs_stats_clearall(stats->xs_stats); 230 return count; 231 } 232 XFS_SYSFS_ATTR_WO(stats_clear); 233 234 static struct attribute *xfs_stats_attrs[] = { 235 ATTR_LIST(stats), 236 ATTR_LIST(stats_clear), 237 NULL, 238 }; 239 240 struct kobj_type xfs_stats_ktype = { 241 .release = xfs_sysfs_release, 242 .sysfs_ops = &xfs_sysfs_ops, 243 .default_attrs = xfs_stats_attrs, 244 }; 245 246 /* xlog */ 247 248 static inline struct xlog * 249 to_xlog(struct kobject *kobject) 250 { 251 struct xfs_kobj *kobj = to_kobj(kobject); 252 253 return container_of(kobj, struct xlog, l_kobj); 254 } 255 256 STATIC ssize_t 257 log_head_lsn_show( 258 struct kobject *kobject, 259 char *buf) 260 { 261 int cycle; 262 int block; 263 struct xlog *log = to_xlog(kobject); 264 265 spin_lock(&log->l_icloglock); 266 cycle = log->l_curr_cycle; 267 block = log->l_curr_block; 268 spin_unlock(&log->l_icloglock); 269 270 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 271 } 272 XFS_SYSFS_ATTR_RO(log_head_lsn); 273 274 STATIC ssize_t 275 log_tail_lsn_show( 276 struct kobject *kobject, 277 char *buf) 278 { 279 int cycle; 280 int block; 281 struct xlog *log = to_xlog(kobject); 282 283 xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); 284 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 285 } 286 XFS_SYSFS_ATTR_RO(log_tail_lsn); 287 288 STATIC ssize_t 289 reserve_grant_head_show( 290 struct kobject *kobject, 291 char *buf) 292 293 { 294 int cycle; 295 int bytes; 296 struct xlog *log = to_xlog(kobject); 297 298 xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes); 299 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 300 } 301 XFS_SYSFS_ATTR_RO(reserve_grant_head); 302 303 STATIC ssize_t 304 write_grant_head_show( 305 struct kobject *kobject, 306 char *buf) 307 { 308 int cycle; 309 int bytes; 310 struct xlog *log = to_xlog(kobject); 311 312 xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes); 313 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 314 } 315 XFS_SYSFS_ATTR_RO(write_grant_head); 316 317 #ifdef DEBUG 318 STATIC ssize_t 319 log_badcrc_factor_store( 320 struct kobject *kobject, 321 const char *buf, 322 size_t count) 323 { 324 struct xlog *log = to_xlog(kobject); 325 int ret; 326 uint32_t val; 327 328 ret = kstrtouint(buf, 0, &val); 329 if (ret) 330 return ret; 331 332 log->l_badcrc_factor = val; 333 334 return count; 335 } 336 337 STATIC ssize_t 338 log_badcrc_factor_show( 339 struct kobject *kobject, 340 char *buf) 341 { 342 struct xlog *log = to_xlog(kobject); 343 344 return snprintf(buf, PAGE_SIZE, "%d\n", log->l_badcrc_factor); 345 } 346 347 XFS_SYSFS_ATTR_RW(log_badcrc_factor); 348 #endif /* DEBUG */ 349 350 static struct attribute *xfs_log_attrs[] = { 351 ATTR_LIST(log_head_lsn), 352 ATTR_LIST(log_tail_lsn), 353 ATTR_LIST(reserve_grant_head), 354 ATTR_LIST(write_grant_head), 355 #ifdef DEBUG 356 ATTR_LIST(log_badcrc_factor), 357 #endif 358 NULL, 359 }; 360 361 struct kobj_type xfs_log_ktype = { 362 .release = xfs_sysfs_release, 363 .sysfs_ops = &xfs_sysfs_ops, 364 .default_attrs = xfs_log_attrs, 365 }; 366 367 /* 368 * Metadata IO error configuration 369 * 370 * The sysfs structure here is: 371 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs> 372 * 373 * where <class> allows us to discriminate between data IO and metadata IO, 374 * and any other future type of IO (e.g. special inode or directory error 375 * handling) we care to support. 376 */ 377 static inline struct xfs_error_cfg * 378 to_error_cfg(struct kobject *kobject) 379 { 380 struct xfs_kobj *kobj = to_kobj(kobject); 381 return container_of(kobj, struct xfs_error_cfg, kobj); 382 } 383 384 static inline struct xfs_mount * 385 err_to_mp(struct kobject *kobject) 386 { 387 struct xfs_kobj *kobj = to_kobj(kobject); 388 return container_of(kobj, struct xfs_mount, m_error_kobj); 389 } 390 391 static ssize_t 392 max_retries_show( 393 struct kobject *kobject, 394 char *buf) 395 { 396 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 397 398 return snprintf(buf, PAGE_SIZE, "%d\n", cfg->max_retries); 399 } 400 401 static ssize_t 402 max_retries_store( 403 struct kobject *kobject, 404 const char *buf, 405 size_t count) 406 { 407 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 408 int ret; 409 int val; 410 411 ret = kstrtoint(buf, 0, &val); 412 if (ret) 413 return ret; 414 415 if (val < -1) 416 return -EINVAL; 417 418 cfg->max_retries = val; 419 return count; 420 } 421 XFS_SYSFS_ATTR_RW(max_retries); 422 423 static ssize_t 424 retry_timeout_seconds_show( 425 struct kobject *kobject, 426 char *buf) 427 { 428 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 429 430 return snprintf(buf, PAGE_SIZE, "%ld\n", 431 jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC); 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 */ 449 if (val < 0 || val > 86400) 450 return -EINVAL; 451 452 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC); 453 return count; 454 } 455 XFS_SYSFS_ATTR_RW(retry_timeout_seconds); 456 457 static ssize_t 458 fail_at_unmount_show( 459 struct kobject *kobject, 460 char *buf) 461 { 462 struct xfs_mount *mp = err_to_mp(kobject); 463 464 return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount); 465 } 466 467 static ssize_t 468 fail_at_unmount_store( 469 struct kobject *kobject, 470 const char *buf, 471 size_t count) 472 { 473 struct xfs_mount *mp = err_to_mp(kobject); 474 int ret; 475 int val; 476 477 ret = kstrtoint(buf, 0, &val); 478 if (ret) 479 return ret; 480 481 if (val < 0 || val > 1) 482 return -EINVAL; 483 484 mp->m_fail_unmount = val; 485 return count; 486 } 487 XFS_SYSFS_ATTR_RW(fail_at_unmount); 488 489 static struct attribute *xfs_error_attrs[] = { 490 ATTR_LIST(max_retries), 491 ATTR_LIST(retry_timeout_seconds), 492 NULL, 493 }; 494 495 496 struct kobj_type xfs_error_cfg_ktype = { 497 .release = xfs_sysfs_release, 498 .sysfs_ops = &xfs_sysfs_ops, 499 .default_attrs = xfs_error_attrs, 500 }; 501 502 struct kobj_type xfs_error_ktype = { 503 .release = xfs_sysfs_release, 504 .sysfs_ops = &xfs_sysfs_ops, 505 }; 506 507 /* 508 * Error initialization tables. These need to be ordered in the same 509 * order as the enums used to index the array. All class init tables need to 510 * define a "default" behaviour as the first entry, all other entries can be 511 * empty. 512 */ 513 struct xfs_error_init { 514 char *name; 515 int max_retries; 516 int retry_timeout; /* in seconds */ 517 }; 518 519 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = { 520 { .name = "default", 521 .max_retries = XFS_ERR_RETRY_FOREVER, 522 .retry_timeout = 0, 523 }, 524 { .name = "EIO", 525 .max_retries = XFS_ERR_RETRY_FOREVER, 526 .retry_timeout = 0, 527 }, 528 { .name = "ENOSPC", 529 .max_retries = XFS_ERR_RETRY_FOREVER, 530 .retry_timeout = 0, 531 }, 532 { .name = "ENODEV", 533 .max_retries = 0, 534 }, 535 }; 536 537 static int 538 xfs_error_sysfs_init_class( 539 struct xfs_mount *mp, 540 int class, 541 const char *parent_name, 542 struct xfs_kobj *parent_kobj, 543 const struct xfs_error_init init[]) 544 { 545 struct xfs_error_cfg *cfg; 546 int error; 547 int i; 548 549 ASSERT(class < XFS_ERR_CLASS_MAX); 550 551 error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype, 552 &mp->m_error_kobj, parent_name); 553 if (error) 554 return error; 555 556 for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) { 557 cfg = &mp->m_error_cfg[class][i]; 558 error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype, 559 parent_kobj, init[i].name); 560 if (error) 561 goto out_error; 562 563 cfg->max_retries = init[i].max_retries; 564 cfg->retry_timeout = msecs_to_jiffies( 565 init[i].retry_timeout * MSEC_PER_SEC); 566 } 567 return 0; 568 569 out_error: 570 /* unwind the entries that succeeded */ 571 for (i--; i >= 0; i--) { 572 cfg = &mp->m_error_cfg[class][i]; 573 xfs_sysfs_del(&cfg->kobj); 574 } 575 xfs_sysfs_del(parent_kobj); 576 return error; 577 } 578 579 int 580 xfs_error_sysfs_init( 581 struct xfs_mount *mp) 582 { 583 int error; 584 585 /* .../xfs/<dev>/error/ */ 586 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype, 587 &mp->m_kobj, "error"); 588 if (error) 589 return error; 590 591 error = sysfs_create_file(&mp->m_error_kobj.kobject, 592 ATTR_LIST(fail_at_unmount)); 593 594 if (error) 595 goto out_error; 596 597 /* .../xfs/<dev>/error/metadata/ */ 598 error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA, 599 "metadata", &mp->m_error_meta_kobj, 600 xfs_error_meta_init); 601 if (error) 602 goto out_error; 603 604 return 0; 605 606 out_error: 607 xfs_sysfs_del(&mp->m_error_kobj); 608 return error; 609 } 610 611 void 612 xfs_error_sysfs_del( 613 struct xfs_mount *mp) 614 { 615 struct xfs_error_cfg *cfg; 616 int i, j; 617 618 for (i = 0; i < XFS_ERR_CLASS_MAX; i++) { 619 for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) { 620 cfg = &mp->m_error_cfg[i][j]; 621 622 xfs_sysfs_del(&cfg->kobj); 623 } 624 } 625 xfs_sysfs_del(&mp->m_error_meta_kobj); 626 xfs_sysfs_del(&mp->m_error_kobj); 627 } 628 629 struct xfs_error_cfg * 630 xfs_error_get_cfg( 631 struct xfs_mount *mp, 632 int error_class, 633 int error) 634 { 635 struct xfs_error_cfg *cfg; 636 637 if (error < 0) 638 error = -error; 639 640 switch (error) { 641 case EIO: 642 cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO]; 643 break; 644 case ENOSPC: 645 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC]; 646 break; 647 case ENODEV: 648 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV]; 649 break; 650 default: 651 cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT]; 652 break; 653 } 654 655 return cfg; 656 } 657