summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/ubi/cdev.c8
-rw-r--r--drivers/mtd/ubi/kapi.c15
-rw-r--r--drivers/mtd/ubi/ubi.h8
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 3410ea8109f8..f5c715c32dcd 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -61,13 +61,13 @@ static int get_exclusive(struct ubi_device *ubi, struct ubi_volume_desc *desc)
struct ubi_volume *vol = desc->vol;
spin_lock(&vol->ubi->volumes_lock);
- users = vol->readers + vol->writers + vol->exclusive;
+ users = vol->readers + vol->writers + vol->exclusive + vol->metaonly;
ubi_assert(users > 0);
if (users > 1) {
ubi_err(ubi, "%d users for volume %d", users, vol->vol_id);
err = -EBUSY;
} else {
- vol->readers = vol->writers = 0;
+ vol->readers = vol->writers = vol->metaonly = 0;
vol->exclusive = 1;
err = desc->mode;
desc->mode = UBI_EXCLUSIVE;
@@ -87,13 +87,15 @@ static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
struct ubi_volume *vol = desc->vol;
spin_lock(&vol->ubi->volumes_lock);
- ubi_assert(vol->readers == 0 && vol->writers == 0);
+ ubi_assert(vol->readers == 0 && vol->writers == 0 && vol->metaonly == 0);
ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE);
vol->exclusive = 0;
if (mode == UBI_READONLY)
vol->readers = 1;
else if (mode == UBI_READWRITE)
vol->writers = 1;
+ else if (mode == UBI_METAONLY)
+ vol->metaonly = 1;
else
vol->exclusive = 1;
spin_unlock(&vol->ubi->volumes_lock);
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index f3bab669f6bb..589c423fac2d 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -137,7 +137,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
return ERR_PTR(-EINVAL);
if (mode != UBI_READONLY && mode != UBI_READWRITE &&
- mode != UBI_EXCLUSIVE)
+ mode != UBI_EXCLUSIVE && mode != UBI_METAONLY)
return ERR_PTR(-EINVAL);
/*
@@ -182,10 +182,17 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
break;
case UBI_EXCLUSIVE:
- if (vol->exclusive || vol->writers || vol->readers)
+ if (vol->exclusive || vol->writers || vol->readers ||
+ vol->metaonly)
goto out_unlock;
vol->exclusive = 1;
break;
+
+ case UBI_METAONLY:
+ if (vol->metaonly || vol->exclusive)
+ goto out_unlock;
+ vol->metaonly = 1;
+ break;
}
get_device(&vol->dev);
vol->ref_count += 1;
@@ -343,6 +350,10 @@ void ubi_close_volume(struct ubi_volume_desc *desc)
break;
case UBI_EXCLUSIVE:
vol->exclusive = 0;
+ break;
+ case UBI_METAONLY:
+ vol->metaonly = 0;
+ break;
}
vol->ref_count -= 1;
spin_unlock(&ubi->volumes_lock);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index f80ffaba9058..20cabc060b61 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -261,6 +261,7 @@ struct ubi_fm_pool {
* @readers: number of users holding this volume in read-only mode
* @writers: number of users holding this volume in read-write mode
* @exclusive: whether somebody holds this volume in exclusive mode
+ * @metaonly: whether somebody is altering only meta data of this volume
*
* @reserved_pebs: how many physical eraseblocks are reserved for this volume
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
@@ -309,6 +310,7 @@ struct ubi_volume {
int readers;
int writers;
int exclusive;
+ int metaonly;
int reserved_pebs;
int vol_type;
@@ -339,7 +341,8 @@ struct ubi_volume {
/**
* struct ubi_volume_desc - UBI volume descriptor returned when it is opened.
* @vol: reference to the corresponding volume description object
- * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE)
+ * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, %UBI_EXCLUSIVE
+ * or %UBI_METAONLY)
*/
struct ubi_volume_desc {
struct ubi_volume *vol;
@@ -390,7 +393,8 @@ struct ubi_debug_info {
* @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs,
* @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count,
* @vol->readers, @vol->writers, @vol->exclusive,
- * @vol->ref_count, @vol->mapping and @vol->eba_tbl.
+ * @vol->metaonly, @vol->ref_count, @vol->mapping and
+ * @vol->eba_tbl.
* @ref_count: count of references on the UBI device
* @image_seq: image sequence number recorded on EC headers
*