diff options
Diffstat (limited to 'target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch')
-rw-r--r-- | target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch b/target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch new file mode 100644 index 0000000000..04cf52b096 --- /dev/null +++ b/target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch @@ -0,0 +1,85 @@ +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)) |