Whamcloud - gitweb
b=15440
authoryury <yury>
Tue, 3 Jun 2008 08:14:35 +0000 (08:14 +0000)
committeryury <yury>
Tue, 3 Jun 2008 08:14:35 +0000 (08:14 +0000)
r=shadow,nikita

- fixes missed CFS_INIT_LIST_HEAD(&ns->ns_list_chain);
- cleanups about ns list maintaining;
- cleanups about function names;
- call ldlm_namespace_unregister() before waiting for refc == 0 as ldlm_namespace_unregister() drops ns refc.

lustre/include/lustre_dlm.h
lustre/ldlm/ldlm_pool.c
lustre/ldlm/ldlm_resource.c

index 70a0733..e8a3bbf 100644 (file)
@@ -698,12 +698,14 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client,
 int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags);
 void ldlm_namespace_free(struct ldlm_namespace *ns,
                          struct obd_import *imp, int force);
-void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client);
-struct ldlm_namespace *ldlm_namespace_first(ldlm_side_t client);
+void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client);
+void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client);
+void ldlm_namespace_move_locked(struct ldlm_namespace *ns, ldlm_side_t client);
+struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t client);
+void ldlm_namespace_get_locked(struct ldlm_namespace *ns);
+void ldlm_namespace_put_locked(struct ldlm_namespace *ns, int wakeup);
 void ldlm_namespace_get(struct ldlm_namespace *ns);
 void ldlm_namespace_put(struct ldlm_namespace *ns, int wakeup);
-void ldlm_namespace_get_nolock(struct ldlm_namespace *ns);
-void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup);
 int ldlm_proc_setup(void);
 #ifdef LPROCFS
 void ldlm_proc_cleanup(void);
index dcae254..fbcf055 100644 (file)
@@ -783,9 +783,9 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,
                         mutex_up(ldlm_namespace_lock(client));
                         return 0;
                 }
-                ns = ldlm_namespace_first(client);
+                ns = ldlm_namespace_first_locked(client);
                 ldlm_namespace_get(ns);
-                ldlm_namespace_move(ns, client);
+                ldlm_namespace_move_locked(ns, client);
                 mutex_up(ldlm_namespace_lock(client));
                 total += ldlm_pool_shrink(&ns->ns_pool, 0, gfp_mask);
                 ldlm_namespace_put(ns, 1);
@@ -810,9 +810,9 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,
                         cached = 0;
                         break;
                 }
-                ns = ldlm_namespace_first(client);
+                ns = ldlm_namespace_first_locked(client);
                 ldlm_namespace_get(ns);
-                ldlm_namespace_move(ns, client);
+                ldlm_namespace_move_locked(ns, client);
                 mutex_up(ldlm_namespace_lock(client));
                 
                 nr_locks = ldlm_pool_granted(&ns->ns_pool);
@@ -909,9 +909,9 @@ void ldlm_pools_recalc(ldlm_side_t client)
                         mutex_up(ldlm_namespace_lock(client));
                         break;
                 }
-                ns = ldlm_namespace_first(client);
+                ns = ldlm_namespace_first_locked(client);
                 ldlm_namespace_get(ns);
-                ldlm_namespace_move(ns, client);
+                ldlm_namespace_move_locked(ns, client);
                 mutex_up(ldlm_namespace_lock(client));
 
                 /* After setup is done - recalc the pool. */
index 2629a64..477eda9 100644 (file)
@@ -321,6 +321,7 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client,
         strcpy(ns->ns_name, name);
 
         CFS_INIT_LIST_HEAD(&ns->ns_root_list);
+        CFS_INIT_LIST_HEAD(&ns->ns_list_chain);
         ns->ns_refcount = 0;
         ns->ns_client = client;
         spin_lock_init(&ns->ns_hash_lock);
@@ -354,12 +355,7 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client,
         }
 
         at_init(&ns->ns_at_estimate, ldlm_enqueue_min, 0);
-
-        mutex_down(ldlm_namespace_lock(client));
-        list_add(&ns->ns_list_chain, ldlm_namespace_list(client));
-        atomic_inc(ldlm_namespace_nr(client));
-        mutex_up(ldlm_namespace_lock(client));
-
+        ldlm_namespace_register(ns, client);
         RETURN(ns);
 out_proc:
         ldlm_namespace_cleanup(ns, 0);
@@ -552,6 +548,8 @@ void ldlm_namespace_free_prior(struct ldlm_namespace *ns,
                 return;
         }
 
+        ldlm_namespace_unregister(ns, ns->ns_client);
+
         /* Can fail with -EINTR when force == 0 in which case try harder */
         rc = __ldlm_namespace_free(ns, force);
         if (rc != ELDLM_OK) {
@@ -575,16 +573,14 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns)
                 EXIT;
                 return;
         }
