[PATCH] ubi: Make volume resize power cut aware

Ezequiel Garcia ezequiel at vanguardiasur.com.ar
Fri Jun 24 11:05:31 PDT 2016


Hi guys,

I have a few questions.

On 23 June 2016 at 14:30, Richard Weinberger <richard at nod.at> wrote:
> When the volume resize operation shrinks a volume,
> LEBs will be unmapped. Since unmapping will not erase these
> LEBs immediately we have to wait for that operation to finish.
> Otherwise in case of a power cut right after writing the new
> volume table the UBI attach process can find more LEBs than the
> volume table knows. This will render the UBI image unattachable.
>
> Fix this issue by waiting for erase to complete and write the new volume table afterward.
>
> Cc: <stable at vger.kernel.org>
> Reported-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Richard Weinberger <richard at nod.at>
> ---
>  drivers/mtd/ubi/vmt.c | 25 ++++++++++++++++++-------
>  1 file changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
> index 10059df..0138f52 100644
> --- a/drivers/mtd/ubi/vmt.c
> +++ b/drivers/mtd/ubi/vmt.c
> @@ -488,13 +488,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
>                 spin_unlock(&ubi->volumes_lock);
>         }
>
> -       /* Change volume table record */
> -       vtbl_rec = ubi->vtbl[vol_id];
> -       vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
> -       err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
> -       if (err)
> -               goto out_acc;
> -
>         if (pebs < 0) {
>                 for (i = 0; i < -pebs; i++) {
>                         err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
> @@ -512,6 +505,24 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
>                 spin_unlock(&ubi->volumes_lock);
>         }
>
> +       /*
> +        * When we shrink a volume we have to flush all pending (erase) work.
> +        * Otherwise it can happen that upon next attach UBI finds a LEB with
> +        * lnum > highest_lnum and refuses to attach.
> +        */
> +       if (pebs < 0) {
> +               err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
> +               if (err)
> +                       goto out_acc;
> +       }
> +

What will happen if the power-cut happens right here,
before the volume table is written?

> +       /* Change volume table record */
> +       vtbl_rec = ubi->vtbl[vol_id];
> +       vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
> +       err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
> +       if (err)
> +               goto out_acc;
> +
>         vol->reserved_pebs = reserved_pebs;
>         if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
>                 vol->used_ebs = reserved_pebs;


Also, should we have a similar change for ubi_remove_volume?
-- 
Ezequiel García, VanguardiaSur
www.vanguardiasur.com.ar



More information about the linux-mtd mailing list