
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBEN7H 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 94349af34627d25a109176af9d365a4d5bfb90ef. Fixes: 94349af34627 ("xfs: atomic drop extent entries when inactiving attr") Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/xfs/xfs_attr_inactive.c | 62 ++++++++++---------------------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 9de68b6a148c..f03fa219e1cb 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -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, - XFS_ATTR_FORK); + 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 = xfs_buf_daddr(bp); @@ -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. */ @@ -397,7 +368,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; -- 2.39.2