aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/summary.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-20 23:00:01 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-20 23:00:01 -0400
commit49f11d40751b974f3b829f208eefa6f97a10cac8 (patch)
tree3a08ec1f7f94e6fc81754a40ef4dfcaf0c489d11 /fs/jffs2/summary.c
parent25090a6b23906552cf3d204aa421f811327e1b15 (diff)
[JFFS2] Mark gaps in summary list as dirty space
Make sure we allocate a ref for any dirty space which exists between nodes which we find in an eraseblock summary. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r--fs/jffs2/summary.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 11ea54c90f44..e60289ada833 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -369,6 +369,23 @@ no_mem:
369 return -ENOMEM; 369 return -ENOMEM;
370} 370}
371 371
372static struct jffs2_raw_node_ref *alloc_ref_at(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
373 uint32_t offset)
374{
375 struct jffs2_raw_node_ref *ref;
376 /* If there was a gap, mark it dirty */
377 if (offset > c->sector_size - jeb->free_size) {
378 int ret = jffs2_scan_dirty_space(c, jeb, offset - (c->sector_size - jeb->free_size));
379 if (ret)
380 return NULL;
381 }
382 ref = jffs2_alloc_raw_node_ref();
383 if (!ref)
384 return NULL;
385
386 ref->flash_offset = jeb->offset + offset;
387 return ref;
388}
372 389
373/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */ 390/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
374 391
@@ -397,7 +414,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
397 dbg_summary("Inode at 0x%08x\n", 414 dbg_summary("Inode at 0x%08x\n",
398 jeb->offset + je32_to_cpu(spi->offset)); 415 jeb->offset + je32_to_cpu(spi->offset));
399 416
400 raw = jffs2_alloc_raw_node_ref(); 417 raw = alloc_ref_at(c, jeb, je32_to_cpu(spi->offset));
401 if (!raw) { 418 if (!raw) {
402 JFFS2_NOTICE("allocation of node reference failed\n"); 419 JFFS2_NOTICE("allocation of node reference failed\n");
403 return -ENOMEM; 420 return -ENOMEM;
@@ -410,7 +427,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
410 return -ENOMEM; 427 return -ENOMEM;
411 } 428 }
412 429
413 raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED; 430 raw->flash_offset |= REF_UNCHECKED;
414 431
415 raw->next_in_ino = ic->nodes; 432 raw->next_in_ino = ic->nodes;
416 ic->nodes = raw; 433 ic->nodes = raw;
@@ -438,7 +455,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
438 memcpy(&fd->name, spd->name, spd->nsize); 455 memcpy(&fd->name, spd->name, spd->nsize);
439 fd->name[spd->nsize] = 0; 456 fd->name[spd->nsize] = 0;
440 457
441 raw = jffs2_alloc_raw_node_ref(); 458 raw = alloc_ref_at(c, jeb, je32_to_cpu(spd->offset));
442 if (!raw) { 459 if (!raw) {
443 jffs2_free_full_dirent(fd); 460 jffs2_free_full_dirent(fd);
444 JFFS2_NOTICE("allocation of node reference failed\n"); 461 JFFS2_NOTICE("allocation of node reference failed\n");
@@ -452,7 +469,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
452 return -ENOMEM; 469 return -ENOMEM;
453 } 470 }
454 471
455 raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE; 472 raw->flash_offset |= REF_PRISTINE;
456 raw->next_in_ino = ic->nodes; 473 raw->next_in_ino = ic->nodes;
457 ic->nodes = raw; 474 ic->nodes = raw;
458 475
@@ -477,13 +494,12 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
477 case JFFS2_NODETYPE_XATTR: { 494 case JFFS2_NODETYPE_XATTR: {
478 struct jffs2_xattr_datum *xd; 495 struct jffs2_xattr_datum *xd;
479 struct jffs2_sum_xattr_flash *spx; 496 struct jffs2_sum_xattr_flash *spx;
480 uint32_t ofs;
481 497
482 spx = (struct jffs2_sum_xattr_flash *)sp; 498 spx = (struct jffs2_sum_xattr_flash *)sp;
483 ofs = jeb->offset + je32_to_cpu(spx->offset); 499 dbg_summary("xattr at %#08x (xid=%u, version=%u)\n",
484 dbg_summary("xattr at %#08x (xid=%u, version=%u)\n", ofs, 500 jeb->offset + je32_to_cpu(spx->offset),
485 je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); 501 je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
486 raw = jffs2_alloc_raw_node_ref(); 502 raw = alloc_ref_at(c, jeb, je32_to_cpu(spx->offset));
487 if (!raw) { 503 if (!raw) {
488 JFFS2_NOTICE("allocation of node reference failed\n"); 504 JFFS2_NOTICE("allocation of node reference failed\n");
489 kfree(summary); 505 kfree(summary);
@@ -506,7 +522,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
506 } 522 }
507 xd->node = raw; 523 xd->node = raw;
508 524
509 raw->flash_offset = ofs | REF_UNCHECKED; 525 raw->flash_offset |= REF_UNCHECKED;
510 raw->next_in_ino = (void *)xd; 526 raw->next_in_ino = (void *)xd;
511 527
512 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen))); 528 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen)));
@@ -519,13 +535,12 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
519 case JFFS2_NODETYPE_XREF: { 535 case JFFS2_NODETYPE_XREF: {
520 struct jffs2_xattr_ref *ref; 536 struct jffs2_xattr_ref *ref;
521 struct jffs2_sum_xref_flash *spr; 537 struct jffs2_sum_xref_flash *spr;
522 uint32_t ofs;
523 538
524 spr = (struct jffs2_sum_xref_flash *)sp; 539 spr = (struct jffs2_sum_xref_flash *)sp;
525 ofs = jeb->offset + je32_to_cpu(spr->offset); 540 dbg_summary("xref at %#08x (xid=%u, ino=%u)\n",
526 dbg_summary("xref at %#08x (xid=%u, ino=%u)\n", ofs, 541 jeb->offset + je32_to_cpu(spr->offset),
527 je32_to_cpu(spr->xid), je32_to_cpu(spr->ino)); 542 je32_to_cpu(spr->xid), je32_to_cpu(spr->ino));
528 raw = jffs2_alloc_raw_node_ref(); 543 raw = alloc_ref_at(c, jeb, je32_to_cpu(spr->offset));
529 if (!raw) { 544 if (!raw) {
530 JFFS2_NOTICE("allocation of node reference failed\n"); 545 JFFS2_NOTICE("allocation of node reference failed\n");
531 kfree(summary); 546 kfree(summary);
@@ -544,12 +559,12 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
544 ref->next = c->xref_temp; 559 ref->next = c->xref_temp;
545 c->xref_temp = ref; 560 c->xref_temp = ref;
546 561
547 raw->flash_offset = ofs | REF_UNCHECKED; 562 raw->flash_offset |= REF_UNCHECKED;
548 raw->next_in_ino = (void *)ref; 563 raw->next_in_ino = (void *)ref;
549 564
550 jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref))); 565 jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref)));
551 566
552 *pseudo_random += ofs; 567 *pseudo_random += raw->flash_offset;
553 sp += JFFS2_SUMMARY_XREF_SIZE; 568 sp += JFFS2_SUMMARY_XREF_SIZE;
554 569
555 break; 570 break;
@@ -589,10 +604,10 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
589 uint32_t crc; 604 uint32_t crc;
590 int err; 605 int err;
591 606
592 ofs = jeb->offset + c->sector_size - sumsize; 607 ofs = c->sector_size - sumsize;
593 608
594 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", 609 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
595 jeb->offset, ofs, sumsize); 610 jeb->offset, jeb->offset + ofs, sumsize);
596 611
597 /* OK, now check for node validity and CRC */ 612 /* OK, now check for node validity and CRC */
598 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 613 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -654,11 +669,6 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
654 } 669 }
655 } 670 }
656 671
657 if (je32_to_cpu(summary->padded)) {
658 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(summary->padded))))
659 return err;
660 }
661
662 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); 672 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
663 /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full 673 /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full
664 scan of this eraseblock. So return zero */ 674 scan of this eraseblock. So return zero */
@@ -668,7 +678,7 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
668 return ret; /* real error */ 678 return ret; /* real error */
669 679
670 /* for PARANOIA_CHECK */ 680 /* for PARANOIA_CHECK */
671 cache_ref = jffs2_alloc_raw_node_ref(); 681 cache_ref = alloc_ref_at(c, jeb, ofs);
672 682
673 if (!cache_ref) { 683 if (!cache_ref) {
674 JFFS2_NOTICE("Failed to allocate node ref for cache\n"); 684 JFFS2_NOTICE("Failed to allocate node ref for cache\n");
@@ -676,15 +686,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
676 } 686 }
677 687
678 cache_ref->next_in_ino = NULL; 688 cache_ref->next_in_ino = NULL;
679 cache_ref->next_phys = NULL; 689 cache_ref->flash_offset |= REF_NORMAL;
680 cache_ref->flash_offset = ofs | REF_NORMAL;
681 690
682 jffs2_link_node_ref(c, jeb, cache_ref, sumsize); 691 jffs2_link_node_ref(c, jeb, cache_ref, sumsize);
683 692
684 jeb->wasted_size += jeb->free_size; 693 if (unlikely(jeb->free_size)) {
685 c->wasted_size += jeb->free_size; 694 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
686 c->free_size -= jeb->free_size; 695 jeb->free_size, jeb->offset);
687 jeb->free_size = 0; 696 jeb->wasted_size += jeb->free_size;
697 c->wasted_size += jeb->free_size;
698 c->free_size -= jeb->free_size;
699 jeb->free_size = 0;
700 }
688 701
689 return jffs2_scan_classify_jeb(c, jeb); 702 return jffs2_scan_classify_jeb(c, jeb);
690 703