浏览代码

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.
Linus Torvalds 16 年之前
父节点
当前提交
490213556a
共有 2 个文件被更改,包括 12 次插入10 次删除
  1. 2 1
      drivers/md/raid1.c
  2. 10 9
      drivers/md/raid10.c

+ 2 - 1
drivers/md/raid1.c

@@ -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
drivers/md/raid10.c

@@ -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,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...
 	 */
 	 */
-	{
-	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 ++;
 	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)