aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/readinode.c
diff options
context:
space:
mode:
authorArtem B. Bityutskiy <dedekind@infradead.org>2005-08-01 08:05:22 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 12:22:17 -0500
commit1e0da3cb6cd4a909c64c870344183185bd6815b1 (patch)
treef7ffedba74681cd8f7662990dfb4f3919dcaef23 /fs/jffs2/readinode.c
parente0e3006f79a6d995c9a7de7556f11a9b97536423 (diff)
[JFFS2] Build fragtree in reverse order
Instead of building fragtree starting from node with the smallest version number, start from the highest. This helps to avoid reading and checking obsolete nodes. Signed-off-by: Artem B. Bityutskiy <dedekind@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/readinode.c')
-rw-r--r--fs/jffs2/readinode.c475
1 files changed, 290 insertions, 185 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index f3b12d7fe9ab..488787a823b6 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.134 2005/07/31 08:20:44 dedekind Exp $ 10 * $Id: readinode.c,v 1.135 2005/08/01 12:05:19 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -21,8 +21,8 @@
21#include <linux/compiler.h> 21#include <linux/compiler.h>
22#include "nodelist.h" 22#include "nodelist.h"
23 23
24/* 24/*
25 * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in 25 * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
26 * order of increasing version. 26 * order of increasing version.
27 */ 27 */
28static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) 28static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
@@ -38,11 +38,11 @@ static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root
38 /* There may actually be a collision here, but it doesn't 38 /* There may actually be a collision here, but it doesn't
39 actually matter. As long as the two nodes with the same 39 actually matter. As long as the two nodes with the same
40 version are together, it's all fine. */ 40 version are together, it's all fine. */
41 if (tn->version < this->version) 41 if (tn->version > this->version)
42 p = &(*p)->rb_left; 42 p = &(*p)->rb_left;
43 else 43 else
44 p = &(*p)->rb_right; 44 p = &(*p)->rb_right;
45 } 45 }
46 46
47 rb_link_node(&tn->rb, parent, p); 47 rb_link_node(&tn->rb, parent, p);
48 rb_insert_color(&tn->rb, list); 48 rb_insert_color(&tn->rb, list);
@@ -111,14 +111,9 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r
111 * 1 if the node should be marked obsolete; 111 * 1 if the node should be marked obsolete;
112 * negative error code on failure. 112 * negative error code on failure.
113 */ 113 */
114static inline int 114static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
115read_direntry(struct jffs2_sb_info *c, 115 struct jffs2_raw_dirent *rd, uint32_t read, struct jffs2_full_dirent **fdp,
116 struct jffs2_raw_node_ref *ref, 116 uint32_t *latest_mctime, uint32_t *mctime_ver)
117 struct jffs2_raw_dirent *rd,
118 uint32_t read,
119 struct jffs2_full_dirent **fdp,
120 int32_t *latest_mctime,
121 uint32_t *mctime_ver)
122{ 117{
123 struct jffs2_full_dirent *fd; 118 struct jffs2_full_dirent *fd;
124 119
@@ -196,30 +191,35 @@ read_direntry(struct jffs2_sb_info *c,
196 * 1 if the node should be marked obsolete; 191 * 1 if the node should be marked obsolete;
197 * negative error code on failure. 192 * negative error code on failure.
198 */ 193 */
199static inline int 194static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
200read_dnode(struct jffs2_sb_info *c, 195 struct jffs2_raw_inode *rd, struct rb_root *tnp, int rdlen,
201 struct jffs2_raw_node_ref *ref, 196 uint32_t *latest_mctime, uint32_t *mctime_ver)
202 struct jffs2_raw_inode *rd,
203 uint32_t read,
204 struct rb_root *tnp,
205 int32_t *latest_mctime,
206 uint32_t *mctime_ver)
207{ 197{
208 struct jffs2_eraseblock *jeb;
209 struct jffs2_tmp_dnode_info *tn; 198 struct jffs2_tmp_dnode_info *tn;
199 uint32_t len, csize;
200 int ret = 1;
210 201
211 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
212 BUG_ON(ref_obsolete(ref)); 203 BUG_ON(ref_obsolete(ref));
213 204
205 tn = jffs2_alloc_tmp_dnode_info();
206 if (!tn) {
207 JFFS2_ERROR("failed to allocate tn (%d bytes).\n", sizeof(*tn));
208 return -ENOMEM;
209 }
210
211 tn->partial_crc = 0;
212 csize = je32_to_cpu(rd->csize);
213
214 /* If we've never checked the CRCs on this node, check them now */ 214 /* If we've never checked the CRCs on this node, check them now */
215 if (ref_flags(ref) == REF_UNCHECKED) { 215 if (ref_flags(ref) == REF_UNCHECKED) {
216 uint32_t crc, len; 216 uint32_t crc;
217 217
218 crc = crc32(0, rd, sizeof(*rd) - 8); 218 crc = crc32(0, rd, sizeof(*rd) - 8);
219 if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 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", 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); 221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
222 return 1; 222 goto free_out;
223 } 223 }
224 224
225 /* Sanity checks */ 225 /* Sanity checks */
@@ -227,107 +227,102 @@ read_dnode(struct jffs2_sb_info *c,
227 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 227 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
228 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); 228 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
229 jffs2_dbg_dump_node(c, ref_offset(ref)); 229 jffs2_dbg_dump_node(c, ref_offset(ref));
230 return 1; 230 goto free_out;
231 } 231 }
232 232
233 if (rd->compr != JFFS2_COMPR_ZERO && je32_to_cpu(rd->csize)) { 233 if (jffs2_is_writebuffered(c) && csize != 0) {
234 unsigned char *buf = NULL; 234 /* At this point we are supposed to check the data CRC
235 uint32_t pointed = 0; 235 * of our unchecked node. But thus far, we do not
236 int err; 236 * know whether the node is valid or obsolete. To
237#ifndef __ECOS 237 * figure this out, we need to walk all the nodes of
238 if (c->mtd->point) { 238 * the inode and build the inode fragtree. We don't
239 err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize), 239 * want to spend time checking data of nodes which may
240 &read, &buf); 240 * later be found to be obsolete. So we put off the full
241 if (unlikely(read < je32_to_cpu(rd->csize)) && likely(!err)) { 241 * data CRC checking until we have read all the inode
242 JFFS2_ERROR("MTD point returned len too short: 0x%zx\n", read); 242 * nodes and have started building the fragtree.
243 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), 243 *
244 je32_to_cpu(rd->csize)); 244 * The fragtree is being built starting with nodes
245 } else if (unlikely(err)){ 245 * having the highest version number, so we'll be able
246 JFFS2_ERROR("MTD point failed %d\n", err); 246 * to detect whether a node is valid (i.e., it is not
247 } else 247 * overlapped by a node with higher version) or not.
248 pointed = 1; /* succefully pointed to device */ 248 * And we'll be able to check only those nodes, which
249 } 249 * are not obsolete.
250#endif 250 *
251 if(!pointed){ 251 * Of course, this optimization only makes sense in case
252 buf = kmalloc(je32_to_cpu(rd->csize), GFP_KERNEL); 252 * of NAND flashes (or other flashes whith
253 if (!buf) 253 * !jffs2_can_mark_obsolete()), since on NOR flashes
254 return -ENOMEM; 254 * nodes are marked obsolete physically.
255 255 *
256 err = jffs2_flash_read(c, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize), 256 * Since NAND flashes (or other flashes with
257 &read, buf); 257 * jffs2_is_writebuffered(c)) are anyway read by
258 if (unlikely(read != je32_to_cpu(rd->csize)) && likely(!err)) 258 * fractions of c->wbuf_pagesize, and we have just read
259 err = -EIO; 259 * the node header, it is likely that the starting part
260 if (err) { 260 * of the node data is also read when we read the
261 kfree(buf); 261 * header. So we don't mind to check the CRC of the
262 return err; 262 * starting part of the data of the node now, and check
263 } 263 * the second part later (in jffs2_check_node_data()).
264 } 264 * Of course, we will not need to re-read and re-check
265 crc = crc32(0, buf, je32_to_cpu(rd->csize)); 265 * the NAND page which we have just read. This is why we
266 if(!pointed) 266 * read the whole NAND page at jffs2_get_inode_nodes(),
267 kfree(buf); 267 * while we needed only the node header.
268#ifndef __ECOS 268 */
269 else 269 unsigned char *buf;
270 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize)); 270
271#endif 271 /* 'buf' will point to the start of data */
272 272 buf = (unsigned char *)rd + sizeof(*rd);
273 if (crc != je32_to_cpu(rd->data_crc)) { 273 /* len will be the read data length */
274 JFFS2_NOTICE("data CRC failed on node at %#08x: read %#08x, calculated %#08x\n", 274 len = min_t(uint32_t, rdlen - sizeof(*rd), csize);
275 ref_offset(ref), je32_to_cpu(rd->data_crc), crc);
276 return 1;
277 }
278 275
279 } 276 if (len)
280 277 tn->partial_crc = crc = crc32(0, buf, len);
281 /* Mark the node as having been checked and fix the accounting accordingly */ 278
282 jeb = &c->blocks[ref->flash_offset / c->sector_size]; 279 /* If we actually calculated the whole data CRC
283 len = ref_totlen(c, jeb, ref); 280 * and it is wrong, drop the node. */
284 281 if (unlikely(tn->partial_crc
285 spin_lock(&c->erase_completion_lock); 282 != je32_to_cpu(rd->data_crc)) &&
286 jeb->used_size += len; 283 len == csize)
287 jeb->unchecked_size -= len; 284 goto free_out;
288 c->used_size += len;
289 c->unchecked_size -= len;
290
291 /* If node covers at least a whole page, or if it starts at the
292 beginning of a page and runs to the end of the file, or if
293 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
294 285
295 If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) 286 } else if (csize == 0) {
296 when the overlapping node(s) get added to the tree anyway. 287 /*
297 */ 288 * We checked the header CRC. If the node has no data, adjust
298 if ((je32_to_cpu(rd->dsize) >= PAGE_CACHE_SIZE) || 289 * the space accounting now. For other nodes this will be done
299 ( ((je32_to_cpu(rd->offset) & (PAGE_CACHE_SIZE-1))==0) && 290 * later either when the node is marked obsolete or when its
300 (je32_to_cpu(rd->dsize) + je32_to_cpu(rd->offset) == je32_to_cpu(rd->isize)))) { 291 * data is checked.
301 JFFS2_DBG_READINODE("marking node at %#08x REF_PRISTINE\n", ref_offset(ref)); 292 */
302 ref->flash_offset = ref_offset(ref) | REF_PRISTINE; 293 struct jffs2_eraseblock *jeb;
303 } else { 294
304 JFFS2_DBG_READINODE("marking node at %#08x REF_NORMAL\n", ref_offset(ref)); 295 JFFS2_DBG_READINODE("the node has no data.\n");
296 jeb = &c->blocks[ref->flash_offset / c->sector_size];
297 len = ref_totlen(c, jeb, ref);
298
299 spin_lock(&c->erase_completion_lock);
300 jeb->used_size += len;
301 jeb->unchecked_size -= len;
302 c->used_size += len;
303 c->unchecked_size -= len;
305 ref->flash_offset = ref_offset(ref) | REF_NORMAL; 304 ref->flash_offset = ref_offset(ref) | REF_NORMAL;
305 spin_unlock(&c->erase_completion_lock);
306 } 306 }
307 spin_unlock(&c->erase_completion_lock);
308 }
309
310 tn = jffs2_alloc_tmp_dnode_info();
311 if (!tn) {
312 JFFS2_ERROR("alloc tn failed\n");
313 return -ENOMEM;
314 } 307 }
315 308
316 tn->fn = jffs2_alloc_full_dnode(); 309 tn->fn = jffs2_alloc_full_dnode();
317 if (!tn->fn) { 310 if (!tn->fn) {
318 JFFS2_ERROR("alloc fn failed\n"); 311 JFFS2_ERROR("alloc fn failed\n");
319 jffs2_free_tmp_dnode_info(tn); 312 ret = -ENOMEM;
320 return -ENOMEM; 313 goto free_out;
321 } 314 }
322 315
323 tn->version = je32_to_cpu(rd->version); 316 tn->version = je32_to_cpu(rd->version);
324 tn->fn->ofs = je32_to_cpu(rd->offset); 317 tn->fn->ofs = je32_to_cpu(rd->offset);
318 tn->data_crc = je32_to_cpu(rd->data_crc);
319 tn->csize = csize;
325 tn->fn->raw = ref; 320 tn->fn->raw = ref;
326 321
327 /* There was a bug where we wrote hole nodes out with 322 /* There was a bug where we wrote hole nodes out with
328 csize/dsize swapped. Deal with it */ 323 csize/dsize swapped. Deal with it */
329 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && je32_to_cpu(rd->csize)) 324 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
330 tn->fn->size = je32_to_cpu(rd->csize); 325 tn->fn->size = csize;
331 else // normal case... 326 else // normal case...
332 tn->fn->size = je32_to_cpu(rd->dsize); 327 tn->fn->size = je32_to_cpu(rd->dsize);
333 328
@@ -337,6 +332,10 @@ read_dnode(struct jffs2_sb_info *c,
337 jffs2_add_tn_to_tree(tn, tnp); 332 jffs2_add_tn_to_tree(tn, tnp);
338 333
339 return 0; 334 return 0;
335
336free_out:
337 jffs2_free_tmp_dnode_info(tn);
338 return ret;
340} 339}
341 340
342/* 341/*
@@ -347,11 +346,7 @@ read_dnode(struct jffs2_sb_info *c,
347 * 1 if the node should be marked obsolete; 346 * 1 if the node should be marked obsolete;
348 * negative error code on failure. 347 * negative error code on failure.
349 */ 348 */
350static inline int 349static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
351read_unknown(struct jffs2_sb_info *c,
352 struct jffs2_raw_node_ref *ref,
353 struct jffs2_unknown_node *un,
354 uint32_t read)
355{ 350{
356 /* We don't mark unknown nodes as REF_UNCHECKED */ 351 /* We don't mark unknown nodes as REF_UNCHECKED */
357 BUG_ON(ref_flags(ref) == REF_UNCHECKED); 352 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
@@ -394,9 +389,62 @@ read_unknown(struct jffs2_sb_info *c,
394 return 0; 389 return 0;
395} 390}
396 391
392/*
393 * Helper function for jffs2_get_inode_nodes().
394 * The function detects whether more data should be read and reads it if yes.
395 *
396 * Returns: 0 on succes;
397 * negative error code on failure.
398 */
399static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
400 int right_size, int *rdlen, unsigned char *buf, unsigned char *bufstart)
401{
402 int right_len, err, len;
403 size_t retlen;
404 uint32_t offs;
405
406 if (jffs2_is_writebuffered(c)) {
407 right_len = c->wbuf_pagesize - (bufstart - buf);
408 if (right_size + (int)(bufstart - buf) > c->wbuf_pagesize)
409 right_len += c->wbuf_pagesize;
410 } else
411 right_len = right_size;
412
413 if (*rdlen == right_len)
414 return 0;
415
416 /* We need to read more data */
417 offs = ref_offset(ref) + *rdlen;
418 if (jffs2_is_writebuffered(c)) {
419 bufstart = buf + c->wbuf_pagesize;
420 len = c->wbuf_pagesize;
421 } else {
422 bufstart = buf + *rdlen;
423 len = right_size - *rdlen;
424 }
425
426 JFFS2_DBG_READINODE("read more %d bytes.", len);
427
428 err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
429 if (err) {
430 JFFS2_ERROR("can not read %d bytes from 0x%08x, "
431 "error code: %d.\n", len, offs, err);
432 return err;
433 }
434
435 if (retlen < len) {
436 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n",
437 offs, retlen, len);
438 return -EIO;
439 }
440
441 *rdlen = right_len;
442
443 return 0;
444}
445
397/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated 446/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
398 with this ino, returning the former in order of version */ 447 with this ino, returning the former in order of version */
399
400static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 448static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
401 struct rb_root *tnp, struct jffs2_full_dirent **fdp, 449 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
402 uint32_t *highest_version, uint32_t *latest_mctime, 450 uint32_t *highest_version, uint32_t *latest_mctime,
@@ -405,22 +453,47 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
405 struct jffs2_raw_node_ref *ref, *valid_ref; 453 struct jffs2_raw_node_ref *ref, *valid_ref;
406 struct rb_root ret_tn = RB_ROOT; 454 struct rb_root ret_tn = RB_ROOT;
407 struct jffs2_full_dirent *ret_fd = NULL; 455 struct jffs2_full_dirent *ret_fd = NULL;
408 union jffs2_node_union node; 456 unsigned char *buf = NULL;
457 union jffs2_node_union *node;
409 size_t retlen; 458 size_t retlen;
410 int err; 459 int len, err;
411 460
412 *mctime_ver = 0; 461 *mctime_ver = 0;
413 462
414 JFFS2_DBG_READINODE("ino #%u\n", f->inocache->ino); 463 JFFS2_DBG_READINODE("ino #%u\n", f->inocache->ino);
415 464
416 spin_lock(&c->erase_completion_lock); 465 if (jffs2_is_writebuffered(c)) {
466 /*
467 * If we have the write buffer, we assume the minimal I/O unit
468 * is c->wbuf_pagesize. We implement some optimizations which in
469 * this case and we need a temporary buffer of size =
470 * 2*c->wbuf_pagesize bytes (see comments in read_dnode()).
471 * Basically, we want to read not only the node header, but the
472 * whole wbuf (NAND page in case of NAND) or 2, if the node
473 * header overlaps the border between the 2 wbufs.
474 */
475 len = 2*c->wbuf_pagesize;
476 } else {
477 /*
478 * When there is no write buffer, the size of the temporary
479 * buffer is the size of the larges node header.
480 */
481 len = sizeof(union jffs2_node_union);
482 }
417 483
484 /* FIXME: in case of NOR and available ->point() this
485 * needs to be fixed. */
486 buf = kmalloc(len, GFP_KERNEL);
487 if (!buf)
488 return -ENOMEM;
489
490 spin_lock(&c->erase_completion_lock);
418 valid_ref = jffs2_first_valid_node(f->inocache->nodes); 491 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
419 492 if (!valid_ref && f->inocache->ino != 1)
420 if (!valid_ref && (f->inocache->ino != 1)) 493 JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino);
421 JFFS2_WARNING("no valid nodes for ino #%u\n", f->inocache->ino);
422
423 while (valid_ref) { 494 while (valid_ref) {
495 unsigned char *bufstart;
496
424 /* We can hold a pointer to a non-obsolete node without the spinlock, 497 /* We can hold a pointer to a non-obsolete node without the spinlock,
425 but _obsolete_ nodes may disappear at any time, if the block 498 but _obsolete_ nodes may disappear at any time, if the block
426 they're in gets erased. So if we mark 'ref' obsolete while we're 499 they're in gets erased. So if we mark 'ref' obsolete while we're
@@ -433,70 +506,100 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
433 506
434 cond_resched(); 507 cond_resched();
435 508
509 /*
510 * At this point we don't know the type of the node we're going
511 * to read, so we do not know the size of its header. In order
512 * to minimize the amount of flash IO we assume the node has
513 * size = JFFS2_MIN_NODE_HEADER.
514 */
515 if (jffs2_is_writebuffered(c)) {
516 /*
517 * We treat 'buf' as 2 adjacent wbufs. We want to
518 * adjust bufstart such as it points to the
519 * beginning of the node within this wbuf.
520 */
521 bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize);
522 /* We will read either one wbuf or 2 wbufs. */
523 len = c->wbuf_pagesize - (bufstart - buf);
524 if (JFFS2_MIN_NODE_HEADER +
525 (int)(bufstart - buf) > c->wbuf_pagesize) {
526 /* The header spans the border of the
527 * first wbuf */
528 len += c->wbuf_pagesize;
529 }
530 } else {
531 bufstart = buf;
532 len = JFFS2_MIN_NODE_HEADER;
533 }
534
535 JFFS2_DBG_READINODE("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref));
536
436 /* FIXME: point() */ 537 /* FIXME: point() */
437 err = jffs2_flash_read(c, (ref_offset(ref)), 538 err = jffs2_flash_read(c, ref_offset(ref), len,
438 min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)), 539 &retlen, bufstart);
439 &retlen, (void *)&node);
440 if (err) { 540 if (err) {
441 JFFS2_ERROR("error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref)); 541 JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
542 goto free_out;
543 }
544
545 if (retlen < len) {
546 JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);
547 err = -EIO;
442 goto free_out; 548 goto free_out;
443 } 549 }
550
551 node = (union jffs2_node_union *)bufstart;
444 552
445 switch (je16_to_cpu(node.u.nodetype)) { 553 switch (je16_to_cpu(node->u.nodetype)) {
446 554
447 case JFFS2_NODETYPE_DIRENT: 555 case JFFS2_NODETYPE_DIRENT:
448 JFFS2_DBG_READINODE("node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref));
449
450 if (retlen < sizeof(node.d)) {
451 JFFS2_ERROR("short read dirent at %#08x\n", ref_offset(ref));
452 err = -EIO;
453 goto free_out;
454 }
455 556
456 err = read_direntry(c, ref, &node.d, retlen, &ret_fd, latest_mctime, mctime_ver); 557 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
558 err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart);
559 if (unlikely(err))
560 goto free_out;
561 }
562
563 err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);
457 if (err == 1) { 564 if (err == 1) {
458 jffs2_mark_node_obsolete(c, ref); 565 jffs2_mark_node_obsolete(c, ref);
459 break; 566 break;
460 } else if (unlikely(err)) 567 } else if (unlikely(err))
461 goto free_out; 568 goto free_out;
462 569
463 if (je32_to_cpu(node.d.version) > *highest_version) 570 if (je32_to_cpu(node->d.version) > *highest_version)
464 *highest_version = je32_to_cpu(node.d.version); 571 *highest_version = je32_to_cpu(node->d.version);
465 572
466 break; 573 break;
467 574
468 case JFFS2_NODETYPE_INODE: 575 case JFFS2_NODETYPE_INODE:
469 JFFS2_DBG_READINODE("node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref));
470 576
471 if (retlen < sizeof(node.i)) { 577 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
472 JFFS2_ERROR("short read dnode at %#08x\n", ref_offset(ref)); 578 err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);
473 err = -EIO; 579 if (unlikely(err))
474 goto free_out; 580 goto free_out;
475 } 581 }
476 582
477 err = read_dnode(c, ref, &node.i, retlen, &ret_tn, latest_mctime, mctime_ver); 583 err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver);
478 if (err == 1) { 584 if (err == 1) {
479 jffs2_mark_node_obsolete(c, ref); 585 jffs2_mark_node_obsolete(c, ref);
480 break; 586 break;
481 } else if (unlikely(err)) 587 } else if (unlikely(err))
482 goto free_out; 588 goto free_out;
483 589
484 if (je32_to_cpu(node.i.version) > *highest_version) 590 if (je32_to_cpu(node->i.version) > *highest_version)
485 *highest_version = je32_to_cpu(node.i.version); 591 *highest_version = je32_to_cpu(node->i.version);
486 592
487 JFFS2_DBG_READINODE("version %d, highest_version now %d\n",
488 je32_to_cpu(node.i.version), *highest_version);
489
490 break; 593 break;
491 594
492 default: 595 default:
493 /* Check we've managed to read at least the common node header */ 596 if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {
494 if (retlen < sizeof(struct jffs2_unknown_node)) { 597 err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart);
495 JFFS2_ERROR("short read unknown node at %#08x\n", ref_offset(ref)); 598 if (unlikely(err))
496 return -EIO; 599 goto free_out;
497 } 600 }
498 601
499 err = read_unknown(c, ref, &node.u, retlen); 602 err = read_unknown(c, ref, &node->u);
500 if (err == 1) { 603 if (err == 1) {
501 jffs2_mark_node_obsolete(c, ref); 604 jffs2_mark_node_obsolete(c, ref);
502 break; 605 break;
@@ -505,17 +608,21 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
505 608
506 } 609 }
507 spin_lock(&c->erase_completion_lock); 610 spin_lock(&c->erase_completion_lock);
508
509 } 611 }
612
510 spin_unlock(&c->erase_completion_lock); 613 spin_unlock(&c->erase_completion_lock);
511 *tnp = ret_tn; 614 *tnp = ret_tn;
512 *fdp = ret_fd; 615 *fdp = ret_fd;
616 kfree(buf);
513 617
618 JFFS2_DBG_READINODE("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n",
619 f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver);
514 return 0; 620 return 0;
515 621
516 free_out: 622 free_out:
517 jffs2_free_tmp_dnode_info_list(&ret_tn); 623 jffs2_free_tmp_dnode_info_list(&ret_tn);
518 jffs2_free_full_dirent_list(ret_fd); 624 jffs2_free_full_dirent_list(ret_fd);
625 kfree(buf);
519 return err; 626 return err;
520} 627}
521 628
@@ -523,14 +630,13 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
523 struct jffs2_inode_info *f, 630 struct jffs2_inode_info *f,
524 struct jffs2_raw_inode *latest_node) 631 struct jffs2_raw_inode *latest_node)
525{ 632{
526 struct jffs2_tmp_dnode_info *tn = NULL; 633 struct jffs2_tmp_dnode_info *tn;
527 struct rb_root tn_list; 634 struct rb_root tn_list;
528 struct rb_node *rb, *repl_rb; 635 struct rb_node *rb, *repl_rb;
529 struct jffs2_full_dirent *fd_list; 636 struct jffs2_full_dirent *fd_list;
530 struct jffs2_full_dnode *fn = NULL; 637 struct jffs2_full_dnode *fn, *first_fn = NULL;
531 uint32_t crc; 638 uint32_t crc;
532 uint32_t latest_mctime, mctime_ver; 639 uint32_t latest_mctime, mctime_ver;
533 uint32_t mdata_ver = 0;
534 size_t retlen; 640 size_t retlen;
535 int ret; 641 int ret;
536 642
@@ -550,42 +656,33 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
550 rb = rb_first(&tn_list); 656 rb = rb_first(&tn_list);
551 657
552 while (rb) { 658 while (rb) {
659 cond_resched();
553 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); 660 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
554 fn = tn->fn; 661 fn = tn->fn;
555 662 ret = 1;
556 if (f->metadata) { 663 JFFS2_DBG_READINODE("consider node ver %u, phys offset "
557 if (likely(tn->version >= mdata_ver)) { 664 "%#08x(%d), range %u-%u.\n", tn->version,
558 JFFS2_DBG_READINODE("obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)); 665 ref_offset(fn->raw), ref_flags(fn->raw),
559 jffs2_mark_node_obsolete(c, f->metadata->raw); 666 fn->ofs, fn->ofs + fn->size);
560 jffs2_free_full_dnode(f->metadata);
561 f->metadata = NULL;
562
563 mdata_ver = 0;
564 } else {
565 /* This should never happen. */
566 JFFS2_ERROR("Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
567 ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
568 jffs2_mark_node_obsolete(c, fn->raw);
569 jffs2_free_full_dnode(fn);
570 /* Fill in latest_node from the metadata, not this one we're about to free... */
571 fn = f->metadata;
572 goto next_tn;
573 }
574 }
575 667
576 if (fn->size) { 668 if (fn->size) {
577 jffs2_add_full_dnode_to_inode(c, f, fn); 669 ret = jffs2_add_older_frag_to_fragtree(c, f, tn);
578 } else { 670 /* TODO: the error code isn't checked, check it */
579 /* Zero-sized node at end of version list. Just a metadata update */ 671 jffs2_dbg_fragtree_paranoia_check_nolock(f);
580 JFFS2_DBG_READINODE("metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version); 672 BUG_ON(ret < 0);
673 if (!first_fn && ret == 0)
674 first_fn = fn;
675 } else if (!first_fn) {
676 first_fn = fn;
581 f->metadata = fn; 677 f->metadata = fn;
582 mdata_ver = tn->version; 678 ret = 0; /* Prevent freeing the metadata update node */
583 } 679 } else
584 next_tn: 680 jffs2_mark_node_obsolete(c, fn->raw);
681
585 BUG_ON(rb->rb_left); 682 BUG_ON(rb->rb_left);
586 if (rb->rb_parent && rb->rb_parent->rb_left == rb) { 683 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
587 /* We were then left-hand child of our parent. We need 684 /* We were then left-hand child of our parent. We need
588 to move our own right-hand child into our place. */ 685 * to move our own right-hand child into our place. */
589 repl_rb = rb->rb_right; 686 repl_rb = rb->rb_right;
590 if (repl_rb) 687 if (repl_rb)
591 repl_rb->rb_parent = rb->rb_parent; 688 repl_rb->rb_parent = rb->rb_parent;
@@ -595,7 +692,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
595 rb = rb_next(rb); 692 rb = rb_next(rb);
596 693
597 /* Remove the spent tn from the tree; don't bother rebalancing 694 /* Remove the spent tn from the tree; don't bother rebalancing
598 but put our right-hand child in our own place. */ 695 * but put our right-hand child in our own place. */
599 if (tn->rb.rb_parent) { 696 if (tn->rb.rb_parent) {
600 if (tn->rb.rb_parent->rb_left == &tn->rb) 697 if (tn->rb.rb_parent->rb_left == &tn->rb)
601 tn->rb.rb_parent->rb_left = repl_rb; 698 tn->rb.rb_parent->rb_left = repl_rb;
@@ -606,10 +703,18 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
606 tn->rb.rb_right->rb_parent = NULL; 703 tn->rb.rb_right->rb_parent = NULL;
607 704
608 jffs2_free_tmp_dnode_info(tn); 705 jffs2_free_tmp_dnode_info(tn);
706 if (ret) {
707 JFFS2_DBG_READINODE("delete dnode %u-%u.\n",
708 fn->ofs, fn->ofs + fn->size);
709 jffs2_free_full_dnode(fn);
710 }
609 } 711 }
610 jffs2_dbg_fragtree_paranoia_check_nolock(f); 712 jffs2_dbg_fragtree_paranoia_check_nolock(f);
611 713
612 if (!fn) { 714 BUG_ON(first_fn && ref_obsolete(first_fn->raw));
715
716 fn = first_fn;
717 if (unlikely(!first_fn)) {
613 /* No data nodes for this inode. */ 718 /* No data nodes for this inode. */
614 if (f->inocache->ino != 1) { 719 if (f->inocache->ino != 1) {
615 JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); 720 JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);