diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-11-21 12:08:16 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-11-21 12:08:16 -0500 |
commit | 92525726df0c30e080b0fce9b0eb699c622d261e (patch) | |
tree | 511f16b19bfce5b460e652b37f2400f52b196da6 | |
parent | 8547e583a1140698cab41bc3f687efe8f8b2bb41 (diff) |
[JFFS2] Fix data CRC checking on NOR flash.
We were failing to check the data CRC on data nodes on non-writebuffered
flash, which led to "interesting" behaviour on unclean shutdowns.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | fs/jffs2/readinode.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 2eae5d2dbebe..da22da954597 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -37,23 +37,24 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
37 | 37 | ||
38 | BUG_ON(tn->csize == 0); | 38 | BUG_ON(tn->csize == 0); |
39 | 39 | ||
40 | if (!jffs2_is_writebuffered(c)) | ||
41 | goto adj_acc; | ||
42 | |||
43 | /* Calculate how many bytes were already checked */ | 40 | /* Calculate how many bytes were already checked */ |
44 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); | 41 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); |
45 | len = ofs % c->wbuf_pagesize; | 42 | len = tn->csize; |
46 | if (likely(len)) | 43 | |
47 | len = c->wbuf_pagesize - len; | 44 | if (jffs2_is_writebuffered(c)) { |
48 | 45 | int adj = ofs % c->wbuf_pagesize; | |
49 | if (len >= tn->csize) { | 46 | if (likely(adj)) |
50 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", | 47 | adj = c->wbuf_pagesize - adj; |
51 | ref_offset(ref), tn->csize, ofs); | 48 | |
52 | goto adj_acc; | 49 | if (adj >= tn->csize) { |
53 | } | 50 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", |
51 | ref_offset(ref), tn->csize, ofs); | ||
52 | goto adj_acc; | ||
53 | } | ||
54 | 54 | ||
55 | ofs += len; | 55 | ofs += adj; |
56 | len = tn->csize - len; | 56 | len -= adj; |
57 | } | ||
57 | 58 | ||
58 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", | 59 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", |
59 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); | 60 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); |