@@ -84,7 +84,7 @@ static struct ubi_vtbl_record empty_vtbl_record;
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
struct ubi_vtbl_record *vtbl_rec)
{
- int i, err;
+ int copy, err, err1;
uint32_t crc;
struct ubi_volume *layout_vol;
@@ -99,19 +99,35 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
}
memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record));
- for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) {
- err = ubi_eba_unmap_leb(ubi, layout_vol, i);
+ for (copy = 0; copy < UBI_LAYOUT_VOLUME_EBS; copy++) {
+ err = ubi_eba_unmap_leb(ubi, layout_vol, copy);
if (err)
- return err;
+ goto out_error;
- err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
+ err = ubi_eba_write_leb(ubi, layout_vol, copy, ubi->vtbl, 0,
ubi->vtbl_size, UBI_LONGTERM);
if (err)
- return err;
+ goto out_error;
}
paranoid_vtbl_check(ubi);
return 0;
+
+out_error:
+ ubi_err("error writing volume table copy #%d", copy+1);
+ err1 = ubi_eba_unmap_leb(ubi, layout_vol, copy);
+ if (!err1)
+ ubi_wl_flush(ubi);
+
+ /* Only one valid copy of vtbl left, go to read only mode for safty. */
+ ubi_ro_mode(ubi);
+
+ /*
+ * If first copy was written successfully, this copy will be recovered
+ * during next mount. So vtbl updation should be successful.
+ * But if first copy itself was not written, volume update should fail.
+ */
+ return copy ? 0 : err;
}
/**