aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2021-04-03 00:41:30 +0100
committerDaniel Golle <daniel@makrotopia.org>2021-04-09 16:04:35 +0100
commit2809d0000744b77d5b6cef20f6d44eed75c35e6a (patch)
treebfc220a6c41f870b357ebd4f8f789a92c3b6c1fd /target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch
parentce14445b748db8fbc57bc3e619c69d3989ef3efc (diff)
downloadupstream-2809d0000744b77d5b6cef20f6d44eed75c35e6a.tar.gz
upstream-2809d0000744b77d5b6cef20f6d44eed75c35e6a.tar.bz2
upstream-2809d0000744b77d5b6cef20f6d44eed75c35e6a.zip
kernel: support FIT partition parser on mtdblock devices
Allow using the FIT block-device partition partition parser to work on top of mtdblock devices. This is more tricky than it sounds as it requires to reorganize the procedure of registering mtdblock devices in order to avoid locking troubles caused by the block partition parsers then trying to open the mtdblock device for reading while locks are still being held. Fix that by moving the adding of the disks after the entire device has been probed when locks no longer need to be held. Also address issue with mtdsuper surfaced when using sub-partitions which prevented mounting JFFS2 using the /dev/mtdblock* device. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
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.patch85
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))