mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
xfs: refactor xfs_bmap_count_blocks using newer btree helpers
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>
This commit is contained in:
parent
c2414ad6e6
commit
fec40e220f
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
|
||||
*/
|
||||
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);
|
||||
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;
|
||||
|
||||
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;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
*count += btblocks - 1;
|
||||
|
||||
/* fall through */
|
||||
case XFS_DINODE_FMT_EXTENTS:
|
||||
*nextents = xfs_bmap_count_leaves(ifp, count);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user