Update make-the-bitmap-read-routines-return-real-errors-code to not
[ext4-patch-queue.git] / call-out-crc-and-corruption-errors
blobba63283f9e91449af93c802d4f6993ae55e12488
1 ext4: call out CRC and corruption errors with specific error codes
3 From: "Darrick J. Wong" <darrick.wong@oracle.com>
5 Instead of overloading EIO for CRC errors and corrupt structures,
6 return the same error codes that XFS returns for the same issues.
8 Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  fs/ext4/balloc.c         |    2 +
12  fs/ext4/block_validity.c |    2 +
13  fs/ext4/dir.c            |    4 +-
14  fs/ext4/ext4.h           |    3 ++
15  fs/ext4/extents.c        |   75 +++++++++++++++++++++++-----------------------
16  fs/ext4/ialloc.c         |    1 +
17  fs/ext4/indirect.c       |    2 +
18  fs/ext4/inode.c          |   16 +++++-----
19  fs/ext4/mmp.c            |    8 +++--
20  fs/ext4/namei.c          |   28 +++++++++--------
21  fs/ext4/super.c          |   10 ++++++
22  fs/ext4/symlink.c        |    2 +
23  fs/ext4/xattr.c          |   28 +++++++++--------
24  fs/jbd2/journal.c        |    3 +-
25  fs/jbd2/recovery.c       |    8 ++---
26  include/linux/jbd2.h     |    3 ++
27  16 files changed, 107 insertions(+), 88 deletions(-)
30 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
31 index cd6ea29..f831e10 100644
32 --- a/fs/ext4/balloc.c
33 +++ b/fs/ext4/balloc.c
34 @@ -203,7 +203,7 @@ static int ext4_init_block_bitmap(struct super_block *sb,
35                                            count);
36                 }
37                 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
38 -               return -EIO;
39 +               return -EFSBADCRC;
40         }
41         memset(bh->b_data, 0, sb->s_blocksize);
43 diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
44 index 3522340..02ddec6 100644
45 --- a/fs/ext4/block_validity.c
46 +++ b/fs/ext4/block_validity.c
47 @@ -234,7 +234,7 @@ int ext4_check_blockref(const char *function, unsigned int line,
48                         es->s_last_error_block = cpu_to_le64(blk);
49                         ext4_error_inode(inode, function, line, blk,
50                                          "invalid block");
51 -                       return -EIO;
52 +                       return -EFSCORRUPTED;
53                 }
54         }
55         return 0;
56 diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
57 index f9e1491..b29cb70 100644
58 --- a/fs/ext4/dir.c
59 +++ b/fs/ext4/dir.c
60 @@ -621,14 +621,14 @@ int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf,
61         while ((char *) de < top) {
62                 if (ext4_check_dir_entry(dir, NULL, de, bh,
63                                          buf, buf_size, offset))
64 -                       return -EIO;
65 +                       return -EFSCORRUPTED;
66                 nlen = EXT4_DIR_REC_LEN(de->name_len);
67                 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
68                 de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
69                 offset += rlen;
70         }
71         if ((char *) de > top)
72 -               return -EIO;
73 +               return -EFSCORRUPTED;
75         return 0;
76  }
77 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
78 index 81ce8ae..285b39f 100644
79 --- a/fs/ext4/ext4.h
80 +++ b/fs/ext4/ext4.h
81 @@ -3051,4 +3051,7 @@ extern void ext4_resize_end(struct super_block *sb);
83  #endif /* __KERNEL__ */
85 +#define EFSBADCRC      EBADMSG         /* Bad CRC detected */
86 +#define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
88  #endif /* _EXT4_H */
89 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
90 index 2553aa8..4b6acacc 100644
91 --- a/fs/ext4/extents.c
92 +++ b/fs/ext4/extents.c
93 @@ -442,7 +442,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
94                             int depth, ext4_fsblk_t pblk)
95  {
96         const char *error_msg;
97 -       int max = 0;
98 +       int max = 0, err = -EFSCORRUPTED;
100         if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) {
101                 error_msg = "invalid magic";
102 @@ -473,6 +473,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
103         if (ext_depth(inode) != depth &&
104             !ext4_extent_block_csum_verify(inode, eh)) {
105                 error_msg = "extent tree corrupted";
106 +               err = -EFSBADCRC;
107                 goto corrupted;
108         }
109         return 0;
110 @@ -485,7 +486,7 @@ corrupted:
111                          le16_to_cpu(eh->eh_magic),
112                          le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max),
113                          max, le16_to_cpu(eh->eh_depth), depth);
114 -       return -EIO;
115 +       return err;
118  #define ext4_ext_check(inode, eh, depth, pblk)                 \
119 @@ -910,7 +911,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
120                         put_bh(bh);
121                         EXT4_ERROR_INODE(inode,
122                                          "ppos %d > depth %d", ppos, depth);
123 -                       ret = -EIO;
124 +                       ret = -EFSCORRUPTED;
125                         goto err;
126                 }
127                 path[ppos].p_bh = bh;
128 @@ -959,7 +960,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
129                 EXT4_ERROR_INODE(inode,
130                                  "logical %d == ei_block %d!",
131                                  logical, le32_to_cpu(curp->p_idx->ei_block));
132 -               return -EIO;
133 +               return -EFSCORRUPTED;
134         }
136         if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
137 @@ -968,7 +969,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
138                                  "eh_entries %d >= eh_max %d!",
139                                  le16_to_cpu(curp->p_hdr->eh_entries),
140                                  le16_to_cpu(curp->p_hdr->eh_max));
141 -               return -EIO;
142 +               return -EFSCORRUPTED;
143         }
145         if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
146 @@ -992,7 +993,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
148         if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
149                 EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
150 -               return -EIO;
151 +               return -EFSCORRUPTED;
152         }
154         ix->ei_block = cpu_to_le32(logical);
155 @@ -1001,7 +1002,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
157         if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) {
158                 EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!");
159 -               return -EIO;
160 +               return -EFSCORRUPTED;
161         }
163         err = ext4_ext_dirty(handle, inode, curp);
164 @@ -1042,7 +1043,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
165          * border from split point */
166         if (unlikely(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr))) {
167                 EXT4_ERROR_INODE(inode, "p_ext > EXT_MAX_EXTENT!");
168 -               return -EIO;
169 +               return -EFSCORRUPTED;
170         }
171         if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
172                 border = path[depth].p_ext[1].ee_block;
173 @@ -1086,7 +1087,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
174         newblock = ablocks[--a];
175         if (unlikely(newblock == 0)) {
176                 EXT4_ERROR_INODE(inode, "newblock == 0!");
177 -               err = -EIO;
178 +               err = -EFSCORRUPTED;
179                 goto cleanup;
180         }
181         bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
182 @@ -1112,7 +1113,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
183                 EXT4_ERROR_INODE(inode, "eh_entries %d != eh_max %d!",
184                                  path[depth].p_hdr->eh_entries,
185                                  path[depth].p_hdr->eh_max);
186 -               err = -EIO;
187 +               err = -EFSCORRUPTED;
188                 goto cleanup;
189         }
190         /* start copy from next extent */
191 @@ -1151,7 +1152,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
192         k = depth - at - 1;
193         if (unlikely(k < 0)) {
194                 EXT4_ERROR_INODE(inode, "k %d < 0!", k);
195 -               err = -EIO;
196 +               err = -EFSCORRUPTED;
197                 goto cleanup;
198         }
199         if (k)
200 @@ -1191,7 +1192,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
201                         EXT4_ERROR_INODE(inode,
202                                          "EXT_MAX_INDEX != EXT_LAST_INDEX ee_block %d!",
203                                          le32_to_cpu(path[i].p_ext->ee_block));
204 -                       err = -EIO;
205 +                       err = -EFSCORRUPTED;
206                         goto cleanup;
207                 }
208                 /* start copy indexes */
209 @@ -1425,7 +1426,7 @@ static int ext4_ext_search_left(struct inode *inode,
211         if (unlikely(path == NULL)) {
212                 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
213 -               return -EIO;
214 +               return -EFSCORRUPTED;
215         }
216         depth = path->p_depth;
217         *phys = 0;
218 @@ -1444,7 +1445,7 @@ static int ext4_ext_search_left(struct inode *inode,
219                         EXT4_ERROR_INODE(inode,
220                                          "EXT_FIRST_EXTENT != ex *logical %d ee_block %d!",
221                                          *logical, le32_to_cpu(ex->ee_block));
222 -                       return -EIO;
223 +                       return -EFSCORRUPTED;
224                 }
225                 while (--depth >= 0) {
226                         ix = path[depth].p_idx;
227 @@ -1455,7 +1456,7 @@ static int ext4_ext_search_left(struct inode *inode,
228                                   EXT_FIRST_INDEX(path[depth].p_hdr) != NULL ?
229                 le32_to_cpu(EXT_FIRST_INDEX(path[depth].p_hdr)->ei_block) : 0,
230                                   depth);
231 -                               return -EIO;
232 +                               return -EFSCORRUPTED;
233                         }
234                 }
235                 return 0;
236 @@ -1465,7 +1466,7 @@ static int ext4_ext_search_left(struct inode *inode,
237                 EXT4_ERROR_INODE(inode,
238                                  "logical %d < ee_block %d + ee_len %d!",
239                                  *logical, le32_to_cpu(ex->ee_block), ee_len);
240 -               return -EIO;
241 +               return -EFSCORRUPTED;
242         }
244         *logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
245 @@ -1495,7 +1496,7 @@ static int ext4_ext_search_right(struct inode *inode,
247         if (unlikely(path == NULL)) {
248                 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
249 -               return -EIO;
250 +               return -EFSCORRUPTED;
251         }
252         depth = path->p_depth;
253         *phys = 0;
254 @@ -1514,7 +1515,7 @@ static int ext4_ext_search_right(struct inode *inode,
255                         EXT4_ERROR_INODE(inode,
256                                          "first_extent(path[%d].p_hdr) != ex",
257                                          depth);
258 -                       return -EIO;
259 +                       return -EFSCORRUPTED;
260                 }
261                 while (--depth >= 0) {
262                         ix = path[depth].p_idx;
263 @@ -1522,7 +1523,7 @@ static int ext4_ext_search_right(struct inode *inode,
264                                 EXT4_ERROR_INODE(inode,
265                                                  "ix != EXT_FIRST_INDEX *logical %d!",
266                                                  *logical);
267 -                               return -EIO;
268 +                               return -EFSCORRUPTED;
269                         }
270                 }
271                 goto found_extent;
272 @@ -1532,7 +1533,7 @@ static int ext4_ext_search_right(struct inode *inode,
273                 EXT4_ERROR_INODE(inode,
274                                  "logical %d < ee_block %d + ee_len %d!",
275                                  *logical, le32_to_cpu(ex->ee_block), ee_len);
276 -               return -EIO;
277 +               return -EFSCORRUPTED;
278         }
280         if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
281 @@ -1670,7 +1671,7 @@ static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
282         if (unlikely(ex == NULL || eh == NULL)) {
283                 EXT4_ERROR_INODE(inode,
284                                  "ex %p == NULL or eh %p == NULL", ex, eh);
285 -               return -EIO;
286 +               return -EFSCORRUPTED;
287         }
289         if (depth == 0) {
290 @@ -1938,14 +1939,14 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
291                 mb_flags |= EXT4_MB_DELALLOC_RESERVED;
292         if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
293                 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
294 -               return -EIO;
295 +               return -EFSCORRUPTED;
296         }
297         depth = ext_depth(inode);
298         ex = path[depth].p_ext;
299         eh = path[depth].p_hdr;
300         if (unlikely(path[depth].p_hdr == NULL)) {
301                 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
302 -               return -EIO;
303 +               return -EFSCORRUPTED;
304         }
306         /* try to insert block into found extent and return */
307 @@ -2172,7 +2173,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
308                 if (unlikely(path[depth].p_hdr == NULL)) {
309                         up_read(&EXT4_I(inode)->i_data_sem);
310                         EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
311 -                       err = -EIO;
312 +                       err = -EFSCORRUPTED;
313                         break;
314                 }
315                 ex = path[depth].p_ext;
316 @@ -2241,7 +2242,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
318                 if (unlikely(es.es_len == 0)) {
319                         EXT4_ERROR_INODE(inode, "es.es_len == 0");
320 -                       err = -EIO;
321 +                       err = -EFSCORRUPTED;
322                         break;
323                 }
325 @@ -2264,7 +2265,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
326                                                  "next extent == %u, next "
327                                                  "delalloc extent = %u",
328                                                  next, next_del);
329 -                               err = -EIO;
330 +                               err = -EFSCORRUPTED;
331                                 break;
332                         }
333                 }
334 @@ -2363,7 +2364,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
335         leaf = ext4_idx_pblock(path->p_idx);
336         if (unlikely(path->p_hdr->eh_entries == 0)) {
337                 EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
338 -               return -EIO;
339 +               return -EFSCORRUPTED;
340         }
341         err = ext4_ext_get_access(handle, inode, path);
342         if (err)
343 @@ -2612,7 +2613,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
344         eh = path[depth].p_hdr;
345         if (unlikely(path[depth].p_hdr == NULL)) {
346                 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
347 -               return -EIO;
348 +               return -EFSCORRUPTED;
349         }
350         /* find where to start removing */
351         ex = path[depth].p_ext;
352 @@ -2666,7 +2667,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
353                                          "on extent %u:%u",
354                                          start, end, ex_ee_block,
355                                          ex_ee_block + ex_ee_len - 1);
356 -                       err = -EIO;
357 +                       err = -EFSCORRUPTED;
358                         goto out;
359                 } else if (a != ex_ee_block) {
360                         /* remove tail of the extent */
361 @@ -2841,7 +2842,7 @@ again:
362                                 EXT4_ERROR_INODE(inode,
363                                                  "path[%d].p_hdr == NULL",
364                                                  depth);
365 -                               err = -EIO;
366 +                               err = -EFSCORRUPTED;
367                         }
368                         goto out;
369                 }
370 @@ -2920,7 +2921,7 @@ again:
371                 i = 0;
373                 if (ext4_ext_check(inode, path[0].p_hdr, depth, 0)) {
374 -                       err = -EIO;
375 +                       err = -EFSCORRUPTED;
376                         goto out;
377                 }
378         }
379 @@ -2978,7 +2979,7 @@ again:
380                          * Should be a no-op if we did IO above. */
381                         cond_resched();
382                         if (WARN_ON(i + 1 > depth)) {
383 -                               err = -EIO;
384 +                               err = -EFSCORRUPTED;
385                                 break;
386                         }
387                         path[i + 1].p_bh = bh;
388 @@ -3345,7 +3346,7 @@ static int ext4_split_extent(handle_t *handle,
389         if (!ex) {
390                 EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
391                                  (unsigned long) map->m_lblk);
392 -               return -EIO;
393 +               return -EFSCORRUPTED;
394         }
395         unwritten = ext4_ext_is_unwritten(ex);
396         split_flag1 = 0;
397 @@ -3970,7 +3971,7 @@ convert_initialized_extent(handle_t *handle, struct inode *inode,
398                 if (!ex) {
399                         EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
400                                          (unsigned long) map->m_lblk);
401 -                       return -EIO;
402 +                       return -EFSCORRUPTED;
403                 }
404         }
406 @@ -4308,7 +4309,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
407                                  "lblock: %lu, depth: %d pblock %lld",
408                                  (unsigned long) map->m_lblk, depth,
409                                  path[depth].p_block);
410 -               err = -EIO;
411 +               err = -EFSCORRUPTED;
412                 goto out2;
413         }
415 @@ -5271,7 +5272,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
416                 if (depth == path->p_depth) {
417                         ex_start = path[depth].p_ext;
418                         if (!ex_start)
419 -                               return -EIO;
420 +                               return -EFSCORRUPTED;
422                         ex_last = EXT_LAST_EXTENT(path[depth].p_hdr);
424 @@ -5411,7 +5412,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
425                 if (!extent) {
426                         EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
427                                          (unsigned long) *iterator);
428 -                       return -EIO;
429 +                       return -EFSCORRUPTED;
430                 }
431                 if (SHIFT == SHIFT_LEFT && *iterator >
432                     le32_to_cpu(extent->ee_block)) {
433 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
434 index 619bfc1..f34b1aa 100644
435 --- a/fs/ext4/ialloc.c
436 +++ b/fs/ext4/ialloc.c
437 @@ -1116,6 +1116,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
438         /* Error cases - e2fsck has already cleaned up for us */
439         if (ino > max_ino) {
440                 ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
441 +               err = -EFSCORRUPTED;
442                 goto error;
443         }
445 diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
446 index 2468261..d96ea53 100644
447 --- a/fs/ext4/indirect.c
448 +++ b/fs/ext4/indirect.c
449 @@ -566,7 +566,7 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
450                                        EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
451                 EXT4_ERROR_INODE(inode, "Can't allocate blocks for "
452                                  "non-extent mapped inodes with bigalloc");
453 -               return -EUCLEAN;
454 +               return -EFSCORRUPTED;
455         }
457         /* Set up for the direct block allocation */
458 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
459 index 612fbcf..6facf71 100644
460 --- a/fs/ext4/inode.c
461 +++ b/fs/ext4/inode.c
462 @@ -378,7 +378,7 @@ static int __check_block_validity(struct inode *inode, const char *func,
463                                  "lblock %lu mapped to illegal pblock "
464                                  "(length %d)", (unsigned long) map->m_lblk,
465                                  map->m_len);
466 -               return -EIO;
467 +               return -EFSCORRUPTED;
468         }
469         return 0;
471 @@ -480,7 +480,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
473         /* We can handle the block number less than EXT_MAX_BLOCKS */
474         if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS))
475 -               return -EIO;
476 +               return -EFSCORRUPTED;
478         /* Lookup extent status tree firstly */
479         if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
480 @@ -3820,7 +3820,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
482         iloc->bh = NULL;
483         if (!ext4_valid_inum(sb, inode->i_ino))
484 -               return -EIO;
485 +               return -EFSCORRUPTED;
487         iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
488         gdp = ext4_get_group_desc(sb, iloc->block_group, NULL);
489 @@ -4068,7 +4068,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
490                         EXT4_ERROR_INODE(inode, "bad extra_isize (%u != %u)",
491                                 EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize,
492                                 EXT4_INODE_SIZE(inode->i_sb));
493 -                       ret = -EIO;
494 +                       ret = -EFSCORRUPTED;
495                         goto bad_inode;
496                 }
497         } else
498 @@ -4088,7 +4088,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
500         if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
501                 EXT4_ERROR_INODE(inode, "checksum invalid");
502 -               ret = -EIO;
503 +               ret = -EFSBADCRC;
504                 goto bad_inode;
505         }
507 @@ -4203,7 +4203,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
508             !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
509                 EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
510                                  ei->i_file_acl);
511 -               ret = -EIO;
512 +               ret = -EFSCORRUPTED;
513                 goto bad_inode;
514         } else if (!ext4_has_inline_data(inode)) {
515                 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
516 @@ -4254,7 +4254,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
517         } else if (ino == EXT4_BOOT_LOADER_INO) {
518                 make_bad_inode(inode);
519         } else {
520 -               ret = -EIO;
521 +               ret = -EFSCORRUPTED;
522                 EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
523                 goto bad_inode;
524         }
525 @@ -4272,7 +4272,7 @@ bad_inode:
526  struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
528         if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
529 -               return ERR_PTR(-EIO);
530 +               return ERR_PTR(-EFSCORRUPTED);
531         return ext4_iget(sb, ino);
534 diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
535 index 6eb1a61..0a512aa 100644
536 --- a/fs/ext4/mmp.c
537 +++ b/fs/ext4/mmp.c
538 @@ -98,10 +98,12 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh,
539         }
541         mmp = (struct mmp_struct *)((*bh)->b_data);
542 -       if (le32_to_cpu(mmp->mmp_magic) == EXT4_MMP_MAGIC &&
543 -           ext4_mmp_csum_verify(sb, mmp))
544 +       if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC)
545 +               ret = -EFSCORRUPTED;
546 +       else if (!ext4_mmp_csum_verify(sb, mmp))
547 +               ret = -EFSBADCRC;
548 +       else
549                 return 0;
550 -       ret = -EINVAL;
552  warn_exit:
553         ext4_warning(sb, "Error %d while reading MMP block %llu",
554 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
555 index 9f61e76..8fd8e0d 100644
556 --- a/fs/ext4/namei.c
557 +++ b/fs/ext4/namei.c
558 @@ -109,7 +109,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
559         if (!bh) {
560                 ext4_error_inode(inode, func, line, block,
561                                  "Directory hole found");
562 -               return ERR_PTR(-EIO);
563 +               return ERR_PTR(-EFSCORRUPTED);
564         }
565         dirent = (struct ext4_dir_entry *) bh->b_data;
566         /* Determine whether or not we have an index block */
567 @@ -124,7 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
568         if (!is_dx_block && type == INDEX) {
569                 ext4_error_inode(inode, func, line, block,
570                        "directory leaf block found instead of index block");
571 -               return ERR_PTR(-EIO);
572 +               return ERR_PTR(-EFSCORRUPTED);
573         }
574         if (!ext4_has_metadata_csum(inode->i_sb) ||
575             buffer_verified(bh))
576 @@ -142,7 +142,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
577                         ext4_error_inode(inode, func, line, block,
578                                          "Directory index failed checksum");
579                         brelse(bh);
580 -                       return ERR_PTR(-EIO);
581 +                       return ERR_PTR(-EFSBADCRC);
582                 }
583         }
584         if (!is_dx_block) {
585 @@ -152,7 +152,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
586                         ext4_error_inode(inode, func, line, block,
587                                          "Directory block failed checksum");
588                         brelse(bh);
589 -                       return ERR_PTR(-EIO);
590 +                       return ERR_PTR(-EFSBADCRC);
591                 }
592         }
593         return bh;
594 @@ -1570,19 +1570,19 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
595                 brelse(bh);
596                 if (!ext4_valid_inum(dir->i_sb, ino)) {
597                         EXT4_ERROR_INODE(dir, "bad inode number: %u", ino);
598 -                       return ERR_PTR(-EIO);
599 +                       return ERR_PTR(-EFSCORRUPTED);
600                 }
601                 if (unlikely(ino == dir->i_ino)) {
602                         EXT4_ERROR_INODE(dir, "'%pd' linked to parent dir",
603                                          dentry);
604 -                       return ERR_PTR(-EIO);
605 +                       return ERR_PTR(-EFSCORRUPTED);
606                 }
607                 inode = ext4_iget_normal(dir->i_sb, ino);
608                 if (inode == ERR_PTR(-ESTALE)) {
609                         EXT4_ERROR_INODE(dir,
610                                          "deleted inode referenced: %u",
611                                          ino);
612 -                       return ERR_PTR(-EIO);
613 +                       return ERR_PTR(-EFSCORRUPTED);
614                 }
615                 if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
616                     (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
617 @@ -1619,7 +1619,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
618         if (!ext4_valid_inum(d_inode(child)->i_sb, ino)) {
619                 EXT4_ERROR_INODE(d_inode(child),
620                                  "bad parent inode number: %u", ino);
621 -               return ERR_PTR(-EIO);
622 +               return ERR_PTR(-EFSCORRUPTED);
623         }
625         return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino));
626 @@ -1807,7 +1807,7 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
627         while ((char *) de <= top) {
628                 if (ext4_check_dir_entry(dir, NULL, de, bh,
629                                          buf, buf_size, offset)) {
630 -                       res = -EIO;
631 +                       res = -EFSCORRUPTED;
632                         goto return_result;
633                 }
634                 /* Provide crypto context and crypto buffer to ext4 match */
635 @@ -1967,7 +1967,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
636         if ((char *) de >= (((char *) root) + blocksize)) {
637                 EXT4_ERROR_INODE(dir, "invalid rec_len for '..'");
638                 brelse(bh);
639 -               return -EIO;
640 +               return -EFSCORRUPTED;
641         }
642         len = ((char *) root) + (blocksize - csum_size) - (char *) de;
644 @@ -2315,7 +2315,7 @@ int ext4_generic_delete_entry(handle_t *handle,
645         while (i < buf_size - csum_size) {
646                 if (ext4_check_dir_entry(dir, NULL, de, bh,
647                                          bh->b_data, bh->b_size, i))
648 -                       return -EIO;
649 +                       return -EFSCORRUPTED;
650                 if (de == de_del)  {
651                         if (pde)
652                                 pde->rec_len = ext4_rec_len_to_disk(
653 @@ -2934,7 +2934,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
655         inode = d_inode(dentry);
657 -       retval = -EIO;
658 +       retval = -EFSCORRUPTED;
659         if (le32_to_cpu(de->inode) != inode->i_ino)
660                 goto end_rmdir;
662 @@ -3008,7 +3008,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
664         inode = d_inode(dentry);
666 -       retval = -EIO;
667 +       retval = -EFSCORRUPTED;
668         if (le32_to_cpu(de->inode) != inode->i_ino)
669                 goto end_unlink;
671 @@ -3310,7 +3310,7 @@ static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent)
672         if (!ent->dir_bh)
673                 return retval;
674         if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino)
675 -               return -EIO;
676 +               return -EFSCORRUPTED;
677         BUFFER_TRACE(ent->dir_bh, "get_write_access");
678         return ext4_journal_get_write_access(handle, ent->dir_bh);
680 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
681 index ec9ccb2..99d5efb 100644
682 --- a/fs/ext4/super.c
683 +++ b/fs/ext4/super.c
684 @@ -495,6 +495,12 @@ const char *ext4_decode_error(struct super_block *sb, int errno,
685         char *errstr = NULL;
687         switch (errno) {
688 +       case -EFSCORRUPTED:
689 +               errstr = "Corrupt filesystem";
690 +               break;
691 +       case -EFSBADCRC:
692 +               errstr = "Filesystem failed CRC";
693 +               break;
694         case -EIO:
695                 errstr = "IO failure";
696                 break;
697 @@ -3559,6 +3565,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
698                 ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
699                          "invalid superblock checksum.  Run e2fsck?");
700                 silent = 1;
701 +               ret = -EFSBADCRC;
702                 goto cantfind_ext4;
703         }
705 @@ -3986,6 +3993,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
706         }
707         if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
708                 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
709 +               ret = -EFSCORRUPTED;
710                 goto failed_mount2;
711         }
713 @@ -5050,7 +5058,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
714                "ext4_remount: Checksum for group %u failed (%u!=%u)",
715                 g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
716                                                le16_to_cpu(gdp->bg_checksum));
717 -                                       err = -EINVAL;
718 +                                       err = -EFSBADCRC;
719                                         goto restore_opts;
720                                 }
721                         }
722 diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
723 index c677f2c..abe2401 100644
724 --- a/fs/ext4/symlink.c
725 +++ b/fs/ext4/symlink.c
726 @@ -57,7 +57,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook
727              sizeof(struct ext4_encrypted_symlink_data) - 1) >
728             max_size) {
729                 /* Symlink data on the disk is corrupted */
730 -               res = -EIO;
731 +               res = -EFSCORRUPTED;
732                 goto errout;
733         }
734         plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ?
735 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
736 index 16e28c0..7649422 100644
737 --- a/fs/ext4/xattr.c
738 +++ b/fs/ext4/xattr.c
739 @@ -195,7 +195,7 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end,
740         while (!IS_LAST_ENTRY(e)) {
741                 struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e);
742                 if ((void *)next >= end)
743 -                       return -EIO;
744 +                       return -EFSCORRUPTED;
745                 e = next;
746         }
748 @@ -205,7 +205,7 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end,
749                      (void *)e + sizeof(__u32) ||
750                      value_start + le16_to_cpu(entry->e_value_offs) +
751                     le32_to_cpu(entry->e_value_size) > end))
752 -                       return -EIO;
753 +                       return -EFSCORRUPTED;
754                 entry = EXT4_XATTR_NEXT(entry);
755         }
757 @@ -222,9 +222,9 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
759         if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
760             BHDR(bh)->h_blocks != cpu_to_le32(1))
761 -               return -EIO;
762 +               return -EFSCORRUPTED;
763         if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
764 -               return -EIO;
765 +               return -EFSBADCRC;
766         error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
767                                        bh->b_data);
768         if (!error)
769 @@ -239,7 +239,7 @@ ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
771         if (entry->e_value_block != 0 || value_size > size ||
772             le16_to_cpu(entry->e_value_offs) + value_size > size)
773 -               return -EIO;
774 +               return -EFSCORRUPTED;
775         return 0;
778 @@ -266,7 +266,7 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
779         }
780         *pentry = entry;
781         if (!cmp && ext4_xattr_check_entry(entry, size))
782 -                       return -EIO;
783 +               return -EFSCORRUPTED;
784         return cmp ? -ENODATA : 0;
787 @@ -297,13 +297,13 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
788  bad_block:
789                 EXT4_ERROR_INODE(inode, "bad block %llu",
790                                  EXT4_I(inode)->i_file_acl);
791 -               error = -EIO;
792 +               error = -EFSCORRUPTED;
793                 goto cleanup;
794         }
795         ext4_xattr_cache_insert(ext4_mb_cache, bh);
796         entry = BFIRST(bh);
797         error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
798 -       if (error == -EIO)
799 +       if (error == -EFSCORRUPTED)
800                 goto bad_block;
801         if (error)
802                 goto cleanup;
803 @@ -445,7 +445,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
804         if (ext4_xattr_check_block(inode, bh)) {
805                 EXT4_ERROR_INODE(inode, "bad block %llu",
806                                  EXT4_I(inode)->i_file_acl);
807 -               error = -EIO;
808 +               error = -EFSCORRUPTED;
809                 goto cleanup;
810         }
811         ext4_xattr_cache_insert(ext4_mb_cache, bh);
812 @@ -751,7 +751,7 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
813                 if (ext4_xattr_check_block(inode, bs->bh)) {
814                         EXT4_ERROR_INODE(inode, "bad block %llu",
815                                          EXT4_I(inode)->i_file_acl);
816 -                       error = -EIO;
817 +                       error = -EFSCORRUPTED;
818                         goto cleanup;
819                 }
820                 /* Find the named attribute. */
821 @@ -811,7 +811,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
822                                         bs->bh);
823                         }
824                         unlock_buffer(bs->bh);
825 -                       if (error == -EIO)
826 +                       if (error == -EFSCORRUPTED)
827                                 goto bad_block;
828                         if (!error)
829                                 error = ext4_handle_dirty_xattr_block(handle,
830 @@ -855,7 +855,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
831         }
833         error = ext4_xattr_set_entry(i, s);
834 -       if (error == -EIO)
835 +       if (error == -EFSCORRUPTED)
836                 goto bad_block;
837         if (error)
838                 goto cleanup;
839 @@ -1314,7 +1314,7 @@ retry:
840                 if (ext4_xattr_check_block(inode, bh)) {
841                         EXT4_ERROR_INODE(inode, "bad block %llu",
842                                          EXT4_I(inode)->i_file_acl);
843 -                       error = -EIO;
844 +                       error = -EFSCORRUPTED;
845                         goto cleanup;
846                 }
847                 base = BHDR(bh);
848 @@ -1579,7 +1579,7 @@ ext4_xattr_cmp(struct ext4_xattr_header *header1,
849                     memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
850                         return 1;
851                 if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
852 -                       return -EIO;
853 +                       return -EFSCORRUPTED;
854                 if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
855                            (char *)header2 + le16_to_cpu(entry2->e_value_offs),
856                            le32_to_cpu(entry1->e_value_size)))
857 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
858 index 00f7dbd..474c178 100644
859 --- a/fs/jbd2/journal.c
860 +++ b/fs/jbd2/journal.c
861 @@ -1558,6 +1558,7 @@ static int journal_get_superblock(journal_t *journal)
862         /* Check superblock checksum */
863         if (!jbd2_superblock_csum_verify(journal, sb)) {
864                 printk(KERN_ERR "JBD2: journal checksum error\n");
865 +               err = -EFSBADCRC;
866                 goto out;
867         }
869 @@ -1649,7 +1650,7 @@ int jbd2_journal_load(journal_t *journal)
870                 printk(KERN_ERR "JBD2: journal transaction %u on %s "
871                        "is corrupt.\n", journal->j_failed_commit,
872                        journal->j_devname);
873 -               return -EIO;
874 +               return -EFSCORRUPTED;
875         }
877         /* OK, we've finished with the dynamic journal bits:
878 diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
879 index a9079d0..5c836d7 100644
880 --- a/fs/jbd2/recovery.c
881 +++ b/fs/jbd2/recovery.c
882 @@ -140,7 +140,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
884         if (offset >= journal->j_maxlen) {
885                 printk(KERN_ERR "JBD2: corrupted journal superblock\n");
886 -               return -EIO;
887 +               return -EFSCORRUPTED;
888         }
890         err = jbd2_journal_bmap(journal, offset, &blocknr);
891 @@ -527,7 +527,7 @@ static int do_one_pass(journal_t *journal,
892                                 printk(KERN_ERR "JBD2: Invalid checksum "
893                                        "recovering block %lu in log\n",
894                                        next_log_block);
895 -                               err = -EIO;
896 +                               err = -EFSBADCRC;
897                                 brelse(bh);
898                                 goto failed;
899                         }
900 @@ -602,7 +602,7 @@ static int do_one_pass(journal_t *journal,
901                                                 journal, tag, obh->b_data,
902                                                 be32_to_cpu(tmp->h_sequence))) {
903                                                 brelse(obh);
904 -                                               success = -EIO;
905 +                                               success = -EFSBADCRC;
906                                                 printk(KERN_ERR "JBD2: Invalid "
907                                                        "checksum recovering "
908                                                        "block %llu in log\n",
909 @@ -851,7 +851,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
910         rcount = be32_to_cpu(header->r_count);
912         if (!jbd2_revoke_block_csum_verify(journal, header))
913 -               return -EINVAL;
914 +               return -EFSBADCRC;
916         if (jbd2_journal_has_csum_v2or3(journal))
917                 csum_size = sizeof(struct jbd2_journal_revoke_tail);
918 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
919 index 6da6f89..f2a4b07 100644
920 --- a/include/linux/jbd2.h
921 +++ b/include/linux/jbd2.h
922 @@ -1449,4 +1449,7 @@ static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
924  #endif /* __KERNEL__ */
926 +#define EFSBADCRC      EBADMSG         /* Bad CRC detected */
927 +#define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
929  #endif /* _LINUX_JBD2_H */