summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/vmt.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-17 17:37:26 +0200
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-26 19:15:17 +0200
commite73f4459d969bb266f03dd4cbe21bdba8cb2732c (patch)
tree5af7655da65f2c33f6ea4efdfaa8b0e0670d6aea /drivers/mtd/ubi/vmt.c
parent9f961b57568960a150cc9781c52824c9093a0514 (diff)
downloadblackbird-op-linux-e73f4459d969bb266f03dd4cbe21bdba8cb2732c.tar.gz
blackbird-op-linux-e73f4459d969bb266f03dd4cbe21bdba8cb2732c.zip
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,
{
int ret;
struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);
- struct ubi_device *ubi = vol->ubi;
+ struct ubi_device *ubi;
+
+ ubi = ubi_get_device(vol->ubi->ubi_num);
+ if (!ubi)
+ return -ENODEV;
spin_lock(&ubi->volumes_lock);
if (!ubi->volumes[vol->vol_id]) {
spin_unlock(&ubi->volumes_lock);
+ ubi_put_device(ubi);
return -ENODEV;
}
/* Take a reference to prevent volume removal */
@@ -108,10 +113,12 @@ static ssize_t vol_attribute_show(struct device *dev,
/* This must be a bug */
ret = -EINVAL;
+ /* We've done the operation, drop volume and UBI device references */
spin_lock(&ubi->volumes_lock);
vol->ref_count -= 1;
ubi_assert(vol->ref_count >= 0);
spin_unlock(&ubi->volumes_lock);
+ ubi_put_device(ubi);
return ret;
}
@@ -260,6 +267,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
}
ubi->avail_pebs -= vol->reserved_pebs;
ubi->rsvd_pebs += vol->reserved_pebs;
+ spin_unlock(&ubi->volumes_lock);
vol->vol_id = vol_id;
vol->alignment = req->alignment;
@@ -267,9 +275,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->vol_type = req->vol_type;
vol->name_len = req->name_len;
memcpy(vol->name, req->name, vol->name_len + 1);
- vol->exclusive = 1;
vol->ubi = ubi;
- spin_unlock(&ubi->volumes_lock);
/*
* 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)
goto out_sysfs;
spin_lock(&ubi->volumes_lock);
- ubi->vol_count += 1;
- vol->exclusive = 0;
ubi->volumes[vol_id] = vol;
spin_unlock(&ubi->volumes_lock);
OpenPOWER on IntegriCloud