diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 84dbf801e9b1..16625b79788b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -542,7 +542,7 @@ static void raid1_end_write_request(struct bio *bio) call_bio_endio(r1_bio); } } - } else if (rdev->mddev->serialize_policy) + } else if (test_bit(MD_SERIALIZE_POLICY, &rdev->mddev->flags)) remove_serial(rdev, lo, hi); if (r1_bio->bios[mirror] == NULL) rdev_dec_pending(rdev, conf->mddev); @@ -1319,6 +1319,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, int max_sectors; int rdisk; bool r1bio_existed = !!r1_bio; + bool nowait = bio->bi_opf & REQ_NOWAIT; /* * If r1_bio is set, we are blocking the raid1d thread @@ -1331,9 +1332,14 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, * Still need barrier for READ in case that whole * array is frozen. */ - if (!wait_read_barrier(conf, bio->bi_iter.bi_sector, - bio->bi_opf & REQ_NOWAIT)) { + if (!wait_read_barrier(conf, bio->bi_iter.bi_sector, nowait)) { bio_wouldblock_error(bio); + + if (r1bio_existed) { + set_bit(R1BIO_Returned, &r1_bio->state); + raid_end_bio_io(r1_bio); + } + return; } @@ -1373,7 +1379,11 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, * over-take any writes that are 'behind' */ mddev_add_trace_msg(mddev, "raid1 wait behind writes"); - mddev->bitmap_ops->wait_behind_writes(mddev); + if (!mddev->bitmap_ops->wait_behind_writes(mddev, nowait)) { + bio_wouldblock_error(bio); + set_bit(R1BIO_Returned, &r1_bio->state); + goto err_handle; + } } if (max_sectors < bio_sectors(bio)) { @@ -1581,8 +1591,10 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, * complexity of supporting that is not worth * the benefit. */ - if (bio->bi_opf & REQ_ATOMIC) + if (bio->bi_opf & REQ_ATOMIC) { + rdev_dec_pending(rdev, mddev); goto err_handle; + } good_sectors = first_bad - r1_bio->sector; if (good_sectors < max_sectors) @@ -1644,7 +1656,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, mbio = bio_alloc_clone(rdev->bdev, bio, GFP_NOIO, &mddev->bio_set); - if (mddev->serialize_policy) + if (test_bit(MD_SERIALIZE_POLICY, &mddev->flags)) wait_for_serialization(rdev, r1_bio); } @@ -1746,7 +1758,7 @@ static void raid1_status(struct seq_file *seq, struct mddev *mddev) * - &mddev->degraded is bumped. * * @rdev is marked as &Faulty excluding case when array is failed and - * &mddev->fail_last_dev is off. + * MD_FAILLAST_DEV is not set. */ static void raid1_error(struct mddev *mddev, struct md_rdev *rdev) { @@ -1759,7 +1771,7 @@ static void raid1_error(struct mddev *mddev, struct md_rdev *rdev) (conf->raid_disks - mddev->degraded) == 1) { set_bit(MD_BROKEN, &mddev->flags); - if (!mddev->fail_last_dev) { + if (!test_bit(MD_FAILLAST_DEV, &mddev->flags)) { conf->recovery_disabled = mddev->recovery_disabled; spin_unlock_irqrestore(&conf->device_lock, flags); return; |
