Commit d419284c authored by Yu Kuai's avatar Yu Kuai Committed by Song Liu
Browse files

md/raid10: don't wait for Faulty rdev in wait_blocked_rdev()



Faulty rdev should never be accessed anymore, hence there is no point to
wait for bad block to be acknowledged in this case while handling write
request.

Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
Tested-by: default avatarMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Link: https://lore.kernel.org/r/20241031033114.3845582-7-yukuai1@huaweicloud.com


Signed-off-by: default avatarSong Liu <song@kernel.org>
parent ff31a7ef
Loading
Loading
Loading
Loading
+18 −22
Original line number Diff line number Diff line
@@ -1285,9 +1285,9 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,

static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
{
	int i;
	struct r10conf *conf = mddev->private;
	struct md_rdev *blocked_rdev;
	int i;

retry_wait:
	blocked_rdev = NULL;
@@ -1295,40 +1295,36 @@ static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
		struct md_rdev *rdev, *rrdev;

		rdev = conf->mirrors[i].rdev;
		rrdev = conf->mirrors[i].replacement;
		if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
			atomic_inc(&rdev->nr_pending);
			blocked_rdev = rdev;
			break;
		}
		if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) {
			atomic_inc(&rrdev->nr_pending);
			blocked_rdev = rrdev;
			break;
		}

		if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
		if (rdev) {
			sector_t dev_sector = r10_bio->devs[i].addr;

			/*
			 * Discard request doesn't care the write result
			 * so it doesn't need to wait blocked disk here.
			 */
			if (!r10_bio->sectors)
				continue;

			if (rdev_has_badblock(rdev, dev_sector,
					      r10_bio->sectors) < 0) {
			if (test_bit(WriteErrorSeen, &rdev->flags) &&
			    r10_bio->sectors &&
			    rdev_has_badblock(rdev, dev_sector,
					      r10_bio->sectors) < 0)
				/*
				 * Mustn't write here until the bad block
				 * is acknowledged
				 * Mustn't write here until the bad
				 * block is acknowledged
				 */
				atomic_inc(&rdev->nr_pending);
				set_bit(BlockedBadBlocks, &rdev->flags);

			if (rdev_blocked(rdev)) {
				blocked_rdev = rdev;
				atomic_inc(&rdev->nr_pending);
				break;
			}
		}

		rrdev = conf->mirrors[i].replacement;
		if (rrdev && rdev_blocked(rrdev)) {
			atomic_inc(&rrdev->nr_pending);
			blocked_rdev = rrdev;
			break;
		}
	}

	if (unlikely(blocked_rdev)) {