The on-disk inobt record has two formats depending on whether sparse inode support is enabled or not. If so, the freecount field is a single byte and does not require byte-conversion. Otherwise, it is a 4-byte field and does. Create the inorec_[get|set]_freecount() helpers to abstract this detail away from the core repair code. Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- repair/incore.h | 28 ++++++++++++++++++++++++++++ repair/phase5.c | 12 +++++++----- repair/scan.c | 15 +++------------ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/repair/incore.h b/repair/incore.h index 5a63e1e..c92475e 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -591,4 +591,32 @@ typedef struct bm_cursor { void init_bm_cursor(bmap_cursor_t *cursor, int num_level); +/* + * On-disk inobt record helpers. The sparse inode record format has a single + * byte freecount. The older format has a 32-bit freecount and thus byte + * conversion is necessary. + */ + +static inline int +inorec_get_freecount( + struct xfs_mount *mp, + struct xfs_inobt_rec *rp) +{ + if (xfs_sb_version_hassparseinodes(&mp->m_sb)) + return rp->ir_u.sp.ir_freecount; + return be32_to_cpu(rp->ir_u.f.ir_freecount); +} + +static inline void +inorec_set_freecount( + struct xfs_mount *mp, + struct xfs_inobt_rec *rp, + int freecount) +{ + if (xfs_sb_version_hassparseinodes(&mp->m_sb)) + rp->ir_u.sp.ir_freecount = freecount; + else + rp->ir_u.f.ir_freecount = cpu_to_be32(freecount); +} + #endif /* XFS_REPAIR_INCORE_H */ diff --git a/repair/phase5.c b/repair/phase5.c index 0601810..7372734 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -1258,11 +1258,14 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, inocnt++; } - if (!xfs_sb_version_hassparseinodes(&mp->m_sb)) { - bt_rec[j].ir_u.f.ir_freecount = - cpu_to_be32(finocnt); + /* + * Set the freecount and check whether we need to update + * the sparse format fields. Otherwise, skip to the next + * record. + */ + inorec_set_freecount(mp, &bt_rec[j], finocnt); + if (!xfs_sb_version_hassparseinodes(&mp->m_sb)) goto nextrec; - } /* * Convert the 64-bit in-core sparse inode state to the @@ -1280,7 +1283,6 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno, sparse >>= XFS_INODES_PER_HOLEMASK_BIT; } - bt_rec[j].ir_u.sp.ir_freecount = finocnt; bt_rec[j].ir_u.sp.ir_count = inocnt; bt_rec[j].ir_u.sp.ir_holemask = cpu_to_be16(holemask); diff --git a/repair/scan.c b/repair/scan.c index e3895c2..1a6f0c5 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -786,10 +786,7 @@ scan_single_ino_chunk( off = XFS_AGINO_TO_OFFSET(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, ino); lino = XFS_AGINO_TO_INO(mp, agno, ino); - if (xfs_sb_version_hassparseinodes(&mp->m_sb)) - freecount = rp->ir_u.sp.ir_freecount; - else - freecount = be32_to_cpu(rp->ir_u.f.ir_freecount); + freecount = inorec_get_freecount(mp, rp); /* * on multi-block block chunks, all chunks start @@ -987,10 +984,7 @@ scan_single_finobt_chunk( off = XFS_AGINO_TO_OFFSET(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, ino); lino = XFS_AGINO_TO_INO(mp, agno, ino); - if (xfs_sb_version_hassparseinodes(&mp->m_sb)) - freecount = rp->ir_u.sp.ir_freecount; - else - freecount = be32_to_cpu(rp->ir_u.f.ir_freecount); + freecount = inorec_get_freecount(mp, rp); /* * on multi-block block chunks, all chunks start at the beginning of the @@ -1331,10 +1325,7 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), * the block. skip processing of bogus records. */ for (i = 0; i < numrecs; i++) { - if (xfs_sb_version_hassparseinodes(&mp->m_sb)) - freecount = rp[i].ir_u.sp.ir_freecount; - else - freecount = be32_to_cpu(rp[i].ir_u.f.ir_freecount); + freecount = inorec_get_freecount(mp, &rp[i]); if (magic == XFS_IBT_MAGIC || magic == XFS_IBT_CRC_MAGIC) { -- 1.9.3 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs