| @@ -229,19 +229,21 @@ static void __insert_origin(struct origin *o) · 228 unmodified lines |
| 229 | */ | 229 | */ |
| 230 | static int register_snapshot(struct dm_snapshot *snap) | 230 | static int register_snapshot(struct dm_snapshot *snap) |
| 231 | { | 231 | { |
| 232 | struct origin *o; | 232 | struct origin *o, *new_o; |
| 233 | struct block_device *bdev = snap->origin->bdev; | 233 | struct block_device *bdev = snap->origin->bdev; |
| 234 | | 234 | |
| | 235 | new_o = kmalloc(sizeof(*new_o), GFP_KERNEL); |
| | 236 | if (!new_o) |
| | 237 | return -ENOMEM; |
| | 238 | |
| 235 | down_write(&_origins_lock); | 239 | down_write(&_origins_lock); |
| 236 | o = __lookup_origin(bdev); | 240 | o = __lookup_origin(bdev); |
| 237 | | 241 | |
| 238 | if (!o) { | 242 | if (o) |
| | 243 | kfree(new_o); |
| | 244 | else { |
| 239 | /* New origin */ | 245 | /* New origin */ |
| 240 | o = kmalloc(sizeof(*o), GFP_KERNEL); | 246 | o = new_o; |
| 241 | if (!o) { | | |
| 242 | up_write(&_origins_lock); | | |
| 243 | return -ENOMEM; | | |
| 244 | } | | |
| 245 | | 247 | |
| 246 | /* Initialise the struct */ | 248 | /* Initialise the struct */ |
| 247 | INIT_LIST_HEAD(&o->snapshots); | 249 | INIT_LIST_HEAD(&o->snapshots); |
| @@ -368,6 +370,7 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps · 120 unmodified lines |
| 368 | struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, | 370 | struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, |
| 369 | GFP_NOIO); | 371 | GFP_NOIO); |
| 370 | | 372 | |
| | 373 | atomic_inc(&s->pending_exceptions_count); |
| 371 | pe->snap = s; | 374 | pe->snap = s; |
| 372 | | 375 | |
| 373 | return pe; | 376 | return pe; |
| @@ -375,7 +378,11 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps · 1 unmodified line |
| 375 | | 378 | |
| 376 | static void free_pending_exception(struct dm_snap_pending_exception *pe) | 379 | static void free_pending_exception(struct dm_snap_pending_exception *pe) |
| 377 | { | 380 | { |
| 378 | 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); |
| 379 | } | 386 | } |
| 380 | | 387 | |
| 381 | static void insert_completed_exception(struct dm_snapshot *s, | 388 | static void insert_completed_exception(struct dm_snapshot *s, |
| @@ -600,6 +607,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 218 unmodified lines |
| 600 | | 607 | |
| 601 | s->valid = 1; | 608 | s->valid = 1; |
| 602 | s->active = 0; | 609 | s->active = 0; |
| | 610 | atomic_set(&s->pending_exceptions_count, 0); |
| 603 | init_rwsem(&s->lock); | 611 | init_rwsem(&s->lock); |
| 604 | spin_lock_init(&s->pe_lock); | 612 | spin_lock_init(&s->pe_lock); |
| 605 | s->ti = ti; | 613 | s->ti = ti; |
| @@ -726,6 +734,14 @@ static void snapshot_dtr(struct dm_target *ti) · 120 unmodified lines |
| 726 | /* After this returns there can be no new kcopyd jobs. */ | 734 | /* After this returns there can be no new kcopyd jobs. */ |
| 727 | unregister_snapshot(s); | 735 | unregister_snapshot(s); |
| 728 | | 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 | |
| 729 | #ifdef CONFIG_DM_DEBUG | 745 | #ifdef CONFIG_DM_DEBUG |
| 730 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) | 746 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) |
| 731 | BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); | 747 | BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); |