diff options
author | Jean-Christophe DUBOIS <jcd@tribudubois.net> | 2012-05-10 11:13:44 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-05-14 00:30:34 -0400 |
commit | 9824f75d56298e5fe4f9f57d9f3abd5fbf3d472c (patch) | |
tree | 1eda72635e2a5c7a5a997fdd579656db2a0da6e0 /fs/jffs2 | |
parent | 0e618ef0a6a33cf7ef96c2c824402088dd8ef48c (diff) |
jffs2: allow to discriminate between recoverable and non-recoverable errors
This patch is basically a revert of commit f326966b3df47f4fa7e90425f60efdd30c31fe19.
It allows JFFS2 to make the distinction between a potential transient
error (reading or writing the media) and a non recoverable error like a
bad CRC on the extended attribute data or some insconsitent parameters.
In order to make clear that the error is indeed intended to report a
corrupted attribute, a new local error code (JFFS2_XATTR_IS_CORRUPTED)
is introduced rather than returning a confusing positive EIO, which is
what led to the inappropriate "fix" last time.
This error code is never reported to user space and only checked locally
in this file.
Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/xattr.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index b55b803eddcb..c18c0ab70ea4 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -11,6 +11,8 @@ | |||
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
13 | 13 | ||
14 | #define JFFS2_XATTR_IS_CORRUPTED 1 | ||
15 | |||
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
16 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
@@ -153,7 +155,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat | |||
153 | JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | 155 | JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", |
154 | offset, je32_to_cpu(rx.hdr_crc), crc); | 156 | offset, je32_to_cpu(rx.hdr_crc), crc); |
155 | xd->flags |= JFFS2_XFLAGS_INVALID; | 157 | xd->flags |= JFFS2_XFLAGS_INVALID; |
156 | return -EIO; | 158 | return JFFS2_XATTR_IS_CORRUPTED; |
157 | } | 159 | } |
158 | totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); | 160 | totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); |
159 | if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK | 161 | if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK |
@@ -169,7 +171,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat | |||
169 | je32_to_cpu(rx.xid), xd->xid, | 171 | je32_to_cpu(rx.xid), xd->xid, |
170 | je32_to_cpu(rx.version), xd->version); | 172 | je32_to_cpu(rx.version), xd->version); |
171 | xd->flags |= JFFS2_XFLAGS_INVALID; | 173 | xd->flags |= JFFS2_XFLAGS_INVALID; |
172 | return -EIO; | 174 | return JFFS2_XATTR_IS_CORRUPTED; |
173 | } | 175 | } |
174 | xd->xprefix = rx.xprefix; | 176 | xd->xprefix = rx.xprefix; |
175 | xd->name_len = rx.name_len; | 177 | xd->name_len = rx.name_len; |
@@ -227,12 +229,12 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum | |||
227 | data[xd->name_len] = '\0'; | 229 | data[xd->name_len] = '\0'; |
228 | crc = crc32(0, data, length); | 230 | crc = crc32(0, data, length); |
229 | if (crc != xd->data_crc) { | 231 | if (crc != xd->data_crc) { |
230 | JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)" | 232 | JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XATTR)" |
231 | " at %#08x, read: 0x%08x calculated: 0x%08x\n", | 233 | " at %#08x, read: 0x%08x calculated: 0x%08x\n", |
232 | ref_offset(xd->node), xd->data_crc, crc); | 234 | ref_offset(xd->node), xd->data_crc, crc); |
233 | kfree(data); | 235 | kfree(data); |
234 | xd->flags |= JFFS2_XFLAGS_INVALID; | 236 | xd->flags |= JFFS2_XFLAGS_INVALID; |
235 | return -EIO; | 237 | return JFFS2_XATTR_IS_CORRUPTED; |
236 | } | 238 | } |
237 | 239 | ||
238 | xd->flags |= JFFS2_XFLAGS_HOT; | 240 | xd->flags |= JFFS2_XFLAGS_HOT; |
@@ -270,7 +272,7 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x | |||
270 | if (xd->xname) | 272 | if (xd->xname) |
271 | return 0; | 273 | return 0; |
272 | if (xd->flags & JFFS2_XFLAGS_INVALID) | 274 | if (xd->flags & JFFS2_XFLAGS_INVALID) |
273 | return -EIO; | 275 | return JFFS2_XATTR_IS_CORRUPTED; |
274 | if (unlikely(is_xattr_datum_unchecked(c, xd))) | 276 | if (unlikely(is_xattr_datum_unchecked(c, xd))) |
275 | rc = do_verify_xattr_datum(c, xd); | 277 | rc = do_verify_xattr_datum(c, xd); |
276 | if (!rc) | 278 | if (!rc) |
@@ -462,7 +464,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref | |||
462 | if (crc != je32_to_cpu(rr.node_crc)) { | 464 | if (crc != je32_to_cpu(rr.node_crc)) { |
463 | JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | 465 | JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", |
464 | offset, je32_to_cpu(rr.node_crc), crc); | 466 | offset, je32_to_cpu(rr.node_crc), crc); |
465 | return -EIO; | 467 | return JFFS2_XATTR_IS_CORRUPTED; |
466 | } | 468 | } |
467 | if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK | 469 | if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK |
468 | || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF | 470 | || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF |
@@ -472,7 +474,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref | |||
472 | offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, | 474 | offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, |
473 | je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, | 475 | je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, |
474 | je32_to_cpu(rr.totlen), PAD(sizeof(rr))); | 476 | je32_to_cpu(rr.totlen), PAD(sizeof(rr))); |
475 | return -EIO; | 477 | return JFFS2_XATTR_IS_CORRUPTED; |
476 | } | 478 | } |
477 | ref->ino = je32_to_cpu(rr.ino); | 479 | ref->ino = je32_to_cpu(rr.ino); |
478 | ref->xid = je32_to_cpu(rr.xid); | 480 | ref->xid = je32_to_cpu(rr.xid); |