From: Daniel Golle <daniel@makrotopia.org>
Subject: ubi: auto-create ubiblock device for rootfs

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -609,10 +609,47 @@ match_volume_desc(struct ubi_volume_info
 	return true;
 }
 
+#define UBIFS_NODE_MAGIC  0x06101831
+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc)
+{
+	int ret;
+	uint32_t magic_of, magic;
+	ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4);
+	if (ret)
+		return 0;
+	magic = le32_to_cpu(magic_of);
+	return magic == UBIFS_NODE_MAGIC;
+}
+
+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
+{
+	int ret, is_ubifs;
+	struct ubi_volume_desc *desc;
+
+	if (strcmp(vi->name, "rootfs") &&
+	    strcmp(vi->name, "fit"))
+		return;
+
+	desc = ubi_open_volume(vi->ubi_num, vi->vol_id, UBI_READONLY);
+	if (IS_ERR(desc))
+		return;
+
+	is_ubifs = ubi_vol_is_ubifs(desc);
+	ubi_close_volume(desc);
+	if (is_ubifs)
+		return;
+
+	ret = ubiblock_create(vi);
+	if (ret)
+		pr_err("UBI error: block: can't add '%s' volume, err=%d\n",
+			vi->name, ret);
+}
+
 static void
 ubiblock_create_from_param(struct ubi_volume_info *vi)
 {
 	int i, ret = 0;
+	bool got_param = false;
 	struct ubiblock_param *p;
 
 	/*
@@ -625,6 +662,7 @@ ubiblock_create_from_param(struct ubi_vo
 		if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
 			continue;
 
+		got_param = true;
 		ret = ubiblock_create(vi);
 		if (ret) {
 			pr_err(
@@ -633,6 +671,10 @@ ubiblock_create_from_param(struct ubi_vo
 		}
 		break;
 	}
+
+	/* auto-attach "rootfs" volume if existing and non-ubifs */
+	if (!got_param && IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV))
+		ubiblock_create_auto_rootfs(vi);
 }
 
 static int ubiblock_notify(struct notifier_block *nb,
