diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-log.c | 15 | ||||
| -rw-r--r-- | drivers/md/dm-log.h | 10 | ||||
| -rw-r--r-- | drivers/md/dm-raid1.c | 17 |
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 | ||
| 552 | static void core_complete_resync_work(struct dirty_log *log, region_t region, | 552 | static 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 | ||
| 564 | static region_t core_get_sync_count(struct dirty_log *log) | 567 | static 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 | ||
| 347 | static 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, ®->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 | |||
| 347 | static void rh_update_states(struct region_hash *rh) | 358 | static 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, ®->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 | ||
