Provide better diagnostic messages for bad cylinder groups.

Like the detailed diagnostics produced when a bad superblock
is read, provide similar detailed diagnostics when bad
cylinder groups are read.

Reported by:  Peter Holm
Tested by:    Peter Holm
Sponsored by: The FreeBSD Foundation
This commit is contained in:
Kirk McKusick 2022-08-25 23:56:31 -07:00
parent 8e59ec29e4
commit 495b1baac3

View File

@ -949,12 +949,21 @@ blzero(int fd, ufs2_daddr_t blk, long size)
* Verify cylinder group's magic number and other parameters. If the
* test fails, offer an option to rebuild the whole cylinder group.
*/
#undef CHK
#define CHK(lhs, op, rhs, fmt) \
if (lhs op rhs) { \
pwarn("UFS%d superblock failed: %s (" #fmt ") %s %s (" \
#fmt ")\n", sblock.fs_magic == FS_UFS1_MAGIC ? 1 : \
2, #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs); \
error = 1; \
}
int
check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
{
struct cg *cgp = cgbp->b_un.b_cg;
uint32_t cghash, calchash;
static int prevfailcg = -1;
int error;
/*
* Extended cylinder group checks.
@ -967,19 +976,20 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
calchash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
cgp->cg_ckhash = cghash;
}
if (cgp->cg_ckhash == calchash &&
cg_chkmagic(cgp) &&
cgp->cg_cgx == cg &&
((sblock.fs_magic == FS_UFS1_MAGIC &&
cgp->cg_old_niblk == sblock.fs_ipg &&
cgp->cg_ndblk <= sblock.fs_fpg &&
cgp->cg_old_ncyl <= sblock.fs_old_cpg) ||
(sblock.fs_magic == FS_UFS2_MAGIC &&
cgp->cg_niblk == sblock.fs_ipg &&
cgp->cg_ndblk <= sblock.fs_fpg &&
cgp->cg_initediblk <= sblock.fs_ipg))) {
return (1);
error = 0;
CHK(cgp->cg_ckhash, !=, calchash, "%jd");
CHK(cg_chkmagic(cgp), ==, 0, "%jd");
CHK(cgp->cg_cgx, !=, cg, "%jd");
CHK(cgp->cg_ndblk, >, sblock.fs_fpg, "%jd");
if (sblock.fs_magic == FS_UFS1_MAGIC) {
CHK(cgp->cg_old_niblk, !=, sblock.fs_ipg, "%jd");
CHK(cgp->cg_old_ncyl, >, sblock.fs_old_cpg, "%jd");
} else if (sblock.fs_magic == FS_UFS2_MAGIC) {
CHK(cgp->cg_niblk, !=, sblock.fs_ipg, "%jd");
CHK(cgp->cg_initediblk, >, sblock.fs_ipg, "%jd");
}
if (error == 0)
return (1);
if (prevfailcg == cg)
return (0);
prevfailcg = cg;
@ -1030,6 +1040,7 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
cgp->cg_nextfreeoff = cgp->cg_clusteroff +
howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
}
cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
cgdirty(cgbp);
return (0);
}