aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/generic/files/block/partitions/fit.c17
-rw-r--r--target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch85
-rw-r--r--target/linux/generic/hack-5.10/402-mtd-blktrans-call-add-disks-after-mtd-device.patch103
-rw-r--r--target/linux/generic/hack-5.10/410-block-fit-partition-parser.patch (renamed from target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch)48
4 files changed, 241 insertions, 12 deletions
diff --git a/target/linux/generic/files/block/partitions/fit.c b/target/linux/generic/files/block/partitions/fit.c
index c0d9642505..823ee715de 100644
--- a/target/linux/generic/files/block/partitions/fit.c
+++ b/target/linux/generic/files/block/partitions/fit.c
@@ -112,20 +112,19 @@ int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
dsectors = (dsectors>sectors)?sectors:dsectors;
dsize = dsectors << SECTOR_SHIFT;
- printk(KERN_DEBUG "FIT: volume size: %llu sectors (%llu bytes)\n", dsectors, dsize);
size = fdt_totalsize(init_fit);
- printk(KERN_DEBUG "FIT: FDT structure size: %u bytes\n", size);
+
+ /* silently skip non-external-data legacy FIT images */
if (size > PAGE_SIZE) {
- printk(KERN_ERR "FIT: FDT structure beyond page boundaries, use 'mkimage -E ...'!\n");
put_page(page);
- return -ENOTSUPP;
+ return 0;
}
if (size >= dsize) {
+ state->access_beyond_eod = 1;
put_page(page);
- state->access_beyond_eod = (size >= dsize);
- return 0;
+ return -EFBIG;
}
fit = kmemdup(init_fit, size, GFP_KERNEL);
@@ -158,7 +157,7 @@ int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len);
- printk(KERN_DEBUG "FIT: Default configuration: %s%s%s%s\n", config_default,
+ printk(KERN_DEBUG "FIT: Default configuration: \"%s\"%s%s%s\n", config_default,
config_description?" (":"", config_description?:"", config_description?")":"");
images = fdt_path_offset(fit, FIT_IMAGES_PATH);
@@ -190,7 +189,7 @@ int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
image_description = fdt_getprop(fit, node, FIT_DESC_PROP, &image_description_len);
- printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x - 0x%08x '%s' %s%s%s\n",
+ printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x - 0x%08x \"%s\" %s%s%s\n",
image_type, image_pos, image_pos + image_len, image_name,
image_description?"(":"", image_description?:"", image_description?") ":"");
@@ -230,7 +229,7 @@ int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector,
state->parts[*slot].has_info = true;
if (config_loadables && !strcmp(image_name, config_loadables)) {
- printk(KERN_DEBUG "FIT: selecting configured loadable %s to be root filesystem\n", image_name);
+ printk(KERN_DEBUG "FIT: selecting configured loadable \"%s\" to be root filesystem\n", image_name);
state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV;
}
}
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))
diff --git a/target/linux/generic/hack-5.10/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-5.10/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
new file mode 100644
index 0000000000..bc9e84cac1
--- /dev/null
+++ b/target/linux/generic/hack-5.10/402-mtd-blktrans-call-add-disks-after-mtd-device.patch
@@ -0,0 +1,103 @@
+From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 7 Apr 2021 22:45:54 +0100
+Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device
+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>
+
+Calling device_add_disk while holding mtd_table_mutex leads
+to deadlock in case part_bits!=0 as block partition parsers
+will try to open the newly created disks, trying to acquire
+mutex once again.
+Move device_add_disk to additional function called after
+add partitions of an MTD device have been added and locks
+have been released.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++-------
+ drivers/mtd/mtdcore.c | 3 +++
+ include/linux/mtd/blktrans.h | 1 +
+ 3 files changed, 30 insertions(+), 7 deletions(-)
+
+--- a/drivers/mtd/mtd_blkdevs.c
++++ b/drivers/mtd/mtd_blkdevs.c
+@@ -457,13 +457,6 @@ int add_mtd_blktrans_dev(struct mtd_blkt
+ if (new->readonly)
+ set_disk_ro(gd, 1);
+
+- device_add_disk(&new->mtd->dev, gd, NULL);
+-
+- if (new->disk_attributes) {
+- ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
+- new->disk_attributes);
+- WARN_ON(ret);
+- }
+ return 0;
+ error4:
+ kfree(new->tag_set);
+@@ -475,6 +468,32 @@ error1:
+ return ret;
+ }
+
++void register_mtd_blktrans_devs(struct mtd_info *mtd)
++{
++ struct mtd_blktrans_ops *tr;
++ struct mtd_blktrans_dev *dev, *next;
++ struct mtd_info *top_mtd;
++ int ret;
++
++ list_for_each_entry(tr, &blktrans_majors, list) {
++ list_for_each_entry_safe(dev, next, &tr->devs, list) {
++ top_mtd = dev->mtd;
++ while (top_mtd->parent)
++ top_mtd = top_mtd->parent;
++
++ if (mtd->index != top_mtd->index)
++ continue;
++
++ device_add_disk(&dev->mtd->dev, dev->disk, NULL);
++ if (dev->disk_attributes) {
++ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj,
++ dev->disk_attributes);
++ WARN_ON(ret);
++ }
++ }
++ }
++}
++
+ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
+ {
+ unsigned long flags;
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -32,6 +32,7 @@
+
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/mtd/blktrans.h>
+
+ #include "mtdcore.h"
+
+@@ -858,6 +859,8 @@ int mtd_device_parse_register(struct mtd
+ register_reboot_notifier(&mtd->reboot_notifier);
+ }
+
++ register_mtd_blktrans_devs(mtd);
++
+ out:
+ if (ret && device_is_registered(&mtd->dev))
+ del_mtd_device(mtd);
+--- a/include/linux/mtd/blktrans.h
++++ b/include/linux/mtd/blktrans.h
+@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc
+ extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
+ extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
+ extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
++extern void register_mtd_blktrans_devs(struct mtd_info *mtd);
+
+
+ #endif /* __MTD_TRANS_H__ */
diff --git a/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch b/target/linux/generic/hack-5.10/410-block-fit-partition-parser.patch
index a414be6e84..2528f3afa1 100644
--- a/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch
+++ b/target/linux/generic/hack-5.10/410-block-fit-partition-parser.patch
@@ -122,20 +122,25 @@
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
-@@ -396,7 +396,7 @@ int ubiblock_create(struct ubi_volume_in
+@@ -396,7 +396,11 @@ int ubiblock_create(struct ubi_volume_in
dev->leb_size = vi->usable_leb_size;
/* Initialize the gendisk of this ubiblock device */
-- gd = alloc_disk(1);
++#ifdef CONFIG_FIT_PARTITION
+ gd = alloc_disk(0);
++#else
+ gd = alloc_disk(1);
++#endif
if (!gd) {
pr_err("UBI: block: alloc_disk failed\n");
ret = -ENODEV;
-@@ -413,6 +413,7 @@ int ubiblock_create(struct ubi_volume_in
+@@ -413,6 +417,9 @@ int ubiblock_create(struct ubi_volume_in
goto out_put_disk;
}
gd->private_data = dev;
++#ifdef CONFIG_FIT_PARTITION
+ gd->flags |= GENHD_FL_EXT_DEVT;
++#endif
sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
set_capacity(gd, disk_capacity);
dev->gd = gd;
@@ -175,3 +180,40 @@
typedef struct _gpt_header {
__le64 signature;
+--- a/drivers/mtd/mtdblock.c
++++ b/drivers/mtd/mtdblock.c
+@@ -334,7 +334,11 @@ static void mtdblock_remove_dev(struct m
+ static struct mtd_blktrans_ops mtdblock_tr = {
+ .name = "mtdblock",
+ .major = MTD_BLOCK_MAJOR,
++#ifdef CONFIG_FIT_PARTITION
++ .part_bits = 1,
++#else
+ .part_bits = 0,
++#endif
+ .blksize = 512,
+ .open = mtdblock_open,
+ .flush = mtdblock_flush,
+--- a/drivers/mtd/mtd_blkdevs.c
++++ b/drivers/mtd/mtd_blkdevs.c
+@@ -407,18 +407,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt
+ gd->first_minor = (new->devnum) << tr->part_bits;
+ gd->fops = &mtd_block_ops;
+
+- if (tr->part_bits)
+- if (new->devnum < 26)
+- snprintf(gd->disk_name, sizeof(gd->disk_name),
+- "%s%c", tr->name, 'a' + new->devnum);
+- else
+- snprintf(gd->disk_name, sizeof(gd->disk_name),
+- "%s%c%c", tr->name,
+- 'a' - 1 + new->devnum / 26,
+- 'a' + new->devnum % 26);
+- else
+- snprintf(gd->disk_name, sizeof(gd->disk_name),
+- "%s%d", tr->name, new->devnum);
++ snprintf(gd->disk_name, sizeof(gd->disk_name),
++ "%s%d", tr->name, new->devnum);
+
+ set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
+