Deleting a file range from the middle of an existing extent can cause the per-inode extent count to increase by 1. This commit checks for extent count overflow in such cases. Signed-off-by: Chandan Babu R <chandanrlinux@xxxxxxxxx> --- fs/xfs/libxfs/xfs_inode_fork.h | 6 ++++++ fs/xfs/xfs_bmap_item.c | 4 ++++ fs/xfs/xfs_bmap_util.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 3e7e4b980d49..228359cf9738 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -35,6 +35,12 @@ struct xfs_ifork { #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ #define XFS_IEXT_ADD_CNT 1 +/* + * Removing an extent from the middle of an existing extent + * can cause the extent count to increase by 1. + * i.e. | Old extent | Hole | Old extent | + */ +#define XFS_IEXT_REMOVE_CNT 1 /* * Fork handling. diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index ec3691372e7c..b9c35fb10de4 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -519,6 +519,10 @@ xfs_bui_item_recover( } xfs_trans_ijoin(tp, ip, 0); + error = xfs_iext_count_may_overflow(ip, whichfork, XFS_IEXT_REMOVE_CNT); + if (error) + goto err_inode; + count = bmap->me_len; error = xfs_trans_log_finish_bmap_update(tp, budp, type, ip, whichfork, bmap->me_startoff, bmap->me_startblock, &count, state); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index c470f2cd6e66..94abdb547c7f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -891,6 +891,11 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); + error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK, + XFS_IEXT_REMOVE_CNT); + if (error) + goto out_trans_cancel; + error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done); if (error) goto out_trans_cancel; -- 2.28.0