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 | ||
