btrfs: sysfs: Add entry which shows if rmdir can work on subvolumes
authorMisono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Thu, 17 May 2018 05:24:51 +0000 (14:24 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 28 May 2018 16:23:41 +0000 (18:23 +0200)
Deletion of a subvolume by rmdir(2) has become allowed by the
'commit cd2decf640b1 ("btrfs: Allow rmdir(2) to delete an empty
subvolume")'.

It is a kind of new feature and this commits add a sysfs entry

  /sys/fs/btrfs/features/rmdir_subvol

to indicate the availability of the feature so that a user program
(e.g. fstests) can detect it.

Prior to this commit, all entries in /sys/fs/btrfs/features are feature
which depend on feature bits of superblock (i.e. each feature affects
on-disk format) and managed by attribute_group "btrfs_feature_attr_group".
For each fs, entries in /sys/fs/btrfs/UUID/features indicate which
features are enabled (or can be changed online) for the fs.

However, rmdir_subvol feature only depends on kernel module. Therefore
new attribute_group "btrfs_static_feature_attr_group" is introduced and
sysfs_merge_group() is used to share /sys/fs/btrfs/features directory.
Features in "btrfs_static_feature_attr_group" won't be listed in each
/sys/fs/btrfs/UUID/features.

Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/sysfs.c

index 217d401fe8aeed0ae4a9ff93fb00d7673f1ee8ed..4a4e960c7c665f56a9f418b2806d5a2904e0eb42 100644 (file)
@@ -210,12 +210,42 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
        NULL
 };
 
+/*
+ * Features which depend on feature bits and may differ between each fs.
+ *
+ * /sys/fs/btrfs/features lists all available features of this kernel while
+ * /sys/fs/btrfs/UUID/features shows features of the fs which are enabled or
+ * can be changed online.
+ */
 static const struct attribute_group btrfs_feature_attr_group = {
        .name = "features",
        .is_visible = btrfs_feature_visible,
        .attrs = btrfs_supported_feature_attrs,
 };
 
+static ssize_t rmdir_subvol_show(struct kobject *kobj,
+                                struct kobj_attribute *ka, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "0\n");
+}
+BTRFS_ATTR(static_feature, rmdir_subvol, rmdir_subvol_show);
+
+static struct attribute *btrfs_supported_static_feature_attrs[] = {
+       BTRFS_ATTR_PTR(static_feature, rmdir_subvol),
+       NULL
+};
+
+/*
+ * Features which only depend on kernel version.
+ *
+ * These are listed in /sys/fs/btrfs/features along with
+ * btrfs_feature_attr_group
+ */
+static const struct attribute_group btrfs_static_feature_attr_group = {
+       .name = "features",
+       .attrs = btrfs_supported_static_feature_attrs,
+};
+
 static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)
 {
        u64 val;
@@ -901,8 +931,15 @@ int __init btrfs_init_sysfs(void)
        ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
        if (ret)
                goto out2;
+       ret = sysfs_merge_group(&btrfs_kset->kobj,
+                               &btrfs_static_feature_attr_group);
+       if (ret)
+               goto out_remove_group;
 
        return 0;
+
+out_remove_group:
+       sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
 out2:
        debugfs_remove_recursive(btrfs_debugfs_root_dentry);
 out1:
@@ -913,6 +950,8 @@ out1:
 
 void __cold btrfs_exit_sysfs(void)
 {
+       sysfs_unmerge_group(&btrfs_kset->kobj,
+                           &btrfs_static_feature_attr_group);
        sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
        kset_unregister(btrfs_kset);
        debugfs_remove_recursive(btrfs_debugfs_root_dentry);