Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: call out CRC and corruption errors with specific error codes

Instead of overloading EIO for CRC errors and corrupt structures,
return the same error codes that XFS returns for the same issues.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Darrick J. Wong and committed by
Theodore Ts'o
6a797d27 8c81bd8f

+107 -88
+1 -1
fs/ext4/balloc.c
··· 203 203 count); 204 204 } 205 205 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 206 - return -EIO; 206 + return -EFSBADCRC; 207 207 } 208 208 memset(bh->b_data, 0, sb->s_blocksize); 209 209
+1 -1
fs/ext4/block_validity.c
··· 234 234 es->s_last_error_block = cpu_to_le64(blk); 235 235 ext4_error_inode(inode, function, line, blk, 236 236 "invalid block"); 237 - return -EIO; 237 + return -EFSCORRUPTED; 238 238 } 239 239 } 240 240 return 0;
+2 -2
fs/ext4/dir.c
··· 621 621 while ((char *) de < top) { 622 622 if (ext4_check_dir_entry(dir, NULL, de, bh, 623 623 buf, buf_size, offset)) 624 - return -EIO; 624 + return -EFSCORRUPTED; 625 625 nlen = EXT4_DIR_REC_LEN(de->name_len); 626 626 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); 627 627 de = (struct ext4_dir_entry_2 *)((char *)de + rlen); 628 628 offset += rlen; 629 629 } 630 630 if ((char *) de > top) 631 - return -EIO; 631 + return -EFSCORRUPTED; 632 632 633 633 return 0; 634 634 }
+3
fs/ext4/ext4.h
··· 3064 3064 3065 3065 #endif /* __KERNEL__ */ 3066 3066 3067 + #define EFSBADCRC EBADMSG /* Bad CRC detected */ 3068 + #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ 3069 + 3067 3070 #endif /* _EXT4_H */
+38 -37
fs/ext4/extents.c
··· 442 442 int depth, ext4_fsblk_t pblk) 443 443 { 444 444 const char *error_msg; 445 - int max = 0; 445 + int max = 0, err = -EFSCORRUPTED; 446 446 447 447 if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { 448 448 error_msg = "invalid magic"; ··· 473 473 if (ext_depth(inode) != depth && 474 474 !ext4_extent_block_csum_verify(inode, eh)) { 475 475 error_msg = "extent tree corrupted"; 476 + err = -EFSBADCRC; 476 477 goto corrupted; 477 478 } 478 479 return 0; ··· 486 485 le16_to_cpu(eh->eh_magic), 487 486 le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), 488 487 max, le16_to_cpu(eh->eh_depth), depth); 489 - return -EIO; 488 + return err; 490 489 } 491 490 492 491 #define ext4_ext_check(inode, eh, depth, pblk) \ ··· 911 910 put_bh(bh); 912 911 EXT4_ERROR_INODE(inode, 913 912 "ppos %d > depth %d", ppos, depth); 914 - ret = -EIO; 913 + ret = -EFSCORRUPTED; 915 914 goto err; 916 915 } 917 916 path[ppos].p_bh = bh; ··· 960 959 EXT4_ERROR_INODE(inode, 961 960 "logical %d == ei_block %d!", 962 961 logical, le32_to_cpu(curp->p_idx->ei_block)); 963 - return -EIO; 962 + return -EFSCORRUPTED; 964 963 } 965 964 966 965 if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries) ··· 969 968 "eh_entries %d >= eh_max %d!", 970 969 le16_to_cpu(curp->p_hdr->eh_entries), 971 970 le16_to_cpu(curp->p_hdr->eh_max)); 972 - return -EIO; 971 + return -EFSCORRUPTED; 973 972 } 974 973 975 974 if (logical > le32_to_cpu(curp->p_idx->ei_block)) { ··· 993 992 994 993 if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) { 995 994 EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!"); 996 - return -EIO; 995 + return -EFSCORRUPTED; 997 996 } 998 997 999 998 ix->ei_block = cpu_to_le32(logical); ··· 1002 1001 1003 1002 if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) { 1004 1003 EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!"); 1005 - return -EIO; 1004 + return -EFSCORRUPTED; 1006 1005 } 1007 1006 1008 1007 err = ext4_ext_dirty(handle, inode, curp); ··· 1043 1042 * border from split point */ 1044 1043 if (unlikely(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr))) { 1045 1044 EXT4_ERROR_INODE(inode, "p_ext > EXT_MAX_EXTENT!"); 1046 - return -EIO; 1045 + return -EFSCORRUPTED; 1047 1046 } 1048 1047 if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { 1049 1048 border = path[depth].p_ext[1].ee_block; ··· 1087 1086 newblock = ablocks[--a]; 1088 1087 if (unlikely(newblock == 0)) { 1089 1088 EXT4_ERROR_INODE(inode, "newblock == 0!"); 1090 - err = -EIO; 1089 + err = -EFSCORRUPTED; 1091 1090 goto cleanup; 1092 1091 } 1093 1092 bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS); ··· 1113 1112 EXT4_ERROR_INODE(inode, "eh_entries %d != eh_max %d!", 1114 1113 path[depth].p_hdr->eh_entries, 1115 1114 path[depth].p_hdr->eh_max); 1116 - err = -EIO; 1115 + err = -EFSCORRUPTED; 1117 1116 goto cleanup; 1118 1117 } 1119 1118 /* start copy from next extent */ ··· 1152 1151 k = depth - at - 1; 1153 1152 if (unlikely(k < 0)) { 1154 1153 EXT4_ERROR_INODE(inode, "k %d < 0!", k); 1155 - err = -EIO; 1154 + err = -EFSCORRUPTED; 1156 1155 goto cleanup; 1157 1156 } 1158 1157 if (k) ··· 1192 1191 EXT4_ERROR_INODE(inode, 1193 1192 "EXT_MAX_INDEX != EXT_LAST_INDEX ee_block %d!", 1194 1193 le32_to_cpu(path[i].p_ext->ee_block)); 1195 - err = -EIO; 1194 + err = -EFSCORRUPTED; 1196 1195 goto cleanup; 1197 1196 } 1198 1197 /* start copy indexes */ ··· 1426 1425 1427 1426 if (unlikely(path == NULL)) { 1428 1427 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical); 1429 - return -EIO; 1428 + return -EFSCORRUPTED; 1430 1429 } 1431 1430 depth = path->p_depth; 1432 1431 *phys = 0; ··· 1445 1444 EXT4_ERROR_INODE(inode, 1446 1445 "EXT_FIRST_EXTENT != ex *logical %d ee_block %d!", 1447 1446 *logical, le32_to_cpu(ex->ee_block)); 1448 - return -EIO; 1447 + return -EFSCORRUPTED; 1449 1448 } 1450 1449 while (--depth >= 0) { 1451 1450 ix = path[depth].p_idx; ··· 1456 1455 EXT_FIRST_INDEX(path[depth].p_hdr) != NULL ? 1457 1456 le32_to_cpu(EXT_FIRST_INDEX(path[depth].p_hdr)->ei_block) : 0, 1458 1457 depth); 1459 - return -EIO; 1458 + return -EFSCORRUPTED; 1460 1459 } 1461 1460 } 1462 1461 return 0; ··· 1466 1465 EXT4_ERROR_INODE(inode, 1467 1466 "logical %d < ee_block %d + ee_len %d!", 1468 1467 *logical, le32_to_cpu(ex->ee_block), ee_len); 1469 - return -EIO; 1468 + return -EFSCORRUPTED; 1470 1469 } 1471 1470 1472 1471 *logical = le32_to_cpu(ex->ee_block) + ee_len - 1; ··· 1496 1495 1497 1496 if (unlikely(path == NULL)) { 1498 1497 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical); 1499 - return -EIO; 1498 + return -EFSCORRUPTED; 1500 1499 } 1501 1500 depth = path->p_depth; 1502 1501 *phys = 0; ··· 1515 1514 EXT4_ERROR_INODE(inode, 1516 1515 "first_extent(path[%d].p_hdr) != ex", 1517 1516 depth); 1518 - return -EIO; 1517 + return -EFSCORRUPTED; 1519 1518 } 1520 1519 while (--depth >= 0) { 1521 1520 ix = path[depth].p_idx; ··· 1523 1522 EXT4_ERROR_INODE(inode, 1524 1523 "ix != EXT_FIRST_INDEX *logical %d!", 1525 1524 *logical); 1526 - return -EIO; 1525 + return -EFSCORRUPTED; 1527 1526 } 1528 1527 } 1529 1528 goto found_extent; ··· 1533 1532 EXT4_ERROR_INODE(inode, 1534 1533 "logical %d < ee_block %d + ee_len %d!", 1535 1534 *logical, le32_to_cpu(ex->ee_block), ee_len); 1536 - return -EIO; 1535 + return -EFSCORRUPTED; 1537 1536 } 1538 1537 1539 1538 if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) { ··· 1671 1670 if (unlikely(ex == NULL || eh == NULL)) { 1672 1671 EXT4_ERROR_INODE(inode, 1673 1672 "ex %p == NULL or eh %p == NULL", ex, eh); 1674 - return -EIO; 1673 + return -EFSCORRUPTED; 1675 1674 } 1676 1675 1677 1676 if (depth == 0) { ··· 1939 1938 mb_flags |= EXT4_MB_DELALLOC_RESERVED; 1940 1939 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) { 1941 1940 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0"); 1942 - return -EIO; 1941 + return -EFSCORRUPTED; 1943 1942 } 1944 1943 depth = ext_depth(inode); 1945 1944 ex = path[depth].p_ext; 1946 1945 eh = path[depth].p_hdr; 1947 1946 if (unlikely(path[depth].p_hdr == NULL)) { 1948 1947 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth); 1949 - return -EIO; 1948 + return -EFSCORRUPTED; 1950 1949 } 1951 1950 1952 1951 /* try to insert block into found extent and return */ ··· 2173 2172 if (unlikely(path[depth].p_hdr == NULL)) { 2174 2173 up_read(&EXT4_I(inode)->i_data_sem); 2175 2174 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth); 2176 - err = -EIO; 2175 + err = -EFSCORRUPTED; 2177 2176 break; 2178 2177 } 2179 2178 ex = path[depth].p_ext; ··· 2242 2241 2243 2242 if (unlikely(es.es_len == 0)) { 2244 2243 EXT4_ERROR_INODE(inode, "es.es_len == 0"); 2245 - err = -EIO; 2244 + err = -EFSCORRUPTED; 2246 2245 break; 2247 2246 } 2248 2247 ··· 2265 2264 "next extent == %u, next " 2266 2265 "delalloc extent = %u", 2267 2266 next, next_del); 2268 - err = -EIO; 2267 + err = -EFSCORRUPTED; 2269 2268 break; 2270 2269 } 2271 2270 } ··· 2364 2363 leaf = ext4_idx_pblock(path->p_idx); 2365 2364 if (unlikely(path->p_hdr->eh_entries == 0)) { 2366 2365 EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0"); 2367 - return -EIO; 2366 + return -EFSCORRUPTED; 2368 2367 } 2369 2368 err = ext4_ext_get_access(handle, inode, path); 2370 2369 if (err) ··· 2613 2612 eh = path[depth].p_hdr; 2614 2613 if (unlikely(path[depth].p_hdr == NULL)) { 2615 2614 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth); 2616 - return -EIO; 2615 + return -EFSCORRUPTED; 2617 2616 } 2618 2617 /* find where to start removing */ 2619 2618 ex = path[depth].p_ext; ··· 2667 2666 "on extent %u:%u", 2668 2667 start, end, ex_ee_block, 2669 2668 ex_ee_block + ex_ee_len - 1); 2670 - err = -EIO; 2669 + err = -EFSCORRUPTED; 2671 2670 goto out; 2672 2671 } else if (a != ex_ee_block) { 2673 2672 /* remove tail of the extent */ ··· 2842 2841 EXT4_ERROR_INODE(inode, 2843 2842 "path[%d].p_hdr == NULL", 2844 2843 depth); 2845 - err = -EIO; 2844 + err = -EFSCORRUPTED; 2846 2845 } 2847 2846 goto out; 2848 2847 } ··· 2921 2920 i = 0; 2922 2921 2923 2922 if (ext4_ext_check(inode, path[0].p_hdr, depth, 0)) { 2924 - err = -EIO; 2923 + err = -EFSCORRUPTED; 2925 2924 goto out; 2926 2925 } 2927 2926 } ··· 2979 2978 * Should be a no-op if we did IO above. */ 2980 2979 cond_resched(); 2981 2980 if (WARN_ON(i + 1 > depth)) { 2982 - err = -EIO; 2981 + err = -EFSCORRUPTED; 2983 2982 break; 2984 2983 } 2985 2984 path[i + 1].p_bh = bh; ··· 3346 3345 if (!ex) { 3347 3346 EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 3348 3347 (unsigned long) map->m_lblk); 3349 - return -EIO; 3348 + return -EFSCORRUPTED; 3350 3349 } 3351 3350 unwritten = ext4_ext_is_unwritten(ex); 3352 3351 split_flag1 = 0; ··· 3974 3973 if (!ex) { 3975 3974 EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 3976 3975 (unsigned long) map->m_lblk); 3977 - return -EIO; 3976 + return -EFSCORRUPTED; 3978 3977 } 3979 3978 } 3980 3979 ··· 4312 4311 "lblock: %lu, depth: %d pblock %lld", 4313 4312 (unsigned long) map->m_lblk, depth, 4314 4313 path[depth].p_block); 4315 - err = -EIO; 4314 + err = -EFSCORRUPTED; 4316 4315 goto out2; 4317 4316 } 4318 4317 ··· 5275 5274 if (depth == path->p_depth) { 5276 5275 ex_start = path[depth].p_ext; 5277 5276 if (!ex_start) 5278 - return -EIO; 5277 + return -EFSCORRUPTED; 5279 5278 5280 5279 ex_last = EXT_LAST_EXTENT(path[depth].p_hdr); 5281 5280 ··· 5415 5414 if (!extent) { 5416 5415 EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 5417 5416 (unsigned long) *iterator); 5418 - return -EIO; 5417 + return -EFSCORRUPTED; 5419 5418 } 5420 5419 if (SHIFT == SHIFT_LEFT && *iterator > 5421 5420 le32_to_cpu(extent->ee_block)) {
+1
fs/ext4/ialloc.c
··· 1116 1116 /* Error cases - e2fsck has already cleaned up for us */ 1117 1117 if (ino > max_ino) { 1118 1118 ext4_warning(sb, "bad orphan ino %lu! e2fsck was run?", ino); 1119 + err = -EFSCORRUPTED; 1119 1120 goto error; 1120 1121 } 1121 1122
+1 -1
fs/ext4/indirect.c
··· 566 566 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 567 567 EXT4_ERROR_INODE(inode, "Can't allocate blocks for " 568 568 "non-extent mapped inodes with bigalloc"); 569 - return -EUCLEAN; 569 + return -EFSCORRUPTED; 570 570 } 571 571 572 572 /* Set up for the direct block allocation */
+8 -8
fs/ext4/inode.c
··· 378 378 "lblock %lu mapped to illegal pblock " 379 379 "(length %d)", (unsigned long) map->m_lblk, 380 380 map->m_len); 381 - return -EIO; 381 + return -EFSCORRUPTED; 382 382 } 383 383 return 0; 384 384 } ··· 480 480 481 481 /* We can handle the block number less than EXT_MAX_BLOCKS */ 482 482 if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS)) 483 - return -EIO; 483 + return -EFSCORRUPTED; 484 484 485 485 /* Lookup extent status tree firstly */ 486 486 if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { ··· 3863 3863 3864 3864 iloc->bh = NULL; 3865 3865 if (!ext4_valid_inum(sb, inode->i_ino)) 3866 - return -EIO; 3866 + return -EFSCORRUPTED; 3867 3867 3868 3868 iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb); 3869 3869 gdp = ext4_get_group_desc(sb, iloc->block_group, NULL); ··· 4111 4111 EXT4_ERROR_INODE(inode, "bad extra_isize (%u != %u)", 4112 4112 EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize, 4113 4113 EXT4_INODE_SIZE(inode->i_sb)); 4114 - ret = -EIO; 4114 + ret = -EFSCORRUPTED; 4115 4115 goto bad_inode; 4116 4116 } 4117 4117 } else ··· 4131 4131 4132 4132 if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { 4133 4133 EXT4_ERROR_INODE(inode, "checksum invalid"); 4134 - ret = -EIO; 4134 + ret = -EFSBADCRC; 4135 4135 goto bad_inode; 4136 4136 } 4137 4137 ··· 4246 4246 !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { 4247 4247 EXT4_ERROR_INODE(inode, "bad extended attribute block %llu", 4248 4248 ei->i_file_acl); 4249 - ret = -EIO; 4249 + ret = -EFSCORRUPTED; 4250 4250 goto bad_inode; 4251 4251 } else if (!ext4_has_inline_data(inode)) { 4252 4252 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { ··· 4297 4297 } else if (ino == EXT4_BOOT_LOADER_INO) { 4298 4298 make_bad_inode(inode); 4299 4299 } else { 4300 - ret = -EIO; 4300 + ret = -EFSCORRUPTED; 4301 4301 EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); 4302 4302 goto bad_inode; 4303 4303 } ··· 4315 4315 struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino) 4316 4316 { 4317 4317 if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) 4318 - return ERR_PTR(-EIO); 4318 + return ERR_PTR(-EFSCORRUPTED); 4319 4319 return ext4_iget(sb, ino); 4320 4320 } 4321 4321
+5 -3
fs/ext4/mmp.c
··· 98 98 } 99 99 100 100 mmp = (struct mmp_struct *)((*bh)->b_data); 101 - if (le32_to_cpu(mmp->mmp_magic) == EXT4_MMP_MAGIC && 102 - ext4_mmp_csum_verify(sb, mmp)) 101 + if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) 102 + ret = -EFSCORRUPTED; 103 + else if (!ext4_mmp_csum_verify(sb, mmp)) 104 + ret = -EFSBADCRC; 105 + else 103 106 return 0; 104 - ret = -EINVAL; 105 107 106 108 warn_exit: 107 109 ext4_warning(sb, "Error %d while reading MMP block %llu",
+14 -14
fs/ext4/namei.c
··· 109 109 if (!bh) { 110 110 ext4_error_inode(inode, func, line, block, 111 111 "Directory hole found"); 112 - return ERR_PTR(-EIO); 112 + return ERR_PTR(-EFSCORRUPTED); 113 113 } 114 114 dirent = (struct ext4_dir_entry *) bh->b_data; 115 115 /* Determine whether or not we have an index block */ ··· 124 124 if (!is_dx_block && type == INDEX) { 125 125 ext4_error_inode(inode, func, line, block, 126 126 "directory leaf block found instead of index block"); 127 - return ERR_PTR(-EIO); 127 + return ERR_PTR(-EFSCORRUPTED); 128 128 } 129 129 if (!ext4_has_metadata_csum(inode->i_sb) || 130 130 buffer_verified(bh)) ··· 142 142 ext4_error_inode(inode, func, line, block, 143 143 "Directory index failed checksum"); 144 144 brelse(bh); 145 - return ERR_PTR(-EIO); 145 + return ERR_PTR(-EFSBADCRC); 146 146 } 147 147 } 148 148 if (!is_dx_block) { ··· 152 152 ext4_error_inode(inode, func, line, block, 153 153 "Directory block failed checksum"); 154 154 brelse(bh); 155 - return ERR_PTR(-EIO); 155 + return ERR_PTR(-EFSBADCRC); 156 156 } 157 157 } 158 158 return bh; ··· 1570 1570 brelse(bh); 1571 1571 if (!ext4_valid_inum(dir->i_sb, ino)) { 1572 1572 EXT4_ERROR_INODE(dir, "bad inode number: %u", ino); 1573 - return ERR_PTR(-EIO); 1573 + return ERR_PTR(-EFSCORRUPTED); 1574 1574 } 1575 1575 if (unlikely(ino == dir->i_ino)) { 1576 1576 EXT4_ERROR_INODE(dir, "'%pd' linked to parent dir", 1577 1577 dentry); 1578 - return ERR_PTR(-EIO); 1578 + return ERR_PTR(-EFSCORRUPTED); 1579 1579 } 1580 1580 inode = ext4_iget_normal(dir->i_sb, ino); 1581 1581 if (inode == ERR_PTR(-ESTALE)) { 1582 1582 EXT4_ERROR_INODE(dir, 1583 1583 "deleted inode referenced: %u", 1584 1584 ino); 1585 - return ERR_PTR(-EIO); 1585 + return ERR_PTR(-EFSCORRUPTED); 1586 1586 } 1587 1587 if (!IS_ERR(inode) && ext4_encrypted_inode(dir) && 1588 1588 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || ··· 1619 1619 if (!ext4_valid_inum(d_inode(child)->i_sb, ino)) { 1620 1620 EXT4_ERROR_INODE(d_inode(child), 1621 1621 "bad parent inode number: %u", ino); 1622 - return ERR_PTR(-EIO); 1622 + return ERR_PTR(-EFSCORRUPTED); 1623 1623 } 1624 1624 1625 1625 return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino)); ··· 1807 1807 while ((char *) de <= top) { 1808 1808 if (ext4_check_dir_entry(dir, NULL, de, bh, 1809 1809 buf, buf_size, offset)) { 1810 - res = -EIO; 1810 + res = -EFSCORRUPTED; 1811 1811 goto return_result; 1812 1812 } 1813 1813 /* Provide crypto context and crypto buffer to ext4 match */ ··· 1967 1967 if ((char *) de >= (((char *) root) + blocksize)) { 1968 1968 EXT4_ERROR_INODE(dir, "invalid rec_len for '..'"); 1969 1969 brelse(bh); 1970 - return -EIO; 1970 + return -EFSCORRUPTED; 1971 1971 } 1972 1972 len = ((char *) root) + (blocksize - csum_size) - (char *) de; 1973 1973 ··· 2315 2315 while (i < buf_size - csum_size) { 2316 2316 if (ext4_check_dir_entry(dir, NULL, de, bh, 2317 2317 bh->b_data, bh->b_size, i)) 2318 - return -EIO; 2318 + return -EFSCORRUPTED; 2319 2319 if (de == de_del) { 2320 2320 if (pde) 2321 2321 pde->rec_len = ext4_rec_len_to_disk( ··· 2934 2934 2935 2935 inode = d_inode(dentry); 2936 2936 2937 - retval = -EIO; 2937 + retval = -EFSCORRUPTED; 2938 2938 if (le32_to_cpu(de->inode) != inode->i_ino) 2939 2939 goto end_rmdir; 2940 2940 ··· 3008 3008 3009 3009 inode = d_inode(dentry); 3010 3010 3011 - retval = -EIO; 3011 + retval = -EFSCORRUPTED; 3012 3012 if (le32_to_cpu(de->inode) != inode->i_ino) 3013 3013 goto end_unlink; 3014 3014 ··· 3310 3310 if (!ent->dir_bh) 3311 3311 return retval; 3312 3312 if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino) 3313 - return -EIO; 3313 + return -EFSCORRUPTED; 3314 3314 BUFFER_TRACE(ent->dir_bh, "get_write_access"); 3315 3315 return ext4_journal_get_write_access(handle, ent->dir_bh); 3316 3316 }
+9 -1
fs/ext4/super.c
··· 490 490 char *errstr = NULL; 491 491 492 492 switch (errno) { 493 + case -EFSCORRUPTED: 494 + errstr = "Corrupt filesystem"; 495 + break; 496 + case -EFSBADCRC: 497 + errstr = "Filesystem failed CRC"; 498 + break; 493 499 case -EIO: 494 500 errstr = "IO failure"; 495 501 break; ··· 3198 3192 ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with " 3199 3193 "invalid superblock checksum. Run e2fsck?"); 3200 3194 silent = 1; 3195 + ret = -EFSBADCRC; 3201 3196 goto cantfind_ext4; 3202 3197 } 3203 3198 ··· 3619 3612 } 3620 3613 if (!ext4_check_descriptors(sb, &first_not_zeroed)) { 3621 3614 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); 3615 + ret = -EFSCORRUPTED; 3622 3616 goto failed_mount2; 3623 3617 } 3624 3618 ··· 4672 4664 "ext4_remount: Checksum for group %u failed (%u!=%u)", 4673 4665 g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)), 4674 4666 le16_to_cpu(gdp->bg_checksum)); 4675 - err = -EINVAL; 4667 + err = -EFSBADCRC; 4676 4668 goto restore_opts; 4677 4669 } 4678 4670 }
+1 -1
fs/ext4/symlink.c
··· 57 57 sizeof(struct ext4_encrypted_symlink_data) - 1) > 58 58 max_size) { 59 59 /* Symlink data on the disk is corrupted */ 60 - res = -EIO; 60 + res = -EFSCORRUPTED; 61 61 goto errout; 62 62 } 63 63 plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ?
+14 -14
fs/ext4/xattr.c
··· 195 195 while (!IS_LAST_ENTRY(e)) { 196 196 struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); 197 197 if ((void *)next >= end) 198 - return -EIO; 198 + return -EFSCORRUPTED; 199 199 e = next; 200 200 } 201 201 ··· 205 205 (void *)e + sizeof(__u32) || 206 206 value_start + le16_to_cpu(entry->e_value_offs) + 207 207 le32_to_cpu(entry->e_value_size) > end)) 208 - return -EIO; 208 + return -EFSCORRUPTED; 209 209 entry = EXT4_XATTR_NEXT(entry); 210 210 } 211 211 ··· 222 222 223 223 if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || 224 224 BHDR(bh)->h_blocks != cpu_to_le32(1)) 225 - return -EIO; 225 + return -EFSCORRUPTED; 226 226 if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh))) 227 - return -EIO; 227 + return -EFSBADCRC; 228 228 error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size, 229 229 bh->b_data); 230 230 if (!error) ··· 239 239 240 240 if (entry->e_value_block != 0 || value_size > size || 241 241 le16_to_cpu(entry->e_value_offs) + value_size > size) 242 - return -EIO; 242 + return -EFSCORRUPTED; 243 243 return 0; 244 244 } 245 245 ··· 266 266 } 267 267 *pentry = entry; 268 268 if (!cmp && ext4_xattr_check_entry(entry, size)) 269 - return -EIO; 269 + return -EFSCORRUPTED; 270 270 return cmp ? -ENODATA : 0; 271 271 } 272 272 ··· 297 297 bad_block: 298 298 EXT4_ERROR_INODE(inode, "bad block %llu", 299 299 EXT4_I(inode)->i_file_acl); 300 - error = -EIO; 300 + error = -EFSCORRUPTED; 301 301 goto cleanup; 302 302 } 303 303 ext4_xattr_cache_insert(ext4_mb_cache, bh); 304 304 entry = BFIRST(bh); 305 305 error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1); 306 - if (error == -EIO) 306 + if (error == -EFSCORRUPTED) 307 307 goto bad_block; 308 308 if (error) 309 309 goto cleanup; ··· 445 445 if (ext4_xattr_check_block(inode, bh)) { 446 446 EXT4_ERROR_INODE(inode, "bad block %llu", 447 447 EXT4_I(inode)->i_file_acl); 448 - error = -EIO; 448 + error = -EFSCORRUPTED; 449 449 goto cleanup; 450 450 } 451 451 ext4_xattr_cache_insert(ext4_mb_cache, bh); ··· 751 751 if (ext4_xattr_check_block(inode, bs->bh)) { 752 752 EXT4_ERROR_INODE(inode, "bad block %llu", 753 753 EXT4_I(inode)->i_file_acl); 754 - error = -EIO; 754 + error = -EFSCORRUPTED; 755 755 goto cleanup; 756 756 } 757 757 /* Find the named attribute. */ ··· 811 811 bs->bh); 812 812 } 813 813 unlock_buffer(bs->bh); 814 - if (error == -EIO) 814 + if (error == -EFSCORRUPTED) 815 815 goto bad_block; 816 816 if (!error) 817 817 error = ext4_handle_dirty_xattr_block(handle, ··· 855 855 } 856 856 857 857 error = ext4_xattr_set_entry(i, s); 858 - if (error == -EIO) 858 + if (error == -EFSCORRUPTED) 859 859 goto bad_block; 860 860 if (error) 861 861 goto cleanup; ··· 1314 1314 if (ext4_xattr_check_block(inode, bh)) { 1315 1315 EXT4_ERROR_INODE(inode, "bad block %llu", 1316 1316 EXT4_I(inode)->i_file_acl); 1317 - error = -EIO; 1317 + error = -EFSCORRUPTED; 1318 1318 goto cleanup; 1319 1319 } 1320 1320 base = BHDR(bh); ··· 1579 1579 memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) 1580 1580 return 1; 1581 1581 if (entry1->e_value_block != 0 || entry2->e_value_block != 0) 1582 - return -EIO; 1582 + return -EFSCORRUPTED; 1583 1583 if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), 1584 1584 (char *)header2 + le16_to_cpu(entry2->e_value_offs), 1585 1585 le32_to_cpu(entry1->e_value_size)))
+2 -1
fs/jbd2/journal.c
··· 1558 1558 /* Check superblock checksum */ 1559 1559 if (!jbd2_superblock_csum_verify(journal, sb)) { 1560 1560 printk(KERN_ERR "JBD2: journal checksum error\n"); 1561 + err = -EFSBADCRC; 1561 1562 goto out; 1562 1563 } 1563 1564 ··· 1650 1649 printk(KERN_ERR "JBD2: journal transaction %u on %s " 1651 1650 "is corrupt.\n", journal->j_failed_commit, 1652 1651 journal->j_devname); 1653 - return -EIO; 1652 + return -EFSCORRUPTED; 1654 1653 } 1655 1654 1656 1655 /* OK, we've finished with the dynamic journal bits:
+4 -4
fs/jbd2/recovery.c
··· 140 140 141 141 if (offset >= journal->j_maxlen) { 142 142 printk(KERN_ERR "JBD2: corrupted journal superblock\n"); 143 - return -EIO; 143 + return -EFSCORRUPTED; 144 144 } 145 145 146 146 err = jbd2_journal_bmap(journal, offset, &blocknr); ··· 527 527 printk(KERN_ERR "JBD2: Invalid checksum " 528 528 "recovering block %lu in log\n", 529 529 next_log_block); 530 - err = -EIO; 530 + err = -EFSBADCRC; 531 531 brelse(bh); 532 532 goto failed; 533 533 } ··· 602 602 journal, tag, obh->b_data, 603 603 be32_to_cpu(tmp->h_sequence))) { 604 604 brelse(obh); 605 - success = -EIO; 605 + success = -EFSBADCRC; 606 606 printk(KERN_ERR "JBD2: Invalid " 607 607 "checksum recovering " 608 608 "block %llu in log\n", ··· 851 851 rcount = be32_to_cpu(header->r_count); 852 852 853 853 if (!jbd2_revoke_block_csum_verify(journal, header)) 854 - return -EINVAL; 854 + return -EFSBADCRC; 855 855 856 856 if (jbd2_journal_has_csum_v2or3(journal)) 857 857 csum_size = sizeof(struct jbd2_journal_revoke_tail);
+3
include/linux/jbd2.h
··· 1449 1449 1450 1450 #endif /* __KERNEL__ */ 1451 1451 1452 + #define EFSBADCRC EBADMSG /* Bad CRC detected */ 1453 + #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ 1454 + 1452 1455 #endif /* _LINUX_JBD2_H */