package/ubox: fix jffs2 handling on MTD devices emulated by gluebi
[openwrt/svn-archive/archive.git] / package / system / ubox / patches / 0001-mount_root-fix-jffs2-handling-on-MTD-devices-emulate.patch
1 From ece50ef6d4b5191636c971ee3896ca22fa538625 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Tue, 5 Nov 2013 16:16:03 +0100
4 Subject: [PATCH] mount_root: fix jffs2 handling on MTD devices emulated by
5 gluebi
6
7 The jffs2_ready() function in mount_root.c checks
8 the presence of various JFFS2 markers at the start
9 of a given MTD device. The function works on NOR
10 flashes because JFFS2 puts 'cleanmarker' nodes at
11 the start of freshly erased blocks.
12
13 However if jffs2 is used on a MTD device emulated
14 by the gluebi layer, the 'cleanmarker' nodes are
15 not present and the jffs2_ready() function fails.
16
17 Update the code to handle jffs2 correctly even on
18 MTD devices emulated by the gluebi layer.
19
20 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
21 ---
22 mount_root.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
23 1 file changed, 83 insertions(+), 7 deletions(-)
24
25 --- a/mount_root.c
26 +++ b/mount_root.c
27 @@ -54,6 +54,14 @@ enum {
28 FS_DEADCODE,
29 };
30
31 +enum mtd_type {
32 + MTD_TYPE_NOT_FOUND,
33 + MTD_TYPE_NOR,
34 + MTD_TYPE_NAND,
35 + MTD_TYPE_UBI,
36 + MTD_TYPE_UNKNOWN,
37 +};
38 +
39 static const char *argv0;
40
41 /* this is a raw syscall - man 2 pivot_root */
42 @@ -223,6 +231,64 @@ static int find_mtd_char(char *name, cha
43 return 0;
44 }
45
46 +static enum mtd_type mtd_get_type(char *index)
47 +{
48 + static char p[256];
49 + static char buf[32];
50 + FILE *fp;
51 + size_t sz;
52 +
53 + snprintf(p, sizeof(p), "/sys/class/mtd/mtd%s/type", index);
54 +
55 + fp = fopen(p, "r");
56 + if (!fp) {
57 + ERROR("unable to open %s\n", p);
58 + return MTD_TYPE_NOT_FOUND;
59 + }
60 +
61 + memset(buf, 0, sizeof(buf));
62 + sz = fread(buf, 1, sizeof(buf) - 1, fp);
63 + fclose(fp);
64 +
65 + if (sz <= 1) {
66 + ERROR("unable to read from %s\n", p);
67 + return MTD_TYPE_UNKNOWN;
68 + }
69 +
70 + while (sz > 0) {
71 + sz--;
72 +
73 + if (buf[sz] != '\n')
74 + break;
75 +
76 + buf[sz] = 0;
77 + }
78 +
79 + if (strcmp(buf, "nor") == 0)
80 + return MTD_TYPE_NOR;
81 +
82 + if (strcmp(buf, "nand") == 0)
83 + return MTD_TYPE_NAND;
84 +
85 + if (strcmp(buf, "ubi") == 0)
86 + return MTD_TYPE_UBI;
87 +
88 + ERROR("mtd%s has unknow type '%s'\n", index, buf);
89 + return MTD_TYPE_UNKNOWN;
90 +}
91 +
92 +static enum mtd_type mtd_get_type_by_name(char *name)
93 +{
94 + char *index;
95 +
96 + index = find_mtd_index(name);
97 + if (!index)
98 + return MTD_TYPE_NOT_FOUND;
99 +
100 + return mtd_get_type(index);
101 +}
102 +
103 +
104 static int mtd_unlock(char *mtd)
105 {
106 struct erase_info_user mtdlock;
107 @@ -277,7 +343,7 @@ static int mtd_mount_jffs2(void)
108 return mtd_unlock(rootfs_data);
109 }
110
111 -static int jffs2_ready(char *mtd)
112 +static int jffs2_ready(char *mtd, enum mtd_type type)
113 {
114 FILE *fp = fopen(mtd, "r");
115 __u32 deadc0de;
116 @@ -298,16 +364,21 @@ static int jffs2_ready(char *mtd)
117 }
118
119 deadc0de = __be32_to_cpu(deadc0de);
120 - jffs2 = __be16_to_cpu(deadc0de >> 16);
121 + if (deadc0de == 0xdeadc0de) {
122 + LOG("jffs2 is not ready - EOF marker found\n");
123 + return FS_DEADCODE;
124 + }
125
126 + jffs2 = __be16_to_cpu(deadc0de >> 16);
127 if (jffs2 == 0x1985) {
128 LOG("jffs2 is ready\n");
129 return FS_JFFS2;
130 }
131
132 - if (deadc0de == 0xdeadc0de) {
133 - LOG("jffs2 is not ready - marker found\n");
134 - return FS_DEADCODE;
135 + if (type == MTD_TYPE_UBI &&
136 + deadc0de == 0xffffffff) {
137 + LOG("jffs2 is ready\n");
138 + return FS_JFFS2;
139 }
140
141 ERROR("No jffs2 marker was found\n");
142 @@ -638,6 +709,7 @@ static int main_switch2jffs(int argc, ch
143 char mtd[32];
144 char *mp;
145 int ret = -1;
146 + enum mtd_type type;
147
148 if (find_overlay_mount("overlayfs:/tmp/root"))
149 return -1;
150 @@ -659,7 +731,8 @@ static int main_switch2jffs(int argc, ch
151 return ret;
152 }
153
154 - switch (jffs2_ready(mtd)) {
155 + type = mtd_get_type_by_name("rootfs_data");
156 + switch (jffs2_ready(mtd, type)) {
157 case FS_NONE:
158 ERROR("no jffs2 marker found\n");
159 /* fall through */
160 @@ -781,12 +854,15 @@ int main(int argc, char **argv)
161 LOG("mounting /dev/root\n");
162 mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 0);
163 } else {
164 + enum mtd_type type;
165 +
166 if (!extroot("")) {
167 fprintf(stderr, "mount_root: switched to extroot\n");
168 return 0;
169 }
170
171 - switch (jffs2_ready(mtd)) {
172 + type = mtd_get_type_by_name("rootfs_data");
173 + switch (jffs2_ready(mtd, type)) {
174 case FS_NONE:
175 case FS_DEADCODE:
176 return ramoverlay();