UBI: add UBI devices reference counting

This is one more step on the way to "removable" UBI devices. It
adds reference counting for UBI devices. Every time a volume on
this device is opened - the device's refcount is increased. It
is also increased if someone is reading any sysfs file of this
UBI device or of one of its volumes.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Artem Bityutskiy
2007-12-17 17:37:26 +02:00
parent 9f961b5756
commit e73f4459d9
7 changed files with 201 additions and 63 deletions

View File

@@ -55,23 +55,6 @@
#define VOL_CDEV_IOC_MAX_SEQ 2
#endif
/**
* major_to_device - get UBI device object by character device major number.
* @major: major number
*
* This function returns a pointer to the UBI device object.
*/
static struct ubi_device *major_to_device(int major)
{
int i;
for (i = 0; i < UBI_MAX_DEVICES; i++)
if (ubi_devices[i] && MAJOR(ubi_devices[i]->cdev.dev) == major)
return ubi_devices[i];
BUG();
return NULL;
}
/**
* get_exclusive - get exclusive access to an UBI volume.
* @desc: volume descriptor
@@ -129,9 +112,11 @@ static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
static int vol_cdev_open(struct inode *inode, struct file *file)
{
struct ubi_volume_desc *desc;
const struct ubi_device *ubi = major_to_device(imajor(inode));
int vol_id = iminor(inode) - 1;
int mode;
int vol_id = iminor(inode) - 1, mode, ubi_num;
ubi_num = ubi_major2num(imajor(inode));
if (ubi_num < 0)
return ubi_num;
if (file->f_mode & FMODE_WRITE)
mode = UBI_READWRITE;
@@ -140,7 +125,7 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
dbg_msg("open volume %d, mode %d", vol_id, mode);
desc = ubi_open_volume(ubi->ubi_num, vol_id, mode);
desc = ubi_open_volume(ubi_num, vol_id, mode);
if (IS_ERR(desc))
return PTR_ERR(desc);
@@ -586,9 +571,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
if (!capable(CAP_SYS_RESOURCE))
return -EPERM;
ubi = major_to_device(imajor(inode));
if (IS_ERR(ubi))
return PTR_ERR(ubi);
ubi = ubi_get_by_major(imajor(inode));
if (!ubi)
return -ENODEV;
switch (cmd) {
/* Create volume command */
@@ -695,6 +680,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
break;
}
ubi_put_device(ubi);
return err;
}