[PATCH 4/5] xfs_db: don't error out when blocksize > 64 * inodesize

Darrick J. Wong darrick.wong at oracle.com
Fri Jan 22 18:35:25 CST 2016


When the block size is large enough that multiple inode chunks can fit
in a single block (e.g. 64k blocks, 512 byte inodes) we must calculate
the per-chunk block size and the buffer offset correctly so that check
actually examines the correct metadata.

Signed-off-by: Darrick J. Wong <darrick.wong at oracle.com>
---
 db/check.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)


diff --git a/db/check.c b/db/check.c
index 838db53..4e2768e 100644
--- a/db/check.c
+++ b/db/check.c
@@ -4386,6 +4386,7 @@ scanfunc_ino(
 	__u16			holemask;
 	xfs_agino_t		rino;
 	xfs_extlen_t		cblocks;
+	int			bufoff;
 
 	if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC &&
 	    be32_to_cpu(block->bb_magic) != XFS_IBT_CRC_MAGIC) {
@@ -4455,6 +4456,8 @@ scanfunc_ino(
 				rino = agino + startidx;
 				cblocks = (endidx - startidx) >>
 						mp->m_sb.sb_inopblog;
+				if (cblocks == 0)
+					cblocks = 1;
 
 				/* Check the sparse chunk alignment */
 				if (sparse &&
@@ -4468,8 +4471,9 @@ scanfunc_ino(
 				}
 
 				/* Check the block map */
-				set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, rino),
-					cblocks, DBM_INODE, seqno, bno);
+				if (XFS_AGINO_TO_OFFSET(mp, rino) == 0)
+					set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, rino),
+						cblocks, DBM_INODE, seqno, bno);
 
 				push_cur();
 				set_cur(&typtab[TYP_INODE],
@@ -4489,14 +4493,15 @@ scanfunc_ino(
 				}
 
 				/* Examine each inode in this chunk */
-				for (j = startidx; j < endidx; j++) {
+				bufoff = ((XFS_AGINO_TO_OFFSET(mp, rino) - startidx) << mp->m_sb.sb_inodelog);
+				for (j = startidx; j < endidx; j++, bufoff += (1 << mp->m_sb.sb_inodelog)) {
 					if (ino_issparse(&rp[i], j))
 						continue;
 					isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j);
 					if (isfree)
 						nfree++;
 					process_inode(agf, agino + j,
-						(xfs_dinode_t *)((char *)iocur_top->data + ((j - startidx) << mp->m_sb.sb_inodelog)),
+						(xfs_dinode_t *)((char *)iocur_top->data + bufoff),
 							isfree);
 				}
 				pop_cur();



More information about the xfs mailing list