Change per-module mempool to per-device mempool. Per-module mempools are dangerous, they could theoretically cause a deadlock when the user sets up more snapshot devices stacked each on other. Signed-off-by: Mikulas Patocka --- drivers/md/dm-snap.c | 43 ++++++++++++++++++++++--------------------- drivers/md/dm-snap.h | 2 ++ 2 files changed, 24 insertions(+), 21 deletions(-) Index: linux-2.6.25.3/drivers/md/dm-snap.c =================================================================== --- linux-2.6.25.3.orig/drivers/md/dm-snap.c 2008-05-14 19:22:25.000000000 +0200 +++ linux-2.6.25.3/drivers/md/dm-snap.c 2008-05-14 19:22:34.000000000 +0200 @@ -96,7 +96,6 @@ struct dm_snap_pending_exception { */ static struct kmem_cache *exception_cache; static struct kmem_cache *pending_cache; -static mempool_t *pending_pool; struct dm_snap_tracked_chunk { struct hlist_node node; @@ -363,14 +362,16 @@ static void free_exception(struct dm_sna kmem_cache_free(exception_cache, e); } -static struct dm_snap_pending_exception *alloc_pending_exception(void) +static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snapshot *s) { - return mempool_alloc(pending_pool, GFP_NOIO); + struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, GFP_NOIO); + if (pe) pe->snap = s; + return pe; } static void free_pending_exception(struct dm_snap_pending_exception *pe) { - mempool_free(pe, pending_pool); + mempool_free(pe, pe->snap->pending_pool); } static void insert_completed_exception(struct dm_snapshot *s, @@ -626,10 +627,16 @@ static int snapshot_ctr(struct dm_target goto bad5; } + s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache); + if (!s->pending_pool) { + ti->error = "Could not allocate mempool for pending exceptions"; + goto bad6; + } + s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS, tracked_chunk_cache); if (!s->tracked_chunk_pool) { ti->error = "Could not allocate tracked_chunk mempool for tracking reads"; - goto bad6; + goto bad7; } for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) @@ -641,7 +648,7 @@ static int snapshot_ctr(struct dm_target r = s->store.read_metadata(&s->store); if (r < 0) { ti->error = "Failed to read snapshot metadata"; - goto bad7; + goto bad8; } else if (r > 0) { s->valid = 0; DMWARN("Snapshot is marked invalid."); @@ -655,7 +662,7 @@ static int snapshot_ctr(struct dm_target if (register_snapshot(s)) { r = -EINVAL; ti->error = "Cannot register snapshot origin"; - goto bad7; + goto bad8; } ti->private = s; @@ -663,9 +670,12 @@ static int snapshot_ctr(struct dm_target return 0; - bad7: + bad8: mempool_destroy(s->tracked_chunk_pool); + bad7: + mempool_destroy(s->pending_pool); + bad6: dm_kcopyd_client_destroy(s->kcopyd_client); @@ -716,6 +726,8 @@ static void snapshot_dtr(struct dm_targe __free_exceptions(s); + mempool_destroy(s->pending_pool); + dm_put_device(ti, s->origin); dm_put_device(ti, s->cow); @@ -965,7 +977,7 @@ __find_pending_exception(struct dm_snaps * to hold the lock while we do this. */ up_write(&s->lock); - pe = alloc_pending_exception(); + pe = alloc_pending_exception(s); down_write(&s->lock); if (!s->valid) { @@ -985,7 +997,6 @@ __find_pending_exception(struct dm_snaps bio_list_init(&pe->snapshot_bios); pe->primary_pe = NULL; atomic_set(&pe->ref_count, 0); - pe->snap = s; pe->started = 0; if (s->store.prepare_exception(&s->store, &pe->e)) { @@ -1414,24 +1425,15 @@ static int __init dm_snapshot_init(void) goto bad5; } - pending_pool = mempool_create_slab_pool(128, pending_cache); - if (!pending_pool) { - DMERR("Couldn't create pending pool."); - r = -ENOMEM; - goto bad6; - } - ksnapd = create_singlethread_workqueue("ksnapd"); if (!ksnapd) { DMERR("Failed to create ksnapd workqueue."); r = -ENOMEM; - goto bad7; + goto bad6; } return 0; - bad7: - mempool_destroy(pending_pool); bad6: kmem_cache_destroy(tracked_chunk_cache); bad5: @@ -1462,7 +1464,6 @@ static void __exit dm_snapshot_exit(void DMERR("origin unregister failed %d", r); exit_origin_hash(); - mempool_destroy(pending_pool); kmem_cache_destroy(pending_cache); kmem_cache_destroy(exception_cache); kmem_cache_destroy(tracked_chunk_cache); Index: linux-2.6.25.3/drivers/md/dm-snap.h =================================================================== --- linux-2.6.25.3.orig/drivers/md/dm-snap.h 2008-05-14 19:20:51.000000000 +0200 +++ linux-2.6.25.3/drivers/md/dm-snap.h 2008-05-14 19:22:34.000000000 +0200 @@ -160,6 +160,8 @@ struct dm_snapshot { /* The last percentage we notified */ int last_percent; + mempool_t *pending_pool; + struct exception_table pending; struct exception_table complete;