Whamcloud - gitweb
LU-362 Fix error path in lu_kmem_init().
authorMikhail Pershin <tappro@whamcloud.com>
Wed, 19 Oct 2011 19:55:04 +0000 (23:55 +0400)
committerOleg Drokin <green@whamcloud.com>
Thu, 3 Nov 2011 04:27:30 +0000 (00:27 -0400)
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 <tappro@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/586
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Jinshan Xiong <jay@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lclient/lcommon_cl.c
lustre/obdclass/cl_object.c
lustre/obdclass/lu_object.c
lustre/obdecho/echo_client.c

index e52fcd4..16d7fbd 100644 (file)
@@ -301,15 +301,26 @@ int ccc_global_init(struct lu_device_type *device_type)
         int result;
 
         result = lu_kmem_init(ccc_caches);
         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;
 }
 
         return result;
 }
 
index 574ed68..930384e 100644 (file)
@@ -1243,17 +1243,31 @@ int cl_global_init(void)
                 return result;
 
         result = lu_kmem_init(cl_object_caches);
                 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)
         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;
 }
 
         return result;
 }
 
index 3f1e5e7..f0e9535 100644 (file)
@@ -1925,13 +1925,16 @@ EXPORT_SYMBOL(lu_time_names);
 int lu_kmem_init(struct lu_kmem_descr *caches)
 {
         int result;
 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;
                         result = -ENOMEM;
+                        /* free all previously allocated caches */
+                        lu_kmem_fini(caches);
                         break;
                 }
         }
                         break;
                 }
         }
index 41e6214..75139df 100644 (file)
@@ -2106,14 +2106,14 @@ int echo_client_init(void)
         lprocfs_echo_init_vars(&lvars);
 
         rc = lu_kmem_init(echo_caches);
         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);
                 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;
 }
 
         return rc;
 }