diff options
author | Shaohua Li <shli@fb.com> | 2015-10-08 21:54:08 -0700 |
---|---|---|
committer | NeilBrown <neilb@suse.com> | 2015-11-01 13:48:29 +1100 |
commit | 6e74a9cfb5a55b0a4214809321b67d7065e55555 (patch) | |
tree | 30c3ed87535416ea84cc9698c4a00999598f9bbc /drivers/md/raid5.c | |
parent | c2bb6242ece5a2a0b6bd415c1d58babe83e971a8 (diff) | |
download | linux-6e74a9cfb5a55b0a4214809321b67d7065e55555.tar.bz2 |
raid5-cache: IO error handling
There are 3 places the raid5-cache dispatches IO. The discard IO error
doesn't matter, so we ignore it. The superblock write IO error can be
handled in MD core. The remaining are log write and flush. When the IO
error happens, we mark log disk faulty and fail all write IO. Read IO is
still allowed to run. Userspace will get a notification too and
corresponding daemon can choose setting raid array readonly for example.
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: NeilBrown <neilb@suse.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 693c000e739b..68c36ce4fe8e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3147,6 +3147,7 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, * the data has not reached the cache yet. */ if (!test_bit(R5_Wantfill, &sh->dev[i].flags) && + s->failed > conf->max_degraded && (!test_bit(R5_Insync, &sh->dev[i].flags) || test_bit(R5_ReadError, &sh->dev[i].flags))) { spin_lock_irq(&sh->stripe_lock); @@ -4015,6 +4016,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) s->expanded = test_bit(STRIPE_EXPAND_READY, &sh->state) && !sh->batch_head; s->failed_num[0] = -1; s->failed_num[1] = -1; + s->log_failed = r5l_log_disk_error(conf); /* Now to look around and see what can be done */ rcu_read_lock(); @@ -4358,7 +4360,7 @@ static void handle_stripe(struct stripe_head *sh) /* check if the array has lost more than max_degraded devices and, * if so, some requests might need to be failed. */ - if (s.failed > conf->max_degraded) { + if (s.failed > conf->max_degraded || s.log_failed) { sh->check_state = 0; sh->reconstruct_state = 0; break_stripe_batch_list(sh, 0); |