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: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Bill O'Donnell <billodo@redhat.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
This commit is contained in:
parent
8756a5af18
commit
69775fd15d
|
@ -154,9 +154,10 @@ xfs_validate_sb_write(
|
||||||
* Carry out additional sb summary counter sanity checks when we write
|
* Carry out additional sb summary counter sanity checks when we write
|
||||||
* the superblock. We skip this in the read validator because there
|
* the superblock. We skip this in the read validator because there
|
||||||
* could be newer superblocks in the log and if the values are garbage
|
* 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 ||
|
if (sbp->sb_fdblocks > sbp->sb_dblocks ||
|
||||||
|
!xfs_verify_icount(mp, sbp->sb_icount) ||
|
||||||
sbp->sb_ifree > sbp->sb_icount) {
|
sbp->sb_ifree > sbp->sb_icount) {
|
||||||
xfs_warn(mp, "SB summary counter sanity check failed");
|
xfs_warn(mp, "SB summary counter sanity check failed");
|
||||||
return -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
|
|
|
@ -171,3 +171,37 @@ xfs_verify_rtbno(
|
||||||
{
|
{
|
||||||
return rtbno < mp->m_sb.sb_rblocks;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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_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_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_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__ */
|
#endif /* __XFS_TYPES_H__ */
|
||||||
|
|
Loading…
Reference in New Issue