package/ubox: fix jffs2 handling on MTD devices emulated by gluebi
authorGabor Juhos <juhosg@openwrt.org>
Tue, 5 Nov 2013 16:31:12 +0000 (16:31 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Tue, 5 Nov 2013 16:31:12 +0000 (16:31 +0000)
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>
SVN-Revision: 38654

package/system/ubox/Makefile
package/system/ubox/patches/0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch [new file with mode: 0644]

index 51040fe73b4ea91bb4fca09f43ef8a32e45ece69..6e587a4e3bf617ca9608970641cc82439b6f1cca 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ubox
 PKG_VERSION:=2013-10-27
-PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_RELEASE=$(PKG_SOURCE_VERSION)-1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=git://nbd.name/luci2/ubox.git
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 (file)
index 0000000..6780545
--- /dev/null
@@ -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();