aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-07-03 16:51:19 -0400
committerDavid Woodhouse <dwmw2@bombadil.infradead.org>2007-07-04 10:24:29 -0400
commite2baf4ed168589af8224d51f0ac50e65bcdee3f6 (patch)
tree3cce4ea07535c6b0d204da53d15f91c146d46a70 /fs/jffs2
parentba609a9d97ba231c3d94443c50579ceb5fc33867 (diff)
[JFFS2] Fix readinode failure when read_dnode() detects CRC failure.
We should have stopped returning 1 from read_dnode() to indicate failure. We can just mark the damn thing obsolete immediately. But I missed a case where we don't. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/readinode.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 12e83f67eee4..7b363786c2d2 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -210,8 +210,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *
210 * offset, and the one with the smallest length will come first in the 210 * offset, and the one with the smallest length will come first in the
211 * ordering. 211 * ordering.
212 * 212 *
213 * Returns 0 if the node was inserted 213 * Returns 0 if the node was handled (including marking it obsolete)
214 * 1 if the node is obsolete (because we can't mark it so yet)
215 * < 0 an if error occurred 214 * < 0 an if error occurred
216 */ 215 */
217static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, 216static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
@@ -572,8 +571,7 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r
572 * Helper function for jffs2_get_inode_nodes(). 571 * Helper function for jffs2_get_inode_nodes().
573 * It is called every time an directory entry node is found. 572 * It is called every time an directory entry node is found.
574 * 573 *
575 * Returns: 0 on succes; 574 * Returns: 0 on success;
576 * 1 if the node should be marked obsolete;
577 * negative error code on failure. 575 * negative error code on failure.
578 */ 576 */
579static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 577static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
@@ -680,8 +678,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
680 * Helper function for jffs2_get_inode_nodes(). 678 * Helper function for jffs2_get_inode_nodes().
681 * It is called every time an inode node is found. 679 * It is called every time an inode node is found.
682 * 680 *
683 * Returns: 0 on success; 681 * Returns: 0 on success (possibly after marking a bad node obsolete);
684 * 1 if the node should be marked obsolete;
685 * negative error code on failure. 682 * negative error code on failure.
686 */ 683 */
687static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 684static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
@@ -690,7 +687,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
690{ 687{
691 struct jffs2_tmp_dnode_info *tn; 688 struct jffs2_tmp_dnode_info *tn;
692 uint32_t len, csize; 689 uint32_t len, csize;
693 int ret = 1; 690 int ret = 0;
694 uint32_t crc; 691 uint32_t crc;
695 692
696 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 693 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
@@ -719,8 +716,9 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
719 /* Sanity checks */ 716 /* Sanity checks */
720 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 717 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
721 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 718 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
722 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); 719 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
723 jffs2_dbg_dump_node(c, ref_offset(ref)); 720 jffs2_dbg_dump_node(c, ref_offset(ref));
721 jffs2_mark_node_obsolete(c, ref);
724 goto free_out; 722 goto free_out;
725 } 723 }
726 724
@@ -775,6 +773,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
775 if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { 773 if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) {
776 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 774 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
777 ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); 775 ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc));
776 jffs2_mark_node_obsolete(c, ref);
778 goto free_out; 777 goto free_out;
779 } 778 }
780 779
@@ -854,7 +853,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
854 * It is called every time an unknown node is found. 853 * It is called every time an unknown node is found.
855 * 854 *
856 * Returns: 0 on success; 855 * Returns: 0 on success;
857 * 1 if the node should be marked obsolete;
858 * negative error code on failure. 856 * negative error code on failure.
859 */ 857 */
860static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) 858static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
@@ -1088,10 +1086,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
1088 } 1086 }
1089 1087
1090 err = read_unknown(c, ref, &node->u); 1088 err = read_unknown(c, ref, &node->u);
1091 if (err == 1) { 1089 if (unlikely(err))
1092 jffs2_mark_node_obsolete(c, ref);
1093 break;
1094 } else if (unlikely(err))
1095 goto free_out; 1090 goto free_out;
1096 1091
1097 } 1092 }