Reviewed-by: Jörg Pfähler <pfaehler@xxxxxxx> Am Dienstag, 21. Juni 2016, 00:31:50 CEST schrieb Richard Weinberger: > recover_peb() was never power cut aware, > if a power cut happened right after writing the VID header > upon next attach UBI would blindly use the new partial written > PEB and all data from the old PEB is lost. > > In order to make recover_peb() power cut aware, write the new > VID with a proper crc and copy_flag set such that the UBI attach > process will detect whether the new PEB is completely written > or not. > We cannot directly use ubi_eba_atomic_leb_change() since we'd > have to unlock the LEB which is facing a write error. > > Cc: stable@xxxxxxxxxxxxxxx > Reported-by: Jörg Pfähler <pfaehler@xxxxxxx> > Signed-off-by: Richard Weinberger <richard@xxxxxx> > --- > drivers/mtd/ubi/eba.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > > diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c > index 5780dd1..ebf5172 100644 > --- a/drivers/mtd/ubi/eba.c > +++ b/drivers/mtd/ubi/eba.c > @@ -575,6 +575,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, > int vol_id, int lnum, int err, idx = vol_id2idx(ubi, vol_id), new_pnum, > data_size, tries = 0; struct ubi_volume *vol = ubi->volumes[idx]; > struct ubi_vid_hdr *vid_hdr; > + uint32_t crc; > > vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); > if (!vid_hdr) > @@ -599,14 +600,8 @@ retry: > goto out_put; > } > > - vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); > - err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); > - if (err) { > - up_read(&ubi->fm_eba_sem); > - goto write_error; > - } > + ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC); > > - data_size = offset + len; > mutex_lock(&ubi->buf_mutex); > memset(ubi->peb_buf + offset, 0xFF, len); > > @@ -621,6 +616,19 @@ retry: > > memcpy(ubi->peb_buf + offset, buf, len); > > + data_size = offset + len; > + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size); > + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); > + vid_hdr->copy_flag = 1; > + vid_hdr->data_size = cpu_to_be32(data_size); > + vid_hdr->data_crc = cpu_to_be32(crc); > + err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); > + if (err) { > + mutex_unlock(&ubi->buf_mutex); > + up_read(&ubi->fm_eba_sem); > + goto write_error; > + } > + > err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); > if (err) { > mutex_unlock(&ubi->buf_mutex); -------------------------------------------------------------------------------------- Jörg Pfähler Lehrstuhl für Softwaretechnik Institut für Software and Systems Engineering Universität Augsburg Universitätsstr. 6a, Raum 3014 tel: (+49) 821/598-2229 e-mail: pfaehler@xxxxxxx<mailto:pfaehler@xxxxxxx> -------------------------------------------------------------------------------------- -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html