]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: refactor xfs_reflink_find_shared
authorDarrick J. Wong <djwong@kernel.org>
Sat, 21 Sep 2024 05:19:40 +0000 (07:19 +0200)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 08:48:25 +0000 (10:48 +0200)
Move lookup of the perag structure from the callers into the helpers,
and return the offset into the extent of the shared region instead of
the block number that needs post-processing.  This prepares the
callsites for the creation of an rt-specific variant in the next patch.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: port to the middle of the rtreflink series for cleanliness]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_reflink.c
fs/xfs/xfs_reflink.h

index d6c0a66663b40b0e7871fce148b66ba97bfd01f8..82959b8d0703a96e231628299927b4eb4d0d7542 100644 (file)
  */
 
 /*
- * Given an AG extent, find the lowest-numbered run of shared blocks
- * within that range and return the range in fbno/flen.  If
- * find_end_of_shared is true, return the longest contiguous extent of
- * shared blocks.  If there are no shared extents, fbno and flen will
- * be set to NULLAGBLOCK and 0, respectively.
+ * Given a file mapping for the data device, find the lowest-numbered run of
+ * shared blocks within that mapping and return it in shared_offset/shared_len.
+ * The offset is relative to the start of irec.
+ *
+ * If find_end_of_shared is true, return the longest contiguous extent of shared
+ * blocks.  If there are no shared extents, shared_offset and shared_len will be
+ * set to 0;
  */
 static int
 xfs_reflink_find_shared(
-       struct xfs_perag        *pag,
+       struct xfs_mount        *mp,
        struct xfs_trans        *tp,
-       xfs_agblock_t           agbno,
-       xfs_extlen_t            aglen,
-       xfs_agblock_t           *fbno,
-       xfs_extlen_t            *flen,
+       const struct xfs_bmbt_irec *irec,
+       xfs_extlen_t            *shared_offset,
+       xfs_extlen_t            *shared_len,
        bool                    find_end_of_shared)
 {
        struct xfs_buf          *agbp;
+       struct xfs_perag        *pag;
        struct xfs_btree_cur    *cur;
        int                     error;
+       xfs_agblock_t           orig_bno, found_bno;
+
+       pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, irec->br_startblock));
+       orig_bno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
 
        error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
        if (error)
                return error;
 
-       cur = xfs_refcountbt_init_cursor(pag_mount(pag), tp, agbp, pag);
-
-       error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
-                       find_end_of_shared);
-
+       cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
+       error = xfs_refcount_find_shared(cur, orig_bno, irec->br_blockcount,
+                       &found_bno, shared_len, find_end_of_shared);
        xfs_btree_del_cursor(cur, error);
-
        xfs_trans_brelse(tp, agbp);
+       xfs_perag_put(pag);
+
+       if (!error && *shared_len)
+               *shared_offset = found_bno - orig_bno;
        return error;
 }
 
@@ -172,11 +179,7 @@ xfs_reflink_trim_around_shared(
        bool                    *shared)
 {
        struct xfs_mount        *mp = ip->i_mount;
-       struct xfs_perag        *pag;
-       xfs_agblock_t           agbno;
-       xfs_extlen_t            aglen;
-       xfs_agblock_t           fbno;
-       xfs_extlen_t            flen;
+       xfs_extlen_t            shared_offset, shared_len;
        int                     error = 0;
 
        /* Holes, unwritten, and delalloc extents cannot be shared */
@@ -187,41 +190,33 @@ xfs_reflink_trim_around_shared(
 
        trace_xfs_reflink_trim_around_shared(ip, irec);
 
-       pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, irec->br_startblock));
-       agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
-       aglen = irec->br_blockcount;
-
-       error = xfs_reflink_find_shared(pag, NULL, agbno, aglen, &fbno, &flen,
-                       true);
-       xfs_perag_put(pag);
+       error = xfs_reflink_find_shared(mp, NULL, irec, &shared_offset,
+                       &shared_len, true);
        if (error)
                return error;
 
-       *shared = false;
-       if (fbno == NULLAGBLOCK) {
+       if (!shared_len) {
                /* No shared blocks at all. */
-               return 0;
-       }
-
-       if (fbno == agbno) {
+               *shared = false;
+       } else if (!shared_offset) {
                /*
-                * The start of this extent is shared.  Truncate the
-                * mapping at the end of the shared region so that a
-                * subsequent iteration starts at the start of the
-                * unshared region.
+                * The start of this mapping points to shared space.  Truncate
+                * the mapping at the end of the shared region so that a
+                * subsequent iteration starts at the start of the unshared
+                * region.
                 */
-               irec->br_blockcount = flen;
+               irec->br_blockcount = shared_len;
                *shared = true;
-               return 0;
+       } else {
+               /*
+                * There's a shared region that doesn't start at the beginning
+                * of the mapping.  Truncate the mapping at the start of the
+                * shared extent so that a subsequent iteration starts at the
+                * start of the shared region.
+                */
+               irec->br_blockcount = shared_offset;
+               *shared = false;
        }
-
-       /*
-        * There's a shared extent midway through this extent.
-        * Truncate the mapping at the start of the shared
-        * extent so that a subsequent iteration starts at the
-        * start of the shared region.
-        */
-       irec->br_blockcount = fbno - agbno;
        return 0;
 }
 
@@ -1552,27 +1547,19 @@ xfs_reflink_inode_has_shared_extents(
        *has_shared = false;
        found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got);
        while (found) {
-               struct xfs_perag        *pag;
-               xfs_agblock_t           agbno;
-               xfs_extlen_t            aglen;
-               xfs_agblock_t           rbno;
-               xfs_extlen_t            rlen;
+               xfs_extlen_t            shared_offset, shared_len;
 
                if (isnullstartblock(got.br_startblock) ||
                    got.br_state != XFS_EXT_NORM)
                        goto next;
 
-               pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, got.br_startblock));
-               agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock);
-               aglen = got.br_blockcount;
-               error = xfs_reflink_find_shared(pag, tp, agbno, aglen,
-                               &rbno, &rlen, false);
-               xfs_perag_put(pag);
+               error = xfs_reflink_find_shared(mp, tp, &got, &shared_offset,
+                               &shared_len, false);
                if (error)
                        return error;
 
                /* Is there still a shared block here? */
-               if (rbno != NULLAGBLOCK) {
+               if (shared_len) {
                        *has_shared = true;
                        return 0;
                }
index fb55e4ce49fa1019d2c9e6c4224c4bd7ccc55eee..6dd3b0c3b205ea7ec691d826fe4666cc77c74fea 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef __XFS_REFLINK_H
 #define __XFS_REFLINK_H 1
 
-extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
+int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
                struct xfs_bmbt_irec *irec, bool *shared);
 int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
                bool *shared);