Whamcloud - gitweb
LU-1166 recovery: don't leak a connected client counter.
[fs/lustre-release.git] / lustre / ldlm / ldlm_lib.c
index 57f7eb9..44bdcd4 100644 (file)
@@ -28,9 +28,8 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -858,7 +857,6 @@ int target_handle_connect(struct ptlrpc_request *req)
                 cfs_spin_lock(&export->exp_lock);
                 export->exp_connecting = 1;
                 cfs_spin_unlock(&export->exp_lock);
-                class_export_put(export);
                 LASSERT(export->exp_obd == target);
 
                 rc = target_handle_reconnect(&conn, export, &cluuid);
@@ -946,8 +944,12 @@ dont_check_exports:
                         rc = obd_connect(req->rq_svc_thread->t_env,
                                          &export, target, &cluuid, data,
                                          client_nid);
-                        if (rc == 0)
+                        if (rc == 0) {
                                 conn.cookie = export->exp_handle.h_cookie;
+                                /* LU-1092 reconnect put export refcount in the
+                                 * end, connect needs take one here too. */
+                                class_export_get(export);
+                        }
                 }
         } else {
                 rc = obd_reconnect(req->rq_svc_thread->t_env,
@@ -1037,7 +1039,9 @@ dont_check_exports:
                              &export->exp_connection->c_peer.nid,
                              &export->exp_nid_hash);
         }
-
+        /**
+          class_disconnect->class_export_recovery_cleanup() race
+         */
         if (target->obd_recovering && !export->exp_in_recovery) {
                 int has_transno;
                 __u64 transno = data->ocd_transno;
@@ -1130,6 +1134,8 @@ out:
                 cfs_spin_lock(&export->exp_lock);
                 export->exp_connecting = 0;
                 cfs_spin_unlock(&export->exp_lock);
+
+                class_export_put(export);
         }
         if (targref)
                 class_decref(targref, __FUNCTION__, cfs_current());
@@ -1815,8 +1821,8 @@ static int target_recovery_thread(void *arg)
         struct target_recovery_data *trd = &obd->obd_recovery_data;
         unsigned long delta;
         unsigned long flags;
-        struct lu_env env;
-        struct ptlrpc_thread fake_svc_thread, *thread = &fake_svc_thread;
+        struct lu_env *env;
+        struct ptlrpc_thread *thread = NULL;
         int rc = 0;
         ENTRY;
 
@@ -1827,13 +1833,26 @@ static int target_recovery_thread(void *arg)
         RECALC_SIGPENDING;
         SIGNAL_MASK_UNLOCK(current, flags);
 
-        rc = lu_context_init(&env.le_ctx, LCT_MD_THREAD);
-        if (rc)
+        OBD_ALLOC_PTR(thread);
+        if (thread == NULL)
+                RETURN(-ENOMEM);
+
+        OBD_ALLOC_PTR(env);
+        if (env == NULL) {
+                OBD_FREE_PTR(thread);
+                RETURN(-ENOMEM);
+        }
+
+        rc = lu_context_init(&env->le_ctx, LCT_MD_THREAD);
+        if (rc) {
+                OBD_FREE_PTR(thread);
+                OBD_FREE_PTR(env);
                 RETURN(rc);
+        }
 
-        thread->t_env = &env;
+        thread->t_env = env;
         thread->t_id = -1; /* force filter_iobuf_get/put to use local buffers */
-        env.le_ctx.lc_thread = thread;
+        env->le_ctx.lc_thread = thread;
         thread->t_data = NULL;
         thread->t_watchdog = NULL;
 
@@ -1926,9 +1945,12 @@ static int target_recovery_thread(void *arg)
 
         target_finish_recovery(obd);
 
-        lu_context_fini(&env.le_ctx);
+        lu_context_fini(&env->le_ctx);
         trd->trd_processing_task = 0;
         cfs_complete(&trd->trd_finishing);
+
+        OBD_FREE_PTR(thread);
+        OBD_FREE_PTR(env);
         RETURN(rc);
 }