diff options
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/generic/files/block/partitions/fit.c | 17 | ||||
-rw-r--r-- | target/linux/generic/hack-5.10/401-mtd-super-don-t-reply-on-mtdblock-device-minor.patch | 85 | ||||
-rw-r--r-- | target/linux/generic/hack-5.10/402-mtd-blktrans-call-add-disks-after-mtd-device.patch | 103 | ||||
-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); + |