btrfs: publish device membership in sysfs
authorJeff Mahoney <jeffm@suse.com>
Fri, 1 Nov 2013 17:07:05 +0000 (13:07 -0400)
committerChris Mason <clm@fb.com>
Tue, 28 Jan 2014 21:19:29 +0000 (13:19 -0800)
Now that we have the infrastructure for per-super attributes, we can
publish device membership in /sys/fs/btrfs/<fsid>/devices. The information
is published as symlinks to the block devices.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/ctree.h
fs/btrfs/sysfs.c

index f608306..dbe9b31 100644 (file)
@@ -1530,6 +1530,7 @@ struct btrfs_fs_info {
 
        struct kobject super_kobj;
        struct kobject *space_info_kobj;
+       struct kobject *device_dir_kobj;
        struct completion kobj_unregister;
        int do_barriers;
        int closing;
index e060958..ec63153 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/kobject.h>
 #include <linux/bug.h>
+#include <linux/genhd.h>
 
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
 #include "sysfs.h"
+#include "volumes.h"
 
 static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj);
 
@@ -374,6 +376,8 @@ static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
 void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
 {
        sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
+       kobject_del(fs_info->device_dir_kobj);
+       kobject_put(fs_info->device_dir_kobj);
        kobject_del(fs_info->space_info_kobj);
        kobject_put(fs_info->space_info_kobj);
        kobject_del(&fs_info->super_kobj);
@@ -507,6 +511,30 @@ static int add_unknown_feature_attrs(struct btrfs_fs_info *fs_info)
        return 0;
 }
 
+static int add_device_membership(struct btrfs_fs_info *fs_info)
+{
+       int error = 0;
+       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+       struct btrfs_device *dev;
+
+       fs_info->device_dir_kobj = kobject_create_and_add("devices",
+                                               &fs_info->super_kobj);
+       if (!fs_info->device_dir_kobj)
+               return -ENOMEM;
+
+       list_for_each_entry(dev, &fs_devices->devices, dev_list) {
+               struct hd_struct *disk = dev->bdev->bd_part;
+               struct kobject *disk_kobj = &part_to_dev(disk)->kobj;
+
+               error = sysfs_create_link(fs_info->device_dir_kobj,
+                                         disk_kobj, disk_kobj->name);
+               if (error)
+                       break;
+       }
+
+       return error;
+}
+
 /* /sys/fs/btrfs/ entry */
 static struct kset *btrfs_kset;
 
@@ -528,6 +556,10 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
        if (error)
                goto failure;
 
+       error = add_device_membership(fs_info);
+       if (error)
+               goto failure;
+
        fs_info->space_info_kobj = kobject_create_and_add("allocation",
                                                  &fs_info->super_kobj);
        if (!fs_info->space_info_kobj) {