aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/vmt.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/vmt.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/vmt.c')
-rw-r--r--drivers/mtd/ubi/vmt.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 3ed63dc37386..42d3dd70f2d0 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -71,11 +71,16 @@ static ssize_t vol_attribute_show(struct device *dev,
71{ 71{
72 int ret; 72 int ret;
73 struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); 73 struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);
74 struct ubi_device *ubi = vol->ubi; 74 struct ubi_device *ubi;
75
76 ubi = ubi_get_device(vol->ubi->ubi_num);
77 if (!ubi)
78 return -ENODEV;
75 79
76 spin_lock(&ubi->volumes_lock); 80 spin_lock(&ubi->volumes_lock);
77 if (!ubi->volumes[vol->vol_id]) { 81 if (!ubi->volumes[vol->vol_id]) {
78 spin_unlock(&ubi->volumes_lock); 82 spin_unlock(&ubi->volumes_lock);
83 ubi_put_device(ubi);
79 return -ENODEV; 84 return -ENODEV;
80 } 85 }
81 /* Take a reference to prevent volume removal */ 86 /* Take a reference to prevent volume removal */
@@ -108,10 +113,12 @@ static ssize_t vol_attribute_show(struct device *dev,
108 /* This must be a bug */ 113 /* This must be a bug */
109 ret = -EINVAL; 114 ret = -EINVAL;
110 115
116 /* We've done the operation, drop volume and UBI device references */
111 spin_lock(&ubi->volumes_lock); 117 spin_lock(&ubi->volumes_lock);
112 vol->ref_count -= 1; 118 vol->ref_count -= 1;
113 ubi_assert(vol->ref_count >= 0); 119 ubi_assert(vol->ref_count >= 0);
114 spin_unlock(&ubi->volumes_lock); 120 spin_unlock(&ubi->volumes_lock);
121 ubi_put_device(ubi);
115 return ret; 122 return ret;
116} 123}
117 124
@@ -260,6 +267,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
260 } 267 }
261 ubi->avail_pebs -= vol->reserved_pebs; 268 ubi->avail_pebs -= vol->reserved_pebs;
262 ubi->rsvd_pebs += vol->reserved_pebs; 269 ubi->rsvd_pebs += vol->reserved_pebs;
270 spin_unlock(&ubi->volumes_lock);
263 271
264 vol->vol_id = vol_id; 272 vol->vol_id = vol_id;
265 vol->alignment = req->alignment; 273 vol->alignment = req->alignment;
@@ -267,9 +275,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
267 vol->vol_type = req->vol_type; 275 vol->vol_type = req->vol_type;
268 vol->name_len = req->name_len; 276 vol->name_len = req->name_len;
269 memcpy(vol->name, req->name, vol->name_len + 1); 277 memcpy(vol->name, req->name, vol->name_len + 1);
270 vol->exclusive = 1;
271 vol->ubi = ubi; 278 vol->ubi = ubi;
272 spin_unlock(&ubi->volumes_lock);
273 279
274 /* 280 /*
275 * Finish all pending erases because there may be some LEBs belonging 281 * Finish all pending erases because there may be some LEBs belonging
@@ -350,8 +356,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
350 goto out_sysfs; 356 goto out_sysfs;
351 357
352 spin_lock(&ubi->volumes_lock); 358 spin_lock(&ubi->volumes_lock);
353 ubi->vol_count += 1;
354 vol->exclusive = 0;
355 ubi->volumes[vol_id] = vol; 359 ubi->volumes[vol_id] = vol;
356 spin_unlock(&ubi->volumes_lock); 360 spin_unlock(&ubi->volumes_lock);
357 361