aboutsummaryrefslogtreecommitdiffstats
path: root/package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch')
-rw-r--r--package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch176
1 files changed, 176 insertions, 0 deletions
diff --git a/package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch b/package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch
new file mode 100644
index 0000000000..67805450ba
--- /dev/null
+++ b/package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch
@@ -0,0 +1,176 @@
+From ece50ef6d4b5191636c971ee3896ca22fa538625 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Tue, 5 Nov 2013 16:16:03 +0100
+Subject: [PATCH] mount_root: fix jffs2 handling on MTD devices emulated by
+ gluebi
+
+The jffs2_ready() function in mount_root.c checks
+the presence of various JFFS2 markers at the start
+of a given MTD device. The function works on NOR
+flashes because JFFS2 puts 'cleanmarker' nodes at
+the start of freshly erased blocks.
+
+However if jffs2 is used on a MTD device emulated
+by the gluebi layer, the 'cleanmarker' nodes are
+not present and the jffs2_ready() function fails.
+
+Update the code to handle jffs2 correctly even on
+MTD devices emulated by the gluebi layer.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ mount_root.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 83 insertions(+), 7 deletions(-)
+
+--- a/mount_root.c
++++ b/mount_root.c
+@@ -54,6 +54,14 @@ enum {
+ FS_DEADCODE,
+ };
+
++enum mtd_type {
++ MTD_TYPE_NOT_FOUND,
++ MTD_TYPE_NOR,
++ MTD_TYPE_NAND,
++ MTD_TYPE_UBI,
++ MTD_TYPE_UNKNOWN,
++};
++
+ static const char *argv0;
+
+ /* this is a raw syscall - man 2 pivot_root */
+@@ -223,6 +231,64 @@ static int find_mtd_char(char *name, cha
+ return 0;
+ }
+
++static enum mtd_type mtd_get_type(char *index)
++{
++ static char p[256];
++ static char buf[32];
++ FILE *fp;
++ size_t sz;
++
++ snprintf(p, sizeof(p), "/sys/class/mtd/mtd%s/type", index);
++
++ fp = fopen(p, "r");
++ if (!fp) {
++ ERROR("unable to open %s\n", p);
++ return MTD_TYPE_NOT_FOUND;
++ }
++
++ memset(buf, 0, sizeof(buf));
++ sz = fread(buf, 1, sizeof(buf) - 1, fp);
++ fclose(fp);
++
++ if (sz <= 1) {
++ ERROR("unable to read from %s\n", p);
++ return MTD_TYPE_UNKNOWN;
++ }
++
++ while (sz > 0) {
++ sz--;
++
++ if (buf[sz] != '\n')
++ break;
++
++ buf[sz] = 0;
++ }
++
++ if (strcmp(buf, "nor") == 0)
++ return MTD_TYPE_NOR;
++
++ if (strcmp(buf, "nand") == 0)
++ return MTD_TYPE_NAND;
++
++ if (strcmp(buf, "ubi") == 0)
++ return MTD_TYPE_UBI;
++
++ ERROR("mtd%s has unknow type '%s'\n", index, buf);
++ return MTD_TYPE_UNKNOWN;
++}
++
++static enum mtd_type mtd_get_type_by_name(char *name)
++{
++ char *index;
++
++ index = find_mtd_index(name);
++ if (!index)
++ return MTD_TYPE_NOT_FOUND;
++
++ return mtd_get_type(index);
++}
++
++
+ static int mtd_unlock(char *mtd)
+ {
+ struct erase_info_user mtdlock;
+@@ -277,7 +343,7 @@ static int mtd_mount_jffs2(void)
+ return mtd_unlock(rootfs_data);
+ }
+
+-static int jffs2_ready(char *mtd)
++static int jffs2_ready(char *mtd, enum mtd_type type)
+ {
+ FILE *fp = fopen(mtd, "r");
+ __u32 deadc0de;
+@@ -298,16 +364,21 @@ static int jffs2_ready(char *mtd)
+ }
+
+ deadc0de = __be32_to_cpu(deadc0de);
+- jffs2 = __be16_to_cpu(deadc0de >> 16);
++ if (deadc0de == 0xdeadc0de) {
++ LOG("jffs2 is not ready - EOF marker found\n");
++ return FS_DEADCODE;
++ }
+
++ jffs2 = __be16_to_cpu(deadc0de >> 16);
+ if (jffs2 == 0x1985) {
+ LOG("jffs2 is ready\n");
+ return FS_JFFS2;
+ }
+
+- if (deadc0de == 0xdeadc0de) {
+- LOG("jffs2 is not ready - marker found\n");
+- return FS_DEADCODE;
++ if (type == MTD_TYPE_UBI &&
++ deadc0de == 0xffffffff) {
++ LOG("jffs2 is ready\n");
++ return FS_JFFS2;
+ }
+
+ ERROR("No jffs2 marker was found\n");
+@@ -638,6 +709,7 @@ static int main_switch2jffs(int argc, ch
+ char mtd[32];
+ char *mp;
+ int ret = -1;
++ enum mtd_type type;
+
+ if (find_overlay_mount("overlayfs:/tmp/root"))
+ return -1;
+@@ -659,7 +731,8 @@ static int main_switch2jffs(int argc, ch
+ return ret;
+ }
+
+- switch (jffs2_ready(mtd)) {
++ type = mtd_get_type_by_name("rootfs_data");
++ switch (jffs2_ready(mtd, type)) {
+ case FS_NONE:
+ ERROR("no jffs2 marker found\n");
+ /* fall through */
+@@ -781,12 +854,15 @@ int main(int argc, char **argv)
+ LOG("mounting /dev/root\n");
+ mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 0);
+ } else {
++ enum mtd_type type;
++
+ if (!extroot("")) {
+ fprintf(stderr, "mount_root: switched to extroot\n");
+ return 0;
+ }
+
+- switch (jffs2_ready(mtd)) {
++ type = mtd_get_type_by_name("rootfs_data");
++ switch (jffs2_ready(mtd, type)) {
+ case FS_NONE:
+ case FS_DEADCODE:
+ return ramoverlay();