[PATCH v3 04/13] md/raid1,raid10: set Uptodate and clear badblocks if narrow_write_error success

linan666@huaweicloud.com posted 13 patches 3 days, 10 hours ago
[PATCH v3 04/13] md/raid1,raid10: set Uptodate and clear badblocks if narrow_write_error success
Posted by linan666@huaweicloud.com 3 days, 10 hours ago
From: Li Nan <linan122@huawei.com>

narrow_write_error() returns true when all sectors are rewritten
successfully. In this case, set R1BIO_Uptodate to return success
to upper layers and clear correspondinga badblocks.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/raid1.c  | 24 ++++++++++++++++++++----
 drivers/md/raid10.c | 17 +++++++++++++++--
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 9ffa3ab0fdcc..bd63cf039381 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2587,9 +2587,10 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
 	int m, idx;
 	bool fail = false;
 
-	for (m = 0; m < conf->raid_disks * 2 ; m++)
+	for (m = 0; m < conf->raid_disks * 2 ; m++) {
+		struct md_rdev *rdev = conf->mirrors[m].rdev;
+
 		if (r1_bio->bios[m] == IO_MADE_GOOD) {
-			struct md_rdev *rdev = conf->mirrors[m].rdev;
 			rdev_clear_badblocks(rdev,
 					     r1_bio->sector,
 					     r1_bio->sectors, 0);
@@ -2599,11 +2600,26 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
 			 * narrow down and record precise write
 			 * errors.
 			 */
-			fail = true;
-			narrow_write_error(r1_bio, m);
+			if (narrow_write_error(r1_bio, m)) {
+				/* re-write success */
+				if (rdev_has_badblock(rdev,
+						      r1_bio->sector,
+						      r1_bio->sectors))
+					rdev_clear_badblocks(rdev,
+							     r1_bio->sector,
+							     r1_bio->sectors, 0);
+				if (test_bit(In_sync, &rdev->flags) &&
+				    !test_bit(Faulty, &rdev->flags))
+					set_bit(R1BIO_Uptodate,
+						&r1_bio->state);
+			} else {
+				fail = true;
+			}
+
 			rdev_dec_pending(conf->mirrors[m].rdev,
 					 conf->mddev);
 		}
+	}
 	if (fail) {
 		spin_lock_irq(&conf->device_lock);
 		list_add(&r1_bio->retry_list, &conf->bio_end_io_list);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 21a347c4829b..db6fbd423726 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2939,8 +2939,21 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
 					r10_bio->sectors, 0);
 				rdev_dec_pending(rdev, conf->mddev);
 			} else if (bio != NULL && bio->bi_status) {
-				fail = true;
-				narrow_write_error(r10_bio, m);
+				if (narrow_write_error(r10_bio, m)) {
+					/* re-write success */
+					if (rdev_has_badblock(rdev,
+							r10_bio->devs[m].addr,
+							r10_bio->sectors))
+						rdev_clear_badblocks(
+							rdev,
+							r10_bio->devs[m].addr,
+							r10_bio->sectors, 0);
+					if (test_bit(In_sync, &rdev->flags) &&
+					    !test_bit(Faulty, &rdev->flags))
+						set_bit(R10BIO_Uptodate, &r10_bio->state);
+				} else {
+					fail = true;
+				}
 				rdev_dec_pending(rdev, conf->mddev);
 			}
 			bio = r10_bio->devs[m].repl_bio;
-- 
2.39.2