[dm-devel] [PATCH] dm snapshot: fix memory leak

Sudip Mukherjee sudipm.mukherjee at gmail.com
Tue Oct 13 08:03:08 UTC 2015


If wrong option is given then we are returning but we missed releasing
the workqueue and pstore.
Add an error path and use it to correctly release resources on failure.

Fixes: b0d3cc011e53 ("dm snapshot: add new persistent store option to support overflow")
Signed-off-by: Sudip Mukherjee <sudip at vectorindia.org>
---
 drivers/md/dm-snap-persistent.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 229be55..5ff7c23 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 ret;
 
 	/* 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;
+		ret = -ENOMEM;
+		goto err_free_ps;
 	}
 
 	if (options) {
@@ -879,13 +880,20 @@ 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;
+			ret = -EINVAL;
+			goto err_option;
 		}
 	}
 
 	store->context = ps;
 
 	return 0;
+
+err_option:
+	destroy_workqueue(ps->metadata_wq);
+err_free_ps:
+	kfree(ps);
+	return ret;
 }
 
 static unsigned persistent_status(struct dm_exception_store *store,
-- 
1.9.1




More information about the dm-devel mailing list