From a2a678ed4d0d6cb5f36dbabc411d60d9a4f9c435 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 13 Oct 2015 13:33:08 +0530 Subject: [PATCH 1/2] dm snapshot persistent: fix missing cleanup in persistent_ctr error path If an unsupported option is given then the early return from persistent_ctr() leaked memory allocated for the 'pstore' and never destroyed the 'metadata_wq'. Fixes: b0d3cc011e53 ("dm snapshot: add new persistent store option to support overflow") Signed-off-by: Sudip Mukherjee Signed-off-by: Mike Snitzer --- drivers/md/dm-snap-persistent.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index aeacad9be51d..117a05e40090 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -847,6 +847,7 @@ static void persistent_drop_snapshot(struct dm_exception_store *store) static int persistent_ctr(struct dm_exception_store *store, char *options) { struct pstore *ps; + int r; /* allocate the pstore */ ps = kzalloc(sizeof(*ps), GFP_KERNEL); @@ -868,9 +869,9 @@ static int persistent_ctr(struct dm_exception_store *store, char *options) ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0); if (!ps->metadata_wq) { - kfree(ps); DMERR("couldn't start header metadata update thread"); - return -ENOMEM; + r = -ENOMEM; + goto err_workqueue; } if (options) { @@ -879,13 +880,21 @@ static int persistent_ctr(struct dm_exception_store *store, char *options) store->userspace_supports_overflow = true; else { DMERR("Unsupported persistent store option: %s", options); - return -EINVAL; + r = -EINVAL; + goto err_options; } } store->context = ps; return 0; + +err_options: + destroy_workqueue(ps->metadata_wq); +err_workqueue: + kfree(ps); + + return r; } static unsigned persistent_status(struct dm_exception_store *store, From ba30670f4d5292c4e7f7980bbd5071f7c4794cdd Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 13 Oct 2015 12:04:28 -0400 Subject: [PATCH 2/2] dm thin: fix missing pool reference count decrement in pool_ctr error path Fixes: ac8c3f3df ("dm thin: generate event when metadata threshold passed") Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org # 3.10+ --- drivers/md/dm-thin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 6fcbfb063366..3897b90bd462 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3201,7 +3201,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) metadata_low_callback, pool); if (r) - goto out_free_pt; + goto out_flags_changed; pt->callbacks.congested_fn = pool_is_congested; dm_table_add_target_callbacks(ti->table, &pt->callbacks);