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

Commit 49021355 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
  md: avoid races when stopping resync.
  md/raid10:  Don't call bitmap_cond_end_sync when we are doing recovery.
  md/raid10:  Don't skip more than 1 bitmap-chunk at a time during recovery.
parents f8dacde8 73d5c38a
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error)
	update_head_pos(mirror, r1_bio);
	update_head_pos(mirror, r1_bio);


	if (atomic_dec_and_test(&r1_bio->remaining)) {
	if (atomic_dec_and_test(&r1_bio->remaining)) {
		md_done_sync(mddev, r1_bio->sectors, uptodate);
		sector_t s = r1_bio->sectors;
		put_buf(r1_bio);
		put_buf(r1_bio);
		md_done_sync(mddev, s, uptodate);
	}
	}
}
}


+10 −9
Original line number Original line Diff line number Diff line
@@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error)
	/* for reconstruct, we always reschedule after a read.
	/* for reconstruct, we always reschedule after a read.
	 * for resync, only after all reads
	 * for resync, only after all reads
	 */
	 */
	rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
	if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
	if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
	    atomic_dec_and_test(&r10_bio->remaining)) {
	    atomic_dec_and_test(&r10_bio->remaining)) {
		/* we have read all the blocks,
		/* we have read all the blocks,
@@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error)
		 */
		 */
		reschedule_retry(r10_bio);
		reschedule_retry(r10_bio);
	}
	}
	rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
}
}


static void end_sync_write(struct bio *bio, int error)
static void end_sync_write(struct bio *bio, int error)
@@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error)


	update_head_pos(i, r10_bio);
	update_head_pos(i, r10_bio);


	rdev_dec_pending(conf->mirrors[d].rdev, mddev);
	while (atomic_dec_and_test(&r10_bio->remaining)) {
	while (atomic_dec_and_test(&r10_bio->remaining)) {
		if (r10_bio->master_bio == NULL) {
		if (r10_bio->master_bio == NULL) {
			/* the primary of several recovery bios */
			/* the primary of several recovery bios */
			md_done_sync(mddev, r10_bio->sectors, 1);
			sector_t s = r10_bio->sectors;
			put_buf(r10_bio);
			put_buf(r10_bio);
			md_done_sync(mddev, s, 1);
			break;
			break;
		} else {
		} else {
			r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
			r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
@@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error)
			r10_bio = r10_bio2;
			r10_bio = r10_bio2;
		}
		}
	}
	}
	rdev_dec_pending(conf->mirrors[d].rdev, mddev);
}
}


/*
/*
@@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
	if (!go_faster && conf->nr_waiting)
	if (!go_faster && conf->nr_waiting)
		msleep_interruptible(1000);
		msleep_interruptible(1000);


	bitmap_cond_end_sync(mddev->bitmap, sector_nr);

	/* Again, very different code for resync and recovery.
	/* Again, very different code for resync and recovery.
	 * Both must result in an r10bio with a list of bios that
	 * Both must result in an r10bio with a list of bios that
	 * have bi_end_io, bi_sector, bi_bdev set,
	 * have bi_end_io, bi_sector, bi_bdev set,
@@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
		/* resync. Schedule a read for every block at this virt offset */
		/* resync. Schedule a read for every block at this virt offset */
		int count = 0;
		int count = 0;


		bitmap_cond_end_sync(mddev->bitmap, sector_nr);

		if (!bitmap_start_sync(mddev->bitmap, sector_nr,
		if (!bitmap_start_sync(mddev->bitmap, sector_nr,
				       &sync_blocks, mddev->degraded) &&
				       &sync_blocks, mddev->degraded) &&
		    !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
		    !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
@@ -2010,14 +2011,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
	/* There is nowhere to write, so all non-sync
	/* There is nowhere to write, so all non-sync
	 * drives must be failed, so try the next chunk...
	 * drives must be failed, so try the next chunk...
	 */
	 */
	{
	if (sector_nr + max_sync < max_sector)
	sector_t sec = max_sector - sector_nr;
		max_sector = sector_nr + max_sync;
	sectors_skipped += sec;

	sectors_skipped += (max_sector - sector_nr);
	chunks_skipped ++;
	chunks_skipped ++;
	sector_nr = max_sector;
	sector_nr = max_sector;
	goto skipped;
	goto skipped;
}
}
}


static int run(mddev_t *mddev)
static int run(mddev_t *mddev)
{
{