Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c40b7b06 authored by Chris Mason's avatar Chris Mason
Browse files

Merge branch 'sysfs-fsdevices-4.2-part1' of...

Merge branch 'sysfs-fsdevices-4.2-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into anand
parents 37b8d27d f90fc547
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -1619,10 +1619,7 @@ struct btrfs_fs_info {
	struct task_struct *cleaner_kthread;
	int thread_pool_size;

	struct kobject super_kobj;
	struct kobject *space_info_kobj;
	struct kobject *device_dir_kobj;
	struct completion kobj_unregister;
	int do_barriers;
	int closing;
	int log_root_recovering;
+5 −2
Original line number Diff line number Diff line
@@ -376,6 +376,10 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
	WARN_ON(!tgt_device);
	dev_replace->tgtdev = tgt_device;

	ret = btrfs_kobj_add_device(tgt_device->fs_devices, tgt_device);
	if (ret)
		btrfs_error(root->fs_info, ret, "kobj add dev failed");

	printk_in_rcu(KERN_INFO
		      "BTRFS: dev_replace from %s (devid %llu) to %s started\n",
		      src_device->missing ? "<missing disk>" :
@@ -583,8 +587,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
	mutex_unlock(&uuid_mutex);

	/* replace the sysfs entry */
	btrfs_kobj_rm_device(fs_info, src_device);
	btrfs_kobj_add_device(fs_info, tgt_device);
	btrfs_kobj_rm_device(fs_info->fs_devices, src_device);
	btrfs_rm_dev_replace_free_srcdev(fs_info, src_device);

	/* write back the superblocks */
+17 −2
Original line number Diff line number Diff line
@@ -2497,7 +2497,6 @@ int open_ctree(struct super_block *sb,
	seqlock_init(&fs_info->profiles_lock);
	init_rwsem(&fs_info->delayed_iput_sem);

	init_completion(&fs_info->kobj_unregister);
	INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
	INIT_LIST_HEAD(&fs_info->space_info);
	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
@@ -2877,10 +2876,22 @@ retry_root_backup:

	btrfs_close_extra_devices(fs_devices, 1);

	ret = btrfs_sysfs_add_fsid(fs_devices, NULL);
	if (ret) {
		pr_err("BTRFS: failed to init sysfs fsid interface: %d\n", ret);
		goto fail_block_groups;
	}

	ret = btrfs_sysfs_add_device(fs_devices);
	if (ret) {
		pr_err("BTRFS: failed to init sysfs device interface: %d\n", ret);
		goto fail_fsdev_sysfs;
	}

	ret = btrfs_sysfs_add_one(fs_info);
	if (ret) {
		pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
		goto fail_block_groups;
		goto fail_fsdev_sysfs;
	}

	ret = btrfs_init_space_info(fs_info);
@@ -3058,6 +3069,9 @@ fail_cleaner:
fail_sysfs:
	btrfs_sysfs_remove_one(fs_info);

fail_fsdev_sysfs:
	btrfs_sysfs_remove_fsid(fs_info->fs_devices);

fail_block_groups:
	btrfs_put_block_group_cache(fs_info);
	btrfs_free_block_groups(fs_info);
@@ -3735,6 +3749,7 @@ void close_ctree(struct btrfs_root *root)
	}

	btrfs_sysfs_remove_one(fs_info);
	btrfs_sysfs_remove_fsid(fs_info->fs_devices);

	btrfs_free_fs_roots(fs_info);

+109 −39
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "volumes.h"

static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj);
static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj);

static u64 get_features(struct btrfs_fs_info *fs_info,
			enum btrfs_feature_set set)
@@ -428,7 +429,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,

BTRFS_ATTR(clone_alignment, btrfs_clone_alignment_show);

