Add ability to suppress UFS/FFS superblock check-hash failure messages.

When reading UFS/FFS superblocks that have check hashes, both the kernel
and libufs print an error message if the check hash is incorrect. This
commit adds the ability to request that the error message not be made.
It is intended for use by programs like fsck that wants to print its
own error message and by kernel subsystems like glabel that just wants
to check for possible filesystem types.

This capability will be used in followup commits.

Sponsored by: Netflix
This commit is contained in:
Kirk McKusick 2021-11-15 09:10:47 -08:00
parent 6d38604fc5
commit f2b391528a
2 changed files with 24 additions and 12 deletions

View file

@ -155,7 +155,6 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsblock,
int i, error, size, blks;
uint8_t *space;
int32_t *lp;
int chkhash;
char *buf;
fs = NULL;
@ -168,12 +167,9 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsblock,
return (error);
}
} else {
chkhash = 1;
if (altsblock == STDSB_NOHASHFAIL)
chkhash = 0;
for (i = 0; sblock_try[i] != -1; i++) {
if ((error = readsuper(devfd, &fs, sblock_try[i], 0,
chkhash, readfunc)) == 0)
altsblock, readfunc)) == 0)
break;
if (fs != NULL) {
UFS_FREE(fs, filltype);
@ -279,6 +275,13 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
fs->fs_metackhash &= CK_SUPPORTED;
fs->fs_flags &= FS_SUPPORTED;
if (fs->fs_ckhash != (ckhash = ffs_calc_sbhash(fs))) {
if (chkhash == STDSB_NOMSG)
return (EINTEGRITY);
if (chkhash == STDSB_NOHASHFAIL_NOMSG) {
fs->fs_flags |= FS_NEEDSFSCK;
fs->fs_fmod = 1;
return (0);
}
#ifdef _KERNEL
res = uprintf("Superblock check-hash failed: recorded "
"check-hash 0x%x != computed check-hash 0x%x%s\n",
@ -296,13 +299,12 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
"check-hash 0x%x != computed check-hash "
"0x%x%s\n", fs->fs_ckhash, ckhash,
chkhash == 0 ? " (Ignored)" : "");
if (chkhash == 0) {
fs->fs_flags |= FS_NEEDSFSCK;
fs->fs_fmod = 1;
return (0);
}
fs->fs_fmod = 0;
return (EINTEGRITY);
if (chkhash == STDSB)
return (EINTEGRITY);
/* chkhash == STDSB_NOHASHFAIL */
fs->fs_flags |= FS_NEEDSFSCK;
fs->fs_fmod = 1;
return (0);
}
/* Have to set for old filesystems that predate this field */
fs->fs_sblockactualloc = sblockloc;

View file

@ -86,9 +86,19 @@
* still return the superblock. This is used by the bootstrap code
* to give the system a chance to come up so that fsck can be run
* to correct the problem.
*
* STDSB_NOMSG is the same as STDSB but the kernel does not print an
* error message. It is used by programs like fsck that want to
* print their own error message.
*
* STDSB_NOHASHFAIL_NOMSG is the same as STDSB_NOHASHFAIL but the kernel
* does not print an error message. It is used by clients like glabel
* that just want to check for possible filesystem types.
*/
#define STDSB -1 /* Fail if check-hash is bad */
#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
#define STDSB_NOMSG -3 /* STDSB with no kernel message */
#define STDSB_NOHASHFAIL_NOMSG -4 /* STDSB_NOHASHFAIL with no message */
/*
* Max number of fragments per block. This value is NOT tweakable.