aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorTomasz Majchrzak <tomasz.majchrzak@intel.com>2016-10-28 08:45:58 -0400
committerShaohua Li <shli@fb.com>2016-10-29 01:04:04 -0400
commit7449f699b2fb23bdee0a0f03aa4efb5f96fd403f (patch)
treec0d79a71c7d8171f034a58ffed73e274fbd689b5 /drivers/md
parent9a8b27fac5bbb77337cc2e5d31d37c9936782d87 (diff)
raid1: handle read error also in readonly mode
If write is the first operation on a disk and it happens not to be aligned to page size, block layer sends read request first. If read operation fails, the disk is set as failed as no attempt to fix the error is made because array is in auto-readonly mode. Similarily, the disk is set as failed for read-only array. Take the same approach as in raid10. Don't fail the disk if array is in readonly or auto-readonly mode. Try to redirect the request first and if unsuccessful, return a read error. Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com> Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid1.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index db536a68b2ee..29e2df5cd77b 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2297,17 +2297,23 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
2297 * This is all done synchronously while the array is 2297 * This is all done synchronously while the array is
2298 * frozen 2298 * frozen
2299 */ 2299 */
2300
2301 bio = r1_bio->bios[r1_bio->read_disk];
2302 bdevname(bio->bi_bdev, b);
2303 bio_put(bio);
2304 r1_bio->bios[r1_bio->read_disk] = NULL;
2305
2300 if (mddev->ro == 0) { 2306 if (mddev->ro == 0) {
2301 freeze_array(conf, 1); 2307 freeze_array(conf, 1);
2302 fix_read_error(conf, r1_bio->read_disk, 2308 fix_read_error(conf, r1_bio->read_disk,
2303 r1_bio->sector, r1_bio->sectors); 2309 r1_bio->sector, r1_bio->sectors);
2304 unfreeze_array(conf); 2310 unfreeze_array(conf);
2305 } else 2311 } else {
2306 md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); 2312 r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
2313 }
2314
2307 rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); 2315 rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
2308 2316
2309 bio = r1_bio->bios[r1_bio->read_disk];
2310 bdevname(bio->bi_bdev, b);
2311read_more: 2317read_more:
2312 disk = read_balance(conf, r1_bio, &max_sectors); 2318 disk = read_balance(conf, r1_bio, &max_sectors);
2313 if (disk == -1) { 2319 if (disk == -1) {
@@ -2318,11 +2324,6 @@ read_more:
2318 } else { 2324 } else {
2319 const unsigned long do_sync 2325 const unsigned long do_sync
2320 = r1_bio->master_bio->bi_opf & REQ_SYNC; 2326 = r1_bio->master_bio->bi_opf & REQ_SYNC;
2321 if (bio) {
2322 r1_bio->bios[r1_bio->read_disk] =
2323 mddev->ro ? IO_BLOCKED : NULL;
2324 bio_put(bio);
2325 }
2326 r1_bio->read_disk = disk; 2327 r1_bio->read_disk = disk;
2327 bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev); 2328 bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
2328 bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector, 2329 bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,