Skip to content

Commit

Permalink
Merge tag 'xfs-5.3-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xf…
Browse files Browse the repository at this point in the history
…s-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().
  • Loading branch information
torvalds committed Aug 15, 2019
2 parents 4ec1fa6 + 8612de3 commit a69e905
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 20 deletions.
29 changes: 21 additions & 8 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
19 changes: 12 additions & 7 deletions fs/xfs/libxfs/xfs_da_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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;
}

/*
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/libxfs/xfs_dir2_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 1 addition & 4 deletions fs/xfs/xfs_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a69e905

Please sign in to comment.