aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-02-06 04:39:50 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:18 -0500
commitb47490c9bc73d0b34e4c194db40de183e592e446 (patch)
tree8334581aff7aa0b199df04c6f9d707c1902ad14f /drivers/md
parent66c811e99322767bad5db4368de93aac604f02a2 (diff)
md: Update md bitmap during resync.
Currently an md array with a write-intent bitmap does not updated that bitmap to reflect successful partial resync. Rather the entire bitmap is updated when the resync completes. This is because there is no guarentee that resync requests will complete in order, and tracking each request individually is unnecessarily burdensome. However there is value in regularly updating the bitmap, so add code to periodically pause while all pending sync requests complete, then update the bitmap. Doing this only every few seconds (the same as the bitmap update time) does not notciably affect resync performance. [snitzer@gmail.com: export bitmap_cond_end_sync] Signed-off-by: Neil Brown <neilb@suse.de> Cc: "Mike Snitzer" <snitzer@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bitmap.c35
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/md/raid10.c2
-rw-r--r--drivers/md/raid5.c3
4 files changed, 36 insertions, 5 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 1b1ef3130e6e..9231cd700fe8 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1348,14 +1348,38 @@ void bitmap_close_sync(struct bitmap *bitmap)
1348 */ 1348 */
1349 sector_t sector = 0; 1349 sector_t sector = 0;
1350 int blocks; 1350 int blocks;
1351 if (!bitmap) return; 1351 if (!bitmap)
1352 return;
1352 while (sector < bitmap->mddev->resync_max_sectors) { 1353 while (sector < bitmap->mddev->resync_max_sectors) {
1353 bitmap_end_sync(bitmap, sector, &blocks, 0); 1354 bitmap_end_sync(bitmap, sector, &blocks, 0);
1354/* 1355 sector += blocks;
1355 if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n", 1356 }
1356 (unsigned long long)sector, blocks); 1357}
1357*/ sector += blocks; 1358
1359void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
1360{
1361 sector_t s = 0;
1362 int blocks;
1363
1364 if (!bitmap)
1365 return;
1366 if (sector == 0) {
1367 bitmap->last_end_sync = jiffies;
1368 return;
1369 }
1370 if (time_before(jiffies, (bitmap->last_end_sync
1371 + bitmap->daemon_sleep * HZ)))
1372 return;
1373 wait_event(bitmap->mddev->recovery_wait,
1374 atomic_read(&bitmap->mddev->recovery_active) == 0);
1375
1376 sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
1377 s = 0;
1378 while (s < sector && s < bitmap->mddev->resync_max_sectors) {
1379 bitmap_end_sync(bitmap, s, &blocks, 0);
1380 s += blocks;
1358 } 1381 }
1382 bitmap->last_end_sync = jiffies;
1359} 1383}
1360 1384
1361static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) 1385static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
@@ -1565,3 +1589,4 @@ EXPORT_SYMBOL(bitmap_start_sync);
1565EXPORT_SYMBOL(bitmap_end_sync); 1589EXPORT_SYMBOL(bitmap_end_sync);
1566EXPORT_SYMBOL(bitmap_unplug); 1590EXPORT_SYMBOL(bitmap_unplug);
1567EXPORT_SYMBOL(bitmap_close_sync); 1591EXPORT_SYMBOL(bitmap_close_sync);
1592EXPORT_SYMBOL(bitmap_cond_end_sync);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4a69c416e045..e0b8d0dd7a87 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1684,6 +1684,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1684 if (!go_faster && conf->nr_waiting) 1684 if (!go_faster && conf->nr_waiting)
1685 msleep_interruptible(1000); 1685 msleep_interruptible(1000);
1686 1686
1687 bitmap_cond_end_sync(mddev->bitmap, sector_nr);
1687 raise_barrier(conf); 1688 raise_barrier(conf);
1688 1689
1689 conf->next_resync = sector_nr; 1690 conf->next_resync = sector_nr;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5cdcc9386200..ba125277c6c4 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1670,6 +1670,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1670 if (!go_faster && conf->nr_waiting) 1670 if (!go_faster && conf->nr_waiting)
1671 msleep_interruptible(1000); 1671 msleep_interruptible(1000);
1672 1672
1673 bitmap_cond_end_sync(mddev->bitmap, sector_nr);
1674
1673 /* Again, very different code for resync and recovery. 1675 /* Again, very different code for resync and recovery.
1674 * Both must result in an r10bio with a list of bios that 1676 * Both must result in an r10bio with a list of bios that
1675 * have bi_end_io, bi_sector, bi_bdev set, 1677 * have bi_end_io, bi_sector, bi_bdev set,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e8c8157b02fc..388a974d63ef 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3753,6 +3753,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
3753 return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ 3753 return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
3754 } 3754 }
3755 3755
3756
3757 bitmap_cond_end_sync(mddev->bitmap, sector_nr);
3758
3756 pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); 3759 pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
3757 sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1); 3760 sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
3758 if (sh == NULL) { 3761 if (sh == NULL) {