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 | 37 +++++++++++++++++++------------------ drivers/md/dm-snap.h | 2 ++ 2 files changed, 21 insertions(+), 18 deletions(-) Index: linux-2.6.26-devel/drivers/md/dm-snap.c =================================================================== --- linux-2.6.26-devel.orig/drivers/md/dm-snap.c 2008-07-14 20:03:13.000000000 +0200 +++ linux-2.6.26-devel/drivers/md/dm-snap.c 2008-07-14 20:03:47.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; @@ -364,14 +363,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, @@ -627,12 +628,18 @@ 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 bad_pending_pool; + } + 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 bad_tracked_chunk_pool; } for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) @@ -669,7 +676,10 @@ static int snapshot_ctr(struct dm_target bad_load_and_register: mempool_destroy(s->tracked_chunk_pool); - bad6: + bad_tracked_chunk_pool: + mempool_destroy(s->pending_pool); + + bad_pending_pool: dm_kcopyd_client_destroy(s->kcopyd_client); bad5: @@ -723,6 +733,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); @@ -969,7 +981,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) { @@ -989,7 +1001,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)) { @@ -1418,13 +1429,6 @@ 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 bad_pending_pool; - } - ksnapd = create_singlethread_workqueue("ksnapd"); if (!ksnapd) { DMERR("Failed to create ksnapd workqueue."); @@ -1435,8 +1439,6 @@ static int __init dm_snapshot_init(void) return 0; bad6: - mempool_destroy(pending_pool); - bad_pending_pool: kmem_cache_destroy(tracked_chunk_cache); bad5: kmem_cache_destroy(pending_cache); @@ -1466,7 +1468,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.26-devel/drivers/md/dm-snap.h =================================================================== --- linux-2.6.26-devel.orig/drivers/md/dm-snap.h 2008-07-14 19:58:43.000000000 +0200 +++ linux-2.6.26-devel/drivers/md/dm-snap.h 2008-07-14 20:03:47.000000000 +0200 @@ -161,6 +161,8 @@ struct dm_snapshot { /* The last percentage we notified */ int last_percent; + mempool_t *pending_pool; + struct exception_table pending; struct exception_table complete;