static struct attribute *btrfs_attrs[] = {
static const struct attribute *btrfs_attrs[] = {
	BTRFS_ATTR_PTR(label),
	BTRFS_ATTR_PTR(nodesize),
	BTRFS_ATTR_PTR(sectorsize),
@@ -438,21 +439,29 @@ static struct attribute *btrfs_attrs[] = {

static void btrfs_release_super_kobj(struct kobject *kobj)
{
	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
	complete(&fs_info->kobj_unregister);
	struct btrfs_fs_devices *fs_devs = to_fs_devs(kobj);

	memset(&fs_devs->super_kobj, 0, sizeof(struct kobject));
	complete(&fs_devs->kobj_unregister);
}

static struct kobj_type btrfs_ktype = {
	.sysfs_ops	= &kobj_sysfs_ops,
	.release	= btrfs_release_super_kobj,
	.default_attrs	= btrfs_attrs,
};

static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj)
{
	if (kobj->ktype != &btrfs_ktype)
		return NULL;
	return container_of(kobj, struct btrfs_fs_devices, super_kobj);
}

static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
{
	if (kobj->ktype != &btrfs_ktype)
		return NULL;
	return container_of(kobj, struct btrfs_fs_info, super_kobj);
	return to_fs_devs(kobj)->fs_info;
}

#define NUM_FEATURE_BITS 64
@@ -493,12 +502,12 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
			attrs[0] = &fa->kobj_attr.attr;
			if (add) {
				int ret;
				ret = sysfs_merge_group(&fs_info->super_kobj,
				ret = sysfs_merge_group(&fs_info->fs_devices->super_kobj,
							&agroup);
				if (ret)
					return ret;
			} else
				sysfs_unmerge_group(&fs_info->super_kobj,
				sysfs_unmerge_group(&fs_info->fs_devices->super_kobj,
						    &agroup);
		}

@@ -506,25 +515,49 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
	return 0;
}

static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
static void __btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
{
	if (fs_devs->device_dir_kobj) {
		kobject_del(fs_devs->device_dir_kobj);
		kobject_put(fs_devs->device_dir_kobj);
		fs_devs->device_dir_kobj = NULL;
	}

	if (fs_devs->super_kobj.state_initialized) {
		kobject_del(&fs_devs->super_kobj);
		kobject_put(&fs_devs->super_kobj);
		wait_for_completion(&fs_devs->kobj_unregister);
	}
}

/* when fs_devs is NULL it will remove all fsid kobject */
void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
{
	kobject_del(&fs_info->super_kobj);
	kobject_put(&fs_info->super_kobj);
	wait_for_completion(&fs_info->kobj_unregister);
	struct list_head *fs_uuids = btrfs_get_fs_uuids();

	if (fs_devs) {
		__btrfs_sysfs_remove_fsid(fs_devs);
		return;
	}

	list_for_each_entry(fs_devs, fs_uuids, list) {
		__btrfs_sysfs_remove_fsid(fs_devs);
	}
}

void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
{
	btrfs_reset_fs_info_ptr(fs_info);

	if (fs_info->space_info_kobj) {
		sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
		kobject_del(fs_info->space_info_kobj);
		kobject_put(fs_info->space_info_kobj);
	}
	kobject_del(fs_info->device_dir_kobj);
	kobject_put(fs_info->device_dir_kobj);
	addrm_unknown_feature_attrs(fs_info, false);
	sysfs_remove_group(&fs_info->super_kobj, &btrfs_feature_attr_group);
	__btrfs_sysfs_remove_one(fs_info);
	sysfs_remove_group(&fs_info->fs_devices->super_kobj, &btrfs_feature_attr_group);
	sysfs_remove_files(&fs_info->fs_devices->super_kobj, btrfs_attrs);
	btrfs_kobj_rm_device(fs_info->fs_devices, NULL);
}

const char * const btrfs_feature_set_names[3] = {
@@ -602,40 +635,60 @@ static void init_feature_attrs(void)
	}
}

int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
/* when one_device is NULL, it removes all device links */

int btrfs_kobj_rm_device(struct btrfs_fs_devices *fs_devices,
		struct btrfs_device *one_device)
{
	struct hd_struct *disk;
	struct kobject *disk_kobj;

	if (!fs_info->device_dir_kobj)
	if (!fs_devices->device_dir_kobj)
		return -EINVAL;

