Changes since last update:
- Fix crashes when the attr fork isn't present due to errors but inode inactivation tries to zap the attr data anyway. - Convert more directory corruption debugging asserts to actual EFSCORRUPTED returns instead of blowing up later on. - Don't fail writeback just because we ran out of memory allocating metadata log data. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAl1RlXoACgkQ+H93GTRK tOtc7A/+JIidhI/MHQLs7Ab9GW+PsHHBMSbVTV4Ge+SlfZtPNI38zrC1MC5LWvvV bndOpRjLm4nOJcB7fsoEWufTs1dKOIUjk2yQi8x47ZvE+B/RcA4b6IDhwpbAI8GW kt1RLNec9kpzhxCFFPzsXT9MwjEvvOvTeXfxaXTmiuB2kbJkR5dTlCUS2nUDnqsG FGdmOUDjy1uVfFcSrp75KT/iYaqW08cG+uY/eUHRm+YMUKI8hF1t+n8cDnSg96VX IN2DT1d3dTWiiF+JUZnMhVwJvPgV95DOf+yYy/F7qOcJUEmQ9tD6+0Ml/cI/AeLG zERxHXM9A9Jy8S+2xkvf0J/+HStwfviWNToK3pbMIM1ZsoMTi9q8VgbB3AaFiijf C4Q4T3W0jC44om8X/Ta/c+G/64Tj8yenzLDeTHvtQkoq77QPBam/aYjBc79oYvHi r+R61kHNto+YjJsRbkwgF/S+bzru1qY9Ccr0LJZrUkSzh4d6p94fbQc+NX4L2sv7 WzAc+kOR/7qgVgy4gVr3ju0d89kP/Xn/0e0Ma0V8CSZlX5yg1dMLew5TJq693UYX xjLGD2ltOoFEN8e7/WXI0/ktvvSCAQalmz+sPgJvTlosUhpGXky85ced1PSrKiEV l0tREpmawDo9WVvC/06yBj97Op6PDdb4CovDcyLT6Yt3v1aBZT0= =ivN3 -----END PGP SIGNATURE----- Merge tag 'xfs-5.3-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux Pull xfs fixes from Darrick Wong: - Fix crashes when the attr fork isn't present due to errors but inode inactivation tries to zap the attr data anyway. - Convert more directory corruption debugging asserts to actual EFSCORRUPTED returns instead of blowing up later on. - Don't fail writeback just because we ran out of memory allocating metadata log data. * tag 'xfs-5.3-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: don't crash on null attr fork xfs_bmapi_read xfs: remove more ondisk directory corruption asserts fs: xfs: xfs_log: Don't use KM_MAYFAIL at xfs_log_reserve().
This commit is contained in:
commit
a69e90512d
4 changed files with 36 additions and 20 deletions
|
@ -3835,15 +3835,28 @@ xfs_bmapi_read(
|
|||
XFS_STATS_INC(mp, xs_blk_mapr);
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
if (!ifp) {
|
||||
/* No CoW fork? Return a hole. */
|
||||
if (whichfork == XFS_COW_FORK) {
|
||||
mval->br_startoff = bno;
|
||||
mval->br_startblock = HOLESTARTBLOCK;
|
||||
mval->br_blockcount = len;
|
||||
mval->br_state = XFS_EXT_NORM;
|
||||
*nmap = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No CoW fork? Return a hole. */
|
||||
if (whichfork == XFS_COW_FORK && !ifp) {
|
||||
mval->br_startoff = bno;
|
||||
mval->br_startblock = HOLESTARTBLOCK;
|
||||
mval->br_blockcount = len;
|
||||
mval->br_state = XFS_EXT_NORM;
|
||||
*nmap = 1;
|
||||
return 0;
|
||||
/*
|
||||
* A missing attr ifork implies that the inode says we're in
|
||||
* extents or btree format but failed to pass the inode fork
|
||||
* verifier while trying to load it. Treat that as a file
|
||||
* corruption too.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
xfs_alert(mp, "%s: inode %llu missing fork %d",
|
||||
__func__, ip->i_ino, whichfork);
|
||||
#endif /* DEBUG */
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
|
||||
|
|
|
@ -487,10 +487,8 @@ xfs_da3_split(
|
|||
ASSERT(state->path.active == 0);
|
||||
oldblk = &state->path.blk[0];
|
||||
error = xfs_da3_root_split(state, oldblk, addblk);
|
||||
if (error) {
|
||||
addblk->bp = NULL;
|
||||
return error; /* GROT: dir is inconsistent */
|
||||
}
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Update pointers to the node which used to be block 0 and just got
|
||||
|
@ -505,7 +503,10 @@ xfs_da3_split(
|
|||
*/
|
||||
node = oldblk->bp->b_addr;
|
||||
if (node->hdr.info.forw) {
|
||||
ASSERT(be32_to_cpu(node->hdr.info.forw) == addblk->blkno);
|
||||
if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
node = addblk->bp->b_addr;
|
||||
node->hdr.info.back = cpu_to_be32(oldblk->blkno);
|
||||
xfs_trans_log_buf(state->args->trans, addblk->bp,
|
||||
|
@ -514,15 +515,19 @@ xfs_da3_split(
|
|||
}
|
||||
node = oldblk->bp->b_addr;
|
||||
if (node->hdr.info.back) {
|
||||
ASSERT(be32_to_cpu(node->hdr.info.back) == addblk->blkno);
|
||||
if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
node = addblk->bp->b_addr;
|
||||
node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
|
||||
xfs_trans_log_buf(state->args->trans, addblk->bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr.info,
|
||||
sizeof(node->hdr.info)));
|
||||
}
|
||||
out:
|
||||
addblk->bp = NULL;
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -741,7 +741,8 @@ xfs_dir2_leafn_lookup_for_entry(
|
|||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
|
||||
xfs_dir3_leaf_check(dp, bp);
|
||||
ASSERT(leafhdr.count > 0);
|
||||
if (leafhdr.count <= 0)
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
/*
|
||||
* Look up the hash value in the leaf entries.
|
||||
|
|
|
@ -429,10 +429,7 @@ xfs_log_reserve(
|
|||
|
||||
ASSERT(*ticp == NULL);
|
||||
tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent,
|
||||
KM_SLEEP | KM_MAYFAIL);
|
||||
if (!tic)
|
||||
return -ENOMEM;
|
||||
|
||||
KM_SLEEP);
|
||||
*ticp = tic;
|
||||
|
||||
xlog_grant_push_ail(log, tic->t_cnt ? tic->t_unit_res * tic->t_cnt
|
||||
|
|
Loading…
Reference in a new issue