summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-07-08 19:36:17 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2019-07-09 08:06:20 -0700
commit0df5c39b3e4204b3ed0079d0fa14f3001c6285fe (patch)
tree7da0ad9c9fa31e283050dca224e43de75b00c933
parent211bbf3c38ed90f43a3ec905e246014f96bceed7 (diff)
xfs: bump INUMBERS cursor correctly in xfs_inumbers_walk
There's a subtle unit conversion error when we increment the INUMBERS cursor at the end of xfs_inumbers_walk. If there's an inode chunk at the very end of the AG /and/ the AG size is a perfect power of two, the startino of that last chunk (which is in units of AG inodes) will be 63 less than (1 << agino_log). If we add XFS_INODES_PER_CHUNK to the startino, we end up with a startino that's larger than (1 << agino_log) and when we convert that back to fs inode units we'll rip off that upper bit and wind up back at the start of the AG. Fix this by converting to units of fs inodes before adding XFS_INODES_PER_CHUNK so that we'll harmlessly end up pointing to the next AG. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
-rw-r--r--fs/xfs/xfs_itable.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index cda8ae94480c..a8a06bb78ea8 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -338,15 +338,14 @@ xfs_inumbers_walk(
.xi_version = XFS_INUMBERS_VERSION_V5,
};
struct xfs_inumbers_chunk *ic = data;
- xfs_agino_t agino;
int error;
error = ic->formatter(ic->breq, &inogrp);
if (error && error != XFS_IBULK_ABORT)
return error;
- agino = irec->ir_startino + XFS_INODES_PER_CHUNK;
- ic->breq->startino = XFS_AGINO_TO_INO(mp, agno, agino);
+ ic->breq->startino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino) +
+ XFS_INODES_PER_CHUNK;
return error;
}