git: f2b391528ad9 - main - Add ability to suppress UFS/FFS superblock check-hash failure messages.

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Mon, 15 Nov 2021 17:12:29 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=f2b391528ad9b11a2089457108a55645e358e92f

commit f2b391528ad9b11a2089457108a55645e358e92f
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2021-11-15 17:10:47 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2021-11-15 17:11:54 +0000

    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
---
 sys/ufs/ffs/ffs_subr.c | 26 ++++++++++++++------------
 sys/ufs/ffs/fs.h       | 10 ++++++++++
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 60d90aac5bcc..09f03458e753 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -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;
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index 00c153b9684d..8c0047f17caf 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -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.