From 7e2ecb0b3a79b27a002ec42106e43c43a6e5dbaf Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Wed, 19 Oct 2011 23:55:04 +0400 Subject: [PATCH] LU-362 Fix error path in lu_kmem_init(). When echo client is failed to set up there are memory leaks were noticed, it is related to missed error handling in some functions. - Free all caches if lu_kmem_init() failed - fix error handling in cl_global_init() and ccc_global_init() Change-Id: Ide9e7ad6d40f99a7fbb4330ba63b168cc408356f Signed-off-by: Mikhail Pershin Reviewed-on: http://review.whamcloud.com/586 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/lclient/lcommon_cl.c | 27 +++++++++++++++++++-------- lustre/obdclass/cl_object.c | 34 ++++++++++++++++++++++++---------- lustre/obdclass/lu_object.c | 13 ++++++++----- lustre/obdecho/echo_client.c | 8 ++++---- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index e52fcd4..16d7fbd 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.c @@ -301,15 +301,26 @@ int ccc_global_init(struct lu_device_type *device_type) int result; result = lu_kmem_init(ccc_caches); - if (result == 0) { - result = lu_device_type_init(device_type); - ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, - LCT_REMEMBER|LCT_NOREF); - if (IS_ERR(ccc_inode_fini_env)) - result = PTR_ERR(ccc_inode_fini_env); - else - ccc_inode_fini_env->le_ctx.lc_cookie = 0x4; + if (result) + return result; + + result = lu_device_type_init(device_type); + if (result) + goto out_kmem; + + ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck, + LCT_REMEMBER|LCT_NOREF); + if (IS_ERR(ccc_inode_fini_env)) { + result = PTR_ERR(ccc_inode_fini_env); + goto out_device; } + + ccc_inode_fini_env->le_ctx.lc_cookie = 0x4; + return 0; +out_device: + lu_device_type_fini(device_type); +out_kmem: + lu_kmem_fini(ccc_caches); return result; } diff --git a/lustre/obdclass/cl_object.c b/lustre/obdclass/cl_object.c index 574ed68..930384e 100644 --- a/lustre/obdclass/cl_object.c +++ b/lustre/obdclass/cl_object.c @@ -1243,17 +1243,31 @@ int cl_global_init(void) return result; result = lu_kmem_init(cl_object_caches); - if (result == 0) { - LU_CONTEXT_KEY_INIT(&cl_key); - result = lu_context_key_register(&cl_key); - if (result == 0) { - result = cl_lock_init(); - if (result == 0) - result = cl_page_init(); - } - } if (result) - cl_env_store_fini(); + goto out_store; + + LU_CONTEXT_KEY_INIT(&cl_key); + result = lu_context_key_register(&cl_key); + if (result) + goto out_kmem; + + result = cl_lock_init(); + if (result) + goto out_context; + + result = cl_page_init(); + if (result) + goto out_lock; + + return 0; +out_lock: + cl_lock_fini(); +out_context: + lu_context_key_degister(&cl_key); +out_kmem: + lu_kmem_fini(cl_object_caches); +out_store: + cl_env_store_fini(); return result; } diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index 3f1e5e7..f0e9535 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -1925,13 +1925,16 @@ EXPORT_SYMBOL(lu_time_names); int lu_kmem_init(struct lu_kmem_descr *caches) { int result; + struct lu_kmem_descr *iter = caches; - for (result = 0; caches->ckd_cache != NULL; ++caches) { - *caches->ckd_cache = cfs_mem_cache_create(caches->ckd_name, - caches->ckd_size, - 0, 0); - if (*caches->ckd_cache == NULL) { + for (result = 0; iter->ckd_cache != NULL; ++iter) { + *iter->ckd_cache = cfs_mem_cache_create(iter->ckd_name, + iter->ckd_size, + 0, 0); + if (*iter->ckd_cache == NULL) { result = -ENOMEM; + /* free all previously allocated caches */ + lu_kmem_fini(caches); break; } } diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 41e6214..75139df 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -2106,14 +2106,14 @@ int echo_client_init(void) lprocfs_echo_init_vars(&lvars); rc = lu_kmem_init(echo_caches); - if (rc == 0) + if (rc == 0) { rc = class_register_type(&echo_obd_ops, NULL, lvars.module_vars, LUSTRE_ECHO_CLIENT_NAME, &echo_device_type); - if (rc) - lu_kmem_fini(echo_caches); - + if (rc) + lu_kmem_fini(echo_caches); + } return rc; } -- 1.8.3.1