Skip to content

Commit e7f5d5c

Browse files
committed
xfs: refactor the ifork block counting function
Refactor the inode fork block counting function to count extents for us at the same time. This will be used by the bmbt scrubber function. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Brian Foster <[email protected]>
1 parent d29cb3e commit e7f5d5c

File tree

2 files changed

+70
-43
lines changed

2 files changed

+70
-43
lines changed

fs/xfs/xfs_bmap_util.c

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,16 @@ xfs_bmap_eof(
225225
STATIC void
226226
xfs_bmap_count_leaves(
227227
struct xfs_ifork *ifp,
228-
int *count)
228+
xfs_extnum_t *numrecs,
229+
xfs_filblks_t *count)
229230
{
230231
xfs_extnum_t i;
231232
xfs_extnum_t nr_exts = xfs_iext_count(ifp);
232233

233234
for (i = 0; i < nr_exts; i++) {
234235
xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, i);
235236
if (!isnullstartblock(xfs_bmbt_get_startblock(frp))) {
237+
(*numrecs)++;
236238
*count += xfs_bmbt_get_blockcount(frp);
237239
}
238240
}
@@ -247,7 +249,7 @@ xfs_bmap_disk_count_leaves(
247249
struct xfs_mount *mp,
248250
struct xfs_btree_block *block,
249251
int numrecs,
250-
int *count)
252+
xfs_filblks_t *count)
251253
{
252254
int b;
253255
xfs_bmbt_rec_t *frp;
@@ -262,17 +264,18 @@ xfs_bmap_disk_count_leaves(
262264
* Recursively walks each level of a btree
263265
* to count total fsblocks in use.
264266
*/
265-
STATIC int /* error */
267+
STATIC int
266268
xfs_bmap_count_tree(
267-
xfs_mount_t *mp, /* file system mount point */
268-
xfs_trans_t *tp, /* transaction pointer */
269-
xfs_ifork_t *ifp, /* inode fork pointer */
270-
xfs_fsblock_t blockno, /* file system block number */
271-
int levelin, /* level in btree */
272-
int *count) /* Count of blocks */
269+
struct xfs_mount *mp,
270+
struct xfs_trans *tp,
271+
struct xfs_ifork *ifp,
272+
xfs_fsblock_t blockno,
273+
int levelin,
274+
xfs_extnum_t *nextents,
275+
xfs_filblks_t *count)
273276
{
274277
int error;
275-
xfs_buf_t *bp, *nbp;
278+
struct xfs_buf *bp, *nbp;
276279
int level = levelin;
277280
__be64 *pp;
278281
xfs_fsblock_t bno = blockno;
@@ -305,8 +308,9 @@ xfs_bmap_count_tree(
305308
/* Dive to the next level */
306309
pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
307310
bno = be64_to_cpu(*pp);
308-
if (unlikely((error =
309-
xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
311+
error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, nextents,
312+
count);
313+
if (error) {
310314
xfs_trans_brelse(tp, bp);
311315
XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
312316
XFS_ERRLEVEL_LOW, mp);
@@ -318,6 +322,7 @@ xfs_bmap_count_tree(
318322
for (;;) {
319323
nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
320324
numrecs = be16_to_cpu(block->bb_numrecs);
325+
(*nextents) += numrecs;
321326
xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
322327
xfs_trans_brelse(tp, bp);
323328
if (nextbno == NULLFSBLOCK)
@@ -339,44 +344,61 @@ xfs_bmap_count_tree(
339344
* Count fsblocks of the given fork. Delayed allocation extents are
340345
* not counted towards the totals.
341346
*/
342-
static int /* error */
347+
int
343348
xfs_bmap_count_blocks(
344-
xfs_trans_t *tp, /* transaction pointer */
345-
xfs_inode_t *ip, /* incore inode */
346-
int whichfork, /* data or attr fork */
347-
int *count) /* out: count of blocks */
349+
struct xfs_trans *tp,
350+
struct xfs_inode *ip,
351+
int whichfork,
352+
xfs_extnum_t *nextents,
353+
xfs_filblks_t *count)
348354
{
355+
struct xfs_mount *mp; /* file system mount structure */
356+
__be64 *pp; /* pointer to block address */
349357
struct xfs_btree_block *block; /* current btree block */
358+
struct xfs_ifork *ifp; /* fork structure */
350359
xfs_fsblock_t bno; /* block # of "block" */
351-
xfs_ifork_t *ifp; /* fork structure */
352360
int level; /* btree level, for checking */
353-
xfs_mount_t *mp; /* file system mount structure */
354-
__be64 *pp; /* pointer to block address */
361+
int error;
355362

356363
bno = NULLFSBLOCK;
357364
mp = ip->i_mount;
365+
*nextents = 0;
366+
*count = 0;
358367
ifp = XFS_IFORK_PTR(ip, whichfork);
359-
if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
360-
xfs_bmap_count_leaves(ifp, count);
368+
if (!ifp)
361369
return 0;
362-
}
363370

364-
/*
365-
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
366-
*/
367-
block = ifp->if_broot;
368-
level = be16_to_cpu(block->bb_level);
369-
ASSERT(level > 0);
370-
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
371-
bno = be64_to_cpu(*pp);
372-
ASSERT(bno != NULLFSBLOCK);
373-
ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
374-
ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
375-
376-
if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
377-
XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
378-
mp);
379-
return -EFSCORRUPTED;
371+
switch (XFS_IFORK_FORMAT(ip, whichfork)) {
372+
case XFS_DINODE_FMT_EXTENTS:
373+
xfs_bmap_count_leaves(ifp, nextents, count);
374+
return 0;
375+
case XFS_DINODE_FMT_BTREE:
376+
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
377+
error = xfs_iread_extents(tp, ip, whichfork);
378+
if (error)
379+
return error;
380+
}
381+
382+
/*
383+
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
384+
*/
385+
block = ifp->if_broot;
386+
level = be16_to_cpu(block->bb_level);
387+
ASSERT(level > 0);
388+
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
389+
bno = be64_to_cpu(*pp);
390+
ASSERT(bno != NULLFSBLOCK);
391+
ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
392+
ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
393+
394+
error = xfs_bmap_count_tree(mp, tp, ifp, bno, level,
395+
nextents, count);
396+
if (error) {
397+
XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)",
398+
XFS_ERRLEVEL_LOW, mp);
399+
return -EFSCORRUPTED;
400+
}
401+
return 0;
380402
}
381403

382404
return 0;
@@ -1792,8 +1814,9 @@ xfs_swap_extent_forks(
17921814
int *target_log_flags)
17931815
{
17941816
struct xfs_ifork tempifp, *ifp, *tifp;
1795-
int aforkblks = 0;
1796-
int taforkblks = 0;
1817+
xfs_filblks_t aforkblks = 0;
1818+
xfs_filblks_t taforkblks = 0;
1819+
xfs_extnum_t junk;
17971820
xfs_extnum_t nextents;
17981821
uint64_t tmp;
17991822
int error;
@@ -1803,14 +1826,14 @@ xfs_swap_extent_forks(
18031826
*/
18041827
if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
18051828
(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
1806-
error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK,
1829+
error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk,
18071830
&aforkblks);
18081831
if (error)
18091832
return error;
18101833
}
18111834
if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
18121835
(tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
1813-
error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
1836+
error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk,
18141837
&taforkblks);
18151838
if (error)
18161839
return error;

fs/xfs/xfs_bmap_util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,8 @@ int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
7070

7171
xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb);
7272

73+
int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
74+
int whichfork, xfs_extnum_t *nextents,
75+
xfs_filblks_t *count);
76+
7377
#endif /* __XFS_BMAP_UTIL_H__ */

0 commit comments

Comments
 (0)