aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2014-11-24 16:30:09 -0500
committerRichard Weinberger <richard@nod.at>2015-01-28 09:57:04 -0500
commitfafdd2bf2638157670f28462b641150d16dbaeca (patch)
tree717b6e07e8018eec9e6ac3e5ead6dedffbf4799c
parent346be9bc802ddbaf7ce2ad35145d1ddfba376594 (diff)
UBI: Implement UBI_METAONLY
UBI_METAONLY is a new open mode for UBI volumes, it indicates that only meta data is being changed. Meta data in terms of UBI volumes means data which is stored in the UBI volume table but not on the volume itself. While it does not interfere with UBI_READONLY and UBI_READWRITE it is not allowed to use UBI_METAONLY together with UBI_EXCLUSIVE. Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Cc: Andrew Murray <amurray@embedded-bits.co.uk> Signed-off-by: Richard Weinberger <richard@nod.at> Tested-by: Guido Martínez <guido@vanguardiasur.com.ar> Reviewed-by: Guido Martínez <guido@vanguardiasur.com.ar> Tested-by: Christoph Fritz <chf.fritz@googlemail.com> Tested-by: Andrew Murray <amurray@embedded-bits.co.uk>
-rw-r--r--drivers/mtd/ubi/cdev.c8
-rw-r--r--drivers/mtd/ubi/kapi.c15
-rw-r--r--drivers/mtd/ubi/ubi.h8
-rw-r--r--include/linux/mtd/ubi.h5
4 files changed, 28 insertions, 8 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)
61 struct ubi_volume *vol = desc->vol; 61 struct ubi_volume *vol = desc->vol;
62 62
63 spin_lock(&vol->ubi->volumes_lock); 63 spin_lock(&vol->ubi->volumes_lock);
64 users = vol->readers + vol->writers + vol->exclusive; 64 users = vol->readers + vol->writers + vol->exclusive + vol->metaonly;
65 ubi_assert(users > 0); 65 ubi_assert(users > 0);
66 if (users > 1) { 66 if (users > 1) {
67 ubi_err(ubi, "%d users for volume %d", users, vol->vol_id); 67 ubi_err(ubi, "%d users for volume %d", users, vol->vol_id);
68 err = -EBUSY; 68 err = -EBUSY;
69 } else { 69 } else {
70 vol->readers = vol->writers = 0; 70 vol->readers = vol->writers = vol->metaonly = 0;
71 vol->exclusive = 1; 71 vol->exclusive = 1;
72 err = desc->mode; 72 err = desc->mode;
73 desc->mode = UBI_EXCLUSIVE; 73 desc->mode = UBI_EXCLUSIVE;
@@ -87,13 +87,15 @@ static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
87 struct ubi_volume *vol = desc->vol; 87 struct ubi_volume *vol = desc->vol;
88 88
89 spin_lock(&vol->ubi->volumes_lock); 89 spin_lock(&vol->ubi->volumes_lock);
90 ubi_assert(vol->readers == 0 && vol->writers == 0); 90 ubi_assert(vol->readers == 0 && vol->writers == 0 && vol->metaonly == 0);
91 ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE); 91 ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE);
92 vol->exclusive = 0; 92 vol->exclusive = 0;
93 if (mode == UBI_READONLY) 93 if (mode == UBI_READONLY)
94 vol->readers = 1; 94 vol->readers = 1;
95 else if (mode == UBI_READWRITE) 95 else if (mode == UBI_READWRITE)
96 vol->writers = 1; 96 vol->writers = 1;
97 else if (mode == UBI_METAONLY)
98 vol->metaonly = 1;
97 else 99 else
98 vol->exclusive = 1; 100 vol->exclusive = 1;
99 spin_unlock(&vol->ubi->volumes_lock); 101 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)
137 return ERR_PTR(-EINVAL); 137 return ERR_PTR(-EINVAL);
138 138
139 if (mode != UBI_READONLY && mode != UBI_READWRITE && 139 if (mode != UBI_READONLY && mode != UBI_READWRITE &&
140 mode != UBI_EXCLUSIVE) 140 mode != UBI_EXCLUSIVE && mode != UBI_METAONLY)
141 return ERR_PTR(-EINVAL); 141 return ERR_PTR(-EINVAL);
142 142
143 /* 143 /*
@@ -182,10 +182,17 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
182 break; 182 break;
183 183
184 case UBI_EXCLUSIVE: 184 case UBI_EXCLUSIVE:
185 if (vol->exclusive || vol->writers || vol->readers) 185 if (vol->exclusive || vol->writers || vol->readers ||
186 vol->metaonly)
186 goto out_unlock; 187 goto out_unlock;
187 vol->exclusive = 1; 188 vol->exclusive = 1;
188 break; 189 break;
190
191 case UBI_METAONLY:
192 if (vol->metaonly || vol->exclusive)
193 goto out_unlock;
194 vol->metaonly = 1;
195 break;
189 } 196 }
190 get_device(&vol->dev); 197 get_device(&vol->dev);
191 vol->ref_count += 1; 198 vol->ref_count += 1;
@@ -343,6 +350,10 @@ void ubi_close_volume(struct ubi_volume_desc *desc)
343 break; 350 break;
344 case UBI_EXCLUSIVE: 351 case UBI_EXCLUSIVE:
345 vol->exclusive = 0; 352 vol->exclusive = 0;
353 break;
354 case UBI_METAONLY:
355 vol->metaonly = 0;
356 break;
346 } 357 }
347 vol->ref_count -= 1; 358 vol->ref_count -= 1;
348 spin_unlock(&ubi->volumes_lock); 359 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 {
261 * @readers: number of users holding this volume in read-only mode 261 * @readers: number of users holding this volume in read-only mode
262 * @writers: number of users holding this volume in read-write mode 262 * @writers: number of users holding this volume in read-write mode
263 * @exclusive: whether somebody holds this volume in exclusive mode 263 * @exclusive: whether somebody holds this volume in exclusive mode
264 * @metaonly: whether somebody is altering only meta data of this volume
264 * 265 *
265 * @reserved_pebs: how many physical eraseblocks are reserved for this volume 266 * @reserved_pebs: how many physical eraseblocks are reserved for this volume
266 * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) 267 * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
@@ -309,6 +310,7 @@ struct ubi_volume {
309 int readers; 310 int readers;
310 int writers; 311 int writers;
311 int exclusive; 312 int exclusive;
313 int metaonly;
312 314
313 int reserved_pebs; 315 int reserved_pebs;
314 int vol_type; 316 int vol_type;
@@ -339,7 +341,8 @@ struct ubi_volume {
339/** 341/**
340 * struct ubi_volume_desc - UBI volume descriptor returned when it is opened. 342 * struct ubi_volume_desc - UBI volume descriptor returned when it is opened.
341 * @vol: reference to the corresponding volume description object 343 * @vol: reference to the corresponding volume description object
342 * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE) 344 * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, %UBI_EXCLUSIVE
345 * or %UBI_METAONLY)
343 */ 346 */
344struct ubi_volume_desc { 347struct ubi_volume_desc {
345 struct ubi_volume *vol; 348 struct ubi_volume *vol;
@@ -390,7 +393,8 @@ struct ubi_debug_info {
390 * @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs, 393 * @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs,
391 * @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count, 394 * @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count,
392 * @vol->readers, @vol->writers, @vol->exclusive, 395 * @vol->readers, @vol->writers, @vol->exclusive,
393 * @vol->ref_count, @vol->mapping and @vol->eba_tbl. 396 * @vol->metaonly, @vol->ref_count, @vol->mapping and
397 * @vol->eba_tbl.
394 * @ref_count: count of references on the UBI device 398 * @ref_count: count of references on the UBI device
395 * @image_seq: image sequence number recorded on EC headers 399 * @image_seq: image sequence number recorded on EC headers
396 * 400 *
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index c3918a0684fe..8fa2753316e8 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -34,11 +34,14 @@
34 * UBI_READONLY: read-only mode 34 * UBI_READONLY: read-only mode
35 * UBI_READWRITE: read-write mode 35 * UBI_READWRITE: read-write mode
36 * UBI_EXCLUSIVE: exclusive mode 36 * UBI_EXCLUSIVE: exclusive mode
37 * UBI_METAONLY: modify only the volume meta-data,
38 * i.e. the data stored in the volume table, but not in any of volume LEBs.
37 */ 39 */
38enum { 40enum {
39 UBI_READONLY = 1, 41 UBI_READONLY = 1,
40 UBI_READWRITE, 42 UBI_READWRITE,
41 UBI_EXCLUSIVE 43 UBI_EXCLUSIVE,
44 UBI_METAONLY
42}; 45};
43 46
44/** 47/**