]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_repair: support more than INT_MAX block maps
authorDarrick J. Wong <djwong@kernel.org>
Mon, 15 Apr 2024 23:07:51 +0000 (16:07 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 17 Apr 2024 21:06:28 +0000 (14:06 -0700)
Now that it's possible to have more than INT_MAX block mappings attached
to a file fork, expand the counters used by this data structure so that
it can support all possible block mappings.

Note that in practice we're still never going to exceed 4 billion
extents because the previous patch switched off the block mappings for
regular files.  This is still twice as much as memory as previous, but
it's not totally unconstrained.  Hopefully few people bloat the xattr
structures that large.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
repair/bmap.c
repair/bmap.h
repair/dinode.c
repair/dir2.c

index 7e32fff335942686c39dbb94b794b606105da836..2b4f4fe9803c3b36ea0e127714cd2537b4a1f8e6 100644 (file)
@@ -43,6 +43,7 @@ blkmap_alloc(
 
        if (nex < 1)
                nex = 1;
+       nex = min(nex, XFS_MAX_EXTCNT_DATA_FORK_LARGE);
 
        if (sizeof(long) == 4 && nex > BLKMAP_NEXTS32_MAX) {
                do_warn(
@@ -122,7 +123,7 @@ blkmap_get(
        xfs_fileoff_t   o)
 {
        bmap_ext_t      *ext = blkmap->exts;
-       int             i;
+       xfs_extnum_t    i;
 
        for (i = 0; i < blkmap->nexts; i++, ext++) {
                if (o >= ext->startoff && o < ext->startoff + ext->blockcount)
@@ -144,7 +145,7 @@ blkmap_getn(
 {
        bmap_ext_t      *bmp = NULL;
        bmap_ext_t      *ext;
-       int             i;
+       xfs_extnum_t    i;
        int             nex;
 
        if (nb == 1) {
@@ -240,7 +241,7 @@ xfs_fileoff_t
 blkmap_next_off(
        blkmap_t        *blkmap,
        xfs_fileoff_t   o,
-       int             *t)
+       xfs_extnum_t    *t)
 {
        bmap_ext_t      *ext;
 
@@ -270,7 +271,7 @@ blkmap_grow(
 {
        pthread_key_t   key = dblkmap_key;
        blkmap_t        *new_blkmap;
-       int             new_naexts;
+       xfs_extnum_t    new_naexts;
 
        /* reduce the number of reallocations for large files */
        if (blkmap->naexts < 1000)
@@ -287,18 +288,18 @@ blkmap_grow(
 
        if (sizeof(long) == 4 && new_naexts > BLKMAP_NEXTS32_MAX) {
                do_error(
-       _("Number of extents requested in blkmap_grow (%d) overflows 32 bits.\n"
+       _("Number of extents requested in blkmap_grow (%llu) overflows 32 bits.\n"
          "You need a 64 bit system to repair this filesystem.\n"),
-                       new_naexts);
+                       (unsigned long long)new_naexts);
                return NULL;
        }
 
-       if (new_naexts <= 0) {
+       if (new_naexts > XFS_MAX_EXTCNT_DATA_FORK_LARGE) {
                do_error(
-       _("Number of extents requested in blkmap_grow (%d) overflowed the\n"
-         "maximum number of supported extents (%ld).\n"),
-                       new_naexts,
-                       sizeof(long) == 4 ? BLKMAP_NEXTS32_MAX : INT_MAX);
+       _("Number of extents requested in blkmap_grow (%llu) overflowed the\n"
+         "maximum number of supported extents (%llu).\n"),
+                       (unsigned long long)new_naexts,
+                       (unsigned long long)XFS_MAX_EXTCNT_DATA_FORK_LARGE);
                return NULL;
        }
 
index df9602b31e483ec48f2a38aff3ed29608349b894..7fa671ce8b37608f621e88c02a7cc4ae425522f2 100644 (file)
@@ -20,8 +20,8 @@ typedef struct bmap_ext {
  * Block map.
  */
 typedef        struct blkmap {
-       int             naexts;
-       int             nexts;
+       xfs_extnum_t    naexts;
+       xfs_extnum_t    nexts;
        bmap_ext_t      exts[1];
 } blkmap_t;
 
@@ -43,6 +43,7 @@ int           blkmap_getn(blkmap_t *blkmap, xfs_fileoff_t o,
                            xfs_filblks_t nb, bmap_ext_t **bmpp,
                            bmap_ext_t *bmpp_single);
 xfs_fileoff_t  blkmap_last_off(blkmap_t *blkmap);
-xfs_fileoff_t  blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o, int *t);
+xfs_fileoff_t  blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o,
+                               xfs_extnum_t *t);
 
 #endif /* _XFS_REPAIR_BMAP_H */
index 94f5fdcb4a3758e89f60c553169393cf457b6b62..9d2f71055ebdd375d700d8294cd7908d79002aad 100644 (file)
@@ -1137,7 +1137,7 @@ process_quota_inode(
        xfs_dqid_t              dqid;
        xfs_fileoff_t           qbno;
        int                     i;
-       int                     t = 0;
+       xfs_extnum_t            t = 0;
        int                     error;
 
        switch (ino_type) {
index 022b61b885f6cbe57ec3f3298d3a0be74974a38e..e46ae9ae46f71146e5fa361124d2a45347149f25 100644 (file)
@@ -1327,7 +1327,7 @@ process_leaf_node_dir2(
        int                     i;
        xfs_fileoff_t           ndbno;
        int                     nex;
-       int                     t;
+       xfs_extnum_t            t;
        bmap_ext_t              lbmp;
        int                     dirty = 0;