kernel: mtdsplit_minor: return 0 if not fatal
authorJohn Thomson <git@johnthomson.fastmail.com.au>
Tue, 15 Oct 2024 21:13:25 +0000 (07:13 +1000)
committerRobert Marko <robimarko@gmail.com>
Wed, 30 Oct 2024 10:15:34 +0000 (11:15 +0100)
Introduced with Linux 6.7, in commit:
5c2f7727d437 ("mtd: mtdpart: check for subpartitions parsing result"),
when a parser returns an error, this will be passed up, and
consequently, all parent mtd partitions get torn down.

Adjust the MiNOR mtdsplit driver to only return an error if there is a
critical problem in reading from the mtd device or allocating memory.
Otherwise return 0 to indicate that no partitions were found.
Also add logging to indicate what went wrong.

This mtdsplit parser makes a very limited check of the first YAFFS
header. For example, this will not match expectations when initially booting
an initramfs image with OEM on MTD.

Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
Acked-by: Thibaut VARENE <hacks@slashdirt.org>
Link: https://github.com/openwrt/openwrt/pull/16780
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_minor.c

index af6822e11ab344708051fcbdf59b215441c62287..be69de57987e9de1caa4aa5bddf39c9bb130fbb5 100644 (file)
@@ -61,29 +61,43 @@ static int mtdsplit_parse_minor(struct mtd_info *master,
 
        hdr_len = sizeof(hdr);
        err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr);
-       if (err)
+       if (err) {
+               pr_err("MiNOR mtd_read error: %d\n", err);
                return err;
+       }
 
-       if (retlen != hdr_len)
+       if (retlen != hdr_len) {
+               pr_err("MiNOR mtd_read too short\n");
                return -EIO;
+       }
 
        /* match header */
-       if (hdr.yaffs_type != YAFFS_OBJECT_TYPE_FILE)
-               return -EINVAL;
-
-       if (hdr.yaffs_obj_id != YAFFS_OBJECTID_ROOT)
-               return -EINVAL;
-
-       if (hdr.yaffs_sum_unused != YAFFS_SUM_UNUSED)
-               return -EINVAL;
-
-       if (memcmp(hdr.yaffs_name, YAFFS_NAME, sizeof(YAFFS_NAME)))
-               return -EINVAL;
+       if (hdr.yaffs_type != YAFFS_OBJECT_TYPE_FILE) {
+               pr_info("MiNOR YAFFS first type not matched\n");
+               return 0;
+       }
+
+       if (hdr.yaffs_obj_id != YAFFS_OBJECTID_ROOT) {
+               pr_info("MiNOR YAFFS first objectid not matched\n");
+               return 0;
+       }
+
+       if (hdr.yaffs_sum_unused != YAFFS_SUM_UNUSED) {
+               pr_info("MiNOR YAFFS first sum not matched\n");
+               return 0;
+       }
+
+       if (memcmp(hdr.yaffs_name, YAFFS_NAME, sizeof(YAFFS_NAME))) {
+               pr_info("MiNOR YAFFS first name not matched\n");
+               return 0;
+       }
 
        err = mtd_find_rootfs_from(master, master->erasesize, master->size,
                                   &rootfs_offset, NULL);
-       if (err)
-               return err;
+       if (err) {
+               pr_info("MiNOR mtd_find_rootfs_from error: %d\n", err);
+               return 0;
+       }
 
        parts = kzalloc(MINOR_NR_PARTS * sizeof(*parts), GFP_KERNEL);
        if (!parts)