aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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/**