]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: return a 64-bit block count from xfs_btree_count_blocks
authorDarrick J. Wong <djwong@kernel.org>
Mon, 16 Dec 2024 02:18:41 +0000 (18:18 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:31 +0000 (18:01 -0800)
Source kernel commit: bd27c7bcdca25ce8067ebb94ded6ac1bd7b47317

With the nrext64 feature enabled, it's possible for a data fork to have
2^48 extent mappings.  Even with a 64k fsblock size, that maps out to
a bmbt containing more than 2^32 blocks.  Therefore, this predicate must
return a u64 count to avoid an integer wraparound that will cause scrub
to do the wrong thing.

It's unlikely that any such filesystem currently exists, because the
incore bmbt would consume more than 64GB of kernel memory on its own,
and so far nobody except me has driven a filesystem that far, judging
from the lack of complaints.

Cc: <stable@vger.kernel.org> # v5.19
Fixes: df9ad5cc7a5240 ("xfs: Introduce macros to represent new maximum extent counts for data/attr forks")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_btree.c
libxfs/xfs_btree.h
libxfs/xfs_ialloc_btree.c

index 3d870f3f4a5165701f521c79eeaf861dc70e7253..5c293ccf62333603eb6c91fc5cad1259c312824b 100644 (file)
@@ -5142,7 +5142,7 @@ xfs_btree_count_blocks_helper(
        int                     level,
        void                    *data)
 {
-       xfs_extlen_t            *blocks = data;
+       xfs_filblks_t           *blocks = data;
        (*blocks)++;
 
        return 0;
@@ -5152,7 +5152,7 @@ xfs_btree_count_blocks_helper(
 int
 xfs_btree_count_blocks(
        struct xfs_btree_cur    *cur,
-       xfs_extlen_t            *blocks)
+       xfs_filblks_t           *blocks)
 {
        *blocks = 0;
        return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper,
index 3b739459ebb0f4c51630533c152e24b9d64699f0..c5bff273cae255d94ef5715aeec64121187d0a68 100644 (file)
@@ -484,7 +484,7 @@ typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level,
 int xfs_btree_visit_blocks(struct xfs_btree_cur *cur,
                xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data);
 
-int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks);
+int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_filblks_t *blocks);
 
 union xfs_btree_rec *xfs_btree_rec_addr(struct xfs_btree_cur *cur, int n,
                struct xfs_btree_block *block);
index 19fca9fad62b1d0ce265dd9a140be6b2c52ea83d..4cccac145dc7753490816c19826363e4eece0a55 100644 (file)
@@ -743,6 +743,7 @@ xfs_finobt_count_blocks(
 {
        struct xfs_buf          *agbp = NULL;
        struct xfs_btree_cur    *cur;
+       xfs_filblks_t           blocks;
        int                     error;
 
        error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
@@ -750,9 +751,10 @@ xfs_finobt_count_blocks(
                return error;
 
        cur = xfs_finobt_init_cursor(pag, tp, agbp);
-       error = xfs_btree_count_blocks(cur, tree_blocks);
+       error = xfs_btree_count_blocks(cur, &blocks);
        xfs_btree_del_cursor(cur, error);
        xfs_trans_brelse(tp, agbp);
+       *tree_blocks = blocks;
 
        return error;
 }