sysaufs_sbinfo is a pretty ugly hack. It has a refcount, a kset, some
 attributes, and a way to track if it's been added. This is pretty much
 what a kobject was designed to do.

 Rather than duplicating all the code inside aufs, we can leverage the
 kobject code to do all of that for us.

 For the attribute functions, we don't need to search for anything anymore
 because the kobject can be used to reach a properly protected and
 refcounted sbinfo structure.

Signed-off-by: Jeff Mahoney <[EMAIL PROTECTED]>
---
 fs/aufs/super.c   |   49 ++++--------
 fs/aufs/super.h   |    9 ++
 fs/aufs/sysaufs.c |  205 +++++++++++++-----------------------------------------
 fs/aufs/sysaufs.h |   17 +---
 4 files changed, 80 insertions(+), 200 deletions(-)

--- a/fs/aufs/super.c
+++ b/fs/aufs/super.c
@@ -394,29 +394,16 @@ static void aufs_umount_begin(struct sup
        si_write_unlock(sb);
 }
 
-static void free_sbinfo(struct super_block *sb, int err)
+void aufs_sbinfo_release(struct kobject *kobj)
 {
-       struct aufs_sbinfo *sbinfo;
-
-       AuTraceEnter();
-       sbinfo = stosi(sb);
-       AuDebugOn(!sbinfo || !list_empty(&sbinfo->si_plink));
-
-
-       if (!err) {
-               au_lock_sbilist();
-               au_sbilist_del(sbinfo);
-               si_write_lock(sb);
-               sysaufs_sbinfo_del(sb);
-               au_unlock_sbilist();
-       } else
-               si_write_lock(sb);
+       struct aufs_sbinfo *sbinfo = to_sbinfo(kobj);
+       struct super_block *sb = sbinfo->si_sb;
 
+       si_write_lock(sb);
        xino_clr(sb);
        free_branches(sbinfo);
        kfree(sbinfo->si_branch);
        si_write_unlock(sb);
-       sysaufs_sbinfo_put(sb);
        kfree(sbinfo);
 }
 
