[dm-devel] [RFC PATCH 1/1] dm-log(recover): avoid excessive recovering_bits in dm-log.c
Heinz Mauelshagen
hjm at redhat.com
Thu Mar 6 14:38:09 UTC 2008
Hi Alasdair et al,
this patch avoids the excessive lc->recovering_bits array being used in
the context of core_get_resync_work(), by basing the selection of regions
to be synchronized purely on the lc->sync_bits array.
core_set_region_sync() adjusted lc->sync_search in order to allow for
resynchronization of regions being set out-of-sync.
I'm interested, if resynchronization related semantics are sane.
If acceptable, please apply
(applies on top of my previous dm header move patches).
Heinz
---
drivers/md/dm-log.c | 40 +++++++++++-----------------------------
1 files changed, 11 insertions(+), 29 deletions(-)
diff --git linux-2.6.25-rc4.orig/drivers/md/dm-log.c linux-2.6.25-rc4/drivers/md/dm-log.c
index 6cc12c3..91a7f4a 100644
--- linux-2.6.25-rc4.orig/drivers/md/dm-log.c
+++ linux-2.6.25-rc4/drivers/md/dm-log.c
@@ -189,9 +189,8 @@ struct log_c {
unsigned bitset_uint32_count;
uint32_t *clean_bits;
uint32_t *sync_bits;
- uint32_t *recovering_bits; /* FIXME: this seems excessive */
- int sync_search;
+ unsigned sync_search;
/* Resync flag */
enum sync {
@@ -418,18 +417,6 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
}
memset(lc->sync_bits, (sync == NOSYNC) ? -1 : 0, bitset_size);
lc->sync_count = (sync == NOSYNC) ? region_count : 0;
-
- lc->recovering_bits = vmalloc(bitset_size);
- if (!lc->recovering_bits) {
- DMWARN("couldn't allocate sync bitset");
- vfree(lc->sync_bits);
- if (!dev)
- vfree(lc->clean_bits);
- vfree(lc->disk_header);
- kfree(lc);
- return -ENOMEM;
- }
- memset(lc->recovering_bits, 0, bitset_size);
lc->sync_search = 0;
log->context = lc;
@@ -445,7 +432,6 @@ static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti,
static void destroy_log_context(struct log_c *lc)
{
vfree(lc->sync_bits);
- vfree(lc->recovering_bits);
kfree(lc);
}
@@ -637,23 +623,17 @@ static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
{
struct log_c *lc = (struct log_c *) log->context;
- if (lc->sync_search >= lc->region_count)
- return 0;
-
- do {
+ if (lc->sync_search < lc->region_count) {
*region = ext2_find_next_zero_bit(
- (unsigned long *) lc->sync_bits,
- lc->region_count,
- lc->sync_search);
+ (unsigned long *) lc->sync_bits,
+ lc->region_count, lc->sync_search);
lc->sync_search = *region + 1;
- if (*region >= lc->region_count)
- return 0;
-
- } while (log_test_bit(lc->recovering_bits, *region));
+ if (*region < lc->region_count)
+ return 1;
+ }
- log_set_bit(lc, lc->recovering_bits, *region);
- return 1;
+ return 0;
}
static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
@@ -661,12 +641,14 @@ static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
{
struct log_c *lc = (struct log_c *) log->context;
- log_clear_bit(lc, lc->recovering_bits, region);
if (in_sync) {
log_set_bit(lc, lc->sync_bits, region);
lc->sync_count++;
} else if (log_test_bit(lc->sync_bits, region)) {
lc->sync_count--;
+ if (lc->sync_search > region)
+ lc->sync_search = region;
+
log_clear_bit(lc, lc->sync_bits, region);
}
}
--
1.5.4.1
More information about the dm-devel
mailing list