Commit 49021355 authored by Linus Torvalds's avatar Linus Torvalds

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
...@@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error) ...@@ -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);
} }
} }
......
...@@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i ...@@ -2010,13 +2011,13 @@ 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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment