aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/cdev.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-17 10:37:26 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-26 12:15:17 -0500
commite73f4459d969bb266f03dd4cbe21bdba8cb2732c (patch)
tree5af7655da65f2c33f6ea4efdfaa8b0e0670d6aea /drivers/mtd/ubi/cdev.c
parent9f961b57568960a150cc9781c52824c9093a0514 (diff)
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>
Diffstat (limited to 'drivers/mtd/ubi/cdev.c')
-rw-r--r--drivers/mtd/ubi/cdev.c34
1 files changed, 10 insertions, 24 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index bc900d24cdba..01978b57e9cb 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -56,23 +56,6 @@
56#endif 56#endif
57 57
58/** 58/**
59 * major_to_device - get UBI device object by character device major number.
60 * @major: major number
61 *
62 * This function returns a pointer to the UBI device object.
63 */
64static struct ubi_device *major_to_device(int major)
65{
66 int i;
67
68 for (i = 0; i < UBI_MAX_DEVICES; i++)
69 if (ubi_devices[i] && MAJOR(ubi_devices[i]->cdev.dev) == major)
70 return ubi_devices[i];
71 BUG();
72 return NULL;
73}
74
75/**
76 * get_exclusive - get exclusive access to an UBI volume. 59 * get_exclusive - get exclusive access to an UBI volume.
77 * @desc: volume descriptor 60 * @desc: volume descriptor
78 * 61 *
@@ -129,9 +112,11 @@ static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
129static int vol_cdev_open(struct inode *inode, struct file *file) 112static int vol_cdev_open(struct inode *inode, struct file *file)
130{ 113{
131 struct ubi_volume_desc *desc; 114 struct ubi_volume_desc *desc;
132 const struct ubi_device *ubi = major_to_device(imajor(inode)); 115 int vol_id = iminor(inode) - 1, mode, ubi_num;
133 int vol_id = iminor(inode) - 1; 116
134 int mode; 117 ubi_num = ubi_major2num(imajor(inode));
118 if (ubi_num < 0)
119 return ubi_num;
135 120
136 if (file->f_mode & FMODE_WRITE) 121 if (file->f_mode & FMODE_WRITE)
137 mode = UBI_READWRITE; 122 mode = UBI_READWRITE;
@@ -140,7 +125,7 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
140 125
141 dbg_msg("open volume %d, mode %d", vol_id, mode); 126 dbg_msg("open volume %d, mode %d", vol_id, mode);
142 127
143 desc = ubi_open_volume(ubi->ubi_num, vol_id, mode); 128 desc = ubi_open_volume(ubi_num, vol_id, mode);
144 if (IS_ERR(desc)) 129 if (IS_ERR(desc))
145 return PTR_ERR(desc); 130 return PTR_ERR(desc);
146 131
@@ -586,9 +571,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
586 if (!capable(CAP_SYS_RESOURCE)) 571 if (!capable(CAP_SYS_RESOURCE))
587 return -EPERM; 572 return -EPERM;
588 573
589 ubi = major_to_device(imajor(inode)); 574 ubi = ubi_get_by_major(imajor(inode));
590 if (IS_ERR(ubi)) 575 if (!ubi)
591 return PTR_ERR(ubi); 576 return -ENODEV;
592 577
593 switch (cmd) { 578 switch (cmd) {
594 /* Create volume command */ 579 /* Create volume command */
@@ -695,6 +680,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
695 break; 680 break;
696 } 681 }
697 682
683 ubi_put_device(ubi);
698 return err; 684 return err;
699} 685}
700 686