aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/scan.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-20 22:46:05 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-20 22:46:05 -0400
commit68270995f29f1a82b3eaab01df63ea7e721e2fa6 (patch)
tree44388152f209c9f8f0df8eec33efaaca7817ec6d /fs/jffs2/scan.c
parent7807ef7ba2a41c05f6197381f572dd38baa6c1ce (diff)
[JFFS2] Introduce jffs2_scan_dirty_space() function.
To eliminate the __totlen field from struct jffs2_raw_node_ref, we need to allocate nodes for dirty space instead of just tweaking the accounting data. Introduce jffs2_scan_dirty_space() in preparation for that. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r--fs/jffs2/scan.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 192b0bd21180..b3fc9fd5b03d 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -314,13 +314,15 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
314 struct jffs2_xattr_datum *xd; 314 struct jffs2_xattr_datum *xd;
315 struct jffs2_raw_node_ref *raw; 315 struct jffs2_raw_node_ref *raw;
316 uint32_t totlen, crc; 316 uint32_t totlen, crc;
317 int err;
317 318
318 crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4); 319 crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4);
319 if (crc != je32_to_cpu(rx->node_crc)) { 320 if (crc != je32_to_cpu(rx->node_crc)) {
320 if (je32_to_cpu(rx->node_crc) != 0xffffffff) 321 if (je32_to_cpu(rx->node_crc) != 0xffffffff)
321 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 322 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
322 ofs, je32_to_cpu(rx->node_crc), crc); 323 ofs, je32_to_cpu(rx->node_crc), crc);
323 DIRTY_SPACE(je32_to_cpu(rx->totlen)); 324 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
325 return err;
324 return 0; 326 return 0;
325 } 327 }
326 328
@@ -328,7 +330,8 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
328 if (totlen != je32_to_cpu(rx->totlen)) { 330 if (totlen != je32_to_cpu(rx->totlen)) {
329 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", 331 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
330 ofs, je32_to_cpu(rx->totlen), totlen); 332 ofs, je32_to_cpu(rx->totlen), totlen);
331 DIRTY_SPACE(je32_to_cpu(rx->totlen)); 333 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
334 return err;
332 return 0; 335 return 0;
333 } 336 }
334 337
@@ -340,7 +343,8 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
340 if (IS_ERR(xd)) { 343 if (IS_ERR(xd)) {
341 jffs2_free_raw_node_ref(raw); 344 jffs2_free_raw_node_ref(raw);
342 if (PTR_ERR(xd) == -EEXIST) { 345 if (PTR_ERR(xd) == -EEXIST) {
343 DIRTY_SPACE(PAD(je32_to_cpu(rx->totlen))); 346 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen)))))
347 return err;
344 return 0; 348 return 0;
345 } 349 }
346 return PTR_ERR(xd); 350 return PTR_ERR(xd);
@@ -370,13 +374,15 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
370 struct jffs2_xattr_ref *ref; 374 struct jffs2_xattr_ref *ref;
371 struct jffs2_raw_node_ref *raw; 375 struct jffs2_raw_node_ref *raw;
372 uint32_t crc; 376 uint32_t crc;
377 int err;
373 378
374 crc = crc32(0, rr, sizeof(*rr) - 4); 379 crc = crc32(0, rr, sizeof(*rr) - 4);
375 if (crc != je32_to_cpu(rr->node_crc)) { 380 if (crc != je32_to_cpu(rr->node_crc)) {
376 if (je32_to_cpu(rr->node_crc) != 0xffffffff) 381 if (je32_to_cpu(rr->node_crc) != 0xffffffff)
377 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 382 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
378 ofs, je32_to_cpu(rr->node_crc), crc); 383 ofs, je32_to_cpu(rr->node_crc), crc);
379 DIRTY_SPACE(PAD(je32_to_cpu(rr->totlen))); 384 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))
385 return err;
380 return 0; 386 return 0;
381 } 387 }
382 388
@@ -384,7 +390,8 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
384 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", 390 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
385 ofs, je32_to_cpu(rr->totlen), 391 ofs, je32_to_cpu(rr->totlen),
386 PAD(sizeof(struct jffs2_raw_xref))); 392 PAD(sizeof(struct jffs2_raw_xref)));
387 DIRTY_SPACE(je32_to_cpu(rr->totlen)); 393 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rr->totlen))))
394 return err;
388 return 0; 395 return 0;
389 } 396 }
390 397
@@ -569,7 +576,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
569 if (ofs) { 576 if (ofs) {
570 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, 577 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
571 jeb->offset + ofs)); 578 jeb->offset + ofs));
572 DIRTY_SPACE(ofs); 579 if ((err = jffs2_scan_dirty_space(c, jeb, ofs)))
580 return err;
573 } 581 }
574 582
575 /* Now ofs is a complete physical flash offset as it always was... */ 583 /* Now ofs is a complete physical flash offset as it always was... */
@@ -593,7 +601,8 @@ scan_more:
593 } 601 }
594 if (ofs == prevofs) { 602 if (ofs == prevofs) {
595 printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); 603 printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);
596 DIRTY_SPACE(4); 604 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
605 return err;
597 ofs += 4; 606 ofs += 4;
598 continue; 607 continue;
599 } 608 }
@@ -602,7 +611,8 @@ scan_more:
602 if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { 611 if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
603 D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), 612 D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),
604 jeb->offset, c->sector_size, ofs, sizeof(*node))); 613 jeb->offset, c->sector_size, ofs, sizeof(*node)));
605 DIRTY_SPACE((jeb->offset + c->sector_size)-ofs); 614 if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs)))
615 return err;
606 break; 616 break;
607 } 617 }
608 618
@@ -632,7 +642,8 @@ scan_more:
632 if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { 642 if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {
633 printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", 643 printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
634 empty_start, ofs); 644 empty_start, ofs);
635 DIRTY_SPACE(ofs-empty_start); 645 if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))
646 return err;
636 goto scan_more; 647 goto scan_more;
637 } 648 }
638 649
@@ -669,20 +680,23 @@ scan_more:
669 680
670 if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { 681 if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
671 printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); 682 printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
672 DIRTY_SPACE(4); 683 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
684 return err;
673 ofs += 4; 685 ofs += 4;
674 continue; 686 continue;
675 } 687 }
676 if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { 688 if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
677 D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); 689 D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
678 DIRTY_SPACE(4); 690 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
691 return err;
679 ofs += 4; 692 ofs += 4;
680 continue; 693 continue;
681 } 694 }
682 if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { 695 if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {
683 printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); 696 printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
684 printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); 697 printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
685 DIRTY_SPACE(4); 698 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
699 return err;
686 ofs += 4; 700 ofs += 4;
687 continue; 701 continue;
688 } 702 }
@@ -691,7 +705,8 @@ scan_more:
691 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", 705 noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
692 JFFS2_MAGIC_BITMASK, ofs, 706 JFFS2_MAGIC_BITMASK, ofs,
693 je16_to_cpu(node->magic)); 707 je16_to_cpu(node->magic));
694 DIRTY_SPACE(4); 708 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
709 return err;
695 ofs += 4; 710 ofs += 4;
696 continue; 711 continue;
697 } 712 }
@@ -708,7 +723,8 @@ scan_more:
708 je32_to_cpu(node->totlen), 723 je32_to_cpu(node->totlen),
709 je32_to_cpu(node->hdr_crc), 724 je32_to_cpu(node->hdr_crc),
710 hdr_crc); 725 hdr_crc);
711 DIRTY_SPACE(4); 726 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
727 return err;
712 ofs += 4; 728 ofs += 4;
713 continue; 729 continue;
714 } 730 }
@@ -719,7 +735,8 @@ scan_more:
719 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", 735 printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
720 ofs, je32_to_cpu(node->totlen)); 736 ofs, je32_to_cpu(node->totlen));
721 printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); 737 printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
722 DIRTY_SPACE(4); 738 if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
739 return err;
723 ofs += 4; 740 ofs += 4;
724 continue; 741 continue;
725 } 742 }
@@ -727,7 +744,8 @@ scan_more:
727 if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { 744 if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {
728 /* Wheee. This is an obsoleted node */ 745 /* Wheee. This is an obsoleted node */
729 D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); 746 D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));
730 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 747 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
748 return err;
731 ofs += PAD(je32_to_cpu(node->totlen)); 749 ofs += PAD(je32_to_cpu(node->totlen));
732 continue; 750 continue;
733 } 751 }
@@ -807,11 +825,13 @@ scan_more:
807 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { 825 if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
808 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 826 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
809 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); 827 ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
810 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 828 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node)))))
829 return err;
811 ofs += PAD(sizeof(struct jffs2_unknown_node)); 830 ofs += PAD(sizeof(struct jffs2_unknown_node));
812 } else if (jeb->first_node) { 831 } else if (jeb->first_node) {
813 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); 832 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
814 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); 833 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node)))))
834 return err;
815 ofs += PAD(sizeof(struct jffs2_unknown_node)); 835 ofs += PAD(sizeof(struct jffs2_unknown_node));
816 } else { 836 } else {
817 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 837 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
@@ -831,7 +851,8 @@ scan_more:
831 case JFFS2_NODETYPE_PADDING: 851 case JFFS2_NODETYPE_PADDING:
832 if (jffs2_sum_active()) 852 if (jffs2_sum_active())
833 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen)); 853 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
834 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 854 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
855 return err;
835 ofs += PAD(je32_to_cpu(node->totlen)); 856 ofs += PAD(je32_to_cpu(node->totlen));
836 break; 857 break;
837 858
@@ -842,7 +863,8 @@ scan_more:
842 c->flags |= JFFS2_SB_FLAG_RO; 863 c->flags |= JFFS2_SB_FLAG_RO;
843 if (!(jffs2_is_readonly(c))) 864 if (!(jffs2_is_readonly(c)))
844 return -EROFS; 865 return -EROFS;
845 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 866 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
867 return err;
846 ofs += PAD(je32_to_cpu(node->totlen)); 868 ofs += PAD(je32_to_cpu(node->totlen));
847 break; 869 break;
848 870
@@ -852,7 +874,8 @@ scan_more:
852 874
853 case JFFS2_FEATURE_RWCOMPAT_DELETE: 875 case JFFS2_FEATURE_RWCOMPAT_DELETE:
854 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); 876 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
855 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 877 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
878 return err;
856 ofs += PAD(je32_to_cpu(node->totlen)); 879 ofs += PAD(je32_to_cpu(node->totlen));
857 break; 880 break;
858 881
@@ -930,6 +953,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
930 struct jffs2_raw_node_ref *raw; 953 struct jffs2_raw_node_ref *raw;
931 struct jffs2_inode_cache *ic; 954 struct jffs2_inode_cache *ic;
932 uint32_t ino = je32_to_cpu(ri->ino); 955 uint32_t ino = je32_to_cpu(ri->ino);
956 int err;
933 957
934 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); 958 D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
935 959
@@ -959,7 +983,8 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
959 printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 983 printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
960 ofs, je32_to_cpu(ri->node_crc), crc); 984 ofs, je32_to_cpu(ri->node_crc), crc);
961 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ 985 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
962 DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen))); 986 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen)))))
987 return err;
963 jffs2_free_raw_node_ref(raw); 988 jffs2_free_raw_node_ref(raw);
964 return 0; 989 return 0;
965 } 990 }
@@ -1000,6 +1025,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
1000 struct jffs2_full_dirent *fd; 1025 struct jffs2_full_dirent *fd;
1001 struct jffs2_inode_cache *ic; 1026 struct jffs2_inode_cache *ic;
1002 uint32_t crc; 1027 uint32_t crc;
1028 int err;
1003 1029
1004 D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs)); 1030 D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs));
1005 1031
@@ -1011,7 +1037,8 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
1011 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", 1037 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
1012 ofs, je32_to_cpu(rd->node_crc), crc); 1038 ofs, je32_to_cpu(rd->node_crc), crc);
1013 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ 1039 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
1014 DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); 1040 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rd->totlen)))))
1041 return err;
1015 return 0; 1042 return 0;
1016 } 1043 }
1017 1044
@@ -1032,7 +1059,8 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
1032 jffs2_free_full_dirent(fd); 1059 jffs2_free_full_dirent(fd);
1033 /* FIXME: Why do we believe totlen? */ 1060 /* FIXME: Why do we believe totlen? */
1034 /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */ 1061 /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
1035 DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); 1062 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rd->totlen)))))
1063 return err;
1036 return 0; 1064 return 0;
1037 } 1065 }
1038 raw = jffs2_alloc_raw_node_ref(); 1066 raw = jffs2_alloc_raw_node_ref();