From: Darrick J. Wong <djwong@xxxxxxxxxx> gcc 11.2 complains about certain variables now that xfs_extnum_t is an unsigned 64-bit integer: dinode.c: In function ‘process_exinode’: dinode.c:960:21: error: comparison of unsigned expression in ‘< 0’ is always false [-Werror=type-limits] 960 | if (numrecs < 0) Since we actually have a function that will tell us the maximum supported extent count for an ondisk dinode structure, use a direct comparison instead of tricky integer math to detect overflows. A more exhaustive audit is probably necessary. IOWS, shut up, gcc... Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- db/check.c | 10 +++++++--- db/metadump.c | 11 +++++++---- repair/dinode.c | 14 ++++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/db/check.c b/db/check.c index fb28994d..c9149daa 100644 --- a/db/check.c +++ b/db/check.c @@ -2711,14 +2711,18 @@ process_exinode( int whichfork) { xfs_bmbt_rec_t *rp; + xfs_extnum_t max_nex; rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork); *nex = xfs_dfork_nextents(dip, whichfork); - if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) / + max_nex = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dip), + whichfork); + if (*nex > max_nex || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) / sizeof(xfs_bmbt_rec_t)) { if (!sflag || id->ilist) - dbprintf(_("bad number of extents %d for inode %lld\n"), - *nex, id->ino); + dbprintf(_("bad number of extents %llu for inode %lld\n"), + (unsigned long long)*nex, id->ino); error++; return; } diff --git a/db/metadump.c b/db/metadump.c index 999c68f7..27d1df43 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2278,16 +2278,19 @@ process_exinode( { int whichfork; int used; - xfs_extnum_t nex; + xfs_extnum_t nex, max_nex; whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; nex = xfs_dfork_nextents(dip, whichfork); + max_nex = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dip), + whichfork); used = nex * sizeof(xfs_bmbt_rec_t); - if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) { + if (nex > max_nex || used > XFS_DFORK_SIZE(dip, mp, whichfork)) { if (show_warnings) - print_warning("bad number of extents %d in inode %lld", - nex, (long long)cur_ino); + print_warning("bad number of extents %llu in inode %lld", + (unsigned long long)nex, (long long)cur_ino); return 1; } diff --git a/repair/dinode.c b/repair/dinode.c index 04e7f83e..00de31fb 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -942,7 +942,7 @@ process_exinode( xfs_bmbt_rec_t *rp; xfs_fileoff_t first_key; xfs_fileoff_t last_key; - xfs_extnum_t numrecs; + xfs_extnum_t numrecs, max_numrecs; int ret; lino = XFS_AGINO_TO_INO(mp, agno, ino); @@ -956,7 +956,10 @@ process_exinode( * be in the range of valid on-disk numbers, which is: * 0 < numrecs < 2^31 - 1 */ - if (numrecs < 0) + max_numrecs = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dip), + whichfork); + if (numrecs > max_numrecs) numrecs = *nex; /* @@ -1899,7 +1902,7 @@ process_inode_data_fork( { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); int err = 0; - xfs_extnum_t nex; + xfs_extnum_t nex, max_nex; /* * extent count on disk is only valid for positive values. The kernel @@ -1907,7 +1910,10 @@ process_inode_data_fork( * here, trash it! */ nex = xfs_dfork_data_extents(dino); - if (nex < 0) + max_nex = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dino), + XFS_DATA_FORK); + if (nex > max_nex) *nextents = 1; else *nextents = nex;