diff options
| -rw-r--r-- | drivers/mtd/ubi/cdev.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/ubi/kapi.c | 15 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 8 | ||||
| -rw-r--r-- | include/linux/mtd/ubi.h | 5 |
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 | */ |
| 344 | struct ubi_volume_desc { | 347 | struct 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 | */ |
| 38 | enum { | 40 | enum { |
| 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 | /** |
