diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5dd0c2e59ab98cf246bae49556d956163b20005b..4153da5d40111844616e8247a78e16c561602395 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2196,7 +2196,8 @@ static int narrow_write_error(struct r1bio *r1_bio, int i) if (rdev->badblocks.shift < 0) return 0; - block_sectors = 1 << rdev->badblocks.shift; + block_sectors = roundup(1 << rdev->badblocks.shift, + bdev_logical_block_size(rdev->bdev) >> 9); sector = r1_bio->sector; sectors = ((sector + block_sectors) & ~(sector_t)(block_sectors - 1)) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b8d76b1fba6457dd722410d8d82d752c67f84bba..a7196c49d15d5265df304ac6c2591ff8e1d1a5f3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2572,7 +2572,8 @@ static int narrow_write_error(struct r10bio *r10_bio, int i) if (rdev->badblocks.shift < 0) return 0; - block_sectors = 1 << rdev->badblocks.shift; + block_sectors = roundup(1 << rdev->badblocks.shift, + bdev_logical_block_size(rdev->bdev) >> 9); sector = r10_bio->sector; sectors = ((r10_bio->sector + block_sectors) & ~(sector_t)(block_sectors - 1)) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index aa76865b804b41c2b2af3b78f5b16c83eb034feb..e75d48c0421a41788c9159ef7e74d22ad93d9695 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3170,7 +3170,8 @@ static void handle_stripe_dirtying(struct r5conf *conf, * generate correct data from the parity. */ if (conf->max_degraded == 2 || - (recovery_cp < MaxSector && sh->sector >= recovery_cp)) { + (recovery_cp < MaxSector && sh->sector >= recovery_cp && + s->failed == 0)) { /* Calculate the real rcw later - for now make it * look like rcw is cheaper */