From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751290AbdFBPoT (ORCPT ); Fri, 2 Jun 2017 11:44:19 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:34518 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751274AbdFBPoQ (ORCPT ); Fri, 2 Jun 2017 11:44:16 -0400 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Joern Engel , David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , Cyrille Pitchen , Artem Bityutskiy Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Pali=20Roh=C3=A1r?= Subject: [PATCH 3/5] mtd: block2mtd: Fallback to read-only mode Date: Fri, 2 Jun 2017 17:43:40 +0200 Message-Id: <1496418222-23483-4-git-send-email-pali.rohar@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1496418222-23483-1-git-send-email-pali.rohar@gmail.com> References: <1496418222-23483-1-git-send-email-pali.rohar@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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; + } + #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; + } } #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