Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://neil.brown.name/md
Browse files Browse the repository at this point in the history
* '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.
  • Loading branch information
Linus Torvalds committed Feb 25, 2009
2 parents f8dacde + 73d5c38 commit 4902135
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
3 changes: 2 additions & 1 deletion drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(mirror, r1_bio);

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);
md_done_sync(mddev, s, uptodate);
}
}

Expand Down
19 changes: 10 additions & 9 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,14 +1236,14 @@ static void end_sync_read(struct bio *bio, int error)
/* for reconstruct, we always reschedule after a read.
* for resync, only after all reads
*/
rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
atomic_dec_and_test(&r10_bio->remaining)) {
/* we have read all the blocks,
* do the comparison in process context in raid10d
*/
reschedule_retry(r10_bio);
}
rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
}

static void end_sync_write(struct bio *bio, int error)
Expand All @@ -1264,19 +1264,20 @@ static void end_sync_write(struct bio *bio, int error)

update_head_pos(i, r10_bio);

rdev_dec_pending(conf->mirrors[d].rdev, mddev);
while (atomic_dec_and_test(&r10_bio->remaining)) {
if (r10_bio->master_bio == NULL) {
/* the primary of several recovery bios */
md_done_sync(mddev, r10_bio->sectors, 1);
sector_t s = r10_bio->sectors;
put_buf(r10_bio);
md_done_sync(mddev, s, 1);
break;
} else {
r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
put_buf(r10_bio);
r10_bio = r10_bio2;
}
}
rdev_dec_pending(conf->mirrors[d].rdev, mddev);
}

/*
Expand Down Expand Up @@ -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)
msleep_interruptible(1000);

bitmap_cond_end_sync(mddev->bitmap, sector_nr);

/* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set,
Expand Down Expand Up @@ -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 */
int count = 0;

bitmap_cond_end_sync(mddev->bitmap, sector_nr);

if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
Expand Down Expand Up @@ -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
* drives must be failed, so try the next chunk...
*/
{
sector_t sec = max_sector - sector_nr;
sectors_skipped += sec;
if (sector_nr + max_sync < max_sector)
max_sector = sector_nr + max_sync;

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

static int run(mddev_t *mddev)
Expand Down

0 comments on commit 4902135

Please sign in to comment.