UBI: add UBI control device
This patch is a preparation to make UBI devices dynamic. It adds an UBI control device which has dynamically allocated major number and registers itself as "ubi_ctrl". It does not do anything so far. The idea is that this device will allow to attach/detach MTD devices from userspace. This is symilar to what the Linux device mapper has. The next things to do are: * Fix UBI, because it now assumes UBI devices cannot go away * Implement control device ioctls which will attach/detach MTD devices Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
parent
16f557ecbf
commit
9f961b5756
3 changed files with 54 additions and 11 deletions
|
@ -21,11 +21,16 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* This file includes UBI initialization and building of UBI devices. At the
|
||||
* moment UBI devices may only be added while UBI is initialized, but dynamic
|
||||
* device add/remove functionality is planned. Also, at the moment we only
|
||||
* attach UBI devices by scanning, which will become a bottleneck when flashes
|
||||
* reach certain large size. Then one may improve UBI and add other methods.
|
||||
* This file includes UBI initialization and building of UBI devices.
|
||||
*
|
||||
* When UBI is initialized, it attaches all the MTD devices specified as the
|
||||
* module load parameters or the kernel boot parameters. If MTD devices were
|
||||
* specified, UBI does not attach any MTD device, but it is possible to do
|
||||
* later using the "UBI control device".
|
||||
*
|
||||
* At the moment we only attach UBI devices by scanning, which will become a
|
||||
* bottleneck when flashes reach certain large size. Then one may improve UBI
|
||||
* and add other methods, although it does not seem to be easy to do.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
|
@ -33,6 +38,7 @@
|
|||
#include <linux/moduleparam.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/log2.h>
|
||||
#include "ubi.h"
|
||||
|
||||
|
@ -70,6 +76,12 @@ struct kmem_cache *ubi_ltree_slab;
|
|||
/* Slab cache for wear-leveling entries */
|
||||
struct kmem_cache *ubi_wl_entry_slab;
|
||||
|
||||
/* UBI control character device */
|
||||
static struct miscdevice ubi_ctrl_cdev = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "ubi_ctrl",
|
||||
.fops = &ubi_ctrl_cdev_operations,
|
||||
};
|
||||
|
||||
/* "Show" method for files in '/<sysfs>/class/ubi/' */
|
||||
static ssize_t ubi_version_show(struct class *class, char *buf)
|
||||
|
@ -701,19 +713,31 @@ static int __init ubi_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Create base sysfs directory and sysfs files */
|
||||
ubi_class = class_create(THIS_MODULE, UBI_NAME_STR);
|
||||
if (IS_ERR(ubi_class))
|
||||
return PTR_ERR(ubi_class);
|
||||
if (IS_ERR(ubi_class)) {
|
||||
err = PTR_ERR(ubi_class);
|
||||
printk(KERN_ERR "UBI error: cannot create UBI class\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = class_create_file(ubi_class, &ubi_version);
|
||||
if (err)
|
||||
if (err) {
|
||||
printk(KERN_ERR "UBI error: cannot create sysfs file\n");
|
||||
goto out_class;
|
||||
}
|
||||
|
||||
err = misc_register(&ubi_ctrl_cdev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "UBI error: cannot register device\n");
|
||||
goto out_version;
|
||||
}
|
||||
|
||||
ubi_ltree_slab = kmem_cache_create("ubi_ltree_slab",
|
||||
sizeof(struct ubi_ltree_entry), 0,
|
||||
0, <ree_entry_ctor);
|
||||
if (!ubi_ltree_slab)
|
||||
goto out_version;
|
||||
goto out_dev_unreg;
|
||||
|
||||
ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
|
||||
sizeof(struct ubi_wl_entry),
|
||||
|
@ -727,8 +751,11 @@ static int __init ubi_init(void)
|
|||
|
||||
cond_resched();
|
||||
err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs);
|
||||
if (err)
|
||||
if (err) {
|
||||
printk(KERN_ERR "UBI error: cannot attach %s\n",
|
||||
p->name);
|
||||
goto out_detach;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -739,10 +766,14 @@ out_detach:
|
|||
kmem_cache_destroy(ubi_wl_entry_slab);
|
||||
out_ltree:
|
||||
kmem_cache_destroy(ubi_ltree_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:
|
||||
printk(KERN_ERR "UBI error: cannot initialize UBI, error %d\n", err);
|
||||
return err;
|
||||
}
|
||||
module_init(ubi_init);
|
||||
|
@ -756,6 +787,7 @@ static void __exit ubi_exit(void)
|
|||
detach_mtd_dev(ubi_devices[i]);
|
||||
kmem_cache_destroy(ubi_wl_entry_slab);
|
||||
kmem_cache_destroy(ubi_ltree_slab);
|
||||
misc_deregister(&ubi_ctrl_cdev);
|
||||
class_remove_file(ubi_class, &ubi_version);
|
||||
class_destroy(ubi_class);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
*
|
||||
* Major and minor numbers are assigned dynamically to both UBI and volume
|
||||
* character devices.
|
||||
*
|
||||
* Well, there is the third kind of character devices - the UBI control
|
||||
* character device, which allows to manipulate by UBI devices - create and
|
||||
* delete them. In other words, it is used for attaching and detaching MTD
|
||||
* devices.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -693,6 +698,11 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
|
|||
return err;
|
||||
}
|
||||
|
||||
/* UBI control character device operations */
|
||||
struct file_operations ubi_ctrl_cdev_operations = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/* UBI character device operations */
|
||||
struct file_operations ubi_cdev_operations = {
|
||||
.owner = THIS_MODULE,
|
||||
|
|
|
@ -235,7 +235,7 @@ struct ubi_wl_entry;
|
|||
|
||||
/**
|
||||
* struct ubi_device - UBI device description structure
|
||||
* @dev: class device object to use the the Linux device model
|
||||
* @dev: UBI device object to use the the Linux device model
|
||||
* @cdev: character device object to create character device
|
||||
* @ubi_num: UBI device number
|
||||
* @ubi_name: UBI device name
|
||||
|
@ -398,6 +398,7 @@ struct ubi_device {
|
|||
|
||||
extern struct kmem_cache *ubi_ltree_slab;
|
||||
extern struct kmem_cache *ubi_wl_entry_slab;
|
||||
extern struct file_operations ubi_ctrl_cdev_operations;
|
||||
extern struct file_operations ubi_cdev_operations;
|
||||
extern struct file_operations ubi_vol_cdev_operations;
|
||||
extern struct ubi_device *ubi_devices[];
|
||||
|
|
Loading…
Reference in a new issue