aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r--drivers/md/dm-snap.c16
1 files changed, 15 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
378static void free_pending_exception(struct dm_snap_pending_exception *pe) 379static 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
383static void insert_completed_exception(struct dm_snapshot *s, 388static 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]));