diff options
author | NeilBrown <neilb@suse.de> | 2008-02-06 04:39:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:18 -0500 |
commit | b47490c9bc73d0b34e4c194db40de183e592e446 (patch) | |
tree | 8334581aff7aa0b199df04c6f9d707c1902ad14f /drivers/md/bitmap.c | |
parent | 66c811e99322767bad5db4368de93aac604f02a2 (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/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 35 |
1 files changed, 30 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 | |
1359 | void 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 | ||
1361 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) | 1385 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) |
@@ -1565,3 +1589,4 @@ EXPORT_SYMBOL(bitmap_start_sync); | |||
1565 | EXPORT_SYMBOL(bitmap_end_sync); | 1589 | EXPORT_SYMBOL(bitmap_end_sync); |
1566 | EXPORT_SYMBOL(bitmap_unplug); | 1590 | EXPORT_SYMBOL(bitmap_unplug); |
1567 | EXPORT_SYMBOL(bitmap_close_sync); | 1591 | EXPORT_SYMBOL(bitmap_close_sync); |
1592 | EXPORT_SYMBOL(bitmap_cond_end_sync); | ||