Skip to content

Commit 1332533

Browse files
Dave Chinnercmaiolino
authored andcommitted
xfs: fix sparse inode limits on runt AG
The runt AG at the end of a filesystem is almost always smaller than the mp->m_sb.sb_agblocks. Unfortunately, when setting the max_agbno limit for the inode chunk allocation, we do not take this into account. This means we can allocate a sparse inode chunk that overlaps beyond the end of an AG. When we go to allocate an inode from that sparse chunk, the irec fails validation because the agbno of the start of the irec is beyond valid limits for the runt AG. Prevent this from happening by taking into account the size of the runt AG when allocating inode chunks. Also convert the various checks for valid inode chunk agbnos to use xfs_ag_block_count() so that they will also catch such issues in the future. Fixes: 56d1115 ("xfs: allocate sparse inode chunks on full chunk allocation failure") Signed-off-by: Dave Chinner <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Carlos Maiolino <[email protected]>
1 parent 652f03d commit 1332533

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

fs/xfs/libxfs/xfs_ialloc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,8 @@ xfs_ialloc_ag_alloc(
853853
* the end of the AG.
854854
*/
855855
args.min_agbno = args.mp->m_sb.sb_inoalignmt;
856-
args.max_agbno = round_down(args.mp->m_sb.sb_agblocks,
856+
args.max_agbno = round_down(xfs_ag_block_count(args.mp,
857+
pag_agno(pag)),
857858
args.mp->m_sb.sb_inoalignmt) -
858859
igeo->ialloc_blks;
859860

@@ -2349,9 +2350,9 @@ xfs_difree(
23492350
return -EINVAL;
23502351
}
23512352
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
2352-
if (agbno >= mp->m_sb.sb_agblocks) {
2353-
xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
2354-
__func__, agbno, mp->m_sb.sb_agblocks);
2353+
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) {
2354+
xfs_warn(mp, "%s: agbno >= xfs_ag_block_count (%d >= %d).",
2355+
__func__, agbno, xfs_ag_block_count(mp, pag_agno(pag)));
23552356
ASSERT(0);
23562357
return -EINVAL;
23572358
}
@@ -2474,7 +2475,7 @@ xfs_imap(
24742475
*/
24752476
agino = XFS_INO_TO_AGINO(mp, ino);
24762477
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
2477-
if (agbno >= mp->m_sb.sb_agblocks ||
2478+
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag)) ||
24782479
ino != xfs_agino_to_ino(pag, agino)) {
24792480
error = -EINVAL;
24802481
#ifdef DEBUG
@@ -2484,11 +2485,12 @@ xfs_imap(
24842485
*/
24852486
if (flags & XFS_IGET_UNTRUSTED)
24862487
return error;
2487-
if (agbno >= mp->m_sb.sb_agblocks) {
2488+
if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) {
24882489
xfs_alert(mp,
24892490
"%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)",
24902491
__func__, (unsigned long long)agbno,
2491-
(unsigned long)mp->m_sb.sb_agblocks);
2492+
(unsigned long)xfs_ag_block_count(mp,
2493+
pag_agno(pag)));
24922494
}
24932495
if (ino != xfs_agino_to_ino(pag, agino)) {
24942496
xfs_alert(mp,

0 commit comments

Comments
 (0)