mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 06:57:57 +00:00
86 lines
2.5 KiB
Diff
86 lines
2.5 KiB
Diff
|
From f9760b158f610b1792a222cc924073724c061bfb Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||
|
Date: Wed, 7 Apr 2021 22:37:57 +0100
|
||
|
Subject: [PATCH 1/2] mtd: super: don't reply on mtdblock device minor
|
||
|
To: linux-mtd@lists.infradead.org
|
||
|
Cc: Vignesh Raghavendra <vigneshr@ti.com>,
|
||
|
Richard Weinberger <richard@nod.at>,
|
||
|
Miquel Raynal <miquel.raynal@bootlin.com>,
|
||
|
David Woodhouse <dwmw2@infradead.org>
|
||
|
|
||
|
For blktrans devices with partitions (ie. part_bits != 0) the
|
||
|
assumption that the minor number of the mtdblock device matches
|
||
|
the mtdnum doesn't hold true.
|
||
|
Properly resolve mtd device from blktrans layer instead.
|
||
|
|
||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||
|
---
|
||
|
drivers/mtd/mtdsuper.c | 33 ++++++++++++++++++++++++++-------
|
||
|
1 file changed, 26 insertions(+), 7 deletions(-)
|
||
|
|
||
|
--- a/drivers/mtd/mtdsuper.c
|
||
|
+++ b/drivers/mtd/mtdsuper.c
|
||
|
@@ -9,6 +9,7 @@
|
||
|
*/
|
||
|
|
||
|
#include <linux/mtd/super.h>
|
||
|
+#include <linux/mtd/blktrans.h>
|
||
|
#include <linux/namei.h>
|
||
|
#include <linux/export.h>
|
||
|
#include <linux/ctype.h>
|
||
|
@@ -121,7 +122,8 @@ int get_tree_mtd(struct fs_context *fc,
|
||
|
{
|
||
|
#ifdef CONFIG_BLOCK
|
||
|
struct block_device *bdev;
|
||
|
- int ret, major;
|
||
|
+ struct mtd_blktrans_dev *blktrans_dev;
|
||
|
+ int ret, major, part_bits;
|
||
|
#endif
|
||
|
int mtdnr;
|
||
|
|
||
|
@@ -169,21 +171,38 @@ int get_tree_mtd(struct fs_context *fc,
|
||
|
/* try the old way - the hack where we allowed users to mount
|
||
|
* /dev/mtdblock$(n) but didn't actually _use_ the blockdev
|
||
|
*/
|
||
|
- bdev = lookup_bdev(fc->source);
|
||
|
+ bdev = blkdev_get_by_path(fc->source, FMODE_READ, NULL);
|
||
|
if (IS_ERR(bdev)) {
|
||
|
ret = PTR_ERR(bdev);
|
||
|
errorf(fc, "MTD: Couldn't look up '%s': %d", fc->source, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
- pr_debug("MTDSB: lookup_bdev() returned 0\n");
|
||
|
+ pr_debug("MTDSB: blkdev_get_by_path() returned 0\n");
|
||
|
|
||
|
major = MAJOR(bdev->bd_dev);
|
||
|
- mtdnr = MINOR(bdev->bd_dev);
|
||
|
- bdput(bdev);
|
||
|
|
||
|
- if (major == MTD_BLOCK_MAJOR)
|
||
|
- return mtd_get_sb_by_nr(fc, mtdnr, fill_super);
|
||
|
+ if (major == MTD_BLOCK_MAJOR) {
|
||
|
+ if (!bdev->bd_disk) {
|
||
|
+ blkdev_put(bdev, FMODE_READ);
|
||
|
+ BUG();
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ blktrans_dev = (struct mtd_blktrans_dev *)(bdev->bd_disk->private_data);
|
||
|
+ if (!blktrans_dev || !blktrans_dev->tr) {
|
||
|
+ blkdev_put(bdev, FMODE_READ);
|
||
|
+ BUG();
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ mtdnr = blktrans_dev->devnum;
|
||
|
+ part_bits = blktrans_dev->tr->part_bits;
|
||
|
+ blkdev_put(bdev, FMODE_READ);
|
||
|
+ if (MINOR(bdev->bd_dev) != (mtdnr << part_bits))
|
||
|
+ return -EINVAL;
|
||
|
|
||
|
+ return mtd_get_sb_by_nr(fc, mtdnr, fill_super);
|
||
|
+ }
|
||
|
+ blkdev_put(bdev, FMODE_READ);
|
||
|
#endif /* CONFIG_BLOCK */
|
||
|
|
||
|
if (!(fc->sb_flags & SB_SILENT))
|