Commit e268988e authored by Glen Overby's avatar Glen Overby Committed by Stephen Lord

[XFS] Add error reporting calls in error paths that return EFSCORRUPTED

SGI Modid: 2.5.x-xfs:slinx:136445a
parent ade33956
......@@ -46,7 +46,7 @@ unsigned long xfs_physmem;
* Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
* other XFS code uses these values.
*/
xfs_param_t xfs_params = { 0, 1, 0, 0, 0 };
xfs_param_t xfs_params = { 0, 1, 0, 0, 0, 3 };
/*
* Used to serialize atomicIncWithWrap.
......
......@@ -530,6 +530,7 @@ xfs_iomap_write_allocate(
xfs_trans_t *tp;
int i, nimaps, committed;
int error = 0;
int nres;
*retmap = 0;
......@@ -562,9 +563,19 @@ xfs_iomap_write_allocate(
nimaps = 0;
while (nimaps == 0) {
tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
error = xfs_trans_reserve(tp, 0, XFS_WRITE_LOG_RES(mp),
nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
error = xfs_trans_reserve(tp, nres,
XFS_WRITE_LOG_RES(mp),
0, XFS_TRANS_PERM_LOG_RES,
XFS_WRITE_LOG_COUNT);
if (error == ENOSPC) {
error = xfs_trans_reserve(tp, 0,
XFS_WRITE_LOG_RES(mp),
0,
XFS_TRANS_PERM_LOG_RES,
XFS_WRITE_LOG_COUNT);
}
if (error) {
xfs_trans_cancel(tp, 0);
return XFS_ERROR(error);
......
......@@ -73,6 +73,7 @@
#define irix_sgid_inherit xfs_params.sgid_inherit
#define irix_symlink_mode xfs_params.symlink_mode
#define xfs_panic_mask xfs_params.panic_mask
#define xfs_error_level xfs_params.error_level
typedef struct xfs_dirent { /* data from readdir() */
xfs_ino_t d_ino; /* inode number of entry */
......
......@@ -35,8 +35,8 @@
#include <linux/proc_fs.h>
STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0 };
STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127 };
STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0, 0 };
STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127, 3 };
static struct ctl_table_header *xfs_table_header;
......@@ -87,6 +87,10 @@ STATIC ctl_table xfs_table[] = {
sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
&sysctl_intvec, NULL, &xfs_min[6], &xfs_max[6]},
{XFS_ERRLEVEL, "error_level", &xfs_params.error_level,
sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
&sysctl_intvec, NULL, &xfs_min[7], &xfs_max[7]},
{0}
};
......
......@@ -48,14 +48,31 @@ typedef struct xfs_param {
/* not a member of the parent dir GID. */
ulong symlink_mode; /* Symlink creat mode affected by umask. */
ulong panic_mask; /* bitmask to specify panics on errors. */
ulong error_level; /* Degree of reporting for internal probs*/
} xfs_param_t;
/*
* xfs_error_level:
*
* How much error reporting will be done when internal problems are
* encountered. These problems normally return an EFSCORRUPTED to their
* caller, with no other information reported.
*
* 0 No error reports
* 1 Report EFSCORRUPTED errors that will cause a filesystem shutdown
* 5 Report all EFSCORRUPTED errors (all of the above errors, plus any
* additional errors that are known to not cause shutdowns)
*
* xfs_panic_mask bit 0x8 turns the error reports into panics
*/
enum {
XFS_STATS_CLEAR = 1,
XFS_RESTRICT_CHOWN = 2,
XFS_SGID_INHERIT = 3,
XFS_SYMLINK_MODE = 4,
XFS_PANIC_MASK = 5,
XFS_ERRLEVEL = 6,
};
extern xfs_param_t xfs_params;
......
......@@ -2183,34 +2183,11 @@ xfs_alloc_read_agf(
INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp);
if (XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
XFS_RANDOM_ALLOC_READ_AGF)) {
if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
XFS_RANDOM_ALLOC_READ_AGF))) {
XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
XFS_ERRLEVEL_LOW, mp, agf);
xfs_trans_brelse(tp, bp);
#ifdef __KERNEL__ /* additional, temporary, debugging code */
cmn_err(CE_NOTE,
"xfs_alloc_read_agf: error in <%s> AG %d",
mp->m_fsname, agno);
if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC)
cmn_err(CE_NOTE, "bad agf_magicnum 0x%x",
INT_GET(agf->agf_magicnum, ARCH_CONVERT));
if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT)))
cmn_err(CE_NOTE, "Bad version number 0x%x",
INT_GET(agf->agf_versionnum, ARCH_CONVERT));
if (!(INT_GET(agf->agf_freeblks, ARCH_CONVERT) <=
INT_GET(agf->agf_length, ARCH_CONVERT)))
cmn_err(CE_NOTE, "Bad freeblks %d %d",
INT_GET(agf->agf_freeblks, ARCH_CONVERT),
INT_GET(agf->agf_length, ARCH_CONVERT));
if (!(INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
cmn_err(CE_NOTE, "Bad flfirst %d",
INT_GET(agf->agf_flfirst, ARCH_CONVERT));
if (!(INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
cmn_err(CE_NOTE, "Bad fllast %d",
INT_GET(agf->agf_fllast, ARCH_CONVERT));
if (!(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp)))
cmn_err(CE_NOTE, "Bad flcount %d",
INT_GET(agf->agf_flcount, ARCH_CONVERT));
#endif
return XFS_ERROR(EFSCORRUPTED);
}
pag = &mp->m_perag[agno];
......
......@@ -1125,8 +1125,10 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
return(error);
ASSERT(bp != NULL);
leaf = bp->data;
if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
!= XFS_ATTR_LEAF_MAGIC) {
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
!= XFS_ATTR_LEAF_MAGIC)) {
XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
context->dp->i_mount, leaf);
xfs_da_brelse(NULL, bp);
return(XFS_ERROR(EFSCORRUPTED));
}
......@@ -1806,14 +1808,22 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
XFS_ATTR_FORK);
if (error)
return(error);
if (bp == NULL)
if (unlikely(bp == NULL)) {
XFS_ERROR_REPORT("xfs_attr_node_list(2)",
XFS_ERRLEVEL_LOW,
context->dp->i_mount);
return(XFS_ERROR(EFSCORRUPTED));
}
node = bp->data;
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT)
== XFS_ATTR_LEAF_MAGIC)
break;
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT)
!= XFS_DA_NODE_MAGIC) {
if (unlikely(INT_GET(node->hdr.info.magic, ARCH_CONVERT)
!= XFS_DA_NODE_MAGIC)) {
XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
XFS_ERRLEVEL_LOW,
context->dp->i_mount,
node);
xfs_da_brelse(NULL, bp);
return(XFS_ERROR(EFSCORRUPTED));
}
......@@ -1846,8 +1856,11 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
*/
for (;;) {
leaf = bp->data;
if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
!= XFS_ATTR_LEAF_MAGIC) {
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
!= XFS_ATTR_LEAF_MAGIC)) {
XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
XFS_ERRLEVEL_LOW,
context->dp->i_mount, leaf);
xfs_da_brelse(NULL, bp);
return(XFS_ERROR(EFSCORRUPTED));
}
......@@ -1860,8 +1873,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
&bp, XFS_ATTR_FORK);
if (error)
return(error);
if (bp == NULL)
if (unlikely((bp == NULL))) {
XFS_ERROR_REPORT("xfs_attr_node_list(5)",
XFS_ERRLEVEL_LOW,
context->dp->i_mount);
return(XFS_ERROR(EFSCORRUPTED));
}
}
xfs_da_brelse(NULL, bp);
return(0);
......
......@@ -455,9 +455,13 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
nsbuf = 0;
for (i = 0, sfe = &sf->list[0];
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
if (((char *)sfe < (char *)sf) ||
if (unlikely(
((char *)sfe < (char *)sf) ||
((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)) ||
(sfe->namelen >= MAXNAMELEN)) {
(sfe->namelen >= MAXNAMELEN))) {
XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
XFS_ERRLEVEL_LOW,
context->dp->i_mount, sfe);
xfs_attr_trace_l_c("sf corrupted", context);
kmem_free(sbuf, sbsize);
return XFS_ERROR(EFSCORRUPTED);
......
......@@ -4390,12 +4390,14 @@ xfs_bmap_read_extents(
num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
if (i + num_recs > room) {
if (unlikely(i + num_recs > room)) {
ASSERT(i + num_recs <= room);
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt dinode %Lu, (btree extents). "
"Unmount and run xfs_repair.",
"corrupt dinode %Lu, (btree extents). Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino);
XFS_ERROR_REPORT("xfs_bmap_read_extents(1)",
XFS_ERRLEVEL_LOW,
ip->i_mount);
goto error0;
}
XFS_WANT_CORRUPTED_GOTO(
......@@ -4423,7 +4425,10 @@ xfs_bmap_read_extents(
* any "older" data bmap btree records for a
* set bit in the "extent flag" position.
*/
if (xfs_check_nostate_extents(temp, num_recs)) {
if (unlikely(xfs_check_nostate_extents(temp, num_recs))) {
XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
XFS_ERRLEVEL_LOW,
ip->i_mount);
goto error0;
}
}
......@@ -4600,12 +4605,15 @@ xfs_bmapi(
ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE));
whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
XFS_ATTR_FORK : XFS_DATA_FORK;
if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) {
mp = ip->i_mount;
if (unlikely(XFS_TEST_ERROR(
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
mp = ip->i_mount;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
ifp = XFS_IFORK_PTR(ip, whichfork);
......@@ -5096,8 +5104,11 @@ xfs_bmapi_single(
xfs_bmbt_irec_t prev; /* previous extent list record */
ifp = XFS_IFORK_PTR(ip, whichfork);
if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) {
if (unlikely(
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) {
XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
......@@ -5168,8 +5179,11 @@ xfs_bunmapi(
whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
XFS_ATTR_FORK : XFS_DATA_FORK;
ifp = XFS_IFORK_PTR(ip, whichfork);
if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
if (unlikely(
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
mp = ip->i_mount;
......@@ -5554,11 +5568,11 @@ xfs_getbmap(
ip->i_d.di_aformat != XFS_DINODE_FMT_BTREE &&
ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
return XFS_ERROR(EINVAL);
} else if (ip->i_d.di_aformat != 0 &&
ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
} else if (unlikely(
ip->i_d.di_aformat != 0 &&
ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS)) {
XFS_ERROR_REPORT("xfs_getbmap", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
......@@ -6106,12 +6120,11 @@ xfs_bmap_count_blocks(
mp = ip->i_mount;
ifp = XFS_IFORK_PTR(ip, whichfork);
if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
if (xfs_bmap_count_leaves(ifp->if_u1.if_extents,
if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents,
ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
count) < 0) {
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
count) < 0)) {
XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
return 0;
......@@ -6129,10 +6142,9 @@ xfs_bmap_count_blocks(
ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
bno = INT_GET(*pp, ARCH_CONVERT);
if (xfs_bmap_count_tree(mp, tp, bno, level, count) < 0) {
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) {
XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -6183,12 +6195,11 @@ xfs_bmap_count_tree(
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
bno = INT_GET(*pp, ARCH_CONVERT);
if ((error =
xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0) {
if (unlikely((error =
xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) {
xfs_trans_brelse(tp, bp);
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
xfs_trans_brelse(tp, bp);
......@@ -6199,11 +6210,10 @@ xfs_bmap_count_tree(
numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]);
if (xfs_bmap_count_leaves(frp, numrecs, count) < 0) {
if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) {
xfs_trans_brelse(tp, bp);
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
xfs_trans_brelse(tp, bp);
......
......@@ -190,15 +190,12 @@ xfs_btree_check_lblock(
!INT_ISZERO(block->bb_rightsib, ARCH_CONVERT) &&
(INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO ||
XFS_FSB_SANITY_CHECK(mp, INT_GET(block->bb_rightsib, ARCH_CONVERT)));
if (XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
XFS_RANDOM_BTREE_CHECK_LBLOCK)) {
if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
if (bp)
xfs_buftrace("LBTREE ERROR", bp);
#ifdef __KERNEL__ /* additional, temporary, debugging code */
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
#endif
XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
mp);
return XFS_ERROR(EFSCORRUPTED);
}
return 0;
......@@ -312,22 +309,13 @@ xfs_btree_check_sblock(
(INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK ||
INT_GET(block->bb_rightsib, ARCH_CONVERT) < agflen) &&
!INT_ISZERO(block->bb_rightsib, ARCH_CONVERT);
if (XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
XFS_ERRTAG_BTREE_CHECK_SBLOCK,
XFS_RANDOM_BTREE_CHECK_SBLOCK)) {
XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
if (bp)
xfs_buftrace("SBTREE ERROR", bp);
#ifdef __KERNEL__ /* additional, temporary, debugging code */
cmn_err(CE_NOTE,
"xfs_btree_check_sblock: Not OK:");
cmn_err(CE_NOTE,
"magic 0x%x level %d numrecs %d leftsib %d rightsib %d",
INT_GET(block->bb_magic, ARCH_CONVERT),
INT_GET(block->bb_level, ARCH_CONVERT),
INT_GET(block->bb_numrecs, ARCH_CONVERT),
INT_GET(block->bb_leftsib, ARCH_CONVERT),
INT_GET(block->bb_rightsib, ARCH_CONVERT));
#endif
XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
cur->bc_mp);
return XFS_ERROR(EFSCORRUPTED);
}
return 0;
......
......@@ -570,7 +570,9 @@ int xfs_fsb_sanity_check(struct xfs_mount *mp, xfs_fsblock_t fsb);
{ \
int fs_is_ok = (x); \
ASSERT(fs_is_ok); \
if (!fs_is_ok) { \
if (unlikely(!fs_is_ok)) { \
XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
XFS_ERRLEVEL_LOW, NULL); \
error = XFS_ERROR(EFSCORRUPTED); \
goto l; \
} \
......@@ -580,8 +582,11 @@ int xfs_fsb_sanity_check(struct xfs_mount *mp, xfs_fsblock_t fsb);
{ \
int fs_is_ok = (x); \
ASSERT(fs_is_ok); \
if (!fs_is_ok) \
if (unlikely(!fs_is_ok)) { \
XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
XFS_ERRLEVEL_LOW, NULL); \
return XFS_ERROR(EFSCORRUPTED); \
} \
}
#endif /* __XFS_BTREE_H__ */
......@@ -1791,8 +1791,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
if (error)
return error;
if (lastoff == 0)
if (unlikely(lastoff == 0)) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,
mp);
return XFS_ERROR(EFSCORRUPTED);
}
/*
* Read the last block in the btree space.
*/
......@@ -1833,8 +1836,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
goto done;
sib_info = sib_buf->data;
if (INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT)) {
if (unlikely(
INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
......@@ -1852,9 +1858,12 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
goto done;
sib_info = sib_buf->data;
if ( INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
if (unlikely(
INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
|| INT_GET(sib_info->magic, ARCH_CONVERT)
!= INT_GET(dead_info->magic, ARCH_CONVERT)) {
!= INT_GET(dead_info->magic, ARCH_CONVERT))) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
......@@ -1874,8 +1883,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
goto done;
par_node = par_buf->data;
if (INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
(level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1)) {
if (unlikely(
INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
(level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
......@@ -1885,7 +1897,9 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash;
entno++)
continue;
if (entno == INT_GET(par_node->hdr.count, ARCH_CONVERT)) {
if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
......@@ -1910,15 +1924,20 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT);
xfs_da_brelse(tp, par_buf);
par_buf = NULL;
if (par_blkno == 0) {
if (unlikely(par_blkno == 0)) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
goto done;
par_node = par_buf->data;
if (INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) {
if (unlikely(
INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) {
XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto done;
}
......@@ -2111,6 +2130,26 @@ xfs_da_do_buf(
}
if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) {
error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED);
if (unlikely(error == EFSCORRUPTED)) {
if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
int i;
cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
bno);
cmn_err(CE_ALERT, "dir: inode %lld\n",
dp->i_ino);
for (i = 0; i < nmap; i++) {
cmn_err(CE_ALERT,
"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
i,
mapp[i].br_startoff,
mapp[i].br_startblock,
mapp[i].br_blockcount,
mapp[i].br_state);
}
}
XFS_ERROR_REPORT("xfs_da_do_buf(1)",
XFS_ERRLEVEL_LOW, mp);
}
goto exit0;
}
if (caller != 3 && nmap > 1) {
......@@ -2193,7 +2232,8 @@ xfs_da_do_buf(
free = rbp->data;
magic = INT_GET(info->magic, ARCH_CONVERT);
magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT);
if (XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
if (unlikely(
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
(magic != XFS_DIR_LEAF_MAGIC) &&
(magic != XFS_ATTR_LEAF_MAGIC) &&
(magic != XFS_DIR2_LEAF1_MAGIC) &&
......@@ -2202,8 +2242,10 @@ xfs_da_do_buf(
(magic1 != XFS_DIR2_DATA_MAGIC) &&
(INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC),
mp, XFS_ERRTAG_DA_READ_BUF,
XFS_RANDOM_DA_READ_BUF)) {
XFS_RANDOM_DA_READ_BUF))) {
xfs_buftrace("DA READ ERROR", rbp->bps[0]);
XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
XFS_ERRLEVEL_LOW, mp, info);
error = XFS_ERROR(EFSCORRUPTED);
xfs_da_brelse(trans, rbp);
nbplist = 0;
......
......@@ -962,9 +962,11 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
*/
for (;;) {
leaf = bp->data;
if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC)) {
xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
xfs_da_brelse(trans, bp);
XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
XFS_ERRLEVEL_LOW, mp, leaf);
return XFS_ERROR(EFSCORRUPTED);
}
xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
......@@ -988,8 +990,11 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
XFS_DATA_FORK);
if (error)
return(error);
if (bp == NULL)
if (unlikely(bp == NULL)) {
XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
XFS_ERRLEVEL_LOW, mp);
return(XFS_ERROR(EFSCORRUPTED));
}
}
*eofp = 1;
xfs_dir_trace_g_du("node: E-O-F", dp, uio);
......
......@@ -98,7 +98,10 @@ xfs_dir2_block_addname(
/*
* Check the magic number, corrupted if wrong.
*/
if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) {
if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT)
!= XFS_DIR2_BLOCK_MAGIC)) {
XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
XFS_ERRLEVEL_LOW, mp, block);
xfs_da_brelse(tp, bp);
return XFS_ERROR(EFSCORRUPTED);
}
......
......@@ -511,7 +511,9 @@ xfs_dir2_leafn_lookup_int(
/*
* If it has room, return it.
*/
if (INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF) {
if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) {
XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) {
......
......@@ -103,10 +103,11 @@ xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino)
agblkno != 0 &&
ioff < (1 << mp->m_sb.sb_inopblog) &&
XFS_AGINO_TO_INO(mp, agno, agino) == ino;
if (XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
XFS_RANDOM_DIR_INO_VALIDATE)) {
if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
XFS_RANDOM_DIR_INO_VALIDATE))) {
xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
(unsigned long long) ino);
XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
return 0;
......@@ -455,10 +456,13 @@ xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
for (i = 0, sfe = &sf->list[0];
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
if (((char *)sfe < (char *)sf) ||
if (unlikely(
((char *)sfe < (char *)sf) ||
((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)) ||
(sfe->namelen >= MAXNAMELEN)) {
(sfe->namelen >= MAXNAMELEN))) {
xfs_dir_trace_g_du("sf: corrupted", dp, uio);
XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents",
XFS_ERRLEVEL_LOW, mp, sfe);
kmem_free(sbuf, sbsize);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -1970,9 +1974,12 @@ xfs_dir_leaf_getdents_int(
namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
INT_GET(entry->nameidx, ARCH_CONVERT));
if (((char *)namest < (char *)leaf) ||
if (unlikely(
((char *)namest < (char *)leaf) ||
((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) ||
(entry->namelen >= MAXNAMELEN)) {
(entry->namelen >= MAXNAMELEN))) {
XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)",
XFS_ERRLEVEL_LOW, mp, leaf);
xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -2031,9 +2038,12 @@ xfs_dir_leaf_getdents_int(
namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
INT_GET(entry->nameidx, ARCH_CONVERT));
if (((char *)namest < (char *)leaf) ||
if (unlikely(
((char *)namest < (char *)leaf) ||
((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) ||
(entry->namelen >= MAXNAMELEN)) {
(entry->namelen >= MAXNAMELEN))) {
XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
XFS_ERRLEVEL_LOW, mp, leaf);
xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -2076,11 +2086,14 @@ xfs_dir_leaf_getdents_int(
leaf2 = bp2->data;
if ( (INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT)
if (unlikely(
(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT)
!= XFS_DIR_LEAF_MAGIC)
|| (INT_GET(leaf2->hdr.info.back, ARCH_CONVERT)
!= bno)) { /* GROT */
!= bno))) { /* GROT */
XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
XFS_ERRLEVEL_LOW, mp,
leaf2);
xfs_da_brelse(dp->i_transp, bp2);
return(XFS_ERROR(EFSCORRUPTED));
......
......@@ -238,3 +238,75 @@ xfs_cmn_err(uint64_t panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
xfs_fs_vcmn_err(level, mp, fmt, ap);
va_end(ap);
}
#ifndef __KERNEL__
int xfs_error_level = XFS_ERRLEVEL_HIGH;
#endif /* __KERNEL */
void
xfs_error_report(
char *tag,
int level,
xfs_mount_t *mp,
char *fname,
int linenum,
inst_t *ra)
{
if (level <= xfs_error_level) {
if (mp != NULL) {
xfs_cmn_err(XFS_PTAG_ERROR_REPORT,
CE_ALERT, mp,
"XFS internal error %s at line %d of file %s. Caller 0x%x\n",
tag, linenum, fname, ra);
} else {
cmn_err(CE_ALERT,
"XFS internal error %s at line %d of file %s. Caller 0x%x\n",
tag, linenum, fname, ra);
}
}
}
void
xfs_hex_dump(void *p, int length)
{
__uint8_t *uip = (__uint8_t*)p;
int i;
char sbuf[128], *s;
s = sbuf;
*s = '\0';
for (i=0; i<length; i++, uip++) {
if ((i % 16) == 0) {
if (*s != '\0')
cmn_err(CE_ALERT, "%s\n", sbuf);
s = sbuf;
sprintf(s, "0x%x: ", i);
while( *s != '\0')
s++;
}
sprintf(s, "%02x ", *uip);
/*
* the kernel sprintf is a void; user sprintf returns
* the sprintf'ed string's length. Find the new end-
* of-string
*/
while( *s != '\0')
s++;
}
cmn_err(CE_ALERT, "%s\n", sbuf);
}
void
xfs_corruption_error(
char *tag,
int level,
xfs_mount_t *mp,
void *p,
char *fname,
int linenum,
inst_t *ra)
{
xfs_hex_dump(p, 16);
xfs_error_report(tag, level, mp, fname, linenum, ra);
}
......@@ -52,6 +52,37 @@ extern int xfs_error_trap(int);
#define XFS_ERROR(e) (e)
#endif
extern void
xfs_error_report(
char *tag,
int level,
struct xfs_mount *mp,
char *fname,
int linenum,
inst_t *ra);
extern void
xfs_corruption_error(
char *tag,
int level,
struct xfs_mount *mp,
void *p,
char *fname,
int linenum,
inst_t *ra);
extern void
xfs_hex_dump(void *p, int length);
#define XFS_ERROR_REPORT(e, lvl, mp) \
xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \
xfs_corruption_error(e, lvl, mp, mem, \
__FILE__, __LINE__, __return_address)
#define XFS_ERRLEVEL_OFF 0
#define XFS_ERRLEVEL_LOW 1
#define XFS_ERRLEVEL_HIGH 5
/*
* error injection tags - the labels can be anything you want
......@@ -79,7 +110,8 @@ extern int xfs_error_trap(int);
#define XFS_ERRTAG_STRATREAD_IOERR 18
#define XFS_ERRTAG_STRATCMPL_IOERR 19
#define XFS_ERRTAG_DIOWRITE_IOERR 20
#define XFS_ERRTAG_MAX 21
#define XFS_ERRTAG_BMAPIFORMAT 21
#define XFS_ERRTAG_MAX 22
/*
* Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
......@@ -105,6 +137,7 @@ extern int xfs_error_trap(int);
#define XFS_RANDOM_STRATREAD_IOERR (XFS_RANDOM_DEFAULT/10)
#define XFS_RANDOM_STRATCMPL_IOERR (XFS_RANDOM_DEFAULT/10)
#define XFS_RANDOM_DIOWRITE_IOERR (XFS_RANDOM_DEFAULT/10)
#define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT
#if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
......@@ -146,7 +179,7 @@ int xfs_errortag_clearall_umount(int64_t fsid, char *fsname,
#define XFS_PTAG_IFLUSH 0x0000000000000001LL
#define XFS_PTAG_LOGRES 0x0000000000000002LL
#define XFS_PTAG_AILDELETE 0x0000000000000004LL
#define XFS_PTAG_AVAILABLE 0x0000000000000008LL
#define XFS_PTAG_ERROR_REPORT 0x0000000000000008LL
#define XFS_PTAG_SHUTDOWN_CORRUPT 0x0000000000000010LL
#define XFS_PTAG_SHUTDOWN_IOERROR 0x0000000000000020LL
#define XFS_PTAG_SHUTDOWN_LOGERROR 0x0000000000000040LL
......
......@@ -1303,14 +1303,11 @@ xfs_ialloc_read_agi(
INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
XFS_AGI_GOOD_VERSION(
INT_GET(agi->agi_versionnum, ARCH_CONVERT));
if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
XFS_RANDOM_IALLOC_READ_AGI)) {
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
XFS_RANDOM_IALLOC_READ_AGI))) {
XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
mp, agi);
xfs_trans_brelse(tp, bp);
#ifdef __KERNEL__ /* additional, temporary, debugging code */
cmn_err(CE_NOTE,
"EFSCORRUPTED returned from file %s line %d",
__FILE__, __LINE__);
#endif
return XFS_ERROR(EFSCORRUPTED);
}
pag = &mp->m_perag[agno];
......
......@@ -226,8 +226,9 @@ xfs_inotobp(
di_ok =
INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
if (XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP)) {
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip);
xfs_trans_brelse(tp, bp);
cmn_err(CE_WARN,
"xfs_inotobp: XFS_TEST_ERROR() returned an "
......@@ -369,13 +370,15 @@ xfs_itobp(
(i << mp->m_sb.sb_inodelog));
di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
if (XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP)) {
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
#ifdef DEBUG
prdev("bad inode magic/vsn daddr 0x%llx #%d (magic=%x)",
mp->m_dev, (unsigned long long)imap.im_blkno, i,
INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
#endif
XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_LOW,
mp, dip);
xfs_trans_brelse(tp, bp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -419,9 +422,10 @@ xfs_iformat(
XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
error = 0;
if (INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
if (unlikely(
INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) >
INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)) {
INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt dinode %Lu, extent total = %d, nblocks = %Lu."
" Unmount and run xfs_repair.",
......@@ -430,15 +434,19 @@ xfs_iformat(
+ INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)),
(unsigned long long)
INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT));
XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
if (INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize) {
if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt dinode %Lu, forkoff = 0x%x."
" Unmount and run xfs_repair.",
(unsigned long long)ip->i_ino,
(int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT)));
XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -447,8 +455,11 @@ xfs_iformat(
case IFCHR:
case IFBLK:
case IFSOCK:
if (INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)
if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) {
XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
ip->i_d.di_size = 0;
ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
break;
......@@ -461,24 +472,26 @@ xfs_iformat(
/*
* no local regular files yet
*/
if ((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG) {
if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG)) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode "
"(local format for regular file) %Lu. "
"Unmount and run xfs_repair.",
"corrupt inode (local format for regular file) %Lu. Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino);
XFS_CORRUPTION_ERROR("xfs_iformat(4)",
XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
if (di_size >
XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT)) {
if (unlikely(di_size >
XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT))) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu "
"(bad size %Ld for local inode). "
"Unmount and run xfs_repair.",
"corrupt inode %Lu (bad size %Ld for local inode). Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino,
(long long) di_size);
XFS_CORRUPTION_ERROR("xfs_iformat(5)",
XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -492,11 +505,14 @@ xfs_iformat(
error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
break;
default:
XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
break;
default:
XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
if (error) {
......@@ -557,13 +573,13 @@ xfs_iformat_local(
* is wrong and we just bail out rather than crash in
* kmem_alloc() or memcpy() below.
*/
if (size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) {
if (unlikely(size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu "
"(bad size %d for local fork, size = %d). "
"Unmount and run xfs_repair.",
"corrupt inode %Lu (bad size %d for local fork, size = %d). Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino, size,
XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT));
XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
ifp = XFS_IFORK_PTR(ip, whichfork);
......@@ -619,11 +635,12 @@ xfs_iformat_extents(
* is wrong and we just bail out rather than crash in
* kmem_alloc() or memcpy() below.
*/
if (size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) {
if (unlikely(size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu ((a)extents = %d). "
"Unmount and run xfs_repair.",
"corrupt inode %Lu ((a)extents = %d). Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino, nex);
XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -657,9 +674,13 @@ xfs_iformat_extents(
whichfork);
if (whichfork != XFS_DATA_FORK ||
XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
if (xfs_check_nostate_extents(
ifp->if_u1.if_extents, nex))
if (unlikely(xfs_check_nostate_extents(
ifp->if_u1.if_extents, nex))) {
XFS_ERROR_REPORT("xfs_iformat_extents(2)",
XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
}
ifp->if_flags |= XFS_IFEXTENTS;
return 0;
......@@ -697,14 +718,15 @@ xfs_iformat_btree(
* or the number of extents is greater than the number of
* blocks.
*/
if (XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
|| XFS_BMDR_SPACE_CALC(nrecs) >
XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)
|| XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) {
|| XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu (btree). "
"Unmount and run xfs_repair.",
"corrupt inode %Lu (btree). Unmount and run xfs_repair.",
(unsigned long long) ip->i_ino);
XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -975,8 +997,11 @@ xfs_iread_extents(
xfs_ifork_t *ifp;
size_t size;
if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
ip->i_mount);
return XFS_ERROR(EFSCORRUPTED);
}
size = XFS_IFORK_NEXTENTS(ip, whichfork) * (uint)sizeof(xfs_bmbt_rec_t);
ifp = XFS_IFORK_PTR(ip, whichfork);
/*
......@@ -1817,8 +1842,9 @@ xfs_iunlink(
agi_ok =
INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
XFS_RANDOM_IUNLINK)) {
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
XFS_RANDOM_IUNLINK))) {
XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi);
xfs_trans_brelse(tp, agibp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -1919,8 +1945,10 @@ xfs_iunlink_remove(
agi_ok =
INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
XFS_RANDOM_IUNLINK_REMOVE)) {
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
XFS_RANDOM_IUNLINK_REMOVE))) {
XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW,
mp, agi);
xfs_trans_brelse(tp, agibp);
cmn_err(CE_WARN,
"xfs_iunlink_remove: XFS_TEST_ERROR() returned an error on %s. Returning EFSCORRUPTED.",
......@@ -2745,7 +2773,9 @@ xfs_iflush_fork(
memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
}
if (whichfork == XFS_DATA_FORK) {
if (XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip)) {
if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
XFS_ERROR_REPORT("xfs_iflush_fork",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
}
......
......@@ -166,17 +166,21 @@ xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head)
* a dirty log created in IRIX.
*/
if (INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT) {
if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
xlog_warn("XFS: dirty log written in incompatible format - can't recover");
#ifdef DEBUG
xlog_header_check_dump(mp, head);
#endif
XFS_ERROR_REPORT("xlog_header_check_recover(1)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
} else if (!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {
} else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
xlog_warn("XFS: dirty log entry has mismatched uuid - can't recover");
#ifdef DEBUG
xlog_header_check_dump(mp, head);
#endif
XFS_ERROR_REPORT("xlog_header_check_recover(2)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -202,11 +206,13 @@ xlog_header_check_mount(xfs_mount_t *mp, xlog_rec_header_t *head)
xlog_warn("XFS: nil uuid in log - IRIX style log");
} else if (!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {
} else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
xlog_warn("XFS: log has mismatched uuid - can't recover");
#ifdef DEBUG
xlog_header_check_dump(mp, head);
#endif
XFS_ERROR_REPORT("xlog_header_check_mount",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -1113,8 +1119,11 @@ xlog_clear_stale_blocks(
* the distance from the beginning of the log to the
* tail.
*/
if (head_block < tail_block || head_block >= log->l_logBBsize)
if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
}
tail_distance = tail_block + (log->l_logBBsize - head_block);
} else {
/*
......@@ -1122,8 +1131,11 @@ xlog_clear_stale_blocks(
* so the distance from the head to the tail is just
* the tail block minus the head block.
*/
if (head_block >= tail_block || head_cycle != (tail_cycle + 1))
if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
}
tail_distance = tail_block - head_block;
}
......@@ -1732,10 +1744,12 @@ xlog_recover_do_inode_buffer(xfs_mount_t *mp,
logged_nextp = (xfs_agino_t *)
((char *)(item->ri_buf[item_index].i_addr) +
(next_unlinked_offset - reg_buf_offset));
if (*logged_nextp == 0) {
if (unlikely(*logged_nextp == 0)) {
xfs_fs_cmn_err(CE_ALERT, mp,
"bad inode buffer log record (ptr = 0x%p, bp = 0x%p). XFS trying to replay bad (0) inode di_next_unlinked field",
item, bp);
XFS_ERROR_REPORT("xlog_recover_do_inode_buf",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -1933,6 +1947,8 @@ xlog_recover_do_buffer_trans(xlog_t *log,
xfs_fs_cmn_err(CE_ALERT, log->l_mp,
"xfs_log_recover: unknown buffer type 0x%x, dev 0x%x",
buf_f->blf_type, log->l_dev);
XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -2038,7 +2054,6 @@ xlog_recover_do_inode_trans(xlog_t *log,
imap.im_blkno = 0;
xfs_imap(log->l_mp, 0, ino, &imap, 0);
}
bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
XFS_BUF_LOCK);
if (XFS_BUF_ISERROR(bp)) {
......@@ -2056,34 +2071,42 @@ xlog_recover_do_inode_trans(xlog_t *log,
* Make sure the place we're flushing out to really looks
* like an inode!
*/
if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) {
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
dip, bp, ino);
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
if (dicp->di_magic != XFS_DINODE_MAGIC) {
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, ino %Ld",
item, ino);
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
if ((dicp->di_mode & IFMT) == IFREG) {
if (unlikely((dicp->di_mode & IFMT) == IFREG)) {
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
(dicp->di_format != XFS_DINODE_FMT_BTREE)) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(3)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
item, dip, bp, ino);
return XFS_ERROR(EFSCORRUPTED);
}
} else if ((dicp->di_mode & IFMT) == IFDIR) {
} else if (unlikely((dicp->di_mode & IFMT) == IFDIR)) {
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
(dicp->di_format != XFS_DINODE_FMT_BTREE) &&
(dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(4)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
......@@ -2091,7 +2114,9 @@ xlog_recover_do_inode_trans(xlog_t *log,
return XFS_ERROR(EFSCORRUPTED);
}
}
if (dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks) {
if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(5)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
......@@ -2100,14 +2125,18 @@ xlog_recover_do_inode_trans(xlog_t *log,
dicp->di_nblocks);
return XFS_ERROR(EFSCORRUPTED);
}
if (dicp->di_forkoff > mp->m_sb.sb_inodesize) {
if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
item, dip, bp, ino, dicp->di_forkoff);
return XFS_ERROR(EFSCORRUPTED);
}
if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
XFS_ERRLEVEL_LOW, mp, dicp);
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
......@@ -3229,10 +3258,12 @@ xlog_do_recovery_pass(xlog_t *log,
ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= INT_MAX));
bblks = (int) BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); /* blocks in data section */
if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) ||
(bblks <= 0) ||
(blk_no > log->l_logBBsize)) {
(blk_no > log->l_logBBsize))) {
XFS_ERROR_REPORT("xlog_do_recovery_pass(1)",
XFS_ERRLEVEL_LOW, log->l_mp);
error = EFSCORRUPTED;
goto bread_err2;
}
......@@ -3298,9 +3329,11 @@ xlog_do_recovery_pass(xlog_t *log,
ASSERT(bblks > 0);
blk_no += hblks; /* successfully read header */
if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) ||
(bblks <= 0)) {
(bblks <= 0))) {
XFS_ERROR_REPORT("xlog_do_recovery_pass(2)",
XFS_ERRLEVEL_LOW, log->l_mp);
error = EFSCORRUPTED;
goto bread_err2;
}
......
......@@ -205,13 +205,17 @@ xfs_mount_validate_sb(
return XFS_ERROR(EWRONGFS);
}
if (sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp) {
if (unlikely(sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
cmn_err(CE_WARN, "XFS: filesystem is marked as having an external log; specify logdev on the\nmount command line.");
XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)",
XFS_ERRLEVEL_LOW, mp, sbp);
return XFS_ERROR(EFSCORRUPTED);
}
if (sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp) {
if (unlikely(sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
cmn_err(CE_WARN, "XFS: filesystem is marked as having an internal log; don't specify logdev on\nthe mount command line.");
XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)",
XFS_ERRLEVEL_LOW, mp, sbp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -219,7 +223,8 @@ xfs_mount_validate_sb(
* More sanity checking. These were stolen directly from
* xfs_repair.
*/
if (sbp->sb_agcount <= 0 ||
if (unlikely(
sbp->sb_agcount <= 0 ||
sbp->sb_sectsize < XFS_MIN_SECTORSIZE ||
sbp->sb_sectsize > XFS_MAX_SECTORSIZE ||
sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
......@@ -232,20 +237,25 @@ xfs_mount_validate_sb(
sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
(sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
(sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
sbp->sb_imax_pct > 100) {
sbp->sb_imax_pct > 100)) {
cmn_err(CE_WARN, "XFS: SB sanity check 1 failed");
XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(3)",
XFS_ERRLEVEL_LOW, mp, sbp);
return XFS_ERROR(EFSCORRUPTED);
}
/*
* Sanity check AG count, size fields against data size field
*/
if (sbp->sb_dblocks == 0 ||
if (unlikely(
sbp->sb_dblocks == 0 ||
sbp->sb_dblocks >
(xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
sbp->sb_agblocks + XFS_MIN_AG_BLOCKS) {
sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
cmn_err(CE_WARN, "XFS: SB sanity check 2 failed");
XFS_ERROR_REPORT("xfs_mount_validate_sb(4)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -257,8 +267,10 @@ xfs_mount_validate_sb(
}
#endif
if (sbp->sb_inprogress) {
if (unlikely(sbp->sb_inprogress)) {
cmn_err(CE_WARN, "XFS: file system busy");
XFS_ERROR_REPORT("xfs_mount_validate_sb(5)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
......@@ -636,7 +648,6 @@ xfs_mountfs(
error = XFS_ERROR(EINVAL);
goto error1;
}
mp->m_dalign = mp->m_swidth = 0;
} else {
/*
* Convert the stripe unit and width to FSBs.
......@@ -915,7 +926,7 @@ xfs_mountfs(
/*
* log's mount-time initialization. Perform 1st part recovery if needed
*/
if (sbp->sb_logblocks > 0) { /* check for volume case */
if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */
error = xfs_log_mount(mp, mp->m_logdev_targp->pbr_dev,
XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
......@@ -925,6 +936,7 @@ xfs_mountfs(
}
} else { /* No log has been defined */
cmn_err(CE_WARN, "XFS: no log defined");
XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto error2;
}
......@@ -941,7 +953,7 @@ xfs_mountfs(
ASSERT(rip != NULL);
rvp = XFS_ITOV(rip);
if ((rip->i_d.di_mode & IFMT) != IFDIR) {
if (unlikely((rip->i_d.di_mode & IFMT) != IFDIR)) {
cmn_err(CE_WARN, "XFS: corrupted root inode");
VMAP(rvp, vmap);
prdev("Root inode %llu is not a directory",
......@@ -949,6 +961,8 @@ xfs_mountfs(
xfs_iunlock(rip, XFS_ILOCK_EXCL);
VN_RELE(rvp);
vn_purge(rvp, &vmap);
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp);
error = XFS_ERROR(EFSCORRUPTED);
goto error3;
}
......
......@@ -444,16 +444,22 @@ xfs_qm_unmount_quotas(
xfs_iflock(uqp);
error = xfs_iflush(uqp, XFS_IFLUSH_SYNC);
xfs_iunlock(uqp, XFS_ILOCK_EXCL);
if (error == EFSCORRUPTED)
if (unlikely(error == EFSCORRUPTED)) {
XFS_ERROR_REPORT("xfs_qm_unmount_quotas(1)",
XFS_ERRLEVEL_LOW, mp);
goto out;
}
}
if ((gqp = mp->m_quotainfo->qi_gquotaip) != NULL) {
xfs_ilock(gqp, XFS_ILOCK_EXCL);
xfs_iflock(gqp);
error = xfs_iflush(gqp, XFS_IFLUSH_SYNC);
xfs_iunlock(gqp, XFS_ILOCK_EXCL);
if (error == EFSCORRUPTED)
if (unlikely(error == EFSCORRUPTED)) {
XFS_ERROR_REPORT("xfs_qm_unmount_quotas(2)",
XFS_ERRLEVEL_LOW, mp);
goto out;
}
}
}
if (uqp) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment