@@ -162,6 +162,7 @@ xchk_iallocbt_check_cluster_ifree(
xfs_ino_t fsino;
xfs_agino_t agino;
unsigned int offset;
+ unsigned int cluster_buf_base;
bool irec_free;
bool ino_inuse;
bool freemask_ok;
@@ -174,11 +175,14 @@ xchk_iallocbt_check_cluster_ifree(
* Given an inobt record, an offset of a cluster within the record,
* and an offset of an inode within a cluster, compute which fs inode
* we're talking about and the offset of the inode record within the
- * inode buffer.
+ * inode buffer, being careful about inobt records that don't align
+ * with the start of the inode buffer when block sizes are large.
*/
agino = irec->ir_startino + cluster_base + cluster_index;
fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino);
- offset = cluster_index * mp->m_sb.sb_inodesize;
+ cluster_buf_base = XFS_INO_TO_OFFSET(mp, irec->ir_startino +
+ cluster_base);
+ offset = (cluster_buf_base + cluster_index) * mp->m_sb.sb_inodesize;
if (offset >= BBTOB(cluster_bp->b_length)) {
xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
goto out;