diff options
author | Theodore Ts'o <tytso@mit.edu> | 2012-05-30 22:56:46 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-05-30 22:56:46 -0400 |
commit | 2c0544b23568674efba22532e1f25fb62ce10163 (patch) | |
tree | b3da7424fc1aa1a69ec5c5c6ae6bbd7a74456364 /fs/ext4/super.c | |
parent | 6f2e9f0e7d795214b9cf5a47724a273b705fd113 (diff) |
ext4: add debugging trigger for ext4_error()
Make it easy to test whether or not the error handling subsystem in
ext4 is working correctly. This allows us to simulate an ext4_error()
by echoing a string to /sys/fs/ext4/<dev>/trigger_fs_error.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: ksumrall@google.com
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 628cfcdc0823..9f1ae6b36502 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2473,6 +2473,23 @@ static ssize_t sbi_ui_store(struct ext4_attr *a, | |||
2473 | return count; | 2473 | return count; |
2474 | } | 2474 | } |
2475 | 2475 | ||
2476 | static ssize_t trigger_test_error(struct ext4_attr *a, | ||
2477 | struct ext4_sb_info *sbi, | ||
2478 | const char *buf, size_t count) | ||
2479 | { | ||
2480 | int len = count; | ||
2481 | |||
2482 | if (!capable(CAP_SYS_ADMIN)) | ||
2483 | return -EPERM; | ||
2484 | |||
2485 | if (len && buf[len-1] == '\n') | ||
2486 | len--; | ||
2487 | |||
2488 | if (len) | ||
2489 | ext4_error(sbi->s_sb, "%.*s", len, buf); | ||
2490 | return count; | ||
2491 | } | ||
2492 | |||
2476 | #define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \ | 2493 | #define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \ |
2477 | static struct ext4_attr ext4_attr_##_name = { \ | 2494 | static struct ext4_attr ext4_attr_##_name = { \ |
2478 | .attr = {.name = __stringify(_name), .mode = _mode }, \ | 2495 | .attr = {.name = __stringify(_name), .mode = _mode }, \ |
@@ -2503,6 +2520,7 @@ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); | |||
2503 | EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); | 2520 | EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); |
2504 | EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); | 2521 | EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); |
2505 | EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump); | 2522 | EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump); |
2523 | EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error); | ||
2506 | 2524 | ||
2507 | static struct attribute *ext4_attrs[] = { | 2525 | static struct attribute *ext4_attrs[] = { |
2508 | ATTR_LIST(delayed_allocation_blocks), | 2526 | ATTR_LIST(delayed_allocation_blocks), |
@@ -2517,6 +2535,7 @@ static struct attribute *ext4_attrs[] = { | |||
2517 | ATTR_LIST(mb_stream_req), | 2535 | ATTR_LIST(mb_stream_req), |
2518 | ATTR_LIST(mb_group_prealloc), | 2536 | ATTR_LIST(mb_group_prealloc), |
2519 | ATTR_LIST(max_writeback_mb_bump), | 2537 | ATTR_LIST(max_writeback_mb_bump), |
2538 | ATTR_LIST(trigger_fs_error), | ||
2520 | NULL, | 2539 | NULL, |
2521 | }; | 2540 | }; |
2522 | 2541 | ||
@@ -3087,6 +3106,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3087 | goto out_free_orig; | 3106 | goto out_free_orig; |
3088 | } | 3107 | } |
3089 | sb->s_fs_info = sbi; | 3108 | sb->s_fs_info = sbi; |
3109 | sbi->s_sb = sb; | ||
3090 | sbi->s_mount_opt = 0; | 3110 | sbi->s_mount_opt = 0; |
3091 | sbi->s_resuid = EXT4_DEF_RESUID; | 3111 | sbi->s_resuid = EXT4_DEF_RESUID; |
3092 | sbi->s_resgid = EXT4_DEF_RESGID; | 3112 | sbi->s_resgid = EXT4_DEF_RESGID; |