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

Commit 53cd255c authored by Takashi Iwai's avatar Takashi Iwai Committed by Richard Weinberger
Browse files

UBI: Use static class and attribute groups



This patch cleans up the manual device_create_file() or
class_create_file() calls by replacing with static attribute groups.
It simplifies the code and also avoids the possible races between the
device/class registration and sysfs creations.

For the simplification, also make ubi_class a static instance with
initializers, too.

Amend a bit by Hujianyang.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Tested-by: default avatarSheng Yong <shengyong1@huawei.com>
Signed-off-by: default avatarhujianyang <hujianyang@huawei.com>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 2848594a
Loading
Loading
Loading
Loading
+36 −67
Original line number Diff line number Diff line
@@ -83,8 +83,6 @@ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
static bool fm_autoconvert;
static bool fm_debug;
#endif
/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
struct class *ubi_class;

/* Slab cache for wear-leveling entries */
struct kmem_cache *ubi_wl_entry_slab;
@@ -113,8 +111,17 @@ static ssize_t ubi_version_show(struct class *class,
}

/* UBI version attribute ('/<sysfs>/class/ubi/version') */
static struct class_attribute ubi_version =
	__ATTR(version, S_IRUGO, ubi_version_show, NULL);
static struct class_attribute ubi_class_attrs[] = {
	__ATTR(version, S_IRUGO, ubi_version_show, NULL),
	__ATTR_NULL
};

/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
struct class ubi_class = {
	.name		= UBI_NAME_STR,
	.owner		= THIS_MODULE,
	.class_attrs	= ubi_class_attrs,
};

static ssize_t dev_attribute_show(struct device *dev,
				  struct device_attribute *attr, char *buf);
@@ -385,6 +392,22 @@ static ssize_t dev_attribute_show(struct device *dev,
	return ret;
}

static struct attribute *ubi_dev_attrs[] = {
	&dev_eraseblock_size.attr,
	&dev_avail_eraseblocks.attr,
	&dev_total_eraseblocks.attr,
	&dev_volumes_count.attr,
	&dev_max_ec.attr,
	&dev_reserved_for_bad.attr,
	&dev_bad_peb_count.attr,
	&dev_max_vol_count.attr,
	&dev_min_io_size.attr,
	&dev_bgt_enabled.attr,
	&dev_mtd_num.attr,
	NULL
};
ATTRIBUTE_GROUPS(ubi_dev);

static void dev_release(struct device *dev)
{
	struct ubi_device *ubi = container_of(dev, struct ubi_device, dev);
@@ -407,45 +430,15 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)

	ubi->dev.release = dev_release;
	ubi->dev.devt = ubi->cdev.dev;
	ubi->dev.class = ubi_class;
	ubi->dev.class = &ubi_class;
	ubi->dev.groups = ubi_dev_groups;
	dev_set_name(&ubi->dev, UBI_NAME_STR"%d", ubi->ubi_num);
	err = device_register(&ubi->dev);
	if (err)
		return err;

	*ref = 1;
	err = device_create_file(&ubi->dev, &dev_eraseblock_size);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_avail_eraseblocks);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_total_eraseblocks);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_volumes_count);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_max_ec);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_reserved_for_bad);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_bad_peb_count);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_max_vol_count);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_min_io_size);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_bgt_enabled);
	if (err)
		return err;
	err = device_create_file(&ubi->dev, &dev_mtd_num);
	return err;
	return 0;
}

/**
@@ -454,17 +447,6 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)
 */
static void ubi_sysfs_close(struct ubi_device *ubi)
{
	device_remove_file(&ubi->dev, &dev_mtd_num);
	device_remove_file(&ubi->dev, &dev_bgt_enabled);
	device_remove_file(&ubi->dev, &dev_min_io_size);
	device_remove_file(&ubi->dev, &dev_max_vol_count);
	device_remove_file(&ubi->dev, &dev_bad_peb_count);
	device_remove_file(&ubi->dev, &dev_reserved_for_bad);
	device_remove_file(&ubi->dev, &dev_max_ec);
	device_remove_file(&ubi->dev, &dev_volumes_count);
	device_remove_file(&ubi->dev, &dev_total_eraseblocks);
	device_remove_file(&ubi->dev, &dev_avail_eraseblocks);
	device_remove_file(&ubi->dev, &dev_eraseblock_size);
	device_unregister(&ubi->dev);
}

@@ -1233,23 +1215,14 @@ static int __init ubi_init(void)
	}

	/* Create base sysfs directory and sysfs files */
	ubi_class = class_create(THIS_MODULE, UBI_NAME_STR);
	if (IS_ERR(ubi_class)) {
		err = PTR_ERR(ubi_class);
		pr_err("UBI error: cannot create UBI class");
		goto out;
	}

	err = class_create_file(ubi_class, &ubi_version);
	if (err) {
		pr_err("UBI error: cannot create sysfs file");
		goto out_class;
	}
	err = class_register(&ubi_class);
	if (err < 0)
		return err;

	err = misc_register(&ubi_ctrl_cdev);
	if (err) {
		pr_err("UBI error: cannot register device");
		goto out_version;
		goto out;
	}

	ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
@@ -1333,11 +1306,8 @@ static int __init ubi_init(void)
	kmem_cache_destroy(ubi_wl_entry_slab);
out_dev_unreg:
	misc_deregister(&ubi_ctrl_cdev);
