diff options
| -rw-r--r-- | drivers/mtd/ubi/vtbl.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 1931dffe87b0..f8fc3081bbb4 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
| @@ -30,9 +30,12 @@ | |||
| 30 | * eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each | 30 | * eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each |
| 31 | * other. This redundancy guarantees robustness to unclean reboots. The volume | 31 | * other. This redundancy guarantees robustness to unclean reboots. The volume |
| 32 | * table is basically an array of volume table records. Each record contains | 32 | * table is basically an array of volume table records. Each record contains |
| 33 | * full information about the volume and protected by a CRC checksum. | 33 | * full information about the volume and protected by a CRC checksum. Note, |
| 34 | * nowadays we use the atomic LEB change operation when updating the volume | ||
| 35 | * table, so we do not really need 2 LEBs anymore, but we preserve the older | ||
| 36 | * design for the backward compatibility reasons. | ||
| 34 | * | 37 | * |
| 35 | * The volume table is changed, it is first changed in RAM. Then LEB 0 is | 38 | * When the volume table is changed, it is first changed in RAM. Then LEB 0 is |
| 36 | * erased, and the updated volume table is written back to LEB 0. Then same for | 39 | * erased, and the updated volume table is written back to LEB 0. Then same for |
| 37 | * LEB 1. This scheme guarantees recoverability from unclean reboots. | 40 | * LEB 1. This scheme guarantees recoverability from unclean reboots. |
| 38 | * | 41 | * |
| @@ -96,12 +99,8 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, | |||
| 96 | 99 | ||
| 97 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); | 100 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); |
| 98 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { | 101 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { |
| 99 | err = ubi_eba_unmap_leb(ubi, layout_vol, i); | 102 | err = ubi_eba_atomic_leb_change(ubi, layout_vol, i, ubi->vtbl, |
| 100 | if (err) | 103 | ubi->vtbl_size); |
| 101 | return err; | ||
| 102 | |||
| 103 | err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, | ||
| 104 | ubi->vtbl_size); | ||
| 105 | if (err) | 104 | if (err) |
| 106 | return err; | 105 | return err; |
| 107 | } | 106 | } |
| @@ -148,12 +147,8 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi, | |||
| 148 | 147 | ||
| 149 | layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; | 148 | layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; |
| 150 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { | 149 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { |
| 151 | err = ubi_eba_unmap_leb(ubi, layout_vol, i); | 150 | err = ubi_eba_atomic_leb_change(ubi, layout_vol, i, ubi->vtbl, |
| 152 | if (err) | 151 | ubi->vtbl_size); |
| 153 | return err; | ||
| 154 | |||
| 155 | err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, | ||
| 156 | ubi->vtbl_size); | ||
| 157 | if (err) | 152 | if (err) |
| 158 | return err; | 153 | return err; |
| 159 | } | 154 | } |
