diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-07-03 16:51:19 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-07-03 16:51:19 -0400 |
commit | 14c6381ee46b32b9b38073cd023b618ab4f60629 (patch) | |
tree | afdefe8336a3bc9132cc2d94e91b3fd7108caf06 /fs/jffs2 | |
parent | 8dab169b8bdea3bcbc08b15fdbd9a21526fdbb77 (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.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index b66eb0c4a0c5..170da20b97c7 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 | */ |
217 | static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | 216 | static 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 | */ |
579 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 577 | static 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 | */ |
687 | static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 684 | static 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 | */ |
860 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) | 858 | static 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 | } |