aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan E Brassow <jbrassow@redhat.com>2006-12-08 05:41:11 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:09 -0500
commitf3ee6b2f621fec7bc8bfe43fb465e938c37c8d20 (patch)
tree3d790014bbd3280fc7b0232dc212f4b34f06092f /drivers/md
parent31c93a0c29bf96efd806ccf4ee81cacf04f255de (diff)
[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: Jonathan E Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Cc: dm-devel@redhat.com Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-log.c15
-rw-r--r--drivers/md/dm-log.h10
-rw-r--r--drivers/md/dm-raid1.c17
3 files changed, 26 insertions, 16 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 64b764bd02cc..ce5c5d6fc107 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -549,16 +549,19 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region)
549 return 1; 549 return 1;
550} 550}
551 551
552static void core_complete_resync_work(struct dirty_log *log, region_t region, 552static void core_set_region_sync(struct dirty_log *log, region_t region,
553 int success) 553 int in_sync)
554{ 554{
555 struct log_c *lc = (struct log_c *) log->context; 555 struct log_c *lc = (struct log_c *) log->context;
556 556
557 log_clear_bit(lc, lc->recovering_bits, region); 557 log_clear_bit(lc, lc->recovering_bits, region);
558 if (success) { 558 if (in_sync) {
559 log_set_bit(lc, lc->sync_bits, region); 559 log_set_bit(lc, lc->sync_bits, region);
560 lc->sync_count++; 560 lc->sync_count++;
561 } 561 } else if (log_test_bit(lc->sync_bits, region)) {
562 lc->sync_count--;
563 log_clear_bit(lc, lc->sync_bits, region);
564 }
562} 565}
563 566
564static region_t core_get_sync_count(struct dirty_log *log) 567static region_t core_get_sync_count(struct dirty_log *log)
@@ -625,7 +628,7 @@ static struct dirty_log_type _core_type = {
625 .mark_region = core_mark_region, 628 .mark_region = core_mark_region,
626 .clear_region = core_clear_region, 629 .clear_region = core_clear_region,
627 .get_resync_work = core_get_resync_work, 630 .get_resync_work = core_get_resync_work,
628 .complete_resync_work = core_complete_resync_work, 631 .set_region_sync = core_set_region_sync,
629 .get_sync_count = core_get_sync_count, 632 .get_sync_count = core_get_sync_count,
630 .status = core_status, 633 .status = core_status,
631}; 634};
@@ -644,7 +647,7 @@ static struct dirty_log_type _disk_type = {
644 .mark_region = core_mark_region, 647 .mark_region = core_mark_region,
645 .clear_region = core_clear_region, 648 .clear_region = core_clear_region,
646 .get_resync_work = core_get_resync_work, 649 .get_resync_work = core_get_resync_work,
647 .complete_resync_work = core_complete_resync_work, 650 .set_region_sync = core_set_region_sync,
648 .get_sync_count = core_get_sync_count, 651 .get_sync_count = core_get_sync_count,
649 .status = disk_status, 652 .status = disk_status,
650}; 653};
diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h
index 5ae5309ebf28..86a301c8daf1 100644
--- a/drivers/md/dm-log.h
+++ b/drivers/md/dm-log.h
@@ -90,12 +90,12 @@ struct dirty_log_type {
90 int (*get_resync_work)(struct dirty_log *log, region_t *region); 90 int (*get_resync_work)(struct dirty_log *log, region_t *region);
91 91
92 /* 92 /*
93 * This notifies the log that the resync of an area has 93 * This notifies the log that the resync status of a region
94 * been completed. The log should then mark this region 94 * has changed. It also clears the region from the recovering
95 * as CLEAN. 95 * list (if present).
96 */ 96 */
97 void (*complete_resync_work)(struct dirty_log *log, 97 void (*set_region_sync)(struct dirty_log *log,
98 region_t region, int success); 98 region_t region, int in_sync);
99 99
100 /* 100 /*
101 * Returns the number of regions that are in sync. 101 * Returns the number of regions that are in sync.
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 3b3f4c9c3f09..23a642619bed 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -344,6 +344,17 @@ static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list)
344 } 344 }
345} 345}
346 346
347static void complete_resync_work(struct region *reg, int success)
348{
349 struct region_hash *rh = reg->rh;
350
351 rh->log->type->set_region_sync(rh->log, reg->key, success);
352 dispatch_bios(rh->ms, &reg->delayed_bios);
353 if (atomic_dec_and_test(&rh->recovery_in_flight))
354 wake_up_all(&_kmirrord_recovery_stopped);
355 up(&rh->recovery_count);
356}
357
347static void rh_update_states(struct region_hash *rh) 358static void rh_update_states(struct region_hash *rh)
348{ 359{
349 struct region *reg, *next; 360 struct region *reg, *next;
@@ -383,11 +394,7 @@ static void rh_update_states(struct region_hash *rh)
383 */ 394 */
384 list_for_each_entry_safe (reg, next, &recovered, list) { 395 list_for_each_entry_safe (reg, next, &recovered, list) {
385 rh->log->type->clear_region(rh->log, reg->key); 396 rh->log->type->clear_region(rh->log, reg->key);
386 rh->log->type->complete_resync_work(rh->log, reg->key, 1); 397 complete_resync_work(reg, 1);
387 dispatch_bios(rh->ms, &reg->delayed_bios);
388 if (atomic_dec_and_test(&rh->recovery_in_flight))
389 wake_up_all(&_kmirrord_recovery_stopped);
390 up(&rh->recovery_count);
391 mempool_free(reg, rh->region_pool); 398 mempool_free(reg, rh->region_pool);
392 } 399 }
393 400