summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorLi Nan <linan122@huawei.com>2023-12-15 03:38:52 +0100
committerSong Liu <song@kernel.org>2023-12-16 00:22:15 +0100
commitca294b34aaf3a417fe9069b174e52508ac918ec8 (patch)
tree193b9669717323dacf9f03f6250675e1d9c46a22 /drivers/md
parentmd: factor out a helper exceed_read_errors() to check read_errors (diff)
downloadlinux-ca294b34aaf3a417fe9069b174e52508ac918ec8.tar.xz
linux-ca294b34aaf3a417fe9069b174e52508ac918ec8.zip
md/raid1: support read error check
After commit 1e50915fe0bb ("raid: improve MD/raid10 handling of correctable read errors."), rdev will be set to faulty if it reads data error to many times in raid10. Add this mechanism to raid1 now. Signed-off-by: Li Nan <linan122@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20231215023852.3478228-3-linan666@huaweicloud.com
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid1.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8c65ee0c4445..aaa434f0c175 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2256,16 +2256,24 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio)
* 3. Performs writes following reads for array synchronising.
*/
-static void fix_read_error(struct r1conf *conf, int read_disk,
- sector_t sect, int sectors)
+static void fix_read_error(struct r1conf *conf, struct r1bio *r1_bio)
{
+ sector_t sect = r1_bio->sector;
+ int sectors = r1_bio->sectors;
+ int read_disk = r1_bio->read_disk;
struct mddev *mddev = conf->mddev;
+ struct md_rdev *rdev = rcu_dereference(conf->mirrors[read_disk].rdev);
+
+ if (exceed_read_errors(mddev, rdev)) {
+ r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
+ return;
+ }
+
while(sectors) {
int s = sectors;
int d = read_disk;
int success = 0;
int start;
- struct md_rdev *rdev;
if (s > (PAGE_SIZE>>9))
s = PAGE_SIZE >> 9;
@@ -2506,8 +2514,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
if (mddev->ro == 0
&& !test_bit(FailFast, &rdev->flags)) {
freeze_array(conf, 1);
- fix_read_error(conf, r1_bio->read_disk,
- r1_bio->sector, r1_bio->sectors);
+ fix_read_error(conf, r1_bio);
unfreeze_array(conf);
} else if (mddev->ro == 0 && test_bit(FailFast, &rdev->flags)) {
md_error(mddev, rdev);