aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2023-08-09 00:10:07 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2023-08-09 00:11:04 +0000
commit6dff61a1d1878ea5e9f6e5c36521b3f39cd34b33 (patch)
treeec0ac509a03f598599af94c8c79fef3a722876fc
parent76f28f656eb5db81b49d6d89e1d43815aeda3128 (diff)
downloadsrc-6dff61a1d1878ea5e9f6e5c36521b3f39cd34b33.tar.gz
src-6dff61a1d1878ea5e9f6e5c36521b3f39cd34b33.zip
Rate limit kernel UFS/FFS cylinder group check-hash error messages.
When a large file is deleted or a large number of files are deleted, even a single cylinder group with a bad check hash can generate thousands of check-hash warnings. As with other filesystem messages such as out-of-space, print a maximum of one check-hash error per second. Note the limit is per filesystem. If two filesystems have cylinder group(s) with a bad check hash, each will print a maximum of one check-hash error message per second. MFC-after: 1 week Sponsored-by: The FreeBSD Foundation
-rw-r--r--sys/ufs/ffs/ffs_alloc.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index e173253720c6..f6bf4c1dadc0 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -2991,15 +2991,6 @@ ffs_mapsearch(struct fs *fs,
return (-1);
}
-static const struct statfs *
-ffs_getmntstat(struct vnode *devvp)
-{
-
- if (devvp->v_type == VCHR)
- return (&devvp->v_rdev->si_mountpt->mnt_stat);
- return (ffs_getmntstat(VFSTOUFS(devvp->v_mount)->um_devvp));
-}
-
/*
* Fetch and verify a cylinder group.
*/
@@ -3013,6 +3004,7 @@ ffs_getcg(struct fs *fs,
{
struct buf *bp;
struct cg *cgp;
+ struct mount *mp;
const struct statfs *sfs;
daddr_t blkno;
int error;
@@ -3021,10 +3013,13 @@ ffs_getcg(struct fs *fs,
*cgpp = NULL;
if ((fs->fs_metackhash & CK_CYLGRP) != 0)
flags |= GB_CKHASH;
- if (devvp->v_type == VREG)
- blkno = fragstoblks(fs, cgtod(fs, cg));
- else
+ if (devvp->v_type == VCHR) {
blkno = fsbtodb(fs, cgtod(fs, cg));
+ mp = devvp->v_rdev->si_mountpt;
+ } else {
+ blkno = fragstoblks(fs, cgtod(fs, cg));
+ mp = devvp->v_mount;
+ }
error = breadn_flags(devvp, blkno, blkno, (int)fs->fs_cgsize, NULL,
NULL, 0, NOCRED, flags, ffs_ckhash_cg, &bp);
if (error != 0)
@@ -3033,28 +3028,35 @@ ffs_getcg(struct fs *fs,
if ((fs->fs_metackhash & CK_CYLGRP) != 0 &&
(bp->b_flags & B_CKHASH) != 0 &&
cgp->cg_ckhash != bp->b_ckhash) {
- sfs = ffs_getmntstat(devvp);
- printf("UFS %s%s (%s) cylinder checksum failed: cg %ju, cgp: "
- "0x%x != bp: 0x%jx\n",
- devvp->v_type == VCHR ? "" : "snapshot of ",
- sfs->f_mntfromname, sfs->f_mntonname,
- (intmax_t)cg, cgp->cg_ckhash, (uintmax_t)bp->b_ckhash);
+ if (ppsratecheck(&VFSTOUFS(mp)->um_last_integritymsg,
+ &VFSTOUFS(mp)->um_secs_integritymsg, 1)) {
+ sfs = &mp->mnt_stat;
+ printf("UFS %s%s (%s) cylinder checkhash failed: "
+ "cg %ju, cgp: 0x%x != bp: 0x%jx\n",
+ devvp->v_type == VCHR ? "" : "snapshot of ",
+ sfs->f_mntfromname, sfs->f_mntonname, (intmax_t)cg,
+ cgp->cg_ckhash, (uintmax_t)bp->b_ckhash);
+ }
bp->b_flags &= ~B_CKHASH;
bp->b_flags |= B_INVAL | B_NOCACHE;
brelse(bp);
return (EIO);
}
if (!cg_chkmagic(cgp) || cgp->cg_cgx != cg) {
- sfs = ffs_getmntstat(devvp);
- printf("UFS %s%s (%s)",
- devvp->v_type == VCHR ? "" : "snapshot of ",
- sfs->f_mntfromname, sfs->f_mntonname);
- if (!cg_chkmagic(cgp))
- printf(" cg %ju: bad magic number 0x%x should be "
- "0x%x\n", (intmax_t)cg, cgp->cg_magic, CG_MAGIC);
- else
- printf(": wrong cylinder group cg %ju != cgx %u\n",
- (intmax_t)cg, cgp->cg_cgx);
+ if (ppsratecheck(&VFSTOUFS(mp)->um_last_integritymsg,
+ &VFSTOUFS(mp)->um_secs_integritymsg, 1)) {
+ sfs = &mp->mnt_stat;
+ printf("UFS %s%s (%s)",
+ devvp->v_type == VCHR ? "" : "snapshot of ",
+ sfs->f_mntfromname, sfs->f_mntonname);
+ if (!cg_chkmagic(cgp))
+ printf(" cg %ju: bad magic number 0x%x should "
+ "be 0x%x\n", (intmax_t)cg, cgp->cg_magic,
+ CG_MAGIC);
+ else
+ printf(": wrong cylinder group cg %ju != "
+ "cgx %u\n", (intmax_t)cg, cgp->cg_cgx);
+ }
bp->b_flags &= ~B_CKHASH;
bp->b_flags |= B_INVAL | B_NOCACHE;
brelse(bp);