Whamcloud - gitweb
LU-4604 obdclass: handle ldt_device_nr/ldt_linkage properly
[fs/lustre-release.git] / lustre / obdclass / lu_object.c
index 0b8df84..ed44efa 100644 (file)
@@ -92,6 +92,8 @@ CFS_MODULE_PARM(lu_cache_nr, "l", long, 0644,
 
 static void lu_object_free(const struct lu_env *env, struct lu_object *o);
 
+extern spinlock_t obd_types_lock;
+
 /**
  * Decrease reference counter on object. If last reference is freed, return
  * object to the cache, unless lu_object_is_dying(o) holds. In the latter
@@ -862,34 +864,30 @@ int lu_device_type_init(struct lu_device_type *ldt)
 {
        int result = 0;
 
+       atomic_set(&ldt->ldt_device_nr, 0);
        CFS_INIT_LIST_HEAD(&ldt->ldt_linkage);
        if (ldt->ldt_ops->ldto_init)
                result = ldt->ldt_ops->ldto_init(ldt);
-       if (result == 0)
+
+       if (result == 0) {
+               spin_lock(&obd_types_lock);
                cfs_list_add(&ldt->ldt_linkage, &lu_device_types);
+               spin_unlock(&obd_types_lock);
+       }
        return result;
 }
 EXPORT_SYMBOL(lu_device_type_init);
 
 void lu_device_type_fini(struct lu_device_type *ldt)
 {
+       spin_lock(&obd_types_lock);
        cfs_list_del_init(&ldt->ldt_linkage);
+       spin_unlock(&obd_types_lock);
        if (ldt->ldt_ops->ldto_fini)
                ldt->ldt_ops->ldto_fini(ldt);
 }
 EXPORT_SYMBOL(lu_device_type_fini);
 
-void lu_types_stop(void)
-{
-        struct lu_device_type *ldt;
-
-       cfs_list_for_each_entry(ldt, &lu_device_types, ldt_linkage) {
-               if (ldt->ldt_device_nr == 0 && ldt->ldt_ops->ldto_stop)
-                       ldt->ldt_ops->ldto_stop(ldt);
-       }
-}
-EXPORT_SYMBOL(lu_types_stop);
-
 /**
  * Global list of all sites on this node
  */
@@ -1224,14 +1222,15 @@ EXPORT_SYMBOL(lu_device_put);
  */
 int lu_device_init(struct lu_device *d, struct lu_device_type *t)
 {
-        if (t->ldt_device_nr++ == 0 && t->ldt_ops->ldto_start != NULL)
-                t->ldt_ops->ldto_start(t);
-        memset(d, 0, sizeof *d);
-        cfs_atomic_set(&d->ld_ref, 0);
-        d->ld_type = t;
-        lu_ref_init(&d->ld_reference);
-        CFS_INIT_LIST_HEAD(&d->ld_linkage);
-        return 0;
+       if (atomic_inc_return(&t->ldt_device_nr) == 1 &&
+           t->ldt_ops->ldto_start != NULL)
+               t->ldt_ops->ldto_start(t);
+
+       memset(d, 0, sizeof *d);
+       d->ld_type = t;
+       lu_ref_init(&d->ld_reference);
+       CFS_INIT_LIST_HEAD(&d->ld_linkage);
+       return 0;
 }
 EXPORT_SYMBOL(lu_device_init);
 
@@ -1251,9 +1250,11 @@ void lu_device_fini(struct lu_device *d)
         lu_ref_fini(&d->ld_reference);
         LASSERTF(cfs_atomic_read(&d->ld_ref) == 0,
                  "Refcount is %u\n", cfs_atomic_read(&d->ld_ref));
-        LASSERT(t->ldt_device_nr > 0);
-        if (--t->ldt_device_nr == 0 && t->ldt_ops->ldto_stop != NULL)
-                t->ldt_ops->ldto_stop(t);
+       LASSERT(atomic_read(&t->ldt_device_nr) > 0);
+
+       if (atomic_dec_and_test(&t->ldt_device_nr) &&
+           t->ldt_ops->ldto_stop != NULL)
+               t->ldt_ops->ldto_stop(t);
 }
 EXPORT_SYMBOL(lu_device_fini);