When running generic/525 with rtinherit=1 and rextsize=28k, generic/525
trips over the following block mapping:
data offset
2251799813685247 startblock 7 (0/7) count 1 flag 0
data offset
2251799813685248 startblock 8 (0/8) count 6 flag 1
with this error:
inode 155 - extent exceeds max offset - start
2251799813685248, count 6,
physical block 8
This is due to an incorrect check in xfs_repair, which tries to validate
that a block mapping cannot exceed what it thinks is the maximum file
offset. Unfortunately, the check is wrong, because only br_startoff is
subject to the 2^52-1 limit -- not br_startoff + br_blockcount.
Nowadays libxfs provides a symbol XFS_MAX_FILEOFF for the maximum
allowable file block offset that can be mapped into a file. Use this
instead of the open-coded logic in versions.c and correct all the other
checks. Note that this problem only surfaced when rtgroups were enabled
because hch changed xfs_repair to use the same tree-based block state
data structure that we use for AGs when rtgroups are enabled.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
}
/* Ensure this extent does not extend beyond the max offset */
if (irec.br_startoff + irec.br_blockcount - 1 >
- fs_max_file_offset) {
+ XFS_MAX_FILEOFF) {
do_warn(
_("inode %" PRIu64 " - extent exceeds max offset - start %" PRIu64 ", "
"count %" PRIu64 ", physical block %" PRIu64 "\n"),
unsigned int glob_agcount;
int chunks_pblock; /* # of 64-ino chunks per allocation */
int max_symlink_blocks;
-int64_t fs_max_file_offset;
/* realtime info */
extern unsigned int glob_agcount;
extern int chunks_pblock; /* # of 64-ino chunks per allocation */
extern int max_symlink_blocks;
-extern int64_t fs_max_file_offset;
/* realtime info */
if (((i > 0) && (op + cp > irec.br_startoff)) ||
(irec.br_blockcount == 0) ||
- (irec.br_startoff >= fs_max_file_offset))
+ (irec.br_startoff + irec.br_blockcount - 1 >= XFS_MAX_FILEOFF))
goto out_free;
if (!libxfs_verify_fsbno(mp, irec.br_startblock) ||
fs_ino_alignment = mp->m_sb.sb_inoalignmt;
}
- /*
- * calculate maximum file offset for this geometry
- */
- fs_max_file_offset = 0x7fffffffffffffffLL >> mp->m_sb.sb_blocklog;
-
- return(0);
+ return 0;
}