@@ -225,14 +225,16 @@ xfs_bmap_eof(
225
225
STATIC void
226
226
xfs_bmap_count_leaves (
227
227
struct xfs_ifork * ifp ,
228
- int * count )
228
+ xfs_extnum_t * numrecs ,
229
+ xfs_filblks_t * count )
229
230
{
230
231
xfs_extnum_t i ;
231
232
xfs_extnum_t nr_exts = xfs_iext_count (ifp );
232
233
233
234
for (i = 0 ; i < nr_exts ; i ++ ) {
234
235
xfs_bmbt_rec_host_t * frp = xfs_iext_get_ext (ifp , i );
235
236
if (!isnullstartblock (xfs_bmbt_get_startblock (frp ))) {
237
+ (* numrecs )++ ;
236
238
* count += xfs_bmbt_get_blockcount (frp );
237
239
}
238
240
}
@@ -247,7 +249,7 @@ xfs_bmap_disk_count_leaves(
247
249
struct xfs_mount * mp ,
248
250
struct xfs_btree_block * block ,
249
251
int numrecs ,
250
- int * count )
252
+ xfs_filblks_t * count )
251
253
{
252
254
int b ;
253
255
xfs_bmbt_rec_t * frp ;
@@ -262,17 +264,18 @@ xfs_bmap_disk_count_leaves(
262
264
* Recursively walks each level of a btree
263
265
* to count total fsblocks in use.
264
266
*/
265
- STATIC int /* error */
267
+ STATIC int
266
268
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 )
273
276
{
274
277
int error ;
275
- xfs_buf_t * bp , * nbp ;
278
+ struct xfs_buf * bp , * nbp ;
276
279
int level = levelin ;
277
280
__be64 * pp ;
278
281
xfs_fsblock_t bno = blockno ;
@@ -305,8 +308,9 @@ xfs_bmap_count_tree(
305
308
/* Dive to the next level */
306
309
pp = XFS_BMBT_PTR_ADDR (mp , block , 1 , mp -> m_bmap_dmxr [1 ]);
307
310
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 ) {
310
314
xfs_trans_brelse (tp , bp );
311
315
XFS_ERROR_REPORT ("xfs_bmap_count_tree(1)" ,
312
316
XFS_ERRLEVEL_LOW , mp );
@@ -318,6 +322,7 @@ xfs_bmap_count_tree(
318
322
for (;;) {
319
323
nextbno = be64_to_cpu (block -> bb_u .l .bb_rightsib );
320
324
numrecs = be16_to_cpu (block -> bb_numrecs );
325
+ (* nextents ) += numrecs ;
321
326
xfs_bmap_disk_count_leaves (mp , block , numrecs , count );
322
327
xfs_trans_brelse (tp , bp );
323
328
if (nextbno == NULLFSBLOCK )
@@ -339,44 +344,61 @@ xfs_bmap_count_tree(
339
344
* Count fsblocks of the given fork. Delayed allocation extents are
340
345
* not counted towards the totals.
341
346
*/
342
- static int /* error */
347
+ int
343
348
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 )
348
354
{
355
+ struct xfs_mount * mp ; /* file system mount structure */
356
+ __be64 * pp ; /* pointer to block address */
349
357
struct xfs_btree_block * block ; /* current btree block */
358
+ struct xfs_ifork * ifp ; /* fork structure */
350
359
xfs_fsblock_t bno ; /* block # of "block" */
351
- xfs_ifork_t * ifp ; /* fork structure */
352
360
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 ;
355
362
356
363
bno = NULLFSBLOCK ;
357
364
mp = ip -> i_mount ;
365
+ * nextents = 0 ;
366
+ * count = 0 ;
358
367
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 )
361
369
return 0 ;
362
- }
363
370
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 ;
380
402
}
381
403
382
404
return 0 ;
@@ -1792,8 +1814,9 @@ xfs_swap_extent_forks(
1792
1814
int * target_log_flags )
1793
1815
{
1794
1816
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 ;
1797
1820
xfs_extnum_t nextents ;
1798
1821
uint64_t tmp ;
1799
1822
int error ;
@@ -1803,14 +1826,14 @@ xfs_swap_extent_forks(
1803
1826
*/
1804
1827
if ( ((XFS_IFORK_Q (ip ) != 0 ) && (ip -> i_d .di_anextents > 0 )) &&
1805
1828
(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 ,
1807
1830
& aforkblks );
1808
1831
if (error )
1809
1832
return error ;
1810
1833
}
1811
1834
if ( ((XFS_IFORK_Q (tip ) != 0 ) && (tip -> i_d .di_anextents > 0 )) &&
1812
1835
(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 ,
1814
1837
& taforkblks );
1815
1838
if (error )
1816
1839
return error ;
0 commit comments