git: 82e72f1d12fa - main - Add d_sblockloc to libufs(3) disk structure to allow options to be added.

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Mon, 25 Jul 2022 01:12:57 UTC
The branch main has been updated by mckusick:

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

commit 82e72f1d12fa8a3baaefe46509d9aa33406cbf4d
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2022-07-25 01:10:39 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2022-07-25 01:12:25 +0000

    Add d_sblockloc to libufs(3) disk structure to allow options to be added.
    
    By making the disk block parameter used by the libufs(3) sbread(3)
    function visible, applications using sbread(3) can set their own
    addition options such as using the STDSB_NOHASHFAIL request to
    say that they want the superblock read to succeed even when
    the superblock checkhash is incorrect.
    
    While here also add an error message when a check-hash failure
    is detected.
---
 lib/libufs/libufs.h |  1 +
 lib/libufs/sblock.c | 22 +++++++++++++++++++---
 lib/libufs/type.c   |  1 +
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index 63a8dc170997..5045117b5d7d 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -65,6 +65,7 @@ struct uufsd {
 	int d_ccg;			/* current cylinder group */
 	int d_lcg;			/* last cylinder group (in d_cg) */
 	const char *d_error;		/* human readable disk error */
+	off_t	d_sblockloc;		/* where to look for the superblock */
 	int d_mine;			/* internal flags */
 #define	d_fs	d_sbunion.d_fs
 #define	d_sb	d_sbunion.d_sb
diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c
index 3b65e79b02b5..9ba012400f1d 100644
--- a/lib/libufs/sblock.c
+++ b/lib/libufs/sblock.c
@@ -49,21 +49,37 @@ __FBSDID("$FreeBSD$");
 
 #include <libufs.h>
 
+static int handle_disk_read(struct uufsd *, struct fs *, int);
+
+/*
+ * Read the standard superblock.
+ */
 int
 sbread(struct uufsd *disk)
 {
 	struct fs *fs;
+	int error;
 
-	ERROR(disk, NULL);
+	error = sbget(disk->d_fd, &fs, disk->d_sblockloc);
+	return (handle_disk_read(disk, fs, error));
+}
 
-	if ((errno = sbget(disk->d_fd, &fs, STDSB)) != 0) {
-		switch (errno) {
+static int
+handle_disk_read(struct uufsd *disk, struct fs *fs, int error)
+{
+
+	ERROR(disk, NULL);
+	if (error != 0) {
+		switch (error) {
 		case EIO:
 			ERROR(disk, "non-existent or truncated superblock");
 			break;
 		case ENOENT:
 			ERROR(disk, "no usable known superblock found");
 			break;
+		case EINTEGRITY:
+			ERROR(disk, "superblock check-hash failure");
+			break;
 		case ENOSPC:
 			ERROR(disk, "failed to allocate space for superblock "
 			    "information");
diff --git a/lib/libufs/type.c b/lib/libufs/type.c
index a060f8ec5abf..ac5b8d17e84c 100644
--- a/lib/libufs/type.c
+++ b/lib/libufs/type.c
@@ -168,6 +168,7 @@ again:	if ((ret = stat(name, &st)) < 0) {
 	disk->d_ufs = 0;
 	disk->d_error = NULL;
 	disk->d_si = NULL;
+	disk->d_sblockloc = STDSB;
 
 	if (oname != name) {
 		name = strdup(name);