aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r--fs/jffs2/scan.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 5847e76ce16c..40d62d057aa4 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -437,11 +437,12 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
437} 437}
438#endif 438#endif
439 439
440/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into
441 the flash, XIP-style */
440static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 442static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
441 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) { 443 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
442 struct jffs2_unknown_node *node; 444 struct jffs2_unknown_node *node;
443 struct jffs2_unknown_node crcnode; 445 struct jffs2_unknown_node crcnode;
444 struct jffs2_sum_marker *sm;
445 uint32_t ofs, prevofs; 446 uint32_t ofs, prevofs;
446 uint32_t hdr_crc, buf_ofs, buf_len; 447 uint32_t hdr_crc, buf_ofs, buf_len;
447 int err; 448 int err;
@@ -475,44 +476,70 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
475#endif 476#endif
476 477
477 if (jffs2_sum_active()) { 478 if (jffs2_sum_active()) {
478 sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL); 479 struct jffs2_sum_marker *sm;
479 if (!sm) { 480 void *sumptr = NULL;
480 return -ENOMEM; 481 uint32_t sumlen;
481 } 482
483 if (!buf_size) {
484 /* XIP case. Just look, point at the summary if it's there */
485 sm = (void *)buf + jeb->offset - sizeof(*sm);
486 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {
487 sumptr = buf + je32_to_cpu(sm->offset);
488 sumlen = c->sector_size - je32_to_cpu(sm->offset);
489 }
490 } else {
491 /* If NAND flash, read a whole page of it. Else just the end */
492 if (c->wbuf_pagesize)
493 buf_len = c->wbuf_pagesize;
494 else
495 buf_len = sizeof(*sm);
496
497 /* Read as much as we want into the _end_ of the preallocated buffer */
498 err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
499 jeb->offset + c->sector_size - buf_len,
500 buf_len);
501 if (err)
502 return err;
503
504 sm = (void *)buf + buf_size - sizeof(*sm);
505 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {
506 sumlen = c->sector_size - je32_to_cpu(sm->offset);
507 sumptr = buf + buf_size - sumlen;
508
509 /* Now, make sure the summary itself is available */
510 if (sumlen > buf_size) {
511 /* Need to kmalloc for this. */
512 sumptr = kmalloc(sumlen, GFP_KERNEL);
513 if (!sumptr)
514 return -ENOMEM;
515 memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len);
516 }
517 if (buf_len < sumlen) {
518 /* Need to read more so that the entire summary node is present */
519 err = jffs2_fill_scan_buf(c, sumptr,
520 jeb->offset + c->sector_size - sumlen,
521 sumlen - buf_len);
522 if (err)
523 return err;
524 }
525 }
482 526
483 err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
484 sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
485 if (err) {
486 kfree(sm);
487 return err;
488 } 527 }
489 528
490 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) { 529 if (sumptr) {
491 err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random); 530 err = jffs2_sum_scan_sumnode(c, jeb, sumptr, sumlen, &pseudo_random);
492 if (err) { 531 if (err)
493 kfree(sm);
494 return err; 532 return err;
495 } 533 if (buf_size && sumlen > buf_size)
534 kfree(sumptr);
496 } 535 }
497
498 kfree(sm);
499
500 ofs = jeb->offset;
501 prevofs = jeb->offset - 1;
502 } 536 }
503 537
504 buf_ofs = jeb->offset; 538 buf_ofs = jeb->offset;
505 539
506 if (!buf_size) { 540 if (!buf_size) {
541 /* This is the XIP case -- we're reading _directly_ from the flash chip */
507 buf_len = c->sector_size; 542 buf_len = c->sector_size;
508
509 if (jffs2_sum_active()) {
510 /* must reread because of summary test */
511 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
512 if (err)
513 return err;
514 }
515
516 } else { 543 } else {
517 buf_len = EMPTY_SCAN_SIZE(c->sector_size); 544 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
518 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 545 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);