Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69775fd1 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: verify icount in superblock write



Add a helper predicate to check the inode count for sanity, then use it
in the superblock write verifier to inspect sb_icount.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBill O'Donnell <billodo@redhat.com>
Reviewed-by: default avatarEric Sandeen <sandeen@redhat.com>
parent 8756a5af
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -154,9 +154,10 @@ xfs_validate_sb_write(
	 * Carry out additional sb summary counter sanity checks when we write
	 * the superblock.  We skip this in the read validator because there
	 * could be newer superblocks in the log and if the values are garbage
	 * we'll recalculate them at the end of log mount.
	 * even after replay we'll recalculate them at the end of log mount.
	 */
	if (sbp->sb_fdblocks > sbp->sb_dblocks ||
	    !xfs_verify_icount(mp, sbp->sb_icount) ||
	    sbp->sb_ifree > sbp->sb_icount) {
		xfs_warn(mp, "SB summary counter sanity check failed");
		return -EFSCORRUPTED;
+34 −0
Original line number Diff line number Diff line
@@ -171,3 +171,37 @@ xfs_verify_rtbno(
{
	return rtbno < mp->m_sb.sb_rblocks;
}

/* Calculate the range of valid icount values. */
static void
xfs_icount_range(
	struct xfs_mount	*mp,
	unsigned long long	*min,
	unsigned long long	*max)
{
	unsigned long long	nr_inos = 0;
	xfs_agnumber_t		agno;

	/* root, rtbitmap, rtsum all live in the first chunk */
	*min = XFS_INODES_PER_CHUNK;

	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
		xfs_agino_t	first, last;

		xfs_agino_range(mp, agno, &first, &last);
		nr_inos += last - first + 1;
	}
	*max = nr_inos;
}

/* Sanity-checking of inode counts. */
bool
xfs_verify_icount(
	struct xfs_mount	*mp,
	unsigned long long	icount)
{
	unsigned long long	min, max;

	xfs_icount_range(mp, &min, &max);
	return icount >= min && icount <= max;
}
+1 −0
Original line number Diff line number Diff line
@@ -165,5 +165,6 @@ bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount);

#endif	/* __XFS_TYPES_H__ */