aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/hack-5.15/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/hack-5.15/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch')
-rw-r--r--target/linux/generic/hack-5.15/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch85
1 files changed, 85 insertions, 0 deletions
diff --git a/target/linux/generic/hack-5.15/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch b/target/linux/generic/hack-5.15/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.15/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))