-        mutex_down(ldlm_namespace_lock(ns->ns_client));
-        /*
-         * Some asserts and possibly other parts of code still using 
-         * list_empty(&ns->ns_list_chain). This is why it is important
-         * to use list_del_init() here.
+
+        /* 
+         * Fini pool _before_ parent proc dir is removed. This is important as
+         * ldlm_pool_fini() removes own proc dir which is child to @dir. Removing
+         * it after @dir may cause oops.
          */
-        list_del_init(&ns->ns_list_chain);
-        atomic_dec(ldlm_namespace_nr(ns->ns_client));
         ldlm_pool_fini(&ns->ns_pool);
-        mutex_up(ldlm_namespace_lock(ns->ns_client));
+
 #ifdef LPROCFS
         {
                 struct proc_dir_entry *dir;
@@ -634,7 +630,7 @@ void ldlm_namespace_free(struct ldlm_namespace *ns,
         ldlm_namespace_free_post(ns);
 }
 
-void ldlm_namespace_get_nolock(struct ldlm_namespace *ns)
+void ldlm_namespace_get_locked(struct ldlm_namespace *ns)
 {
         LASSERT(ns->ns_refcount >= 0);
         ns->ns_refcount++;
@@ -643,11 +639,11 @@ void ldlm_namespace_get_nolock(struct ldlm_namespace *ns)
 void ldlm_namespace_get(struct ldlm_namespace *ns)
 {
         spin_lock(&ns->ns_hash_lock);
-        ldlm_namespace_get_nolock(ns);
+        ldlm_namespace_get_locked(ns);
         spin_unlock(&ns->ns_hash_lock);
 }
 
-void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup)
+void ldlm_namespace_put_locked(struct ldlm_namespace *ns, int wakeup)
 {
         LASSERT(ns->ns_refcount > 0);
         ns->ns_refcount--;
@@ -658,12 +654,37 @@ void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup)
 void ldlm_namespace_put(struct ldlm_namespace *ns, int wakeup)
 {
         spin_lock(&ns->ns_hash_lock);
-        ldlm_namespace_put_nolock(ns, wakeup);
+        ldlm_namespace_put_locked(ns, wakeup);
         spin_unlock(&ns->ns_hash_lock);
 }
 
+/* Register @ns in the list of namespaces */
+void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client)
+{
+        mutex_down(ldlm_namespace_lock(client));
+        LASSERT(list_empty(&ns->ns_list_chain));
+        list_add(&ns->ns_list_chain, ldlm_namespace_list(client));
+        atomic_inc(ldlm_namespace_nr(client));
+        mutex_up(ldlm_namespace_lock(client));
+}
+
+/* Unregister @ns from the list of namespaces */
+void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client)
+{
+        mutex_down(ldlm_namespace_lock(client));
+        LASSERT(!list_empty(&ns->ns_list_chain));
+        /*
+         * Some asserts and possibly other parts of code still using 
+         * list_empty(&ns->ns_list_chain). This is why it is important
+         * to use list_del_init() here.
+         */
+        list_del_init(&ns->ns_list_chain);
+        atomic_dec(ldlm_namespace_nr(client));
+        mutex_up(ldlm_namespace_lock(client));
+}
+
 /* Should be called under ldlm_namespace_lock(client) taken */
-void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client)
+void ldlm_namespace_move_locked(struct ldlm_namespace *ns, ldlm_side_t client)
 {
         LASSERT(!list_empty(&ns->ns_list_chain));
         LASSERT_SEM_LOCKED(ldlm_namespace_lock(client));
@@ -671,7 +692,7 @@ void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client)
 }
 
 /* Should be called under ldlm_namespace_lock(client) taken */
-struct ldlm_namespace *ldlm_namespace_first(ldlm_side_t client)
+struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t client)
 {
         LASSERT_SEM_LOCKED(ldlm_namespace_lock(client));
         LASSERT(!list_empty(ldlm_namespace_list(client)));
@@ -786,7 +807,7 @@ ldlm_resource_add(struct ldlm_namespace *ns, struct ldlm_resource *parent,
         bucket = ns->ns_hash + hash;
         list_add(&res->lr_hash, bucket);
         ns->ns_resources++;
-        ldlm_namespace_get_nolock(ns);
+        ldlm_namespace_get_locked(ns);
 
         if (parent == NULL) {
                 list_add(&res->lr_childof, &ns->ns_root_list);
@@ -885,7 +906,7 @@ void __ldlm_resource_putref_final(struct ldlm_resource *res)
 
         /* Pass 0 as second argument to not wake up ->ns_waitq yet, will do it
          * later. */
-        ldlm_namespace_put_nolock(ns, 0);
+        ldlm_namespace_put_locked(ns, 0);
         list_del_init(&res->lr_hash);
         list_del_init(&res->lr_childof);