]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/ext4/super.c
ext4: add interface to advertise ext4 features in sysfs
[mv-sheeva.git] / fs / ext4 / super.c
index 5066537e5a38421650cefcd3e521f5d2ce65bf4e..c5b890140d01663a3543e548d539c063c3a7f339 100644 (file)
@@ -57,6 +57,7 @@ struct proc_dir_entry *ext4_proc_root;
 static struct kset *ext4_kset;
 struct ext4_lazy_init *ext4_li_info;
 struct mutex ext4_li_mtx;
+struct ext4_features *ext4_feat;
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
                             unsigned long journal_devnum);
@@ -709,6 +710,7 @@ static void ext4_put_super(struct super_block *sb)
        struct ext4_super_block *es = sbi->s_es;
        int i, err;
 
+       ext4_unregister_li_request(sb);
        dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 
        flush_workqueue(sbi->dio_unwritten_wq);
@@ -727,7 +729,6 @@ static void ext4_put_super(struct super_block *sb)
        }
 
        del_timer(&sbi->s_err_report);
-       ext4_unregister_li_request(sb);
        ext4_release_system_zone(sb);
        ext4_mb_release(sb);
        ext4_ext_release(sb);
@@ -2416,6 +2417,7 @@ static struct ext4_attr ext4_attr_##_name = {                     \
 #define EXT4_ATTR(name, mode, show, store) \
 static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
 
+#define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL)
 #define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL)
 #define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store)
 #define EXT4_RW_ATTR_SBI_UI(name, elname)      \
@@ -2452,6 +2454,14 @@ static struct attribute *ext4_attrs[] = {
        NULL,
 };
 
+/* Features this copy of ext4 supports */
+EXT4_INFO_ATTR(lazy_itable_init);
+
+static struct attribute *ext4_feat_attrs[] = {
+       ATTR_LIST(lazy_itable_init),
+       NULL,
+};
+
 static ssize_t ext4_attr_show(struct kobject *kobj,
                              struct attribute *attr, char *buf)
 {
@@ -2480,7 +2490,6 @@ static void ext4_sb_release(struct kobject *kobj)
        complete(&sbi->s_kobj_unregister);
 }
 
-
 static const struct sysfs_ops ext4_attr_ops = {
        .show   = ext4_attr_show,
        .store  = ext4_attr_store,
@@ -2492,6 +2501,17 @@ static struct kobj_type ext4_ktype = {
        .release        = ext4_sb_release,
 };
 
+static void ext4_feat_release(struct kobject *kobj)
+{
+       complete(&ext4_feat->f_kobj_unregister);
+}
+
+static struct kobj_type ext4_feat_ktype = {
+       .default_attrs  = ext4_feat_attrs,
+       .sysfs_ops      = &ext4_attr_ops,
+       .release        = ext4_feat_release,
+};
+
 /*
  * Check whether this filesystem can be mounted based on
  * the features present and the RDONLY/RDWR mount requested.
@@ -4720,6 +4740,30 @@ static struct file_system_type ext4_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV,
 };
 
+int __init ext4_init_feat_adverts(void)
+{
+       struct ext4_features *ef;
+       int ret = -ENOMEM;
+
+       ef = kzalloc(sizeof(struct ext4_features), GFP_KERNEL);
+       if (!ef)
+               goto out;
+
+       ef->f_kobj.kset = ext4_kset;
+       init_completion(&ef->f_kobj_unregister);
+       ret = kobject_init_and_add(&ef->f_kobj, &ext4_feat_ktype, NULL,
+                                  "features");
+       if (ret) {
+               kfree(ef);
+               goto out;
+       }
+
+       ext4_feat = ef;
+       ret = 0;
+out:
+       return ret;
+}
+
 static int __init init_ext4_fs(void)
 {
        int err;
@@ -4732,6 +4776,9 @@ static int __init init_ext4_fs(void)
        if (!ext4_kset)
                goto out4;
        ext4_proc_root = proc_mkdir("fs/ext4", NULL);
+
+       err = ext4_init_feat_adverts();
+
        err = init_ext4_mballoc();
        if (err)
                goto out3;
@@ -4760,6 +4807,7 @@ out1:
 out2:
        exit_ext4_mballoc();
 out3:
+       kfree(ext4_feat);
        remove_proc_entry("fs/ext4", NULL);
        kset_unregister(ext4_kset);
 out4: