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-cache.c | |
parent | c2bb6242ece5a2a0b6bd415c1d58babe83e971a8 (diff) |
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-cache.c')
-rw-r--r-- | drivers/md/raid5-cache.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 7071c7598f5d..62e5fe4afae8 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -190,7 +190,6 @@ static void r5l_io_run_stripes(struct r5l_io_unit *io) } } -/* XXX: totally ignores I/O errors */ static void r5l_log_run_stripes(struct r5l_log *log) { struct r5l_io_unit *io, *next; @@ -213,6 +212,9 @@ static void r5l_log_endio(struct bio *bio) struct r5l_log *log = io->log; unsigned long flags; + if (bio->bi_error) + md_error(log->rdev->mddev, log->rdev); + bio_put(bio); spin_lock_irqsave(&log->io_list_lock, flags); @@ -598,6 +600,9 @@ static void r5l_log_flush_endio(struct bio *bio) unsigned long flags; struct r5l_io_unit *io; + if (bio->bi_error) + md_error(log->rdev->mddev, log->rdev); + spin_lock_irqsave(&log->io_list_lock, flags); list_for_each_entry(io, &log->flushing_ios, log_sibling) r5l_io_run_stripes(io); @@ -684,6 +689,7 @@ static void r5l_write_super_and_discard_space(struct r5l_log *log, md_update_sb(mddev, 1); } + /* discard IO error really doesn't matter, ignore it */ if (log->last_checkpoint < end) { blkdev_issue_discard(bdev, log->last_checkpoint + log->rdev->data_offset, @@ -798,6 +804,13 @@ void r5l_quiesce(struct r5l_log *log, int state) } } +bool r5l_log_disk_error(struct r5conf *conf) +{ + if (!conf->log) + return false; + return test_bit(Faulty, &conf->log->rdev->flags); +} + struct r5l_recovery_ctx { struct page *meta_page; /* current meta */ sector_t meta_total_blocks; /* total size of current meta and data */ |