diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 23:00:01 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 23:00:01 -0400 |
commit | 49f11d40751b974f3b829f208eefa6f97a10cac8 (patch) | |
tree | 3a08ec1f7f94e6fc81754a40ef4dfcaf0c489d11 | |
parent | 25090a6b23906552cf3d204aa421f811327e1b15 (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>
-rw-r--r-- | fs/jffs2/summary.c | 71 |
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 | ||
372 | static 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 | ||