Hi all, > Later, I thought I could send some demo code that strips the kobject in sbi into a pointer. I made the following modifications, not sure if I'm going the right way. diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 1db018f8c2e8..8e1799f690c0 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -165,8 +165,7 @@ struct erofs_sb_info { u32 feature_incompat; /* sysfs support */ - struct kobject s_kobj; /* /sys/fs/erofs/<devname> */ - struct completion s_kobj_unregister; + struct filesystem_kobject *f_kobj; /* fscache support */ struct fscache_volume *volume; diff --git a/fs/erofs/sysfs.c b/fs/erofs/sysfs.c index 435e515c0792..70e915906012 100644 --- a/fs/erofs/sysfs.c +++ b/fs/erofs/sysfs.c @@ -8,6 +8,33 @@ #include "internal.h" +//maybe we should add following thins to include/linux/filesystem_kobject.h ? +struct filesystem_kobject { + struct kobject kobject; + void *private; +}; + +void filesystem_kobject_put(struct filesystem_kobject *f_kobj) +{ + if (f_kobj) + kobject_put(&f_kobj->kobject); +} + +void filesystem_kobject_set_private(struct filesystem_kobject *f_kobj, void *p) +{ + f_kobj->private = p; +} + +void *filesystem_kobject_get_private(struct filesystem_kobject *f_kobj) +{ + return f_kobj->private; +} + +struct kobject *filesystem_kobject_get_kobject(struct filesystem_kobject *f_kobj) +{ + return &f_kobj->kobject; +} + enum { attr_feature, attr_pointer_ui, @@ -107,8 +134,9 @@ static unsigned char *__struct_ptr(struct erofs_sb_info *sbi, static ssize_t erofs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct erofs_sb_info *sbi = container_of(kobj, struct erofs_sb_info, - s_kobj); + struct filesystem_kobject *f_kobject = container_of(kobj, struct filesystem_kobject, + kobject); + struct erofs_sb_info *sbi = filesystem_kobject_get_private(f_kobject); struct erofs_attr *a = container_of(attr, struct erofs_attr, attr); unsigned char *ptr = __struct_ptr(sbi, a->struct_type, a->offset); @@ -130,8 +158,9 @@ static ssize_t erofs_attr_show(struct kobject *kobj, static ssize_t erofs_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { - struct erofs_sb_info *sbi = container_of(kobj, struct erofs_sb_info, - s_kobj); + struct filesystem_kobject *f_kobject = container_of(kobj, struct filesystem_kobject, + kobject); + struct erofs_sb_info *sbi = filesystem_kobject_get_private(f_kobject); struct erofs_attr *a = container_of(attr, struct erofs_attr, attr); unsigned char *ptr = __struct_ptr(sbi, a->struct_type, a->offset); unsigned long t; @@ -169,9 +198,12 @@ static ssize_t erofs_attr_store(struct kobject *kobj, struct attribute *attr, static void erofs_sb_release(struct kobject *kobj) { - struct erofs_sb_info *sbi = container_of(kobj, struct erofs_sb_info, - s_kobj); - complete(&sbi->s_kobj_unregister); + struct filesystem_kobject *f_kobject = container_of(kobj, struct filesystem_kobject, + kobject); + struct erofs_sb_info *sbi = filesystem_kobject_get_private(f_kobject); + + kfree(f_kobject); + sbi->f_kobj = NULL; } static const struct sysfs_ops erofs_attr_ops = { @@ -205,6 +237,7 @@ static struct kobject erofs_feat = { int erofs_register_sysfs(struct super_block *sb) { struct erofs_sb_info *sbi = EROFS_SB(sb); + struct kobject *kobj; char *name; char *str = NULL; int err; @@ -222,17 +255,24 @@ int erofs_register_sysfs(struct super_block *sb) } else { name = sb->s_id; } - sbi->s_kobj.kset = &erofs_root; - init_completion(&sbi->s_kobj_unregister); - err = kobject_init_and_add(&sbi->s_kobj, &erofs_sb_ktype, NULL, "%s", name); + + sbi->f_kobj = kzalloc(sizeof(struct filesystem_kobject), GFP_KERNEL); + if (!sbi->f_kobj) { + kfree(str); + return -ENOMEM; + } + filesystem_kobject_set_private(sbi->f_kobj, sbi); + kobj = filesystem_kobject_get_kobject(sbi->f_kobj); + kobj->kset = &erofs_root; + + err = kobject_init_and_add(&sbi->f_kobj->kobject, &erofs_sb_ktype, NULL, "%s", name); kfree(str); if (err) goto put_sb_kobj; return 0; put_sb_kobj: - kobject_put(&sbi->s_kobj); - wait_for_completion(&sbi->s_kobj_unregister); + filesystem_kobject_put(sbi->f_kobj); return err; } @@ -240,11 +280,7 @@ void erofs_unregister_sysfs(struct super_block *sb) { struct erofs_sb_info *sbi = EROFS_SB(sb); - if (sbi->s_kobj.state_in_sysfs) { - kobject_del(&sbi->s_kobj); - kobject_put(&sbi->s_kobj); - wait_for_completion(&sbi->s_kobj_unregister); - } + filesystem_kobject_put(sbi->f_kobj); } int __init erofs_init_sysfs(void)