blkbb, DB_RING_IGN, NULL);
off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
dip = iocur_top->data;
+ iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip);
+ iocur_top->ino_buf = 1;
iocur_top->ino = ino;
iocur_top->mode = be16_to_cpu(dip->di_mode);
if ((iocur_top->mode & S_IFMT) == S_IFDIR)
return;
}
+ if (iocur_top->ino_buf)
+ libxfs_dinode_calc_crc(mp, iocur_top->data);
+
if (iocur_top->bbmap)
write_cur_bbs();
else
iocur_top->ino = ino;
iocur_top->dirino = dirino;
iocur_top->mode = mode;
+ iocur_top->ino_buf = 0;
/* store location in ring */
if (ring_flag)
const struct typ *typ; /* type of "data" */
bbmap_t *bbmap; /* map daddr if fragmented */
struct xfs_buf *bp; /* underlying buffer */
+ int ino_crc_ok:1;
+ int ino_buf:1;
} iocur_t;
#define DB_RING_ADD 1 /* add to ring on set_cur */
static inline bool
iocur_crc_valid()
{
- return (iocur_top->bp && iocur_top->bp->b_error != EFSCORRUPTED);
+ return (iocur_top->bp &&
+ iocur_top->bp->b_error != EFSCORRUPTED &&
+ (!iocur_top->ino_buf || iocur_top->ino_crc_ok));
}
#define libxfs_idata_realloc xfs_idata_realloc
#define libxfs_idestroy_fork xfs_idestroy_fork
+#define libxfs_dinode_verify xfs_dinode_verify
+bool xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino,
+ struct xfs_dinode *dip);
+
/* xfs_sb.h */
#define libxfs_mod_sb xfs_mod_sb
#define libxfs_sb_from_disk xfs_sb_from_disk
}
}
-static bool
+bool
xfs_dinode_verify(
struct xfs_mount *mp,
- struct xfs_inode *ip,
+ xfs_ino_t ino,
struct xfs_dinode *dip)
{
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
offsetof(struct xfs_dinode, di_crc)))
return false;
- if (be64_to_cpu(dip->di_ino) != ip->i_ino)
+ if (be64_to_cpu(dip->di_ino) != ino)
return false;
if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid))
return false;
return error;
/* even unallocated inodes are verified */
- if (!xfs_dinode_verify(mp, ip, dip)) {
+ if (!xfs_dinode_verify(mp, ip->i_ino, dip)) {
xfs_alert(mp, "%s: validation failed for inode %lld failed",
__func__, ip->i_ino);