diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 159 |
1 files changed, 96 insertions, 63 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2c2e6cbc6bed..c977f4e4e63b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -411,20 +411,26 @@ static void ext4_handle_error(struct super_block *sb) | |||
411 | sb->s_id); | 411 | sb->s_id); |
412 | } | 412 | } |
413 | 413 | ||
414 | #define ext4_error_ratelimit(sb) \ | ||
415 | ___ratelimit(&(EXT4_SB(sb)->s_err_ratelimit_state), \ | ||
416 | "EXT4-fs error") | ||
417 | |||
414 | void __ext4_error(struct super_block *sb, const char *function, | 418 | void __ext4_error(struct super_block *sb, const char *function, |
415 | unsigned int line, const char *fmt, ...) | 419 | unsigned int line, const char *fmt, ...) |
416 | { | 420 | { |
417 | struct va_format vaf; | 421 | struct va_format vaf; |
418 | va_list args; | 422 | va_list args; |
419 | 423 | ||
420 | va_start(args, fmt); | 424 | if (ext4_error_ratelimit(sb)) { |
421 | vaf.fmt = fmt; | 425 | va_start(args, fmt); |
422 | vaf.va = &args; | 426 | vaf.fmt = fmt; |
423 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n", | 427 | vaf.va = &args; |
424 | sb->s_id, function, line, current->comm, &vaf); | 428 | printk(KERN_CRIT |
425 | va_end(args); | 429 | "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n", |
430 | sb->s_id, function, line, current->comm, &vaf); | ||
431 | va_end(args); | ||
432 | } | ||
426 | save_error_info(sb, function, line); | 433 | save_error_info(sb, function, line); |
427 | |||
428 | ext4_handle_error(sb); | 434 | ext4_handle_error(sb); |
429 | } | 435 | } |
430 | 436 | ||
@@ -438,22 +444,23 @@ void __ext4_error_inode(struct inode *inode, const char *function, | |||
438 | 444 | ||
439 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); | 445 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); |
440 | es->s_last_error_block = cpu_to_le64(block); | 446 | es->s_last_error_block = cpu_to_le64(block); |
447 | if (ext4_error_ratelimit(inode->i_sb)) { | ||
448 | va_start(args, fmt); | ||
449 | vaf.fmt = fmt; | ||
450 | vaf.va = &args; | ||
451 | if (block) | ||
452 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " | ||
453 | "inode #%lu: block %llu: comm %s: %pV\n", | ||
454 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
455 | block, current->comm, &vaf); | ||
456 | else | ||
457 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " | ||
458 | "inode #%lu: comm %s: %pV\n", | ||
459 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
460 | current->comm, &vaf); | ||
461 | va_end(args); | ||
462 | } | ||
441 | save_error_info(inode->i_sb, function, line); | 463 | save_error_info(inode->i_sb, function, line); |
442 | va_start(args, fmt); | ||
443 | vaf.fmt = fmt; | ||
444 | vaf.va = &args; | ||
445 | if (block) | ||
446 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " | ||
447 | "inode #%lu: block %llu: comm %s: %pV\n", | ||
448 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
449 | block, current->comm, &vaf); | ||
450 | else | ||
451 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " | ||
452 | "inode #%lu: comm %s: %pV\n", | ||
453 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
454 | current->comm, &vaf); | ||
455 | va_end(args); | ||
456 | |||
457 | ext4_handle_error(inode->i_sb); | 464 | ext4_handle_error(inode->i_sb); |
458 | } | 465 | } |
459 | 466 | ||
@@ -469,27 +476,28 @@ void __ext4_error_file(struct file *file, const char *function, | |||
469 | 476 | ||
470 | es = EXT4_SB(inode->i_sb)->s_es; | 477 | es = EXT4_SB(inode->i_sb)->s_es; |
471 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); | 478 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); |
479 | if (ext4_error_ratelimit(inode->i_sb)) { | ||
480 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | ||
481 | if (IS_ERR(path)) | ||
482 | path = "(unknown)"; | ||
483 | va_start(args, fmt); | ||
484 | vaf.fmt = fmt; | ||
485 | vaf.va = &args; | ||
486 | if (block) | ||
487 | printk(KERN_CRIT | ||
488 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
489 | "block %llu: comm %s: path %s: %pV\n", | ||
490 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
491 | block, current->comm, path, &vaf); | ||
492 | else | ||
493 | printk(KERN_CRIT | ||
494 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
495 | "comm %s: path %s: %pV\n", | ||
496 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
497 | current->comm, path, &vaf); | ||
498 | va_end(args); | ||
499 | } | ||
472 | save_error_info(inode->i_sb, function, line); | 500 | save_error_info(inode->i_sb, function, line); |
473 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | ||
474 | if (IS_ERR(path)) | ||
475 | path = "(unknown)"; | ||
476 | va_start(args, fmt); | ||
477 | vaf.fmt = fmt; | ||
478 | vaf.va = &args; | ||
479 | if (block) | ||
480 | printk(KERN_CRIT | ||
481 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
482 | "block %llu: comm %s: path %s: %pV\n", | ||
483 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
484 | block, current->comm, path, &vaf); | ||
485 | else | ||
486 | printk(KERN_CRIT | ||
487 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
488 | "comm %s: path %s: %pV\n", | ||
489 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
490 | current->comm, path, &vaf); | ||
491 | va_end(args); | ||
492 | |||
493 | ext4_handle_error(inode->i_sb); | 501 | ext4_handle_error(inode->i_sb); |
494 | } | 502 | } |
495 | 503 | ||
@@ -543,11 +551,13 @@ void __ext4_std_error(struct super_block *sb, const char *function, | |||
543 | (sb->s_flags & MS_RDONLY)) | 551 | (sb->s_flags & MS_RDONLY)) |
544 | return; | 552 | return; |
545 | 553 | ||
546 | errstr = ext4_decode_error(sb, errno, nbuf); | 554 | if (ext4_error_ratelimit(sb)) { |
547 | printk(KERN_CRIT "EXT4-fs error (device %s) in %s:%d: %s\n", | 555 | errstr = ext4_decode_error(sb, errno, nbuf); |
548 | sb->s_id, function, line, errstr); | 556 | printk(KERN_CRIT "EXT4-fs error (device %s) in %s:%d: %s\n", |
549 | save_error_info(sb, function, line); | 557 | sb->s_id, function, line, errstr); |
558 | } | ||
550 | 559 | ||
560 | save_error_info(sb, function, line); | ||
551 | ext4_handle_error(sb); | 561 | ext4_handle_error(sb); |
552 | } | 562 | } |
553 | 563 | ||
@@ -597,6 +607,9 @@ void __ext4_msg(struct super_block *sb, | |||
597 | struct va_format vaf; | 607 | struct va_format vaf; |
598 | va_list args; | 608 | va_list args; |
599 | 609 | ||
610 | if (!___ratelimit(&(EXT4_SB(sb)->s_msg_ratelimit_state), "EXT4-fs")) | ||
611 | return; | ||
612 | |||
600 | va_start(args, fmt); | 613 | va_start(args, fmt); |
601 | vaf.fmt = fmt; | 614 | vaf.fmt = fmt; |
602 | vaf.va = &args; | 615 | vaf.va = &args; |
@@ -610,6 +623,10 @@ void __ext4_warning(struct super_block *sb, const char *function, | |||
610 | struct va_format vaf; | 623 | struct va_format vaf; |
611 | va_list args; | 624 | va_list args; |
612 | 625 | ||
626 | if (!___ratelimit(&(EXT4_SB(sb)->s_warning_ratelimit_state), | ||
627 | "EXT4-fs warning")) | ||
628 | return; | ||
629 | |||
613 | va_start(args, fmt); | 630 | va_start(args, fmt); |
614 | vaf.fmt = fmt; | 631 | vaf.fmt = fmt; |
615 | vaf.va = &args; | 632 | vaf.va = &args; |
@@ -633,18 +650,20 @@ __acquires(bitlock) | |||
633 | es->s_last_error_block = cpu_to_le64(block); | 650 | es->s_last_error_block = cpu_to_le64(block); |
634 | __save_error_info(sb, function, line); | 651 | __save_error_info(sb, function, line); |
635 | 652 | ||
636 | va_start(args, fmt); | 653 | if (ext4_error_ratelimit(sb)) { |
637 | 654 | va_start(args, fmt); | |
638 | vaf.fmt = fmt; | 655 | vaf.fmt = fmt; |
639 | vaf.va = &args; | 656 | vaf.va = &args; |
640 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: group %u, ", | 657 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: group %u, ", |
641 | sb->s_id, function, line, grp); | 658 | sb->s_id, function, line, grp); |
642 | if (ino) | 659 | if (ino) |
643 | printk(KERN_CONT "inode %lu: ", ino); | 660 | printk(KERN_CONT "inode %lu: ", ino); |
644 | if (block) | 661 | if (block) |
645 | printk(KERN_CONT "block %llu:", (unsigned long long) block); | 662 | printk(KERN_CONT "block %llu:", |
646 | printk(KERN_CONT "%pV\n", &vaf); | 663 | (unsigned long long) block); |
647 | va_end(args); | 664 | printk(KERN_CONT "%pV\n", &vaf); |
665 | va_end(args); | ||
666 | } | ||
648 | 667 | ||
649 | if (test_opt(sb, ERRORS_CONT)) { | 668 | if (test_opt(sb, ERRORS_CONT)) { |
650 | ext4_commit_super(sb, 0); | 669 | ext4_commit_super(sb, 0); |
@@ -2606,6 +2625,12 @@ EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); | |||
2606 | EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128); | 2625 | EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128); |
2607 | EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); | 2626 | EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); |
2608 | EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error); | 2627 | EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error); |
2628 | EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval); | ||
2629 | EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst); | ||
2630 | EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval); | ||
2631 | EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst); | ||
2632 | EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval); | ||
2633 | EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst); | ||
2609 | 2634 | ||
2610 | static struct attribute *ext4_attrs[] = { | 2635 | static struct attribute *ext4_attrs[] = { |
2611 | ATTR_LIST(delayed_allocation_blocks), | 2636 | ATTR_LIST(delayed_allocation_blocks), |
@@ -2623,6 +2648,12 @@ static struct attribute *ext4_attrs[] = { | |||
2623 | ATTR_LIST(max_writeback_mb_bump), | 2648 | ATTR_LIST(max_writeback_mb_bump), |
2624 | ATTR_LIST(extent_max_zeroout_kb), | 2649 | ATTR_LIST(extent_max_zeroout_kb), |
2625 | ATTR_LIST(trigger_fs_error), | 2650 | ATTR_LIST(trigger_fs_error), |
2651 | ATTR_LIST(err_ratelimit_interval_ms), | ||
2652 | ATTR_LIST(err_ratelimit_burst), | ||
2653 | ATTR_LIST(warning_ratelimit_interval_ms), | ||
2654 | ATTR_LIST(warning_ratelimit_burst), | ||
2655 | ATTR_LIST(msg_ratelimit_interval_ms), | ||
2656 | ATTR_LIST(msg_ratelimit_burst), | ||
2626 | NULL, | 2657 | NULL, |
2627 | }; | 2658 | }; |
2628 | 2659 | ||
@@ -3037,7 +3068,6 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb, | |||
3037 | { | 3068 | { |
3038 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 3069 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
3039 | struct ext4_li_request *elr; | 3070 | struct ext4_li_request *elr; |
3040 | unsigned long rnd; | ||
3041 | 3071 | ||
3042 | elr = kzalloc(sizeof(*elr), GFP_KERNEL); | 3072 | elr = kzalloc(sizeof(*elr), GFP_KERNEL); |
3043 | if (!elr) | 3073 | if (!elr) |
@@ -3052,10 +3082,8 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb, | |||
3052 | * spread the inode table initialization requests | 3082 | * spread the inode table initialization requests |
3053 | * better. | 3083 | * better. |
3054 | */ | 3084 | */ |
3055 | get_random_bytes(&rnd, sizeof(rnd)); | 3085 | elr->lr_next_sched = jiffies + (prandom_u32() % |
3056 | elr->lr_next_sched = jiffies + (unsigned long)rnd % | 3086 | (EXT4_DEF_LI_MAX_START_DELAY * HZ)); |
3057 | (EXT4_DEF_LI_MAX_START_DELAY * HZ); | ||
3058 | |||
3059 | return elr; | 3087 | return elr; |
3060 | } | 3088 | } |
3061 | 3089 | ||
@@ -4118,6 +4146,11 @@ no_journal: | |||
4118 | if (es->s_error_count) | 4146 | if (es->s_error_count) |
4119 | mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ | 4147 | mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ |
4120 | 4148 | ||
4149 | /* Enable message ratelimiting. Default is 10 messages per 5 secs. */ | ||
4150 | ratelimit_state_init(&sbi->s_err_ratelimit_state, 5 * HZ, 10); | ||
4151 | ratelimit_state_init(&sbi->s_warning_ratelimit_state, 5 * HZ, 10); | ||
4152 | ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10); | ||
4153 | |||
4121 | kfree(orig_data); | 4154 | kfree(orig_data); |
4122 | return 0; | 4155 | return 0; |
4123 | 4156 | ||