Messages in this thread | | | From | Richard Weinberger <> | Date | Fri, 21 Jul 2017 21:53:26 +0200 | Subject | Re: [PATCH 3/5] mtd: block2mtd: Fallback to read-only mode |
| |
Pali,
On Fri, Jun 2, 2017 at 5:43 PM, Pali Rohár <pali.rohar@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@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
| |