xfs: create a new inode fork block unmap helper
authorDarrick J. Wong <djwong@kernel.org>
Fri, 15 Dec 2023 18:03:43 +0000 (10:03 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 15 Dec 2023 18:03:43 +0000 (10:03 -0800)
Create a new helper to unmap blocks from an inode's fork.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/xfs_inode.c

index a073ca877ceda9c16b970eb02cde318a9e0cb871..523926fe50eb0a3173b91d49dd503f9985f091a0 100644 (file)
@@ -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;
+}
index 8518324db2855631b0e4d87a08b0c487b47300b9..4b83f6148e0071c00c9d88744c2d60261c991fd4 100644 (file)
@@ -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;
 
index ea6b277485a43346c0f07e2e98997c7cf20705f7..1ffc8dfa2a52ce6fe98f21ae6d9001ae967a0ca5 100644 (file)
 
 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,19 +1371,10 @@ 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);
-               if (error)
-                       goto out;
-
-               /* free the just unmapped extents */
-               error = xfs_defer_finish(&tp);
-               if (error)
-                       goto out;
-       }
+       error = xfs_bunmapi_range(&tp, ip, flags, first_unmap_block,
+                       XFS_MAX_FILEOFF);
+       if (error)
+               goto out;
 
        if (whichfork == XFS_DATA_FORK) {
                /* Remove all pending CoW reservations. */