From 82e72f1d12fa8a3baaefe46509d9aa33406cbf4d Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sun, 24 Jul 2022 18:10:39 -0700 Subject: [PATCH] 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 +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 = sbget(disk->d_fd, &fs, disk->d_sblockloc); + return (handle_disk_read(disk, fs, error)); +} + +static int +handle_disk_read(struct uufsd *disk, struct fs *fs, int error) +{ ERROR(disk, NULL); - - if ((errno = sbget(disk->d_fd, &fs, STDSB)) != 0) { - switch (errno) { + 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);