mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
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. [[email protected]: export bitmap_cond_end_sync] Signed-off-by: Neil Brown <[email protected]> Cc: "Mike Snitzer" <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
66c811e993
commit
b47490c9bc
5 changed files with 39 additions and 5 deletions
|
|
@ -1348,16 +1348,40 @@ void bitmap_close_sync(struct bitmap *bitmap)
|
|||
*/
|
||||
sector_t sector = 0;
|
||||
int blocks;
|
||||
if (!bitmap) return;
|
||||
if (!bitmap)
|
||||
return;
|
||||
while (sector < bitmap->mddev->resync_max_sectors) {
|
||||
bitmap_end_sync(bitmap, sector, &blocks, 0);
|
||||
/*
|
||||
if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n",
|
||||
(unsigned long long)sector, blocks);
|
||||
*/ sector += blocks;
|
||||
sector += blocks;
|
||||
}
|
||||
}
|
||||
|
||||
void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
|
||||
{
|
||||
sector_t s = 0;
|
||||
int blocks;
|
||||
|
||||
if (!bitmap)
|
||||
return;
|
||||
if (sector == 0) {
|
||||
bitmap->last_end_sync = jiffies;
|
||||
return;
|
||||
}
|
||||
if (time_before(jiffies, (bitmap->last_end_sync
|
||||
+ bitmap->daemon_sleep * HZ)))
|
||||
return;
|
||||
wait_event(bitmap->mddev->recovery_wait,
|
||||
atomic_read(&bitmap->mddev->recovery_active) == 0);
|
||||
|
||||
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
|
||||
s = 0;
|
||||
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
|
||||
bitmap_end_sync(bitmap, s, &blocks, 0);
|
||||
s += blocks;
|
||||
}
|
||||
bitmap->last_end_sync = jiffies;
|
||||
}
|
||||
|
||||
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
|
||||
{
|
||||
/* For each chunk covered by any of these sectors, set the
|
||||
|
|
@ -1565,3 +1589,4 @@ EXPORT_SYMBOL(bitmap_start_sync);
|
|||
EXPORT_SYMBOL(bitmap_end_sync);
|
||||
EXPORT_SYMBOL(bitmap_unplug);
|
||||
EXPORT_SYMBOL(bitmap_close_sync);
|
||||
EXPORT_SYMBOL(bitmap_cond_end_sync);
|
||||
|
|
|
|||
|
|
@ -1684,6 +1684,7 @@ 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);
|
||||
raise_barrier(conf);
|
||||
|
||||
conf->next_resync = sector_nr;
|
||||
|
|
|
|||
|
|
@ -1670,6 +1670,8 @@ 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,
|
||||
|
|
|
|||
|
|
@ -3753,6 +3753,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
|
|||
return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
|
||||
}
|
||||
|
||||
|
||||
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
|
||||
|
||||
pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
|
||||
sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
|
||||
if (sh == NULL) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue