diff options
Diffstat (limited to 'fs/jffs2/readinode.c')
-rw-r--r-- | fs/jffs2/readinode.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 5351b34d5419..5ea4faafa2d3 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
116 | uint32_t *latest_mctime, uint32_t *mctime_ver) | 116 | uint32_t *latest_mctime, uint32_t *mctime_ver) |
117 | { | 117 | { |
118 | struct jffs2_full_dirent *fd; | 118 | struct jffs2_full_dirent *fd; |
119 | uint32_t crc; | ||
119 | 120 | ||
120 | /* The direntry nodes are checked during the flash scanning */ | ||
121 | BUG_ON(ref_flags(ref) == REF_UNCHECKED); | ||
122 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ | 121 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ |
123 | BUG_ON(ref_obsolete(ref)); | 122 | BUG_ON(ref_obsolete(ref)); |
124 | 123 | ||
125 | /* Sanity check */ | 124 | crc = crc32(0, rd, sizeof(*rd) - 8); |
126 | if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { | 125 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { |
127 | JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", | 126 | JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", |
128 | ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); | 127 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); |
129 | return 1; | 128 | return 1; |
130 | } | 129 | } |
131 | 130 | ||
131 | /* If we've never checked the CRCs on this node, check them now */ | ||
132 | if (ref_flags(ref) == REF_UNCHECKED) { | ||
133 | struct jffs2_eraseblock *jeb; | ||
134 | int len; | ||
135 | |||
136 | /* Sanity check */ | ||
137 | if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { | ||
138 | JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", | ||
139 | ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | ||
144 | len = ref_totlen(c, jeb, ref); | ||
145 | |||
146 | spin_lock(&c->erase_completion_lock); | ||
147 | jeb->used_size += len; | ||
148 | jeb->unchecked_size -= len; | ||
149 | c->used_size += len; | ||
150 | c->unchecked_size -= len; | ||
151 | ref->flash_offset = ref_offset(ref) | REF_PRISTINE; | ||
152 | spin_unlock(&c->erase_completion_lock); | ||
153 | } | ||
154 | |||
132 | fd = jffs2_alloc_full_dirent(rd->nsize + 1); | 155 | fd = jffs2_alloc_full_dirent(rd->nsize + 1); |
133 | if (unlikely(!fd)) | 156 | if (unlikely(!fd)) |
134 | return -ENOMEM; | 157 | return -ENOMEM; |
@@ -198,10 +221,18 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
198 | struct jffs2_tmp_dnode_info *tn; | 221 | struct jffs2_tmp_dnode_info *tn; |
199 | uint32_t len, csize; | 222 | uint32_t len, csize; |
200 | int ret = 1; | 223 | int ret = 1; |
224 | uint32_t crc; | ||
201 | 225 | ||
202 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ | 226 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ |
203 | BUG_ON(ref_obsolete(ref)); | 227 | BUG_ON(ref_obsolete(ref)); |
204 | 228 | ||
229 | crc = crc32(0, rd, sizeof(*rd) - 8); | ||
230 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { | ||
231 | JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", | ||
232 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); | ||
233 | return 1; | ||
234 | } | ||
235 | |||
205 | tn = jffs2_alloc_tmp_dnode_info(); | 236 | tn = jffs2_alloc_tmp_dnode_info(); |
206 | if (!tn) { | 237 | if (!tn) { |
207 | JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); | 238 | JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); |
@@ -213,14 +244,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
213 | 244 | ||
214 | /* If we've never checked the CRCs on this node, check them now */ | 245 | /* If we've never checked the CRCs on this node, check them now */ |
215 | if (ref_flags(ref) == REF_UNCHECKED) { | 246 | if (ref_flags(ref) == REF_UNCHECKED) { |
216 | uint32_t crc; | ||
217 | |||
218 | crc = crc32(0, rd, sizeof(*rd) - 8); | ||
219 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { | ||
220 | JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n", | ||
221 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); | ||
222 | goto free_out; | ||
223 | } | ||
224 | 247 | ||
225 | /* Sanity checks */ | 248 | /* Sanity checks */ |
226 | if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || | 249 | if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || |