@@ -111,8 +111,7 @@ struct obd_type {
int typ_refcnt;
struct lu_device_type *typ_lu;
spinlock_t obd_type_lock;
- struct kobject typ_kobj;
- struct completion typ_kobj_unregister;
+ struct kobject *typ_kobj;
};
struct brw_page {
@@ -33,6 +33,7 @@
#ifndef __CLASS_OBD_H
#define __CLASS_OBD_H
+#include <linux/kobject.h>
#include <obd_support.h>
#include <lustre_import.h>
#include <lustre_net.h>
@@ -59,6 +60,7 @@
/* genops.c */
struct obd_export *class_conn2export(struct lustre_handle *conn);
+struct kobject *class_setup_tunables(const char *name);
int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
const char *name, struct lu_device_type *ldt);
int class_unregister_type(const char *name);
@@ -43,40 +43,20 @@
static struct kobject *llite_kobj;
static struct dentry *llite_root;
-static void class_sysfs_release(struct kobject *kobj)
-{
- kfree(kobj);
-}
-
-static struct kobj_type class_ktype = {
- .sysfs_ops = &lustre_sysfs_ops,
- .release = class_sysfs_release,
-};
-
int llite_tunables_register(void)
{
- const char *name = "llite";
- struct kobject *kobj;
int rc = 0;
- kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
- if (!kobj)
- return -ENOMEM;
-
- kobj->kset = lustre_kset;
- kobject_init(kobj, &class_ktype);
- rc = kobject_add(kobj, &lustre_kset->kobj, "%s", name);
- if (rc) {
- kobject_put(kobj);
- return -ENOMEM;
- }
- llite_kobj = kobj;
+ llite_kobj = class_setup_tunables("llite");
+ if (IS_ERR(llite_kobj))
+ return PTR_ERR(llite_kobj);
llite_root = debugfs_create_dir("llite", debugfs_lustre_root);
if (IS_ERR_OR_NULL(llite_root)) {
rc = llite_root ? PTR_ERR(llite_root) : -ENOMEM;
llite_root = NULL;
- kobject_put(kobj);
+ kobject_put(llite_kobj);
+ llite_kobj = NULL;
}
return rc;
@@ -135,10 +135,7 @@ void class_put_type(struct obd_type *type)
static void class_sysfs_release(struct kobject *kobj)
{
- struct obd_type *type = container_of(kobj, struct obd_type,
- typ_kobj);
-
- complete(&type->typ_kobj_unregister);
+ kfree(kobj);
}
static struct kobj_type class_ktype = {
@@ -146,6 +143,26 @@ static void class_sysfs_release(struct kobject *kobj)
.release = class_sysfs_release,
};
+struct kobject *class_setup_tunables(const char *name)
+{
+ struct kobject *kobj;
+ int rc;
+
+ kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
+ if (!kobj)
+ return ERR_PTR(-ENOMEM);
+
+ kobj->kset = lustre_kset;
+ kobject_init(kobj, &class_ktype);
+ rc = kobject_add(kobj, &lustre_kset->kobj, "%s", name);
+ if (rc) {
+ kobject_put(kobj);
+ return ERR_PTR(rc);
+ }
+ return kobj;
+}
+EXPORT_SYMBOL(class_setup_tunables);
+
#define CLASS_MAX_NAME 1024
int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
@@ -187,19 +204,17 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
type->typ_debugfs_entry = debugfs_create_dir(type->typ_name,
debugfs_lustre_root);
- type->typ_kobj.kset = lustre_kset;
- init_completion(&type->typ_kobj_unregister);
- rc = kobject_init_and_add(&type->typ_kobj, &class_ktype,
- &lustre_kset->kobj, "%s", type->typ_name);
- if (rc)
+ type->typ_kobj = class_setup_tunables(type->typ_name);
+ if (IS_ERR(type->typ_kobj)) {
+ rc = PTR_ERR(type->typ_kobj);
goto failed;
-
+ }
if (ldt) {
type->typ_lu = ldt;
rc = lu_device_type_init(ldt);
if (rc != 0) {
- kobject_put(&type->typ_kobj);
+ kobject_put(type->typ_kobj);
goto failed;
}
}
@@ -237,8 +252,7 @@ int class_unregister_type(const char *name)
return -EBUSY;
}
- kobject_put(&type->typ_kobj);
- wait_for_completion(&type->typ_kobj_unregister);
+ kobject_put(type->typ_kobj);
debugfs_remove_recursive(type->typ_debugfs_entry);
@@ -1027,7 +1027,7 @@ int lprocfs_obd_setup(struct obd_device *obd, bool uuid_only)
obd->obd_ktype.sysfs_ops = &lustre_sysfs_ops;
obd->obd_ktype.release = obd_sysfs_release;
- obd->obd_kset.kobj.parent = &obd->obd_type->typ_kobj;
+ obd->obd_kset.kobj.parent = obd->obd_type->typ_kobj;
obd->obd_kset.kobj.ktype = &obd->obd_ktype;
init_completion(&obd->obd_kobj_unregister);
rc = kset_register(&obd->obd_kset);