Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19d5f834 authored by NeilBrown's avatar NeilBrown
Browse files

md/raid10: unify handling of write completion.



A write can complete at two different places:
1/ when the last member-device write completes, through
   raid10_end_write_request
2/ in make_request() when we remove the initial bias from ->remaining.

These two should do exactly the same thing and the comment says they
do, but they don't.

So factor the correct code out into a function and call it in both
places.  This makes the code much more similar to RAID1.

The difference is only significant if there is an error, and they
usually take a while, so it is unlikely that there will be an error
already when make_request is completing, so this is unlikely to cause
real problems.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 94007751
Loading
Loading
Loading
Loading
+18 −20
Original line number Diff line number Diff line
@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio)
	md_write_end(r10_bio->mddev);
}

static void one_write_done(r10bio_t *r10_bio)
{
	if (atomic_dec_and_test(&r10_bio->remaining)) {
		if (test_bit(R10BIO_WriteError, &r10_bio->state))
			reschedule_retry(r10_bio);
		else {
			close_write(r10_bio);
			if (test_bit(R10BIO_MadeGood, &r10_bio->state))
				reschedule_retry(r10_bio);
			else
				raid_end_bio_io(r10_bio);
		}
	}
}

static void raid10_end_write_request(struct bio *bio, int error)
{
	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -387,17 +402,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
	 * Let's see if all mirrored write operations have finished
	 * already.
	 */
	if (atomic_dec_and_test(&r10_bio->remaining)) {
		if (test_bit(R10BIO_WriteError, &r10_bio->state))
			reschedule_retry(r10_bio);
		else {
			close_write(r10_bio);
			if (test_bit(R10BIO_MadeGood, &r10_bio->state))
				reschedule_retry(r10_bio);
			else
				raid_end_bio_io(r10_bio);
		}
	}
	one_write_done(r10_bio);
	if (dec_rdev)
		rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
}
@@ -1127,15 +1132,8 @@ static int make_request(mddev_t *mddev, struct bio * bio)
		spin_unlock_irqrestore(&conf->device_lock, flags);
	}

	if (atomic_dec_and_test(&r10_bio->remaining)) {
		/* This matches the end of raid10_end_write_request() */
		bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
				r10_bio->sectors,
				!test_bit(R10BIO_Degraded, &r10_bio->state),
				0);
		md_write_end(mddev);
		raid_end_bio_io(r10_bio);
	}
	/* Remove the bias on 'remaining' */
	one_write_done(r10_bio);

	/* In case raid10d snuck in to freeze_array */
	wake_up(&conf->wait_barrier);