Commit f3ee6b2f authored by Jonathan E Brassow's avatar Jonathan E Brassow Committed by Linus Torvalds

[PATCH] dm: log: rename complete_resync_work

The complete_resync_work function only provides the ability to change an
out-of-sync region to in-sync.  This patch enhances the function to allow us
to change the status from in-sync to out-of-sync as well, something that is
needed when a mirror write to one of the devices or an initial resync on a
given region fails.
Signed-off-by: default avatarJonathan E Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Cc: dm-devel@redhat.com
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 31c93a0c
...@@ -549,16 +549,19 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) ...@@ -549,16 +549,19 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region)
return 1; return 1;
} }
static void core_complete_resync_work(struct dirty_log *log, region_t region, static void core_set_region_sync(struct dirty_log *log, region_t region,
int success) int in_sync)
{ {
struct log_c *lc = (struct log_c *) log->context; struct log_c *lc = (struct log_c *) log->context;
log_clear_bit(lc, lc->recovering_bits, region); log_clear_bit(lc, lc->recovering_bits, region);
if (success) { if (in_sync) {
log_set_bit(lc, lc->sync_bits, region); log_set_bit(lc, lc->sync_bits, region);
lc->sync_count++; lc->sync_count++;
} } else if (log_test_bit(lc->sync_bits, region)) {
lc->sync_count--;
log_clear_bit(lc, lc->sync_bits, region);
}
} }
static region_t core_get_sync_count(struct dirty_log *log) static region_t core_get_sync_count(struct dirty_log *log)
...@@ -625,7 +628,7 @@ static struct dirty_log_type _core_type = { ...@@ -625,7 +628,7 @@ static struct dirty_log_type _core_type = {
.mark_region = core_mark_region, .mark_region = core_mark_region,
.clear_region = core_clear_region, .clear_region = core_clear_region,
.get_resync_work = core_get_resync_work, .get_resync_work = core_get_resync_work,
.complete_resync_work = core_complete_resync_work, .set_region_sync = core_set_region_sync,
.get_sync_count = core_get_sync_count, .get_sync_count = core_get_sync_count,
.status = core_status, .status = core_status,
}; };
...@@ -644,7 +647,7 @@ static struct dirty_log_type _disk_type = { ...@@ -644,7 +647,7 @@ static struct dirty_log_type _disk_type = {
.mark_region = core_mark_region, .mark_region = core_mark_region,
.clear_region = core_clear_region, .clear_region = core_clear_region,
.get_resync_work = core_get_resync_work, .get_resync_work = core_get_resync_work,
.complete_resync_work = core_complete_resync_work, .set_region_sync = core_set_region_sync,
.get_sync_count = core_get_sync_count, .get_sync_count = core_get_sync_count,
.status = disk_status, .status = disk_status,
}; };
......
...@@ -90,12 +90,12 @@ struct dirty_log_type { ...@@ -90,12 +90,12 @@ struct dirty_log_type {
int (*get_resync_work)(struct dirty_log *log, region_t *region); int (*get_resync_work)(struct dirty_log *log, region_t *region);
/* /*
* This notifies the log that the resync of an area has * This notifies the log that the resync status of a region
* been completed. The log should then mark this region * has changed. It also clears the region from the recovering
* as CLEAN. * list (if present).
*/ */
void (*complete_resync_work)(struct dirty_log *log, void (*set_region_sync)(struct dirty_log *log,
region_t region, int success); region_t region, int in_sync);
/* /*
* Returns the number of regions that are in sync. * Returns the number of regions that are in sync.
......
...@@ -344,6 +344,17 @@ static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list) ...@@ -344,6 +344,17 @@ static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list)
} }
} }
static void complete_resync_work(struct region *reg, int success)
{
struct region_hash *rh = reg->rh;
rh->log->type->set_region_sync(rh->log, reg->key, success);
dispatch_bios(rh->ms, &reg->delayed_bios);
if (atomic_dec_and_test(&rh->recovery_in_flight))
wake_up_all(&_kmirrord_recovery_stopped);
up(&rh->recovery_count);
}
static void rh_update_states(struct region_hash *rh) static void rh_update_states(struct region_hash *rh)
{ {
struct region *reg, *next; struct region *reg, *next;
...@@ -383,11 +394,7 @@ static void rh_update_states(struct region_hash *rh) ...@@ -383,11 +394,7 @@ static void rh_update_states(struct region_hash *rh)
*/ */
list_for_each_entry_safe (reg, next, &recovered, list) { list_for_each_entry_safe (reg, next, &recovered, list) {
rh->log->type->clear_region(rh->log, reg->key); rh->log->type->clear_region(rh->log, reg->key);
rh->log->type->complete_resync_work(rh->log, reg->key, 1); complete_resync_work(reg, 1);
dispatch_bios(rh->ms, &reg->delayed_bios);
if (atomic_dec_and_test(&rh->recovery_in_flight))
wake_up_all(&_kmirrord_recovery_stopped);
up(&rh->recovery_count);
mempool_free(reg, rh->region_pool); mempool_free(reg, rh->region_pool);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment