aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libufs/Makefile2
-rw-r--r--lib/libufs/libufs.h4
-rw-r--r--lib/libufs/sblock.c54
-rw-r--r--lib/libufs/sbread.369
4 files changed, 108 insertions, 21 deletions
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index a767546f457f..623d5ae541a0 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -20,6 +20,8 @@ MLINKS+= cgread.3 cgput.3
MLINKS+= getinode.3 putinode.3
MLINKS+= sbread.3 sbwrite.3
MLINKS+= sbread.3 sbget.3
+MLINKS+= sbread.3 sbsearch.3
+MLINKS+= sbread.3 sbfind.3
MLINKS+= sbread.3 sbput.3
MLINKS+= ufs_disk_close.3 ufs_disk_fillout.3
MLINKS+= ufs_disk_close.3 ufs_disk_fillout_blank.3
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index cb8774454b38..5dbf9c2a5c28 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -111,6 +111,8 @@ void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int);
void ffs_fragacct(struct fs *, int, int32_t [], int);
int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
+int ffs_sbsearch(void *, struct fs **, int, char *,
+ int (*)(void *, off_t, void **, int));
void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_sbget(void *, struct fs **, off_t, int, char *,
int (*)(void *, off_t, void **, int));
@@ -149,9 +151,11 @@ int putinode(struct uufsd *);
* sblock.c
*/
int sbread(struct uufsd *);
+int sbfind(struct uufsd *, int);
int sbwrite(struct uufsd *, int);
/* low level superblock read/write functions */
int sbget(int, struct fs **, off_t, int);
+int sbsearch(int, struct fs **, int);
int sbput(int, struct fs *, int);
/*
diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c
index 5708d50aa4f9..4dfa0e79a711 100644
--- a/lib/libufs/sblock.c
+++ b/lib/libufs/sblock.c
@@ -73,6 +73,30 @@ sbread(struct uufsd *disk)
return (handle_disk_read(disk, fs, error));
}
+/*
+ * Make an extensive search to find a superblock. If the superblock
+ * in the standard place cannot be used, try looking for one of the
+ * backup superblocks.
+ *
+ * The flags parameter is made up of the following or'ed together options:
+ *
+ * UFS_NOMSG indicates that superblock inconsistency error messages
+ * should not be printed.
+ *
+ * UFS_NOCSUM causes only the superblock itself to be returned, but does
+ * not read in any auxillary data structures like the cylinder group
+ * summary information.
+ */
+int
+sbfind(struct uufsd *disk, int flags)
+{
+ struct fs *fs;
+ int error;
+
+ error = sbsearch(disk->d_fd, &fs, flags);
+ return (handle_disk_read(disk, fs, error));
+}
+
static int
handle_disk_read(struct uufsd *disk, struct fs *fs, int error)
{
@@ -174,8 +198,27 @@ static int use_pwrite(void *devfd, off_t loc, void *buf, int size);
int
sbget(int devfd, struct fs **fsp, off_t sblockloc, int flags)
{
+ int error;
+
+ error = ffs_sbget(&devfd, fsp, sblockloc, flags, "user", use_pread);
+ fflush(NULL); /* flush any messages */
+ return (error);
+}
+
+/*
+ * Make an extensive search of the devfd device to find a superblock.
+ * If the superblock in the standard place cannot be used, try looking
+ * for one of the backup superblocks. If found, memory is allocated and
+ * returned in fsp.
+ */
+int
+sbsearch(int devfd, struct fs **fsp, int flags)
+{
+ int error;
- return (ffs_sbget(&devfd, fsp, sblockloc, flags, "user", use_pread));
+ error = ffs_sbsearch(&devfd, fsp, flags, "user", use_pread);
+ fflush(NULL); /* flush any messages */
+ return (error);
}
/*
@@ -209,11 +252,10 @@ sbput(int devfd, struct fs *fs, int numaltwrite)
off_t savedactualloc;
int i, error;
- if ((error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc,
- use_pwrite)) != 0)
+ error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc, use_pwrite);
+ fflush(NULL); /* flush any messages */
+ if (error != 0 || numaltwrite == 0)
return (error);
- if (numaltwrite == 0)
- return (0);
savedactualloc = fs->fs_sblockactualloc;
if (fs->fs_si != NULL) {
savedcsp = fs->fs_csp;
@@ -223,6 +265,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite)
fs->fs_sblockactualloc = dbtob(fsbtodb(fs, cgsblock(fs, i)));
if ((error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc,
use_pwrite)) != 0) {
+ fflush(NULL); /* flush any messages */
fs->fs_sblockactualloc = savedactualloc;
fs->fs_csp = savedcsp;
return (error);
@@ -231,6 +274,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite)
fs->fs_sblockactualloc = savedactualloc;
if (fs->fs_si != NULL)
fs->fs_csp = savedcsp;
+ fflush(NULL); /* flush any messages */
return (0);
}
diff --git a/lib/libufs/sbread.3 b/lib/libufs/sbread.3
index f579fc7ffdf1..460699842036 100644
--- a/lib/libufs/sbread.3
+++ b/lib/libufs/sbread.3
@@ -3,19 +3,21 @@
.\" Description:
.\" Manual page for libufs functions:
.\" sbget(3)
+.\" sbsearch(3)
.\" sbput(3)
.\" sbread(3)
+.\" sbfind(3)
.\" sbwrite(3)
.\"
.\" This file is in the public domain.
.\"
.\" $FreeBSD$
.\"
-.Dd September 2, 2020
+.Dd August 8, 2022
.Dt SBREAD 3
.Os
.Sh NAME
-.Nm sbget , sbput , sbread , sbwrite
+.Nm sbget , sbsearch , sbput , sbread , sbfind , sbwrite
.Nd read and write superblocks of a UFS file system
.Sh LIBRARY
.Lb libufs
@@ -29,16 +31,22 @@
.Ft int
.Fn sbget "int devfd" "struct fs **fsp" "off_t sblockloc" "int flags"
.Ft int
+.Fn sbsearch "int devfd" "struct fs **fsp" "int flags"
+.Ft int
.Fn sbput "int devfd" "struct fs *fs" "int numaltwrite"
.Ft int
.Fn sbread "struct uufsd *disk"
.Ft int
+.Fn sbfind "struct uufsd *disk" "int flags"
+.Ft int
.Fn sbwrite "struct uufsd *disk" "int all"
.Sh DESCRIPTION
The
-.Fn sbget
+.Fn sbget ,
+.Fn sbsearch ,
+.Fn sbread ,
and
-.Fn sbread
+.Fn sbfind
functions provide superblock reads for
.Xr libufs 3
consumers.
@@ -52,7 +60,9 @@ consumers.
.Pp
The
.Fn sbget
-function first allocates a buffer to hold the superblock.
+and
+.Fn sbsearch
+functions first allocate a buffer to hold the superblock.
Using the
.Va devfd
file descriptor that references the filesystem disk,
@@ -65,26 +75,38 @@ The value
may be specified for
.Va sblockloc
to request that the standard location for the superblock be read.
+The
+.Fn sbsearch
+function uses the
+.Va devfd
+file descriptor that references the filesystem disk,
+to search first for the superblock at the standard location.
+If it is not found or is too damaged to use
+.Fn sbsearch
+will attempt to find one of the filesystem's alternate superblocks.
Flags are specified by
.Em or Ns 'ing
the following values:
.Pp
-.Bl -tag -width UFS_NOHASHFAIL
-.It Cm UFS_NOHASHFAIL
-Will note if the check hash is wrong but will still return the superblock.
+.Bl -tag -width UFS_NOCSUM
+.It Cm UFS_NOCSUM
+Causes only the superblock itself to be returned, but does not read in any
+auxiliary data structures like the cylinder group summary information.
.It Cm UFS_NOMSG
Indicates that superblock inconsistency error messages should not be printed.
-.It Cm UFS_NOCSUM
-Causes only the superblock itself to be returned, but does not read in any auxiliary data structures like the cylinder group summary information.
.El
.Pp
If successful,
.Fn sbget
-returns a pointer to the buffer containing the superblock in
+and
+.Fn sbsearch
+functions return a pointer to the buffer containing the superblock in
.Va fsp .
The
.Fn sbget
-function is safe to use in threaded applications.
+and
+.Fn sbsearch
+functions are safe to use in threaded applications.
.Pp
The
.Fn sbput
@@ -113,7 +135,19 @@ modified and the on-disk copy needs to be updated.
.Pp
The
.Fn sbread
-function reads the standard filesystem superblock into the
+function reads the standard filesystem superblock.
+The
+.Fn sbfind
+function tries to find a usable superblock.
+It searchs first for the superblock at the standard location.
+If it is not found or is too damaged to use
+.Fn sbfind
+will attempt to find one of the filesystem's alternate superblocks.
+If successful
+.Fn sbread
+and
+.Fn sbfind
+return a superblock in the
.Va d_sb ,
structure embedded in the given user-land UFS disk structure.
.Pp
@@ -131,16 +165,19 @@ value is non-zero.
.Sh RETURN VALUES
.Rv -std sbread sbwrite
The
-.Fn sbget
+.Fn sbget ,
+.Fn sbsearch ,
and
.Fn sbput
functions return the value 0 if successful;
otherwise they return one of the errors described below.
.Sh ERRORS
The errors returned by
-.Fn sbget
+.Fn sbget ,
+.Fn sbsearch ,
+.Fn sbread ,
and
-.Fn sbread
+.Fn sbfind ,
include any of the errors specified for the library function
.Xr bread 3 .
Additionally, they may follow the