	if (one_device && one_device->bdev) {
		disk = one_device->bdev->bd_part;
		disk_kobj = &part_to_dev(disk)->kobj;

		sysfs_remove_link(fs_info->device_dir_kobj,
		sysfs_remove_link(fs_devices->device_dir_kobj,
						disk_kobj->name);
	}

	if (one_device)
		return 0;

	list_for_each_entry(one_device,
			&fs_devices->devices, dev_list) {
		if (!one_device->bdev)
			continue;
		disk = one_device->bdev->bd_part;
		disk_kobj = &part_to_dev(disk)->kobj;

		sysfs_remove_link(fs_devices->device_dir_kobj,
						disk_kobj->name);
	}

int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
	return 0;
}

int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
{
	if (!fs_devs->device_dir_kobj)
		fs_devs->device_dir_kobj = kobject_create_and_add("devices",
						&fs_devs->super_kobj);

	if (!fs_devs->device_dir_kobj)
		return -ENOMEM;

	return 0;
}

int btrfs_kobj_add_device(struct btrfs_fs_devices *fs_devices,
				struct btrfs_device *one_device)
{
	int error = 0;
	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
	struct btrfs_device *dev;

	if (!fs_info->device_dir_kobj)
		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;
		struct kobject *disk_kobj;
@@ -649,7 +702,7 @@ int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
		disk = dev->bdev->bd_part;
		disk_kobj = &part_to_dev(disk)->kobj;

		error = sysfs_create_link(fs_info->device_dir_kobj,
		error = sysfs_create_link(fs_devices->device_dir_kobj,
					  disk_kobj, disk_kobj->name);
		if (error)
			break;
@@ -667,34 +720,51 @@ static struct dentry *btrfs_debugfs_root_dentry;
/* Debugging tunables and exported data */
u64 btrfs_debugfs_test;

/*
 * Can be called by the device discovery thread.
 * And parent can be specified for seed device
 */
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
				struct kobject *parent)
{
	int error;

	init_completion(&fs_devs->kobj_unregister);
	fs_devs->super_kobj.kset = btrfs_kset;
	error = kobject_init_and_add(&fs_devs->super_kobj,
				&btrfs_ktype, parent, "%pU", fs_devs->fsid);
	return error;
}

int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
{
	int error;
	struct btrfs_fs_devices *fs_devs = fs_info->fs_devices;
	struct kobject *super_kobj = &fs_devs->super_kobj;

	btrfs_set_fs_info_ptr(fs_info);

	init_completion(&fs_info->kobj_unregister);
	fs_info->super_kobj.kset = btrfs_kset;
	error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL,
				     "%pU", fs_info->fsid);
	error = btrfs_kobj_add_device(fs_devs, NULL);
	if (error)
		return error;

	error = sysfs_create_group(&fs_info->super_kobj,
				   &btrfs_feature_attr_group);
	error = sysfs_create_files(super_kobj, btrfs_attrs);
	if (error) {
		__btrfs_sysfs_remove_one(fs_info);
		btrfs_kobj_rm_device(fs_devs, NULL);
		return error;
	}

	error = addrm_unknown_feature_attrs(fs_info, true);
	error = sysfs_create_group(super_kobj,
				   &btrfs_feature_attr_group);
	if (error)
		goto failure;

	error = btrfs_kobj_add_device(fs_info, NULL);
	error = addrm_unknown_feature_attrs(fs_info, true);
	if (error)
		goto failure;

	fs_info->space_info_kobj = kobject_create_and_add("allocation",
						  &fs_info->super_kobj);
						  super_kobj);
	if (!fs_info->space_info_kobj) {
		error = -ENOMEM;
		goto failure;
+6 −2
Original line number Diff line number Diff line
@@ -82,8 +82,12 @@ char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags);
extern const char * const btrfs_feature_set_names[3];
extern struct kobj_type space_info_ktype;
extern struct kobj_type btrfs_raid_ktype;
int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
int btrfs_kobj_add_device(struct btrfs_fs_devices *fs_devices,
		struct btrfs_device *one_device);
int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
int btrfs_kobj_rm_device(struct btrfs_fs_devices *fs_devices,
                struct btrfs_device *one_device);
int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
				struct kobject *parent);
int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs);
void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs);
#endif /* _BTRFS_SYSFS_H_ */
Loading