Commit a69e9051 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -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)
+12 −7
Original line number Diff line number Diff line
@@ -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;
}

/*
+2 −1
Original line number Diff line number Diff line
@@ -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.
+1 −4
Original line number Diff line number Diff line
@@ -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