Commit a69e9051 authored by Linus Torvalds's avatar Linus Torvalds

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().
parents 4ec1fa69 8612de3f
......@@ -3835,9 +3835,9 @@ 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 && !ifp) {
if (whichfork == XFS_COW_FORK) {
mval->br_startoff = bno;
mval->br_startblock = HOLESTARTBLOCK;
mval->br_blockcount = len;
......@@ -3846,6 +3846,19 @@ xfs_bmapi_read(
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)) {
error = xfs_iread_extents(NULL, ip, whichfork);
if (error)
......
......@@ -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
......
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