aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/summary.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r--fs/jffs2/summary.c162
1 files changed, 49 insertions, 113 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 351ba9f8185e..ccb6803a6e41 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -369,22 +369,18 @@ 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, 372static struct jffs2_raw_node_ref *sum_link_node_ref(struct jffs2_sb_info *c,
373 uint32_t offset) 373 struct jffs2_eraseblock *jeb,
374 uint32_t ofs, uint32_t len,
375 struct jffs2_inode_cache *ic)
374{ 376{
375 struct jffs2_raw_node_ref *ref;
376 /* If there was a gap, mark it dirty */ 377 /* If there was a gap, mark it dirty */
377 if (offset > c->sector_size - jeb->free_size) { 378 if ((ofs & ~3) > c->sector_size - jeb->free_size) {
378 int ret = jffs2_scan_dirty_space(c, jeb, offset - (c->sector_size - jeb->free_size)); 379 /* Ew. Summary doesn't actually tell us explicitly about dirty space */
379 if (ret) 380 jffs2_scan_dirty_space(c, jeb, (ofs & ~3) - (c->sector_size - jeb->free_size));
380 return NULL;
381 } 381 }
382 ref = jffs2_alloc_raw_node_ref();
383 if (!ref)
384 return NULL;
385 382
386 ref->flash_offset = jeb->offset + offset; 383 return jffs2_link_node_ref(c, jeb, jeb->offset + ofs, len, ic);
387 return ref;
388} 384}
389 385
390/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */ 386/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
@@ -392,7 +388,6 @@ static struct jffs2_raw_node_ref *alloc_ref_at(struct jffs2_sb_info *c, struct j
392static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 388static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
393 struct jffs2_raw_summary *summary, uint32_t *pseudo_random) 389 struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
394{ 390{
395 struct jffs2_raw_node_ref *raw;
396 struct jffs2_inode_cache *ic; 391 struct jffs2_inode_cache *ic;
397 struct jffs2_full_dirent *fd; 392 struct jffs2_full_dirent *fd;
398 void *sp; 393 void *sp;
@@ -404,6 +399,11 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
404 for (i=0; i<je32_to_cpu(summary->sum_num); i++) { 399 for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
405 dbg_summary("processing summary index %d\n", i); 400 dbg_summary("processing summary index %d\n", i);
406 401
402 /* Make sure there's a spare ref for dirty space */
403 err = jffs2_prealloc_raw_node_refs(c, 2);
404 if (err)
405 return err;
406
407 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { 407 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
408 case JFFS2_NODETYPE_INODE: { 408 case JFFS2_NODETYPE_INODE: {
409 struct jffs2_sum_inode_flash *spi; 409 struct jffs2_sum_inode_flash *spi;
@@ -415,22 +415,14 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
415 jeb->offset + je32_to_cpu(spi->offset), 415 jeb->offset + je32_to_cpu(spi->offset),
416 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spu->totlen)); 416 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spu->totlen));
417 417
418 raw = alloc_ref_at(c, jeb, je32_to_cpu(spi->offset));
419 if (!raw) {
420 JFFS2_NOTICE("allocation of node reference failed\n");
421 return -ENOMEM;
422 }
423
424 ic = jffs2_scan_make_ino_cache(c, ino); 418 ic = jffs2_scan_make_ino_cache(c, ino);
425 if (!ic) { 419 if (!ic) {
426 JFFS2_NOTICE("scan_make_ino_cache failed\n"); 420 JFFS2_NOTICE("scan_make_ino_cache failed\n");
427 jffs2_free_raw_node_ref(raw);
428 return -ENOMEM; 421 return -ENOMEM;
429 } 422 }
430 423
431 raw->flash_offset |= REF_UNCHECKED; 424 sum_link_node_ref(c, jeb, je32_to_cpu(spi->offset) | REF_UNCHECKED,
432 425 PAD(je32_to_cpu(spi->totlen)), ic);
433 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spi->totlen)), ic);
434 426
435 *pseudo_random += je32_to_cpu(spi->version); 427 *pseudo_random += je32_to_cpu(spi->version);
436 428
@@ -455,24 +447,15 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
455 memcpy(&fd->name, spd->name, spd->nsize); 447 memcpy(&fd->name, spd->name, spd->nsize);
456 fd->name[spd->nsize] = 0; 448 fd->name[spd->nsize] = 0;
457 449
458 raw = alloc_ref_at(c, jeb, je32_to_cpu(spd->offset));
459 if (!raw) {
460 jffs2_free_full_dirent(fd);
461 JFFS2_NOTICE("allocation of node reference failed\n");
462 return -ENOMEM;
463 }
464
465 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino)); 450 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
466 if (!ic) { 451 if (!ic) {
467 jffs2_free_full_dirent(fd); 452 jffs2_free_full_dirent(fd);
468 jffs2_free_raw_node_ref(raw);
469 return -ENOMEM; 453 return -ENOMEM;
470 } 454 }
471 455
472 raw->flash_offset |= REF_PRISTINE; 456 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_PRISTINE,
473 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spd->totlen)), ic); 457 PAD(je32_to_cpu(spd->totlen)), ic);
474 458
475 fd->raw = raw;
476 fd->next = NULL; 459 fd->next = NULL;
477 fd->version = je32_to_cpu(spd->version); 460 fd->version = je32_to_cpu(spd->version);
478 fd->ino = je32_to_cpu(spd->ino); 461 fd->ino = je32_to_cpu(spd->ino);
@@ -497,15 +480,10 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
497 jeb->offset + je32_to_cpu(spx->offset), 480 jeb->offset + je32_to_cpu(spx->offset),
498 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen), 481 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),
499 je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); 482 je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
500 raw = alloc_ref_at(c, jeb, je32_to_cpu(spx->offset)); 483
501 if (!raw) {
502 JFFS2_NOTICE("allocation of node reference failed\n");
503 return -ENOMEM;
504 }
505 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), 484 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
506 je32_to_cpu(spx->version)); 485 je32_to_cpu(spx->version));
507 if (IS_ERR(xd)) { 486 if (IS_ERR(xd)) {
508 jffs2_free_raw_node_ref(raw);
509 if (PTR_ERR(xd) == -EEXIST) { 487 if (PTR_ERR(xd) == -EEXIST) {
510 /* a newer version of xd exists */ 488 /* a newer version of xd exists */
511 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen)))) 489 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen))))
@@ -516,12 +494,10 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
516 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 494 JFFS2_NOTICE("allocation of xattr_datum failed\n");
517 return PTR_ERR(xd); 495 return PTR_ERR(xd);
518 } 496 }
519 xd->node = raw;
520 497
521 raw->flash_offset |= REF_UNCHECKED; 498 xd->node = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
522 499 PAD(je32_to_cpu(spx->totlen)), NULL);
523 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen)), NULL); 500 /* FIXME */ xd->node->next_in_ino = (void *)xd;
524 /* FIXME */ raw->next_in_ino = (void *)xd;
525 501
526 *pseudo_random += je32_to_cpu(spx->xid); 502 *pseudo_random += je32_to_cpu(spx->xid);
527 sp += JFFS2_SUMMARY_XATTR_SIZE; 503 sp += JFFS2_SUMMARY_XATTR_SIZE;
@@ -537,29 +513,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
537 jeb->offset + je32_to_cpu(spr->offset), 513 jeb->offset + je32_to_cpu(spr->offset),
538 jeb->offset + je32_to_cpu(spr->offset) + PAD(sizeof(struct jffs2_raw_xref))); 514 jeb->offset + je32_to_cpu(spr->offset) + PAD(sizeof(struct jffs2_raw_xref)));
539 515
540 raw = alloc_ref_at(c, jeb, je32_to_cpu(spr->offset));
541 if (!raw) {
542 JFFS2_NOTICE("allocation of node reference failed\n");
543 return -ENOMEM;
544 }
545 ref = jffs2_alloc_xattr_ref(); 516 ref = jffs2_alloc_xattr_ref();
546 if (!ref) { 517 if (!ref) {
547 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 518 JFFS2_NOTICE("allocation of xattr_datum failed\n");
548 jffs2_free_raw_node_ref(raw);
549 return -ENOMEM; 519 return -ENOMEM;
550 } 520 }
551 ref->ino = 0xfffffffe; 521 ref->ino = 0xfffffffe;
552 ref->xid = 0xfffffffd; 522 ref->xid = 0xfffffffd;
553 ref->node = raw;
554 ref->next = c->xref_temp; 523 ref->next = c->xref_temp;
555 c->xref_temp = ref; 524 c->xref_temp = ref;
556 525
557 raw->flash_offset |= REF_UNCHECKED; 526 ref->node = sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,
527 PAD(sizeof(struct jffs2_raw_xref)), NULL);
528 /* FIXME */ ref->node->next_in_ino = (void *)ref;
558 529
559 jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref)), NULL); 530 *pseudo_random += ref->node->flash_offset;
560 /* FIXME */ raw->next_in_ino = (void *)ref;
561
562 *pseudo_random += raw->flash_offset;
563 sp += JFFS2_SUMMARY_XREF_SIZE; 531 sp += JFFS2_SUMMARY_XREF_SIZE;
564 532
565 break; 533 break;
@@ -584,7 +552,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
584 } 552 }
585 } 553 }
586 } 554 }
587
588 return 0; 555 return 0;
589} 556}
590 557
@@ -594,7 +561,6 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
594 uint32_t *pseudo_random) 561 uint32_t *pseudo_random)
595{ 562{
596 struct jffs2_unknown_node crcnode; 563 struct jffs2_unknown_node crcnode;
597 struct jffs2_raw_node_ref *cache_ref;
598 int ret, ofs; 564 int ret, ofs;
599 uint32_t crc; 565 uint32_t crc;
600 int err; 566 int err;
@@ -650,16 +616,8 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
650 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr))))) 616 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
651 return err; 617 return err;
652 } else { 618 } else {
653 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 619 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL,
654 620 je32_to_cpu(summary->cln_mkr), NULL);
655 if (!marker_ref) {
656 JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
657 return -ENOMEM;
658 }
659
660 marker_ref->flash_offset = jeb->offset | REF_NORMAL;
661
662 jffs2_link_node_ref(c, jeb, marker_ref, je32_to_cpu(summary->cln_mkr), NULL);
663 } 621 }
664 } 622 }
665 623
@@ -672,16 +630,11 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
672 return ret; /* real error */ 630 return ret; /* real error */
673 631
674 /* for PARANOIA_CHECK */ 632 /* for PARANOIA_CHECK */
675 cache_ref = alloc_ref_at(c, jeb, ofs); 633 ret = jffs2_prealloc_raw_node_refs(c, 1);
676 634 if (ret)
677 if (!cache_ref) { 635 return ret;
678 JFFS2_NOTICE("Failed to allocate node ref for cache\n");
679 return -ENOMEM;
680 }
681
682 cache_ref->flash_offset |= REF_NORMAL;
683 636
684 jffs2_link_node_ref(c, jeb, cache_ref, sumsize, NULL); 637 jffs2_link_node_ref(c, jeb, (jeb->offset + ofs) | REF_NORMAL, sumsize, NULL);
685 638
686 if (unlikely(jeb->free_size)) { 639 if (unlikely(jeb->free_size)) {
687 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n", 640 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
@@ -709,6 +662,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
709 union jffs2_sum_mem *temp; 662 union jffs2_sum_mem *temp;
710 struct jffs2_sum_marker *sm; 663 struct jffs2_sum_marker *sm;
711 struct kvec vecs[2]; 664 struct kvec vecs[2];
665 uint32_t sum_ofs;
712 void *wpage; 666 void *wpage;
713 int ret; 667 int ret;
714 size_t retlen; 668 size_t retlen;
@@ -821,36 +775,31 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
821 vecs[1].iov_base = c->summary->sum_buf; 775 vecs[1].iov_base = c->summary->sum_buf;
822 vecs[1].iov_len = datasize; 776 vecs[1].iov_len = datasize;
823 777
778 sum_ofs = jeb->offset + c->sector_size - jeb->free_size;
779
824 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n", 780 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
825 jeb->offset + c->sector_size - jeb->free_size); 781 sum_ofs);
826 782
827 spin_unlock(&c->erase_completion_lock); 783 ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0);
828 ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
829 jeb->free_size, &retlen, 0);
830 784
831 if (ret || (retlen != infosize)) { 785 if (ret || (retlen != infosize)) {
832 struct jffs2_raw_node_ref *ref;
833 786
834 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n", 787 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
835 infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen); 788 infosize, sum_ofs, ret, retlen);
836 789
837 /* Waste remaining space */ 790 /* Waste remaining space */
838 ref = jffs2_alloc_raw_node_ref(); 791 spin_lock(&c->erase_completion_lock);
839 if (ref) { 792 jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL);
840 spin_lock(&c->erase_completion_lock); 793 spin_unlock(&c->erase_completion_lock);
841
842 ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
843 ref->flash_offset |= REF_OBSOLETE;
844
845 jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size, NULL);
846 }
847 794
848 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; 795 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
849 796
850 return 1; 797 return 0;
851 } 798 }
852 799
853 spin_lock(&c->erase_completion_lock); 800 spin_lock(&c->erase_completion_lock);
801 jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL);
802 spin_unlock(&c->erase_completion_lock);
854 803
855 return 0; 804 return 0;
856} 805}
@@ -859,12 +808,15 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
859 808
860int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) 809int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
861{ 810{
862 struct jffs2_raw_node_ref *summary_ref; 811 int datasize, infosize, padsize;
863 int datasize, infosize, padsize, ret;
864 struct jffs2_eraseblock *jeb; 812 struct jffs2_eraseblock *jeb;
813 int ret;
865 814
866 dbg_summary("called\n"); 815 dbg_summary("called\n");
867 816
817 spin_unlock(&c->erase_completion_lock);
818 jffs2_prealloc_raw_node_refs(c, 1);
819
868 jeb = c->nextblock; 820 jeb = c->nextblock;
869 821
870 if (!c->summary->sum_num || !c->summary->sum_list_head) { 822 if (!c->summary->sum_num || !c->summary->sum_list_head) {
@@ -888,22 +840,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
888 } 840 }
889 841
890 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); 842 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
891 if (ret)
892 return 0; /* can't write out summary, block is marked as NOSUM_SIZE */
893
894 /* for ACCT_PARANOIA_CHECK */
895 spin_unlock(&c->erase_completion_lock);
896 summary_ref = jffs2_alloc_raw_node_ref();
897
898 if (!summary_ref) {
899 JFFS2_NOTICE("Failed to allocate node ref for summary\n");
900 return -ENOMEM;
901 }
902
903 summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
904
905 spin_lock(&c->erase_completion_lock); 843 spin_lock(&c->erase_completion_lock);
906 jffs2_link_node_ref(c, jeb, summary_ref, infosize, NULL); 844 return ret;
907
908 return 0;
909} 845}