[PATCH 3/5] mtd: block2mtd: Fallback to read-only mode

Richard Weinberger richard.weinberger at gmail.com
Fri Jul 21 12:53:26 PDT 2017


Pali,

On Fri, Jun 2, 2017 at 5:43 PM, Pali Rohár <pali.rohar at gmail.com> wrote:
> Sometimes block device is readonly (e.g. loopbacks). This patch allows
> block2mtd to fallback and create read-only MTD_ROM device instead of
> fatal failure.
>
> Signed-off-by: Pali Rohár <pali.rohar at gmail.com>
> ---
>  drivers/mtd/devices/block2mtd.c |   39 ++++++++++++++++++++++++++++++++-------
>  1 file changed, 32 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
> index 5ba5fad..ad96937 100644
> --- a/drivers/mtd/devices/block2mtd.c
> +++ b/drivers/mtd/devices/block2mtd.c
> @@ -38,6 +38,7 @@ struct block2mtd_dev {
>         struct block_device *blkdev;
>         struct mtd_info mtd;
>         struct mutex write_mutex;
> +       bool ro_mode;
>  };
>
>
> @@ -212,7 +213,10 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
>         if (dev->blkdev) {
>                 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
>                                         0, -1);
> -               blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
> +               if (dev->ro_mode)
> +                       blkdev_put(dev->blkdev, FMODE_READ);
> +               else
> +                       blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
>         }
>
>         kfree(dev);
> @@ -240,6 +244,13 @@ static struct block2mtd_dev *add_device(char *devname, uint32_t erase_size,
>         /* Get a handle on the device */
>         bdev = blkdev_get_by_path(devname, mode, dev);
>
> +       /* Try fallback to read only mode */
> +       if (IS_ERR(bdev)) {
> +               bdev = blkdev_get_by_path(devname, FMODE_READ, dev);
> +               if (!IS_ERR(bdev))
> +                       dev->ro_mode = true;
> +       }
> +

Please use bdev_read_only() instead of blindly trying again with another mode.

>  #ifndef MODULE
>         /*
>          * We might not have the root device mounted at this point.
> @@ -261,6 +272,13 @@ static struct block2mtd_dev *add_device(char *devname, uint32_t erase_size,
>                 if (!devt)
>                         continue;
>                 bdev = blkdev_get_by_dev(devt, mode, dev);
> +
> +               /* Try fallback to read only mode */
> +               if (IS_ERR(bdev)) {
> +                       bdev = blkdev_get_by_path(devname, FMODE_READ, dev);
> +                       if (!IS_ERR(bdev))
> +                               dev->ro_mode = true;
> +               }

Same here.

>         }
>  #endif
>
> @@ -295,16 +313,22 @@ static struct block2mtd_dev *add_device(char *devname, uint32_t erase_size,
>
>         dev->mtd.name = name;
>
> +       if (dev->ro_mode) {
> +               dev->mtd.type = MTD_ROM;
> +               dev->mtd.flags = MTD_CAP_ROM;
> +       } else {
> +               dev->mtd.type = MTD_RAM;
> +               dev->mtd.flags = MTD_CAP_RAM;
> +               dev->mtd._erase = block2mtd_erase;
> +               dev->mtd._write = block2mtd_write;
> +               dev->mtd._sync = block2mtd_sync;
> +       }
> +
>         dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
>         dev->mtd.erasesize = erase_size;
>         dev->mtd.writesize = write_size;
>         dev->mtd.subpage_sft = subpage_sft;
>         dev->mtd.writebufsize = PAGE_SIZE;
> -       dev->mtd.type = MTD_RAM;
> -       dev->mtd.flags = MTD_CAP_RAM;
> -       dev->mtd._erase = block2mtd_erase;
> -       dev->mtd._write = block2mtd_write;
> -       dev->mtd._sync = block2mtd_sync;
>         dev->mtd._read = block2mtd_read;
>         dev->mtd.priv = dev;
>         dev->mtd.owner = THIS_MODULE;
> @@ -315,9 +339,10 @@ static struct block2mtd_dev *add_device(char *devname, uint32_t erase_size,
>         }
>
>         list_add(&dev->list, &blkmtd_device_list);
> -       pr_info("mtd%d: [%s] erase_size = %dKiB [%d], write_size = %dKiB [%d], subpage_sft = %d\n",
> +       pr_info("mtd%d: [%s] mode = %s, erase_size = %dKiB [%d], write_size = %dKiB [%d], subpage_sft = %d\n",
>                 dev->mtd.index,
>                 dev->mtd.name + strlen("block2mtd: "),
> +               (dev->ro_mode ? "RO" : "R/W"),
>                 dev->mtd.erasesize >> 10, dev->mtd.erasesize,
>                 dev->mtd.writesize >> 10, dev->mtd.writesize,
>                 dev->mtd.subpage_sft);
> --
> 1.7.9.5
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Thanks,
//richard



More information about the linux-mtd mailing list