forked from Minki/linux
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
|
||||
* 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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user