Commit 48416602 authored by Long Li's avatar Long Li
Browse files

Revert "xfs: atomic drop extent entries when inactiving attr"

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBALAU


CVE: NA

--------------------------------

This patch attempted to unmap attr leaf/node blocks when inactive attr.
Under special attr structures, extent splitting may occur, which would
increase attr bmap entries and allocate new blocks.

Since attr inactive transaction has no block reservation, the splitting
operations mentioned above could fail and eventually cause filesystem
corruption. Considering attr inactive happens during inode gc process
which should free more blocks, reserving blocks in transaction violates
filesystem design. Therefore, revert this patch.

This reverts commit 8fd6df1c.

Fixes: 8fd6df1c ("xfs: atomic drop extent entries when inactiving attr")
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent 0fc31598
Loading
Loading
Loading
Loading
+16 −46
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include "xfs_quota.h"
#include "xfs_dir2.h"
#include "xfs_error.h"
#include "xfs_defer.h"

/*
 * Invalidate any incore buffers associated with this remote attribute value
@@ -140,8 +139,7 @@ xfs_attr3_node_inactive(
	xfs_daddr_t		parent_blkno, child_blkno;
	struct xfs_buf		*child_bp;
	struct xfs_da3_icnode_hdr ichdr;
	int			error, i, done;
	xfs_filblks_t		count = mp->m_attr_geo->fsbcount;
	int			error, i;

	/*
	 * Since this code is recursive (gasp!) we must protect ourselves.
@@ -174,13 +172,10 @@ xfs_attr3_node_inactive(
		 * traversal of the tree so we may deal with many blocks
		 * before we come back to this one.
		 */
		error = __xfs_da3_node_read(*trans, dp, child_fsb,
					    XFS_DABUF_MAP_HOLE_OK, &child_bp,
		error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp,
					  XFS_ATTR_FORK);
		if (error)
			return error;
		if (!child_bp)
			goto next_entry;

		/* save for re-read later */
		child_blkno = xfs_buf_daddr(child_bp);
@@ -212,32 +207,14 @@ xfs_attr3_node_inactive(
		 * Remove the subsidiary block from the cache and from the log.
		 */
		error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
					  child_blkno, XFS_FSB_TO_BB(mp, count),
					  0, &child_bp);
				child_blkno,
				XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
				&child_bp);
		if (error)
			return error;

		error = xfs_bunmapi(*trans, dp, child_fsb, count,
				    XFS_BMAPI_ATTRFORK, 0, &done);
		if (error) {
			xfs_trans_brelse(*trans, child_bp);
			return error;
		}
		xfs_trans_binval(*trans, child_bp);

		error = xfs_defer_finish(trans);
		if (error)
			return error;
		child_bp = NULL;

		/*
		 * Atomically commit the whole invalidate stuff.
		 */
		error = xfs_trans_roll_inode(trans, dp);
		if (error)
			return  error;

next_entry:
		/*
		 * If we're not done, re-read the parent to get the next
		 * child block number.
@@ -255,6 +232,12 @@ xfs_attr3_node_inactive(
			xfs_trans_brelse(*trans, bp);
			bp = NULL;
		}
		/*
		 * Atomically commit the whole invalidate stuff.
		 */
		error = xfs_trans_roll_inode(trans, dp);
		if (error)
			return  error;
	}

	return 0;
@@ -275,8 +258,7 @@ xfs_attr3_root_inactive(
	struct xfs_da_blkinfo	*info;
	struct xfs_buf		*bp;
	xfs_daddr_t		blkno;
	xfs_filblks_t		count = mp->m_attr_geo->fsbcount;
	int			error, done;
	int			error;

	/*
	 * Read block 0 to see what we have to work with.
@@ -284,9 +266,8 @@ xfs_attr3_root_inactive(
	 * the extents in reverse order the extent containing
	 * block 0 must still be there.
	 */
	error = __xfs_da3_node_read(*trans, dp, 0, XFS_DABUF_MAP_HOLE_OK,
				    &bp, XFS_ATTR_FORK);
	if (error || !bp)
	error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
	if (error)
		return error;
	blkno = bp->b_bn;

@@ -317,7 +298,7 @@ xfs_attr3_root_inactive(
	 * Invalidate the incore copy of the root block.
	 */
	error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
				  XFS_FSB_TO_BB(mp, count), 0, &bp);
			XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, &bp);
	if (error)
		return error;
	error = bp->b_error;
@@ -325,17 +306,7 @@ xfs_attr3_root_inactive(
		xfs_trans_brelse(*trans, bp);
		return error;
	}

	error = xfs_bunmapi(*trans, dp, 0, count, XFS_BMAPI_ATTRFORK, 0, &done);
	if (error) {
		xfs_trans_brelse(*trans, bp);
		return error;
	}
	xfs_trans_binval(*trans, bp);	/* remove from cache */

	error = xfs_defer_finish(trans);
	if (error)
		return error;
	/*
	 * Commit the invalidate and start the next transaction.
	 */
@@ -398,7 +369,6 @@ xfs_attr_inactive(
		if (error)
			goto out_shutdown;

		/* Remove the potential leftover remote attr blocks. */
		error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
		if (error)
			goto out_cancel;