aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-11-21 12:08:16 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-11-21 12:08:16 -0500
commit92525726df0c30e080b0fce9b0eb699c622d261e (patch)
tree511f16b19bfce5b460e652b37f2400f52b196da6
parent8547e583a1140698cab41bc3f687efe8f8b2bb41 (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.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 2eae5d2dbeb..da22da95459 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
BUG_ON(tn->csize == 0);
- if (!jffs2_is_writebuffered(c))
- goto adj_acc;
-
/* Calculate how many bytes were already checked */
ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
- len = ofs % c->wbuf_pagesize;
- if (likely(len))
- len = c->wbuf_pagesize - len;
-
- if (len >= tn->csize) {
- dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
- ref_offset(ref), tn->csize, ofs);
- goto adj_acc;
- }
+ len = tn->csize;
+
+ if (jffs2_is_writebuffered(c)) {
+ int adj = ofs % c->wbuf_pagesize;
+ if (likely(adj))
+ adj = c->wbuf_pagesize - adj;
+
+ if (adj >= tn->csize) {
+ dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
+ ref_offset(ref), tn->csize, ofs);
+ goto adj_acc;
+ }
- ofs += len;
- len = tn->csize - len;
+ ofs += adj;
+ len -= adj;
+ }
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",
ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);