diff options
author | Jens Axboe <axboe@kernel.dk> | 2024-08-15 23:53:08 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-08-15 23:53:08 +0300 |
commit | 50faba777177e80fd29a249fcd9f8aa18348d65b (patch) | |
tree | b6555d198877e184e09b9d9b90ddaad51fc77639 | |
parent | 7db4042336580dfd75cb5faa82c12cd51098c90b (diff) | |
parent | c916ca35308d3187c9928664f9be249b22a3a701 (diff) | |
download | linux-50faba777177e80fd29a249fcd9f8aa18348d65b.tar.xz |
Merge tag 'md-6.11-20240815' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into block-6.11
Pull MD fix from Song:
"This patch fixes a potential data corruption in degraded raid0 array
with slow (WriteMostly) drives. This issue was introduced in upstream
6.9 kernel."
* tag 'md-6.11-20240815' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md:
md/raid1: Fix data corruption for degraded array with slow disk
-rw-r--r-- | drivers/md/raid1.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7acfe7c9dc8d..761989d67906 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -617,6 +617,12 @@ static int choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio, return -1; } +static bool rdev_in_recovery(struct md_rdev *rdev, struct r1bio *r1_bio) +{ + return !test_bit(In_sync, &rdev->flags) && + rdev->recovery_offset < r1_bio->sector + r1_bio->sectors; +} + static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio, int *max_sectors) { @@ -635,6 +641,7 @@ static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio, rdev = conf->mirrors[disk].rdev; if (!rdev || test_bit(Faulty, &rdev->flags) || + rdev_in_recovery(rdev, r1_bio) || test_bit(WriteMostly, &rdev->flags)) continue; @@ -673,7 +680,8 @@ static int choose_slow_rdev(struct r1conf *conf, struct r1bio *r1_bio, rdev = conf->mirrors[disk].rdev; if (!rdev || test_bit(Faulty, &rdev->flags) || - !test_bit(WriteMostly, &rdev->flags)) + !test_bit(WriteMostly, &rdev->flags) || + rdev_in_recovery(rdev, r1_bio)) continue; /* there are no bad blocks, we can use this disk */ @@ -733,9 +741,7 @@ static bool rdev_readable(struct md_rdev *rdev, struct r1bio *r1_bio) if (!rdev || test_bit(Faulty, &rdev->flags)) return false; - /* still in recovery */ - if (!test_bit(In_sync, &rdev->flags) && - rdev->recovery_offset < r1_bio->sector + r1_bio->sectors) + if (rdev_in_recovery(rdev, r1_bio)) return false; /* don't read from slow disk unless have to */ |