]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: support deferred bmap updates on the attr fork
authorDarrick J. Wong <djwong@kernel.org>
Mon, 22 Apr 2024 17:01:13 +0000 (10:01 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:41 +0000 (11:37 -0700)
Source kernel commit: 52f807067ba4a122e75bf1e0e0595c78e6a3d8b6

The deferred bmap update log item has always supported the attr fork, so
plumb this in so that higher layers can access this.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
libxfs/xfs_bmap.c
libxfs/xfs_bmap.h

index 38855091283c97c67669408bbb3e578bc07f82c2..f09ec3dfe0c9080e8a3673e41a79caef535d9efa 100644 (file)
@@ -6166,17 +6166,8 @@ del_cursor:
        return error;
 }
 
-/* Deferred mapping is only for real extents in the data fork. */
-static bool
-xfs_bmap_is_update_needed(
-       struct xfs_bmbt_irec    *bmap)
-{
-       return  bmap->br_startblock != HOLESTARTBLOCK &&
-               bmap->br_startblock != DELAYSTARTBLOCK;
-}
-
 /* Record a bmap intent. */
-static int
+static inline void
 __xfs_bmap_add(
        struct xfs_trans                *tp,
        enum xfs_bmap_intent_type       type,
@@ -6186,6 +6177,11 @@ __xfs_bmap_add(
 {
        struct xfs_bmap_intent          *bi;
 
+       if ((whichfork != XFS_DATA_FORK && whichfork != XFS_ATTR_FORK) ||
+           bmap->br_startblock == HOLESTARTBLOCK ||
+           bmap->br_startblock == DELAYSTARTBLOCK)
+               return;
+
        bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
        INIT_LIST_HEAD(&bi->bi_list);
        bi->bi_type = type;
@@ -6194,7 +6190,6 @@ __xfs_bmap_add(
        bi->bi_bmap = *bmap;
 
        xfs_bmap_defer_add(tp, bi);
-       return 0;
 }
 
 /* Map an extent into a file. */
@@ -6202,12 +6197,10 @@ void
 xfs_bmap_map_extent(
        struct xfs_trans        *tp,
        struct xfs_inode        *ip,
+       int                     whichfork,
        struct xfs_bmbt_irec    *PREV)
 {
-       if (!xfs_bmap_is_update_needed(PREV))
-               return;
-
-       __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV);
+       __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, whichfork, PREV);
 }
 
 /* Unmap an extent out of a file. */
@@ -6215,12 +6208,10 @@ void
 xfs_bmap_unmap_extent(
        struct xfs_trans        *tp,
        struct xfs_inode        *ip,
+       int                     whichfork,
        struct xfs_bmbt_irec    *PREV)
 {
-       if (!xfs_bmap_is_update_needed(PREV))
-               return;
-
-       __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV);
+       __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, whichfork, PREV);
 }
 
 /*
@@ -6234,29 +6225,29 @@ xfs_bmap_finish_one(
 {
        struct xfs_bmbt_irec            *bmap = &bi->bi_bmap;
        int                             error = 0;
+       int                             flags = 0;
+
+       if (bi->bi_whichfork == XFS_ATTR_FORK)
+               flags |= XFS_BMAPI_ATTRFORK;
 
        ASSERT(tp->t_highest_agno == NULLAGNUMBER);
 
        trace_xfs_bmap_deferred(bi);
 
-       if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
-               xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
-               return -EFSCORRUPTED;
-       }
-
-       if (XFS_TEST_ERROR(false, tp->t_mountp,
-                       XFS_ERRTAG_BMAP_FINISH_ONE))
+       if (XFS_TEST_ERROR(false, tp->t_mountp, XFS_ERRTAG_BMAP_FINISH_ONE))
                return -EIO;
 
        switch (bi->bi_type) {
        case XFS_BMAP_MAP:
                error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff,
-                               bmap->br_blockcount, bmap->br_startblock, 0);
+                               bmap->br_blockcount, bmap->br_startblock,
+                               flags);
                bmap->br_blockcount = 0;
                break;
        case XFS_BMAP_UNMAP:
                error = __xfs_bunmapi(tp, bi->bi_owner, bmap->br_startoff,
-                               &bmap->br_blockcount, XFS_BMAPI_REMAP, 1);
+                               &bmap->br_blockcount, flags | XFS_BMAPI_REMAP,
+                               1);
                break;
        default:
                ASSERT(0);
index 325cc232a4153df49d8a83e6df0f0cad5529be92..f7662595309d8611ec5de1a731fb7bdaf5097d87 100644 (file)
@@ -247,9 +247,9 @@ struct xfs_bmap_intent {
 
 int    xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
 void   xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
-               struct xfs_bmbt_irec *imap);
+               int whichfork, struct xfs_bmbt_irec *imap);
 void   xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
-               struct xfs_bmbt_irec *imap);
+               int whichfork, struct xfs_bmbt_irec *imap);
 
 static inline uint32_t xfs_bmap_fork_to_state(int whichfork)
 {