diff options
| -rw-r--r-- | drivers/md/dm-snap.c | 16 | ||||
| -rw-r--r-- | drivers/md/dm-snap.h | 2 |
2 files changed, 17 insertions, 1 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 746603b42f86..6c96db26b87c 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
| @@ -370,6 +370,7 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps | |||
| 370 | struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, | 370 | struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, |
| 371 | GFP_NOIO); | 371 | GFP_NOIO); |
| 372 | 372 | ||
| 373 | atomic_inc(&s->pending_exceptions_count); | ||
| 373 | pe->snap = s; | 374 | pe->snap = s; |
| 374 | 375 | ||
| 375 | return pe; | 376 | return pe; |
| @@ -377,7 +378,11 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps | |||
| 377 | 378 | ||
| 378 | static void free_pending_exception(struct dm_snap_pending_exception *pe) | 379 | static void free_pending_exception(struct dm_snap_pending_exception *pe) |
| 379 | { | 380 | { |
| 380 | mempool_free(pe, pe->snap->pending_pool); | 381 | struct dm_snapshot *s = pe->snap; |
| 382 | |||
| 383 | mempool_free(pe, s->pending_pool); | ||
| 384 | smp_mb__before_atomic_dec(); | ||
| 385 | atomic_dec(&s->pending_exceptions_count); | ||
| 381 | } | 386 | } |
| 382 | 387 | ||
| 383 | static void insert_completed_exception(struct dm_snapshot *s, | 388 | static void insert_completed_exception(struct dm_snapshot *s, |
| @@ -602,6 +607,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 602 | 607 | ||
| 603 | s->valid = 1; | 608 | s->valid = 1; |
| 604 | s->active = 0; | 609 | s->active = 0; |
| 610 | atomic_set(&s->pending_exceptions_count, 0); | ||
| 605 | init_rwsem(&s->lock); | 611 | init_rwsem(&s->lock); |
| 606 | spin_lock_init(&s->pe_lock); | 612 | spin_lock_init(&s->pe_lock); |
| 607 | s->ti = ti; | 613 | s->ti = ti; |
| @@ -728,6 +734,14 @@ static void snapshot_dtr(struct dm_target *ti) | |||
| 728 | /* After this returns there can be no new kcopyd jobs. */ | 734 | /* After this returns there can be no new kcopyd jobs. */ |
| 729 | unregister_snapshot(s); | 735 | unregister_snapshot(s); |
| 730 | 736 | ||
| 737 | while (atomic_read(&s->pending_exceptions_count)) | ||
| 738 | yield(); | ||
| 739 | /* | ||
| 740 | * Ensure instructions in mempool_destroy aren't reordered | ||
| 741 | * before atomic_read. | ||
| 742 | */ | ||
| 743 | smp_mb(); | ||
| 744 | |||
| 731 | #ifdef CONFIG_DM_DEBUG | 745 | #ifdef CONFIG_DM_DEBUG |
| 732 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) | 746 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) |
| 733 | BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); | 747 | BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); |
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index f07315fe2362..99c0106ede2d 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h | |||
| @@ -160,6 +160,8 @@ struct dm_snapshot { | |||
| 160 | 160 | ||
| 161 | mempool_t *pending_pool; | 161 | mempool_t *pending_pool; |
| 162 | 162 | ||
| 163 | atomic_t pending_exceptions_count; | ||
| 164 | |||
| 163 | struct exception_table pending; | 165 | struct exception_table pending; |
| 164 | struct exception_table complete; | 166 | struct exception_table complete; |
| 165 | 167 | ||
