diff options
author | Thomas Gleixner <tglx@inhell4.tec.linutronix.de> | 2007-04-05 05:09:01 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-04-17 13:26:18 -0400 |
commit | 53043002ef6cc0369fd5c5fa0a257f290ba6a3a6 (patch) | |
tree | cad0817f06b09b442eb395b4fc201e1deade8f3f /fs/jffs2 | |
parent | 873b6a230652803d1de480f5d3b802e4ffd0bcad (diff) |
[JFFS2] check node crc before doing anything else
Check the node CRC on scan before doing anything else with the node.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/scan.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 7fb45bd4915c..a5103df5242e 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -952,8 +952,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
952 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) | 952 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) |
953 | { | 953 | { |
954 | struct jffs2_inode_cache *ic; | 954 | struct jffs2_inode_cache *ic; |
955 | uint32_t ino = je32_to_cpu(ri->ino); | 955 | uint32_t crc, ino = je32_to_cpu(ri->ino); |
956 | int err; | ||
957 | 956 | ||
958 | D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); | 957 | D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); |
959 | 958 | ||
@@ -966,21 +965,22 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
966 | Which means that the _full_ amount of time to get to proper write mode with GC | 965 | Which means that the _full_ amount of time to get to proper write mode with GC |
967 | operational may actually be _longer_ than before. Sucks to be me. */ | 966 | operational may actually be _longer_ than before. Sucks to be me. */ |
968 | 967 | ||
968 | /* Check the node CRC in any case. */ | ||
969 | crc = crc32(0, ri, sizeof(*ri)-8); | ||
970 | if (crc != je32_to_cpu(ri->node_crc)) { | ||
971 | printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on " | ||
972 | "node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", | ||
973 | ofs, je32_to_cpu(ri->node_crc), crc); | ||
974 | /* | ||
975 | * We believe totlen because the CRC on the node | ||
976 | * _header_ was OK, just the node itself failed. | ||
977 | */ | ||
978 | return jffs2_scan_dirty_space(c, jeb, | ||
979 | PAD(je32_to_cpu(ri->totlen))); | ||
980 | } | ||
981 | |||
969 | ic = jffs2_get_ino_cache(c, ino); | 982 | ic = jffs2_get_ino_cache(c, ino); |
970 | if (!ic) { | 983 | if (!ic) { |
971 | /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the | ||
972 | first node we found for this inode. Do a CRC check to protect against the former | ||
973 | case */ | ||
974 | uint32_t crc = crc32(0, ri, sizeof(*ri)-8); | ||
975 | |||
976 | if (crc != je32_to_cpu(ri->node_crc)) { | ||
977 | printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", | ||
978 | ofs, je32_to_cpu(ri->node_crc), crc); | ||
979 | /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ | ||
980 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen))))) | ||
981 | return err; | ||
982 | return 0; | ||
983 | } | ||
984 | ic = jffs2_scan_make_ino_cache(c, ino); | 984 | ic = jffs2_scan_make_ino_cache(c, ino); |
985 | if (!ic) | 985 | if (!ic) |
986 | return -ENOMEM; | 986 | return -ENOMEM; |