From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> The onstack inode in xfs_check's process_inode is a potential landmine since it's not a /real/ incore inode. The upcoming 5.8 merge will make this messier wrt inode forks, so just remove the onstack inode and reference the ondisk fields directly. This also reduces the amount of thinking that I have to do w.r.t. future libxfs porting efforts. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- db/check.c | 100 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/db/check.c b/db/check.c index 12c03b6d..96abea21 100644 --- a/db/check.c +++ b/db/check.c @@ -2707,7 +2707,6 @@ process_inode( { blkmap_t *blkmap; xfs_fsblock_t bno = 0; - struct xfs_inode xino; inodata_t *id = NULL; xfs_ino_t ino; xfs_extnum_t nextents = 0; @@ -2724,6 +2723,12 @@ process_inode( xfs_qcnt_t rc = 0; int v = 0; mode_t mode; + uint16_t diflags; + uint64_t diflags2 = 0; + xfs_nlink_t nlink; + xfs_dqid_t uid; + xfs_dqid_t gid; + xfs_dqid_t prid; static char okfmts[] = { 0, /* type 0 unused */ 1 << XFS_DINODE_FMT_DEV, /* FIFO */ @@ -2750,10 +2755,6 @@ process_inode( "dev", "local", "extents", "btree", "uuid" }; - /* xfs_inode_from_disk expects to have an mp to work with */ - xino.i_mount = mp; - libxfs_inode_from_disk(&xino, dip); - ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino); if (!isfree) { id = find_inode(ino, 1); @@ -2775,12 +2776,25 @@ process_inode( error++; return; } + if (dip->di_version == 1) { + nlink = be16_to_cpu(dip->di_onlink); + prid = 0; + } else { + nlink = be32_to_cpu(dip->di_nlink); + prid = (xfs_dqid_t)be16_to_cpu(dip->di_projid_hi) << 16 | + be16_to_cpu(dip->di_projid_lo); + } + uid = be32_to_cpu(dip->di_uid); + gid = be32_to_cpu(dip->di_gid); + diflags = be16_to_cpu(dip->di_flags); + if (xfs_sb_version_has_v3inode(&mp->m_sb)) + diflags2 = be64_to_cpu(dip->di_flags2); if (isfree) { - if (xino.i_d.di_nblocks != 0) { + if (be64_to_cpu(dip->di_nblocks) != 0) { if (v) dbprintf(_("bad nblocks %lld for free inode " "%lld\n"), - xino.i_d.di_nblocks, ino); + be64_to_cpu(dip->di_nblocks), ino); error++; } if (dip->di_nlink != 0) { @@ -2809,24 +2823,24 @@ process_inode( */ mode = be16_to_cpu(dip->di_mode); if ((((mode & S_IFMT) >> 12) > 15) || - (!(okfmts[(mode & S_IFMT) >> 12] & (1 << xino.i_d.di_format)))) { + (!(okfmts[(mode & S_IFMT) >> 12] & (1 << dip->di_format)))) { if (v) dbprintf(_("bad format %d for inode %lld type %#o\n"), - xino.i_d.di_format, id->ino, mode & S_IFMT); + dip->di_format, id->ino, mode & S_IFMT); error++; return; } if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= XFS_LITINO(mp)) { if (v) dbprintf(_("bad fork offset %d for inode %lld\n"), - xino.i_d.di_forkoff, id->ino); + dip->di_forkoff, id->ino); error++; return; } - if ((unsigned int)xino.i_d.di_aformat > XFS_DINODE_FMT_BTREE) { + if ((unsigned int)dip->di_aformat > XFS_DINODE_FMT_BTREE) { if (v) dbprintf(_("bad attribute format %d for inode %lld\n"), - xino.i_d.di_aformat, id->ino); + dip->di_aformat, id->ino); error++; return; } @@ -2834,43 +2848,43 @@ process_inode( dbprintf(_("inode %lld mode %#o fmt %s " "afmt %s " "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"), - id->ino, mode, fmtnames[(int)xino.i_d.di_format], - fmtnames[(int)xino.i_d.di_aformat], - xino.i_d.di_nextents, - xino.i_d.di_anextents, - xino.i_d.di_nblocks, xino.i_d.di_size, - xino.i_d.di_flags & XFS_DIFLAG_REALTIME ? " rt" : "", - xino.i_d.di_flags & XFS_DIFLAG_PREALLOC ? " pre" : "", - xino.i_d.di_flags & XFS_DIFLAG_IMMUTABLE? " imm" : "", - xino.i_d.di_flags & XFS_DIFLAG_APPEND ? " app" : "", - xino.i_d.di_flags & XFS_DIFLAG_SYNC ? " syn" : "", - xino.i_d.di_flags & XFS_DIFLAG_NOATIME ? " noa" : "", - xino.i_d.di_flags & XFS_DIFLAG_NODUMP ? " nod" : ""); + id->ino, mode, fmtnames[(int)dip->di_format], + fmtnames[(int)dip->di_aformat], + be32_to_cpu(dip->di_nextents), + be16_to_cpu(dip->di_anextents), + be64_to_cpu(dip->di_nblocks), be64_to_cpu(dip->di_size), + diflags & XFS_DIFLAG_REALTIME ? " rt" : "", + diflags & XFS_DIFLAG_PREALLOC ? " pre" : "", + diflags & XFS_DIFLAG_IMMUTABLE? " imm" : "", + diflags & XFS_DIFLAG_APPEND ? " app" : "", + diflags & XFS_DIFLAG_SYNC ? " syn" : "", + diflags & XFS_DIFLAG_NOATIME ? " noa" : "", + diflags & XFS_DIFLAG_NODUMP ? " nod" : ""); security = 0; switch (mode & S_IFMT) { case S_IFDIR: type = DBM_DIR; - if (xino.i_d.di_format == XFS_DINODE_FMT_LOCAL) + if (dip->di_format == XFS_DINODE_FMT_LOCAL) break; - blkmap = blkmap_alloc(xino.i_d.di_nextents); + blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents)); break; case S_IFREG: - if (xino.i_d.di_flags & XFS_DIFLAG_REALTIME) + if (diflags & XFS_DIFLAG_REALTIME) type = DBM_RTDATA; else if (id->ino == mp->m_sb.sb_rbmino) { type = DBM_RTBITMAP; - blkmap = blkmap_alloc(xino.i_d.di_nextents); + blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents)); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_rsumino) { type = DBM_RTSUM; - blkmap = blkmap_alloc(xino.i_d.di_nextents); + blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents)); addlink_inode(id); } else if (id->ino == mp->m_sb.sb_uquotino || id->ino == mp->m_sb.sb_gquotino || id->ino == mp->m_sb.sb_pquotino) { type = DBM_QUOTA; - blkmap = blkmap_alloc(xino.i_d.di_nextents); + blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents)); addlink_inode(id); } else @@ -2887,10 +2901,10 @@ process_inode( break; } - id->isreflink = !!(xino.i_d.di_flags2 & XFS_DIFLAG2_REFLINK); - setlink_inode(id, VFS_I(&xino)->i_nlink, type == DBM_DIR, security); + id->isreflink = !!(diflags2 & XFS_DIFLAG2_REFLINK); + setlink_inode(id, nlink, type == DBM_DIR, security); - switch (xino.i_d.di_format) { + switch (dip->di_format) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, type, &totdblocks, &totiblocks, &nextents, &blkmap, XFS_DATA_FORK); @@ -2906,7 +2920,7 @@ process_inode( } if (XFS_DFORK_Q(dip)) { sbversion |= XFS_SB_VERSION_ATTRBIT; - switch (xino.i_d.di_aformat) { + switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: process_lclinode(id, dip, DBM_ATTR, &atotdblocks, &atotiblocks, &anextents, NULL, XFS_ATTR_FORK); @@ -2941,30 +2955,28 @@ process_inode( default: break; } - if (ic) { - quota_add(&xino.i_d.di_projid, &VFS_I(&xino)->i_gid, - &VFS_I(&xino)->i_uid, 0, bc, ic, rc); - } + if (ic) + quota_add(&prid, &gid, &uid, 0, bc, ic, rc); } totblocks = totdblocks + totiblocks + atotdblocks + atotiblocks; - if (totblocks != xino.i_d.di_nblocks) { + if (totblocks != be64_to_cpu(dip->di_nblocks)) { if (v) dbprintf(_("bad nblocks %lld for inode %lld, counted " "%lld\n"), - xino.i_d.di_nblocks, id->ino, totblocks); + be64_to_cpu(dip->di_nblocks), id->ino, totblocks); error++; } - if (nextents != xino.i_d.di_nextents) { + if (nextents != be32_to_cpu(dip->di_nextents)) { if (v) dbprintf(_("bad nextents %d for inode %lld, counted %d\n"), - xino.i_d.di_nextents, id->ino, nextents); + be32_to_cpu(dip->di_nextents), id->ino, nextents); error++; } - if (anextents != xino.i_d.di_anextents) { + if (anextents != be16_to_cpu(dip->di_anextents)) { if (v) dbprintf(_("bad anextents %d for inode %lld, counted " "%d\n"), - xino.i_d.di_anextents, id->ino, anextents); + be16_to_cpu(dip->di_anextents), id->ino, anextents); error++; } if (type == DBM_DIR)