out_version:
	class_remove_file(ubi_class, &ubi_version);
out_class:
	class_destroy(ubi_class);
out:
	class_unregister(&ubi_class);
	pr_err("UBI error: cannot initialize UBI, error %d", err);
	return err;
}
@@ -1358,8 +1328,7 @@ static void __exit ubi_exit(void)
	ubi_debugfs_exit();
	kmem_cache_destroy(ubi_wl_entry_slab);
	misc_deregister(&ubi_ctrl_cdev);
	class_remove_file(ubi_class, &ubi_version);
	class_destroy(ubi_class);
	class_unregister(&ubi_class);
}
module_exit(ubi_exit);

+1 −1
Original line number Diff line number Diff line
@@ -775,7 +775,7 @@ extern struct kmem_cache *ubi_wl_entry_slab;
extern const struct file_operations ubi_ctrl_cdev_operations;
extern const struct file_operations ubi_cdev_operations;
extern const struct file_operations ubi_vol_cdev_operations;
extern struct class *ubi_class;
extern struct class ubi_class;
extern struct mutex ubi_devices_mutex;
extern struct blocking_notifier_head ubi_notifiers;

+20 −74
Original line number Diff line number Diff line
@@ -120,6 +120,19 @@ static ssize_t vol_attribute_show(struct device *dev,
	return ret;
}

static struct attribute *volume_dev_attrs[] = {
	&attr_vol_reserved_ebs.attr,
	&attr_vol_type.attr,
	&attr_vol_name.attr,
	&attr_vol_corrupted.attr,
	&attr_vol_alignment.attr,
	&attr_vol_usable_eb_size.attr,
	&attr_vol_data_bytes.attr,
	&attr_vol_upd_marker.attr,
	NULL
};
ATTRIBUTE_GROUPS(volume_dev);

/* Release method for volume devices */
static void vol_release(struct device *dev)
{
@@ -129,64 +142,6 @@ static void vol_release(struct device *dev)
	kfree(vol);
}

/**
 * volume_sysfs_init - initialize sysfs for new volume.
 * @ubi: UBI device description object
 * @vol: volume description object
 *
 * This function returns zero in case of success and a negative error code in
 * case of failure.
 *
 * Note, this function does not free allocated resources in case of failure -
 * the caller does it. This is because this would cause release() here and the
 * caller would oops.
 */
static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
{
	int err;

	err = device_create_file(&vol->dev, &attr_vol_reserved_ebs);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_type);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_name);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_corrupted);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_alignment);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_usable_eb_size);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_data_bytes);
	if (err)
		return err;
	err = device_create_file(&vol->dev, &attr_vol_upd_marker);
	return err;
}

/**
 * volume_sysfs_close - close sysfs for a volume.
 * @vol: volume description object
 */
static void volume_sysfs_close(struct ubi_volume *vol)
{
	device_remove_file(&vol->dev, &attr_vol_upd_marker);
	device_remove_file(&vol->dev, &attr_vol_data_bytes);
	device_remove_file(&vol->dev, &attr_vol_usable_eb_size);
	device_remove_file(&vol->dev, &attr_vol_alignment);
	device_remove_file(&vol->dev, &attr_vol_corrupted);
	device_remove_file(&vol->dev, &attr_vol_name);
	device_remove_file(&vol->dev, &attr_vol_type);
	device_remove_file(&vol->dev, &attr_vol_reserved_ebs);
	device_unregister(&vol->dev);
}

/**
 * ubi_create_volume - create volume.
 * @ubi: UBI device description object
@@ -323,7 +278,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
	vol->dev.release = vol_release;
	vol->dev.parent = &ubi->dev;
	vol->dev.devt = dev;
	vol->dev.class = ubi_class;
	vol->dev.class = &ubi_class;
	vol->dev.groups = volume_dev_groups;

	dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
	err = device_register(&vol->dev);
@@ -332,10 +288,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
		goto out_cdev;
	}

	err = volume_sysfs_init(ubi, vol);
	if (err)
		goto out_sysfs;

	/* Fill volume table record */
	memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record));
	vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs);
@@ -372,7 +324,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
	 */
	do_free = 0;
	get_device(&vol->dev);
	volume_sysfs_close(vol);
	device_unregister(&vol->dev);
out_cdev:
	cdev_del(&vol->cdev);
out_mapping:
@@ -440,7 +392,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
	}

	cdev_del(&vol->cdev);
	volume_sysfs_close(vol);
	device_unregister(&vol->dev);

	spin_lock(&ubi->volumes_lock);
	ubi->rsvd_pebs -= reserved_pebs;
@@ -653,19 +605,13 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
	vol->dev.release = vol_release;
	vol->dev.parent = &ubi->dev;
	vol->dev.devt = dev;
	vol->dev.class = ubi_class;
	vol->dev.class = &ubi_class;
	vol->dev.groups = volume_dev_groups;
	dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
	err = device_register(&vol->dev);
	if (err)
		goto out_cdev;

	err = volume_sysfs_init(ubi, vol);
	if (err) {
		cdev_del(&vol->cdev);
		volume_sysfs_close(vol);
		return err;
	}

	self_check_volumes(ubi);
	return err;

@@ -688,7 +634,7 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)

	ubi->volumes[vol->vol_id] = NULL;
	cdev_del(&vol->cdev);
	volume_sysfs_close(vol);
	device_unregister(&vol->dev);
}

/**