]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: check for shared rt extents when rebuilding rt file's data fork
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:21:15 +0000 (16:21 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 23 Dec 2024 21:06:16 +0000 (13:06 -0800)
When we're rebuilding the data fork of a realtime file, we need to
cross-reference each mapping with the rt refcount btree to ensure that
the reflink flag is set if there are any shared extents found.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/scrub/bmap_repair.c

index fd64bdf4e13887036e5bb1101d44ff8794a8fdf3..1084213b8e9b8876f461714781d142a12264a758 100644 (file)
@@ -101,14 +101,21 @@ xrep_bmap_discover_shared(
        xfs_filblks_t           blockcount)
 {
        struct xfs_scrub        *sc = rb->sc;
+       struct xfs_btree_cur    *cur;
        xfs_agblock_t           agbno;
        xfs_agblock_t           fbno;
        xfs_extlen_t            flen;
        int                     error;
 
-       agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock);
-       error = xfs_refcount_find_shared(sc->sa.refc_cur, agbno, blockcount,
-                       &fbno, &flen, false);
+       if (XFS_IS_REALTIME_INODE(sc->ip)) {
+               agbno = xfs_rtb_to_rgbno(sc->mp, startblock);
+               cur = sc->sr.refc_cur;
+       } else {
+               agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock);
+               cur = sc->sa.refc_cur;
+       }
+       error = xfs_refcount_find_shared(cur, agbno, blockcount, &fbno, &flen,
+                       false);
        if (error)
                return error;
 
@@ -450,7 +457,9 @@ xrep_bmap_scan_rtgroup(
                return 0;
 
        error = xrep_rtgroup_init(sc, rtg, &sc->sr,
-                       XFS_RTGLOCK_RMAP | XFS_RTGLOCK_BITMAP_SHARED);
+                       XFS_RTGLOCK_RMAP |
+                       XFS_RTGLOCK_REFCOUNT |
+                       XFS_RTGLOCK_BITMAP_SHARED);
        if (error)
                return error;
 
@@ -903,10 +912,6 @@ xrep_bmap_init_reflink_scan(
        if (whichfork != XFS_DATA_FORK)
                return RLS_IRRELEVANT;
 
-       /* cannot share realtime extents */
-       if (XFS_IS_REALTIME_INODE(sc->ip))
-               return RLS_IRRELEVANT;
-
        return RLS_UNKNOWN;
 }