@@ -435,7 +422,10 @@ static void aufs_put_super(struct super_
        /* umount_begin() may not be called. */
        aufs_umount_begin(sb);
 #endif
-       free_sbinfo(sb, /*err*/0);
+       au_lock_sbilist();
+       au_sbilist_del(sbinfo);
+       au_unlock_sbilist();
+       sysaufs_unregister(sb);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -791,17 +781,16 @@ static int alloc_sbinfo(struct super_blo
 
        AuTraceEnter();
 
-       sbinfo = kmalloc(sizeof(*sbinfo), GFP_KERNEL);
+       sbinfo = kzalloc(sizeof(*sbinfo), GFP_KERNEL);
        //if (LktrCond) {kfree(sbinfo); sbinfo = NULL;}
        if (unlikely(!sbinfo))
                goto out;
+
+       sbinfo->si_sb = sb;
        sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_KERNEL);
        //if (LktrCond) {kfree(sbinfo->si_branch); sbinfo->si_branch = NULL;}
        if (unlikely(!sbinfo->si_branch))
                goto out_sbinfo;
-       sbinfo->si_sa = sysaufs_sbinfo_alloc();
-       if (unlikely(!sbinfo->si_sa))
-               goto out_branch;
 
        rw_init_wlock(&sbinfo->si_rwsem);
        sbinfo->si_generation = 0;
@@ -854,8 +843,6 @@ static int alloc_sbinfo(struct super_blo
 #endif
        return 0; /* success */
 
- out_branch:
-       kfree(sbinfo->si_branch);
  out_sbinfo:
        kfree(sbinfo);
  out:
@@ -987,17 +974,17 @@ static int aufs_fill_super(struct super_
        aufs_write_unlock(root);
        vfsub_i_unlock(inode);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
        au_lock_sbilist();
        au_sbilist_add(stosi(sb));
-       si_write_lock(sb);
-       sysaufs_sbinfo_add(sb);
-       si_write_unlock(sb);
        au_unlock_sbilist();
-#endif
+       err = sysaufs_register(sb);
        //AuDbgSb(sb);
-       goto out_opts; /* success */
+       if (!err)
+               goto out_opts; /* success */
 
+       au_lock_sbilist();
+       au_sbilist_del(stosi(sb));
+       au_unlock_sbilist();
  out_unlock:
        aufs_write_unlock(root);
        vfsub_i_unlock(inode);
@@ -1005,7 +992,7 @@ static int aufs_fill_super(struct super_
        dput(root);
        sb->s_root = NULL;
  out_info:
-       free_sbinfo(sb, /*err*/1);
+       kfree(stosi(sb));
        sb->s_fs_info = NULL;
  out_opts:
        free_page((unsigned long)opts.opt);
--- a/fs/aufs/super.h
+++ b/fs/aufs/super.h
@@ -81,6 +81,7 @@ struct au_wbr_mfs {
 struct sysaufs_sbinfo;
 struct aufs_branch;
 struct aufs_sbinfo {
+       struct super_block *    si_sb;
        /* nowait tasks in the system-wide workqueue */
        struct au_nowait_tasks  si_nowait;
 
@@ -147,7 +148,7 @@ struct aufs_sbinfo {
        /* sysfs */
        /* super_blocks list is not exported */
        struct list_head        si_list;
-       struct sysaufs_sbinfo   *si_sa; // todo: move inside ifdef
+       struct kobject          si_kobj;
 
 #ifdef CONFIG_AUFS_ROBR
        /* locked vma list for mmap() */ // very dirty
@@ -156,6 +157,11 @@ struct aufs_sbinfo {
 #endif
 };
 
+static inline struct aufs_sbinfo *to_sbinfo(struct kobject *kobj)
+{
+       return container_of(kobj, struct aufs_sbinfo, si_kobj);
+}
+
 /* ---------------------------------------------------------------------- */
 /* mount flags */
 //todo: revert to bit-flag
@@ -185,6 +191,7 @@ struct seq_file;
 //todo: make static
 int au_show_brs(struct seq_file *seq, struct super_block *sb);
 extern struct file_system_type aufs_fs_type;
+void aufs_sbinfo_release(struct kobject *kobj);
 
 /* sbinfo.c */
 //todo: prefix
--- a/fs/aufs/sysaufs.c
+++ b/fs/aufs/sysaufs.c
@@ -350,39 +350,25 @@ static int sysaufs_sbi_br(struct seq_fil
 
 /* ---------------------------------------------------------------------- */
 
-static struct sysaufs_sbi_entry {
-       char *name;
-       sysaufs_sbi_sub_show_t show;
-} sysaufs_sbi_entry[SysaufsSb_Last] = {
-       [SysaufsSb_XINO]        = {
-               .name   = "xino",
-               .show   = sysaufs_sbi_xino
-       },
-       [SysaufsSb_MNTPNT1]     = {
-               .name   = "mntpnt1",
-               .show   = sysaufs_sbi_mntpnt1
-       }
+struct sbi_attribute {
+       struct attribute attr;
+       int (*show)(struct seq_file *seq, struct super_block *sb);
 };
 
-static struct super_block *find_sb_lock(struct kobject *kobj)
-{
-       struct super_block *sb;
-       struct aufs_sbinfo *sbinfo;
-
-       AuTraceEnter();
-       MtxMustLock(&au_sbilist_mtx);
-
-       sb = NULL;
-       list_for_each_entry(sbinfo, &au_sbilist, si_list) {
-               if (&sbinfo->si_sa->kset.kobj != kobj)
-                       continue;
-               sb = sbinfo->si_mnt->mnt_sb;
-               si_read_lock(sb, !AuLock_FLUSH);
-               break;
-       }
-       return sb;
+#define __SYSAUFS_ATTR(_name) { \
+       .attr   = { .name = __stringify(_name), .mode = 0444 }, \
+       .show   = sysaufs_sbi_##_name,                          \
 }
 
+static struct sbi_attribute xino_attr = __SYSAUFS_ATTR(xino);
+static struct sbi_attribute mntpnt1_attr = __SYSAUFS_ATTR(mntpnt1);
+
+static struct attribute *aufs_sbinfo_attrs[] = {
+       &xino_attr.attr,
+       &mntpnt1_attr.attr,
+       NULL,
+};
+
 static struct seq_file *au_seq(char *p, ssize_t len)
 {
        struct seq_file *seq;
@@ -406,18 +392,17 @@ static ssize_t sysaufs_sbi_show(struct k
                                char *buf)
 {
        ssize_t err;
-       struct super_block *sb;
        struct seq_file *seq;
        char *name;
        int i;
+       struct aufs_sbinfo *sbinfo = to_sbinfo(kobj);
+       struct super_block *sb = sbinfo->si_sb;
 
        LKTRTrace("%s/%s\n", kobject_name(kobj), attr->name);
 
        err = -ENOENT;
-       mutex_lock(&au_sbilist_mtx);
-       sb = find_sb_lock(kobj);
-       if (unlikely(!sb))
-               goto out;
+
+       si_read_lock(sb, !AuLock_FLUSH);
 
        seq = au_seq(buf, PAGE_SIZE);
        err = PTR_ERR(seq);
@@ -425,9 +410,12 @@ static ssize_t sysaufs_sbi_show(struct k
                goto out;
 
        name = (void *)attr->name;
-       for (i = 0; i < SysaufsSb_Last; i++) {
-               if (!strcmp(name, sysaufs_sbi_entry[i].name)) {
-                       err = sysaufs_sbi_entry[i].show(seq, sb);
+       for (i = 0; aufs_sbinfo_attrs[i]; i++) {
+               struct attribute *cattr = aufs_sbinfo_attrs[i];
+               if (!strcmp(name, cattr->name)) {
+                       struct sbi_attribute *sattr;
+                       sattr = container_of(cattr, struct sbi_attribute, attr);
+                       err = sattr->show(seq, sb);
                        goto out_seq;
                }
        }
@@ -449,20 +437,10 @@ static ssize_t sysaufs_sbi_show(struct k
        kfree(seq);
  out:
        si_read_unlock(sb);
-       mutex_unlock(&au_sbilist_mtx);
        AuTraceErr(err);
        return err;
 }
 
-static struct sysfs_ops sysaufs_sbi_ops = {
-       .show   = sysaufs_sbi_show
-};
-
-static struct kobj_type sysaufs_sbi_ktype = {
-       //.release      = dir_release,
-       .sysfs_ops      = &sysaufs_sbi_ops
-};
-
 /* ---------------------------------------------------------------------- */
 
 static void sysaufs_br_free(struct kref *ref)
@@ -501,14 +479,14 @@ void sysaufs_br_put(struct aufs_branch *
 void sysaufs_brs_del(struct super_block *sb)
 {
        aufs_bindex_t bindex, bend;
-       struct sysaufs_sbinfo *sa;
+       struct aufs_sbinfo *sa;
        struct sysaufs_br *sabr;
        struct aufs_branch *br;
 
        AuTraceEnter();
 
-       sa = stosi(sb)->si_sa;
-       if (!sysaufs_brs || !sa->added)
+       sa = stosi(sb);
+       if (!sysaufs_brs)
                return;
 
        bend = sbend(sb);
@@ -519,7 +497,7 @@ void sysaufs_brs_del(struct super_block 
                        continue;
 
                sabr->added = 0;
-               sysfs_remove_file(&sa->kset.kobj, &sabr->attr);
+               sysfs_remove_file(&sa->si_kobj, &sabr->attr);
                sysaufs_br_put(br);
                /* for older sysfs */
                module_put(THIS_MODULE);
@@ -531,13 +509,13 @@ void sysaufs_brs_add(struct super_block 
        int err;
        aufs_bindex_t bindex, bend;
        struct sysaufs_br *sabr;
-       struct sysaufs_sbinfo *sa;
+       struct aufs_sbinfo *sa;
        struct aufs_branch *br;
 
        AuTraceEnter();
 
-       sa = stosi(sb)->si_sa;
-       if (!sysaufs_brs || !sa->added)
+       sa = stosi(sb);
+       if (!sysaufs_brs)
                return;
 
        bend = sbend(sb);
@@ -553,7 +531,7 @@ void sysaufs_brs_add(struct super_block 
                sabr->attr.owner = THIS_MODULE;
                /* for older sysfs */
                BUG_ON(!try_module_get(THIS_MODULE));
-               err = sysfs_create_file(&sa->kset.kobj, &sabr->attr);
+               err = sysfs_create_file(&sa->si_kobj, &sabr->attr);
                if (!err)
                        sabr->added = 1;
                else
@@ -563,115 +541,32 @@ void sysaufs_brs_add(struct super_block 
 
 /* ---------------------------------------------------------------------- */
 
-static void sysaufs_sbinfo_free(struct kref *ref)
-{
-       AuTraceEnter();
-       //AuDbg("here\n");
-       kfree(container_of(ref, struct sysaufs_sbinfo, ref));
-}
-
-struct sysaufs_sbinfo *sysaufs_sbinfo_alloc(void)
-{
-       struct sysaufs_sbinfo *sa;
-
-       AuTraceEnter();
-       //AuDbg("here\n");
-
-       sa = kcalloc(sizeof(*sa), 1, GFP_KERNEL);
-       if (sa)
-               kref_init(&sa->ref);
-
-       AuTraceErrPtr(sa);
-       return sa;
-}
+static struct sysfs_ops aufs_sbinfo_ops = {
+       .show   = sysaufs_sbi_show
+};
 
-void sysaufs_sbinfo_get(struct super_block *sb)
-{
-       kref_get(&stosi(sb)->si_sa->ref);
-}
+static struct kobj_type aufs_sbinfo_ktype = {
+       .release        = aufs_sbinfo_release,
+       .sysfs_ops      = &aufs_sbinfo_ops,
+       .default_attrs  = aufs_sbinfo_attrs,
+};
 
-void sysaufs_sbinfo_put(struct super_block *sb)
-{
-       kref_put(&stosi(sb)->si_sa->ref, sysaufs_sbinfo_free);
-}
+/* ---------------------------------------------------------------------- */
 
-void sysaufs_sbinfo_add(struct super_block *sb)
+int sysaufs_register(struct super_block *sb)
 {
-       int err, i;
-       const char *name;
-       struct aufs_sbinfo *sbinfo = stosi(sb);
-       struct sysaufs_sbinfo *sa = sbinfo->si_sa;
-
-       AuTraceEnter();
-       MtxMustLock(&au_sbilist_mtx);
-
-       err = kobject_set_name(&sa->kset.kobj, "sbi_%p", sbinfo);
-       if (unlikely(err))
-               goto out;
-       name = kobject_name(&sa->kset.kobj);
-       kobj_set_kset_s(&sa->kset, aufs_subsys);
-       //sa->kset.kobj.ktype = &sysaufs_ktype;
-       err = kset_register(&sa->kset);
-       if (unlikely(err))
-               goto out;
-#if 1
-       if (sa->kset.kobj.ktype)
-               sysaufs_sbi_ktype = *(sa->kset.kobj.ktype);
-       sysaufs_sbi_ktype.sysfs_ops = &sysaufs_sbi_ops;
-       sa->kset.kobj.ktype = &sysaufs_sbi_ktype;
-#endif
-
-       for (i = 0; i < SysaufsSb_Last; i++) {
-               sa->attr[i].name = sysaufs_sbi_entry[i].name;
-               sa->attr[i].mode = S_IRUGO;
-               sa->attr[i].owner = THIS_MODULE;
-               /* for older sysfs */
-               BUG_ON(!try_module_get(THIS_MODULE));
-               err = sysfs_create_file(&sa->kset.kobj, sa->attr + i);
-               if (unlikely(err))
-                       goto out_reg;
-       }
-
-       sa->added = 1;
-       sysaufs_brs_add(sb);
-       goto out; /* success */
-
- out_reg:
-       for (; i >= 0; i--) {
-               sysfs_remove_file(&sa->kset.kobj, sa->attr + i);
-               /* for older sysfs */
-               module_put(THIS_MODULE);
-       }
-       kset_unregister(&sa->kset);
- out:
-       if (!err)
-               sysaufs_sbinfo_get(sb);
-       else
-               AuWarn("failed adding sysfs (%d)\n", err);
+       struct aufs_sbinfo *si = stosi(sb);
+       si->si_kobj.ktype = &aufs_sbinfo_ktype;
+       kobject_set_name(&si->si_kobj, "sbi_%p", si);
+       si->si_kobj.kset = &aufs_subsys;
+       return kobject_register(&si->si_kobj);
 }
 
-void sysaufs_sbinfo_del(struct super_block *sb)
+void sysaufs_unregister(struct super_block *sb)
 {
-       struct aufs_sbinfo *sbinfo = stosi(sb);
-       struct sysaufs_sbinfo *sa = sbinfo->si_sa;
-       int i;
-
-       AuTraceEnter();
-       MtxMustLock(&au_sbilist_mtx);
-
-       sysaufs_brs_del(sb);
-       for (i = 0; i < SysaufsSb_Last; i++) {
-               sysfs_remove_file(&sa->kset.kobj, sa->attr + i);
-               /* for older sysfs */
-               module_put(THIS_MODULE);
-       }
-       sa->added = 0;
-       kset_unregister(&sa->kset);
-       sysaufs_sbinfo_put(sb);
+       kobject_unregister(&stosi(sb)->si_kobj);
 }
 
-/* ---------------------------------------------------------------------- */
-
 int __init sysaufs_init(void)
 {
        int err;
--- a/fs/aufs/sysaufs.h
+++ b/fs/aufs/sysaufs.h
@@ -44,13 +44,6 @@ enum {
        SysaufsSb_Last
 };
 
-struct sysaufs_sbinfo {
-       struct kset             kset;
-       struct attribute        attr[SysaufsSb_Last];
-       struct kref             ref;
-       int                     added;
-};
-
 /* 'brN' entry under sysfs per super block */
 struct sysaufs_br {
        char                    name[8];
@@ -77,7 +70,7 @@ static inline void au_unlock_sbilist(voi
 
 static inline void au_sbilist_del(struct aufs_sbinfo *sbinfo)
 {
-       list_del(&sbinfo->si_list);
+       list_del_init(&sbinfo->si_list);
 }
 
 static inline void au_sbilist_add(struct aufs_sbinfo *sbinfo)
@@ -86,16 +79,14 @@ static inline void au_sbilist_add(struct
        list_add_tail(&sbinfo->si_list, &au_sbilist);
 }
 
+int sysaufs_register(struct super_block *sb);
+void sysaufs_unregister(struct super_block *sb);
+
 struct sysaufs_br *sysaufs_br_alloc(void);
 void sysaufs_br_get(struct aufs_branch *br);
 void sysaufs_br_put(struct aufs_branch *br);
 void sysaufs_brs_add(struct super_block *sb);
 void sysaufs_brs_del(struct super_block *sb);
-struct sysaufs_sbinfo *sysaufs_sbinfo_alloc(void);
-void sysaufs_sbinfo_get(struct super_block *sb);
-void sysaufs_sbinfo_put(struct super_block *sb);
-void sysaufs_sbinfo_add(struct super_block *sb);
-void sysaufs_sbinfo_del(struct super_block *sb);
 int __init sysaufs_init(void);
 void sysaufs_fin(void);
 

-- 
Jeff Mahoney
SUSE Labs


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

Reply via email to