]> git.dujemihanovic.xyz Git - linux.git/commitdiff
btrfs: sysfs: introduce global qgroup attribute group
authorQu Wenruo <wqu@suse.com>
Wed, 24 Aug 2022 01:14:05 +0000 (09:14 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 26 Sep 2022 10:28:01 +0000 (12:28 +0200)
Although we already have info kobject for each qgroup, we don't have
global qgroup info attributes to show things like enabled or
inconsistent status flags.

Add this qgroups attribute groups, and the first member is qgroup_flags,
which is a read-only attribute to show human readable qgroup flags.

The path is:
  /sys/fs/btrfs/<uuid>/qgroups/enabled
  /sys/fs/btrfs/<uuid>/qgroups/inconsistent

The output is simple, just 1 or 0.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/sysfs.c

index ed3fbfd50a27b0237bb7cbc8918cdbe8a870036f..736d81d911f9edc89091feba131048f962e422b1 100644 (file)
@@ -2015,6 +2015,59 @@ failure:
        return error;
 }
 
+static ssize_t qgroup_enabled_show(struct kobject *qgroups_kobj,
+                                  struct kobj_attribute *a,
+                                  char *buf)
+{
+       struct btrfs_fs_info *fs_info = to_fs_info(qgroups_kobj->parent);
+       bool enabled;
+
+       spin_lock(&fs_info->qgroup_lock);
+       enabled = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON;
+       spin_unlock(&fs_info->qgroup_lock);
+
+       return sysfs_emit(buf, "%d\n", enabled);
+}
+BTRFS_ATTR(qgroups, enabled, qgroup_enabled_show);
+
+static ssize_t qgroup_inconsistent_show(struct kobject *qgroups_kobj,
+                                       struct kobj_attribute *a,
+                                       char *buf)
+{
+       struct btrfs_fs_info *fs_info = to_fs_info(qgroups_kobj->parent);
+       bool inconsistent;
+
+       spin_lock(&fs_info->qgroup_lock);
+       inconsistent = (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT);
+       spin_unlock(&fs_info->qgroup_lock);
+
+       return sysfs_emit(buf, "%d\n", inconsistent);
+}
+BTRFS_ATTR(qgroups, inconsistent, qgroup_inconsistent_show);
+
+/*
+ * Qgroups global info
+ *
+ * Path: /sys/fs/btrfs/<uuid>/qgroups/
+ */
+static struct attribute *qgroups_attrs[] = {
+       BTRFS_ATTR_PTR(qgroups, enabled),
+       BTRFS_ATTR_PTR(qgroups, inconsistent),
+       NULL
+};
+ATTRIBUTE_GROUPS(qgroups);
+
+static void qgroups_release(struct kobject *kobj)
+{
+       kfree(kobj);
+}
+
+static struct kobj_type qgroups_ktype = {
+       .sysfs_ops = &kobj_sysfs_ops,
+       .default_groups = qgroups_groups,
+       .release = qgroups_release,
+};
+
 static inline struct btrfs_fs_info *qgroup_kobj_to_fs_info(struct kobject *kobj)
 {
        return to_fs_info(kobj->parent->parent);
@@ -2140,11 +2193,15 @@ int btrfs_sysfs_add_qgroups(struct btrfs_fs_info *fs_info)
        if (fs_info->qgroups_kobj)
                return 0;
 
-       fs_info->qgroups_kobj = kobject_create_and_add("qgroups", fsid_kobj);
-       if (!fs_info->qgroups_kobj) {
-               ret = -ENOMEM;
+       fs_info->qgroups_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
+       if (!fs_info->qgroups_kobj)
+               return -ENOMEM;
+
+       ret = kobject_init_and_add(fs_info->qgroups_kobj, &qgroups_ktype,
+                                  fsid_kobj, "qgroups");
+       if (ret < 0)
                goto out;
-       }
+
        rbtree_postorder_for_each_entry_safe(qgroup, next,
                                             &fs_info->qgroup_tree, node) {
                ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);