Commit a59eb5fc authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: create a new inode fork block unmap helper



Create a new helper to unmap blocks from an inode's fork.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 5a8e07e7
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -5239,7 +5239,7 @@ xfs_bmap_del_extent_real(
 * that value.  If not all extents in the block range can be removed then
 * *done is set.
 */
int						/* error */
static int
__xfs_bunmapi(
	struct xfs_trans	*tp,		/* transaction pointer */
	struct xfs_inode	*ip,		/* incore inode */
@@ -6220,3 +6220,42 @@ xfs_bmap_validate_extent(
	return xfs_bmap_validate_extent_raw(ip->i_mount,
			XFS_IS_REALTIME_INODE(ip), whichfork, irec);
}

/*
 * Used in xfs_itruncate_extents().  This is the maximum number of extents
 * freed from a file in a single transaction.
 */
#define	XFS_ITRUNC_MAX_EXTENTS	2

/*
 * Unmap every extent in part of an inode's fork.  We don't do any higher level
 * invalidation work at all.
 */
int
xfs_bunmapi_range(
	struct xfs_trans	**tpp,
	struct xfs_inode	*ip,
	uint32_t		flags,
	xfs_fileoff_t		startoff,
	xfs_fileoff_t		endoff)
{
	xfs_filblks_t		unmap_len = endoff - startoff + 1;
	int			error = 0;

	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));

	while (unmap_len > 0) {
		ASSERT((*tpp)->t_highest_agno == NULLAGNUMBER);
		error = __xfs_bunmapi(*tpp, ip, startoff, &unmap_len, flags,
				XFS_ITRUNC_MAX_EXTENTS);
		if (error)
			goto out;

		/* free the just unmapped extents */
		error = xfs_defer_finish(tpp);
		if (error)
			goto out;
	}
out:
	return error;
}
+2 −3
Original line number Diff line number Diff line
@@ -190,9 +190,6 @@ int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno,
int	xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip,
		xfs_fileoff_t bno, xfs_filblks_t len, uint32_t flags,
		xfs_extlen_t total, struct xfs_bmbt_irec *mval, int *nmap);
int	__xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
		xfs_fileoff_t bno, xfs_filblks_t *rlen, uint32_t flags,
		xfs_extnum_t nexts);
int	xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
		xfs_fileoff_t bno, xfs_filblks_t len, uint32_t flags,
		xfs_extnum_t nexts, int *done);
@@ -273,6 +270,8 @@ int xfs_bmap_complain_bad_rec(struct xfs_inode *ip, int whichfork,
int	xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
		xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
		uint32_t flags);
int	xfs_bunmapi_range(struct xfs_trans **tpp, struct xfs_inode *ip,
		uint32_t flags, xfs_fileoff_t startoff, xfs_fileoff_t endoff);

extern struct kmem_cache	*xfs_bmap_intent_cache;

+4 −20
Original line number Diff line number Diff line
@@ -41,12 +41,6 @@

struct kmem_cache *xfs_inode_cache;

/*
 * Used in xfs_itruncate_extents().  This is the maximum number of extents
 * freed from a file in a single transaction.
 */
#define	XFS_ITRUNC_MAX_EXTENTS	2

STATIC int xfs_iunlink(struct xfs_trans *, struct xfs_inode *);
STATIC int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag,
	struct xfs_inode *);
@@ -1346,7 +1340,6 @@ xfs_itruncate_extents_flags(
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_trans	*tp = *tpp;
	xfs_fileoff_t		first_unmap_block;
	xfs_filblks_t		unmap_len;
	int			error = 0;

	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -1378,20 +1371,11 @@ xfs_itruncate_extents_flags(
		return 0;
	}

	unmap_len = XFS_MAX_FILEOFF - first_unmap_block + 1;
	while (unmap_len > 0) {
		ASSERT(tp->t_highest_agno == NULLAGNUMBER);
		error = __xfs_bunmapi(tp, ip, first_unmap_block, &unmap_len,
				flags, XFS_ITRUNC_MAX_EXTENTS);
	error = xfs_bunmapi_range(&tp, ip, flags, first_unmap_block,
			XFS_MAX_FILEOFF);
	if (error)
		goto out;

		/* free the just unmapped extents */
		error = xfs_defer_finish(&tp);
		if (error)
			goto out;
	}

	if (whichfork == XFS_DATA_FORK) {
		/* Remove all pending CoW reservations. */
		error = xfs_reflink_cancel_cow_blocks(ip, &tp,