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

Commit cc8a0a94 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'upstream-4.2-rc1' of git://git.infradead.org/linux-ubifs

Pull UBI/UBIFS updates from Richard Weinberger:
 "Minor fixes for UBI and UBIFS"

* tag 'upstream-4.2-rc1' of git://git.infradead.org/linux-ubifs:
  UBI: Remove unnecessary `\'
  UBI: Use static class and attribute groups
  UBI: add a helper function for updatting on-flash layout volumes
  UBI: Fastmap: Do not add vol if it already exists
  UBI: Init vol->reserved_pebs by assignment
  UBI: Fastmap: Rename variables to make them meaningful
  UBI: Fastmap: Remove unnecessary `\'
  UBI: Fastmap: Use max() to get the larger value
  ubifs: fix to check error code of register_shrinker
  UBI: block: Dynamically allocate minor numbers
parents d857da7b 669d3d12
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include <linux/blk-mq.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
#include <linux/idr.h>
#include <asm/div64.h>

#include "ubi-media.h"
@@ -353,6 +354,8 @@ static struct blk_mq_ops ubiblock_mq_ops = {
	.map_queue      = blk_mq_map_queue,
};

static DEFINE_IDR(ubiblock_minor_idr);

int ubiblock_create(struct ubi_volume_info *vi)
{
	struct ubiblock *dev;
@@ -390,7 +393,13 @@ int ubiblock_create(struct ubi_volume_info *vi)

	gd->fops = &ubiblock_ops;
	gd->major = ubiblock_major;
	gd->first_minor = dev->ubi_num * UBI_MAX_VOLUMES + dev->vol_id;
	gd->first_minor = idr_alloc(&ubiblock_minor_idr, dev, 0, 0, GFP_KERNEL);
	if (gd->first_minor < 0) {
		dev_err(disk_to_dev(gd),
			"block: dynamic minor allocation failed");
		ret = -ENODEV;
		goto out_put_disk;
	}
	gd->private_data = dev;
	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
	set_capacity(gd, disk_capacity);
@@ -407,7 +416,7 @@ int ubiblock_create(struct ubi_volume_info *vi)
	ret = blk_mq_alloc_tag_set(&dev->tag_set);
	if (ret) {
		dev_err(disk_to_dev(dev->gd), "blk_mq_alloc_tag_set failed");
		goto out_put_disk;
		goto out_remove_minor;
	}

	dev->rq = blk_mq_init_queue(&dev->tag_set);
@@ -445,6 +454,8 @@ int ubiblock_create(struct ubi_volume_info *vi)
	blk_cleanup_queue(dev->rq);
out_free_tags:
	blk_mq_free_tag_set(&dev->tag_set);
out_remove_minor:
	idr_remove(&ubiblock_minor_idr, gd->first_minor);
out_put_disk:
	put_disk(dev->gd);
out_free_dev:
@@ -463,6 +474,7 @@ static void ubiblock_cleanup(struct ubiblock *dev)
	blk_cleanup_queue(dev->rq);
	blk_mq_free_tag_set(&dev->tag_set);
	dev_info(disk_to_dev(dev->gd), "released");
	idr_remove(&ubiblock_minor_idr, dev->gd->first_minor);
	put_disk(dev->gd);
}

+38 −69
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);
}

@@ -947,8 +929,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
	 */
	ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size,
		ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE);
	if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE)
		ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE;
	ubi->fm_pool.max_size = max(ubi->fm_pool.max_size,
		UBI_FM_MIN_POOL_SIZE);

	ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2;
	ubi->fm_disabled = !fm_autoconvert;
@@ -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);

+45 −38
Original line number Diff line number Diff line
@@ -88,13 +88,13 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi)
{
	size_t size;

	size = sizeof(struct ubi_fm_sb) + \
		sizeof(struct ubi_fm_hdr) + \
		sizeof(struct ubi_fm_scan_pool) + \
		sizeof(struct ubi_fm_scan_pool) + \
		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
		(sizeof(struct ubi_fm_eba) + \
		(ubi->peb_count * sizeof(__be32))) + \
	size = sizeof(struct ubi_fm_sb) +
		sizeof(struct ubi_fm_hdr) +
		sizeof(struct ubi_fm_scan_pool) +
		sizeof(struct ubi_fm_scan_pool) +
		(ubi->peb_count * sizeof(struct ubi_fm_ec)) +
		(sizeof(struct ubi_fm_eba) +
		(ubi->peb_count * sizeof(__be32))) +
		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
	return roundup(size, ubi->leb_size);
}
@@ -192,8 +192,10 @@ static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,

		if (vol_id > av->vol_id)
			p = &(*p)->rb_left;
		else
		else if (vol_id < av->vol_id)
			p = &(*p)->rb_right;
		else
			return ERR_PTR(-EINVAL);
	}

	av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
