kernel: support FIT partition parser on mtdblock devices
[openwrt/staging/hauke.git] / target / linux / generic / hack-5.10 / 402-mtd-blktrans-call-add-disks-after-mtd-device.patch
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 (file)
index 0000000..bc9e84c
--- /dev/null
@@ -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__ */