diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-17 10:37:26 -0500 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-26 12:15:17 -0500 |
commit | e73f4459d969bb266f03dd4cbe21bdba8cb2732c (patch) | |
tree | 5af7655da65f2c33f6ea4efdfaa8b0e0670d6aea /drivers/mtd/ubi/cdev.c | |
parent | 9f961b57568960a150cc9781c52824c9093a0514 (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.c | 34 |
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 | */ | ||
64 | static 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) | |||
129 | static int vol_cdev_open(struct inode *inode, struct file *file) | 112 | static 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 | ||