@@ -314,7 +316,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
			list_add_tail(&victim->u.list, &ai->erase);

			if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
				av->last_data_size = \
				av->last_data_size =
					be32_to_cpu(new_vh->data_size);

			dbg_bld("vol %i: AEB %i's PEB %i is the newer",
@@ -601,7 +603,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
	struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb;
	struct ubi_fm_sb *fmsb;
	struct ubi_fm_hdr *fmhdr;
	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
	struct ubi_fm_scan_pool *fmpl, *fmpl_wl;
	struct ubi_fm_ec *fmec;
	struct ubi_fm_volhdr *fmvhdr;
	struct ubi_fm_eba *fm_eba;
@@ -631,30 +633,30 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
		goto fail_bad;
	}

	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl1);
	fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
	if (be32_to_cpu(fmpl->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
			be32_to_cpu(fmpl->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl2);
	fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl_wl);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
	if (be32_to_cpu(fmpl_wl->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err(ubi, "bad fastmap WL pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl_wl->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	pool_size = be16_to_cpu(fmpl1->size);
	wl_pool_size = be16_to_cpu(fmpl2->size);
	fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
	fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);
	pool_size = be16_to_cpu(fmpl->size);
	wl_pool_size = be16_to_cpu(fmpl_wl->size);
	fm->max_pool_size = be16_to_cpu(fmpl->max_size);
	fm->max_wl_pool_size = be16_to_cpu(fmpl_wl->max_size);

	if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
		ubi_err(ubi, "bad pool size: %i", pool_size);
@@ -748,6 +750,11 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,

		if (!av)
			goto fail_bad;
		if (PTR_ERR(av) == -EINVAL) {
			ubi_err(ubi, "volume (ID %i) already exists",
				fmvhdr->vol_id);
			goto fail_bad;
		}

		ai->vols_found++;
		if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id))
@@ -796,11 +803,11 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
		}
	}

	ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum, &free);
	ret = scan_pool(ubi, ai, fmpl->pebs, pool_size, &max_sqnum, &free);
	if (ret)
		goto fail;

	ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum, &free);
	ret = scan_pool(ubi, ai, fmpl_wl->pebs, wl_pool_size, &max_sqnum, &free);
	if (ret)
		goto fail;

@@ -1083,7 +1090,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	void *fm_raw;
	struct ubi_fm_sb *fmsb;
	struct ubi_fm_hdr *fmh;
	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
	struct ubi_fm_scan_pool *fmpl, *fmpl_wl;
	struct ubi_fm_ec *fec;
	struct ubi_fm_volhdr *fvh;
	struct ubi_fm_eba *feba;
@@ -1141,25 +1148,25 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	erase_peb_count = 0;
	vol_count = 0;

	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl1);
	fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl1->size = cpu_to_be16(ubi->fm_pool.size);
	fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size);
	fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl);
	fmpl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl->size = cpu_to_be16(ubi->fm_pool.size);
	fmpl->max_size = cpu_to_be16(ubi->fm_pool.max_size);

	for (i = 0; i < ubi->fm_pool.size; i++) {
		fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]);
		fmpl->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]);
		set_seen(ubi, ubi->fm_pool.pebs[i], seen_pebs);
	}

	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl2);
	fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size);
	fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size);
	fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl_wl);
	fmpl_wl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl_wl->size = cpu_to_be16(ubi->fm_wl_pool.size);
	fmpl_wl->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size);

	for (i = 0; i < ubi->fm_wl_pool.size; i++) {
		fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]);
		fmpl_wl->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]);
		set_seen(ubi, ubi->fm_wl_pool.pebs[i], seen_pebs);
	}

+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;

+22 −76
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
@@ -253,7 +208,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)

	/* Calculate how many eraseblocks are requested */
	vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
	vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1,
	vol->reserved_pebs = div_u64(req->bytes + vol->usable_leb_size - 1,
				     vol->usable_leb_size);

	/* Reserve physical eraseblocks */
@@ -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);
}

/**
Loading