]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xfs: refactor xfs_bmap_count_blocks using newer btree helpers
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 28 Oct 2019 23:12:35 +0000 (16:12 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Tue, 29 Oct 2019 16:50:11 +0000 (09:50 -0700)
Currently, this function open-codes walking a bmbt to count the extents
and blocks in use by a particular inode fork.  Since we now have a
function to tally extent records from the incore extent tree and a btree
helper to count every block in a btree, replace all that with calls to
the helpers.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_bmap_util.c

index fb31d7d6701eb8f1670259ea52310574ba71a9e9..b16081c9d646945ff02efe0f005dbacad2fbfbbc 100644 (file)
@@ -229,106 +229,6 @@ xfs_bmap_count_leaves(
        return numrecs;
 }
 
-/*
- * Count leaf blocks given a range of extent records originally
- * in btree format.
- */
-STATIC void
-xfs_bmap_disk_count_leaves(
-       struct xfs_mount        *mp,
-       struct xfs_btree_block  *block,
-       int                     numrecs,
-       xfs_filblks_t           *count)
-{
-       int             b;
-       xfs_bmbt_rec_t  *frp;
-
-       for (b = 1; b <= numrecs; b++) {
-               frp = XFS_BMBT_REC_ADDR(mp, block, b);
-               *count += xfs_bmbt_disk_get_blockcount(frp);
-       }
-}
-
-/*
- * Recursively walks each level of a btree
- * to count total fsblocks in use.
- */
-STATIC int
-xfs_bmap_count_tree(
-       struct xfs_mount        *mp,
-       struct xfs_trans        *tp,
-       struct xfs_ifork        *ifp,
-       xfs_fsblock_t           blockno,
-       int                     levelin,
-       xfs_extnum_t            *nextents,
-       xfs_filblks_t           *count)
-{
-       int                     error;
-       struct xfs_buf          *bp, *nbp;
-       int                     level = levelin;
-       __be64                  *pp;
-       xfs_fsblock_t           bno = blockno;
-       xfs_fsblock_t           nextbno;
-       struct xfs_btree_block  *block, *nextblock;
-       int                     numrecs;
-
-       error = xfs_btree_read_bufl(mp, tp, bno, &bp, XFS_BMAP_BTREE_REF,
-                                               &xfs_bmbt_buf_ops);
-       if (error)
-               return error;
-       *count += 1;
-       block = XFS_BUF_TO_BLOCK(bp);
-
-       if (--level) {
-               /* Not at node above leaves, count this level of nodes */
-               nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
-               while (nextbno != NULLFSBLOCK) {
-                       error = xfs_btree_read_bufl(mp, tp, nextbno, &nbp,
-                                               XFS_BMAP_BTREE_REF,
-                                               &xfs_bmbt_buf_ops);
-                       if (error)
-                               return error;
-                       *count += 1;
-                       nextblock = XFS_BUF_TO_BLOCK(nbp);
-                       nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib);
-                       xfs_trans_brelse(tp, nbp);
-               }
-
-               /* Dive to the next level */
-               pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
-               bno = be64_to_cpu(*pp);
-               error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, nextents,
-                               count);
-               if (error) {
-                       xfs_trans_brelse(tp, bp);
-                       XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
-                                        XFS_ERRLEVEL_LOW, mp);
-                       return -EFSCORRUPTED;
-               }
-               xfs_trans_brelse(tp, bp);
-       } else {
-               /* count all level 1 nodes and their leaves */
-               for (;;) {
-                       nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
-                       numrecs = be16_to_cpu(block->bb_numrecs);
-                       (*nextents) += numrecs;
-                       xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
-                       xfs_trans_brelse(tp, bp);
-                       if (nextbno == NULLFSBLOCK)
-                               break;
-                       bno = nextbno;
-                       error = xfs_btree_read_bufl(mp, tp, bno, &bp,
-                                               XFS_BMAP_BTREE_REF,
-                                               &xfs_bmbt_buf_ops);
-                       if (error)
-                               return error;
-                       *count += 1;
-                       block = XFS_BUF_TO_BLOCK(bp);
-               }
-       }
-       return 0;
-}
-
 /*
  * Count fsblocks of the given fork.  Delayed allocation extents are
  * not counted towards the totals.
@@ -341,26 +241,19 @@ xfs_bmap_count_blocks(
        xfs_extnum_t            *nextents,
        xfs_filblks_t           *count)
 {
-       struct xfs_mount        *mp;    /* file system mount structure */
-       __be64                  *pp;    /* pointer to block address */
-       struct xfs_btree_block  *block; /* current btree block */
-       struct xfs_ifork        *ifp;   /* fork structure */
-       xfs_fsblock_t           bno;    /* block # of "block" */
-       int                     level;  /* btree level, for checking */
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, whichfork);
+       struct xfs_btree_cur    *cur;
+       xfs_extlen_t            btblocks = 0;
        int                     error;
 
-       bno = NULLFSBLOCK;
-       mp = ip->i_mount;
        *nextents = 0;
        *count = 0;
-       ifp = XFS_IFORK_PTR(ip, whichfork);
+
        if (!ifp)
                return 0;
 
        switch (XFS_IFORK_FORMAT(ip, whichfork)) {
-       case XFS_DINODE_FMT_EXTENTS:
-               *nextents = xfs_bmap_count_leaves(ifp, count);
-               return 0;
        case XFS_DINODE_FMT_BTREE:
                if (!(ifp->if_flags & XFS_IFEXTENTS)) {
                        error = xfs_iread_extents(tp, ip, whichfork);
@@ -368,26 +261,23 @@ xfs_bmap_count_blocks(
                                return error;
                }
 
+               cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
+               error = xfs_btree_count_blocks(cur, &btblocks);
+               xfs_btree_del_cursor(cur, error);
+               if (error)
+                       return error;
+
                /*
-                * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
+                * xfs_btree_count_blocks includes the root block contained in
+                * the inode fork in @btblocks, so subtract one because we're
+                * only interested in allocated disk blocks.
                 */
-               block = ifp->if_broot;
-               level = be16_to_cpu(block->bb_level);
-               ASSERT(level > 0);
-               pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
-               bno = be64_to_cpu(*pp);
-               ASSERT(bno != NULLFSBLOCK);
-               ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
-               ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
-
-               error = xfs_bmap_count_tree(mp, tp, ifp, bno, level,
-                               nextents, count);
-               if (error) {
-                       XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)",
-                                       XFS_ERRLEVEL_LOW, mp);
-                       return -EFSCORRUPTED;
-               }
-               return 0;
+               *count += btblocks - 1;
+
+               /* fall through */
+       case XFS_DINODE_FMT_EXTENTS:
+               *nextents = xfs_bmap_count_leaves(ifp, count);
+               break;
        }
 
        return 0;