diff options
Diffstat (limited to 'lib/libufs')
-rw-r--r-- | lib/libufs/Makefile | 8 | ||||
-rw-r--r-- | lib/libufs/Makefile.depend | 1 | ||||
-rw-r--r-- | lib/libufs/block.c | 50 | ||||
-rw-r--r-- | lib/libufs/bread.3 | 2 | ||||
-rw-r--r-- | lib/libufs/cgread.3 | 2 | ||||
-rw-r--r-- | lib/libufs/cgroup.c | 9 | ||||
-rw-r--r-- | lib/libufs/getinode.3 | 2 | ||||
-rw-r--r-- | lib/libufs/inode.c | 33 | ||||
-rw-r--r-- | lib/libufs/libufs.3 | 4 | ||||
-rw-r--r-- | lib/libufs/libufs.h | 73 | ||||
-rw-r--r-- | lib/libufs/sblock.c | 116 | ||||
-rw-r--r-- | lib/libufs/sbread.3 | 83 | ||||
-rw-r--r-- | lib/libufs/type.c | 19 | ||||
-rw-r--r-- | lib/libufs/ufs_disk_close.3 | 11 |
14 files changed, 270 insertions, 143 deletions
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile index a767546f457f..3b1911d7a5cd 100644 --- a/lib/libufs/Makefile +++ b/lib/libufs/Makefile @@ -1,9 +1,9 @@ -# $FreeBSD$ +PACKAGE= ufs +LIB_PACKAGE= -PACKAGE= runtime LIB= ufs SHLIBDIR?= /lib -SHLIB_MAJOR= 7 +SHLIB_MAJOR= 8 SRCS= block.c cgroup.c gsb_crc32.c inode.c sblock.c type.c ffs_subr.c SRCS+= ffs_tables.c @@ -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/Makefile.depend b/lib/libufs/Makefile.depend index 8d409f5263ac..6ef78fac5cbf 100644 --- a/lib/libufs/Makefile.depend +++ b/lib/libufs/Makefile.depend @@ -1,4 +1,3 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ diff --git a/lib/libufs/block.c b/lib/libufs/block.c index 3c99d288a402..8bccc18ed3dd 100644 --- a/lib/libufs/block.c +++ b/lib/libufs/block.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Juli Mallett. All rights reserved. * @@ -27,9 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/mount.h> #include <sys/disk.h> @@ -59,19 +56,10 @@ bread(struct uufsd *disk, ufs2_daddr_t blockno, void *data, size_t size) ERROR(disk, NULL); - p2 = data; - /* - * XXX: various disk controllers require alignment of our buffer - * XXX: which is stricter than struct alignment. - * XXX: Bounce the buffer if not 64 byte aligned. - * XXX: this can be removed if/when the kernel is fixed - */ - if (((intptr_t)data) & 0x3f) { - p2 = malloc(size); - if (p2 == NULL) { - ERROR(disk, "allocate bounce buffer"); - goto fail; - } + BUF_MALLOC(&p2, data, size); + if (p2 == NULL) { + ERROR(disk, "allocate bounce buffer"); + goto fail; } cnt = pread(disk->d_fd, p2, size, (off_t)(blockno * disk->d_bsize)); if (cnt == -1) { @@ -103,7 +91,7 @@ bwrite(struct uufsd *disk, ufs2_daddr_t blockno, const void *data, size_t size) { ssize_t cnt; int rv; - void *p2 = NULL; + void *p2; ERROR(disk, NULL); @@ -112,24 +100,15 @@ bwrite(struct uufsd *disk, ufs2_daddr_t blockno, const void *data, size_t size) ERROR(disk, "failed to open disk for writing"); return (-1); } - - /* - * XXX: various disk controllers require alignment of our buffer - * XXX: which is stricter than struct alignment. - * XXX: Bounce the buffer if not 64 byte aligned. - * XXX: this can be removed if/when the kernel is fixed - */ - if (((intptr_t)data) & 0x3f) { - p2 = malloc(size); - if (p2 == NULL) { - ERROR(disk, "allocate bounce buffer"); - return (-1); - } - memcpy(p2, data, size); - data = p2; + BUF_MALLOC(&p2, data, size); + if (p2 == NULL) { + ERROR(disk, "allocate bounce buffer"); + return (-1); } - cnt = pwrite(disk->d_fd, data, size, (off_t)(blockno * disk->d_bsize)); - if (p2 != NULL) + if (p2 != data) + memcpy(p2, data, size); + cnt = pwrite(disk->d_fd, p2, size, (off_t)(blockno * disk->d_bsize)); + if (p2 != data) free(p2); if (cnt == -1) { ERROR(disk, "write error to block device"); @@ -139,7 +118,6 @@ bwrite(struct uufsd *disk, ufs2_daddr_t blockno, const void *data, size_t size) ERROR(disk, "short write to block device"); return (-1); } - return (cnt); } diff --git a/lib/libufs/bread.3 b/lib/libufs/bread.3 index 9109166bea49..b3a61b4a5325 100644 --- a/lib/libufs/bread.3 +++ b/lib/libufs/bread.3 @@ -7,8 +7,6 @@ .\" .\" This file is in the public domain. .\" -.\" $FreeBSD$ -.\" .Dd June 4, 2003 .Dt BREAD 3 .Os diff --git a/lib/libufs/cgread.3 b/lib/libufs/cgread.3 index cbc633708506..78a62f75e82b 100644 --- a/lib/libufs/cgread.3 +++ b/lib/libufs/cgread.3 @@ -11,8 +11,6 @@ .\" .\" This file is in the public domain. .\" -.\" $FreeBSD$ -.\" .Dd September 2, 2020 .Dt CGREAD 3 .Os diff --git a/lib/libufs/cgroup.c b/lib/libufs/cgroup.c index 90b28eadad2c..7c7ca0d242b4 100644 --- a/lib/libufs/cgroup.c +++ b/lib/libufs/cgroup.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2003 Juli Mallett. All rights reserved. * @@ -27,9 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/mount.h> #include <sys/disklabel.h> @@ -268,6 +265,10 @@ cgwrite1(struct uufsd *disk, int cg) static char errmsg[BUFSIZ]; if (cg == disk->d_cg.cg_cgx) { + if (ufs_disk_write(disk) == -1) { + ERROR(disk, "failed to open disk for writing"); + return (-1); + } if (cgput(disk->d_fd, &disk->d_fs, &disk->d_cg) == 0) return (0); ERROR(disk, NULL); diff --git a/lib/libufs/getinode.3 b/lib/libufs/getinode.3 index fde249e86102..1668e65551e5 100644 --- a/lib/libufs/getinode.3 +++ b/lib/libufs/getinode.3 @@ -7,8 +7,6 @@ .\" .\" This file is in the public domain. .\" -.\" $FreeBSD$ -.\" .Dd September 2, 2020 .Dt GETINODE 3 .Os diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c index c4a0cab9e95a..863e71867daa 100644 --- a/lib/libufs/inode.c +++ b/lib/libufs/inode.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Juli Mallett. All rights reserved. * @@ -27,9 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/mount.h> #include <sys/disklabel.h> @@ -46,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <libufs.h> @@ -56,6 +54,7 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) ino_t min, max; caddr_t inoblock; struct fs *fs; + struct timespec now; ERROR(disk, NULL); @@ -64,17 +63,13 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) ERROR(disk, "inode number out of range"); return (-1); } - inoblock = disk->d_inoblock; + inoblock = (caddr_t)&disk->d_inos[0]; min = disk->d_inomin; max = disk->d_inomax; - if (inoblock == NULL) { - inoblock = malloc(fs->fs_bsize); - if (inoblock == NULL) { - ERROR(disk, "unable to allocate inode block"); - return (-1); - } - disk->d_inoblock = inoblock; + if (clock_gettime(CLOCK_REALTIME_FAST, &now) != 0) { + ERROR(disk, "cannot get current time of day"); + return (-1); } if (inum >= min && inum < max) goto gotit; @@ -85,6 +80,8 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) gotit: switch (disk->d_ufs) { case 1: disk->d_dp.dp1 = &((struct ufs1_dinode *)inoblock)[inum - min]; + if (ffs_oldfscompat_inode_read(fs, disk->d_dp, now.tv_sec)) + putinode(disk); if (dp != NULL) *dp = disk->d_dp; return (0); @@ -92,8 +89,12 @@ gotit: switch (disk->d_ufs) { disk->d_dp.dp2 = &((struct ufs2_dinode *)inoblock)[inum - min]; if (dp != NULL) *dp = disk->d_dp; - if (ffs_verify_dinode_ckhash(fs, disk->d_dp.dp2) == 0) + if (ffs_verify_dinode_ckhash(fs, disk->d_dp.dp2) == 0) { + if (ffs_oldfscompat_inode_read(fs, disk->d_dp, + now.tv_sec)) + putinode(disk); return (0); + } ERROR(disk, "check-hash failed for inode read from disk"); return (-1); default: @@ -109,14 +110,10 @@ putinode(struct uufsd *disk) struct fs *fs; fs = &disk->d_fs; - if (disk->d_inoblock == NULL) { - ERROR(disk, "No inode block allocated"); - return (-1); - } if (disk->d_ufs == 2) ffs_update_dinode_ckhash(fs, disk->d_dp.dp2); if (bwrite(disk, fsbtodb(fs, ino_to_fsba(&disk->d_fs, disk->d_inomin)), - disk->d_inoblock, disk->d_fs.fs_bsize) <= 0) + (caddr_t)&disk->d_inos[0], disk->d_fs.fs_bsize) <= 0) return (-1); return (0); } diff --git a/lib/libufs/libufs.3 b/lib/libufs/libufs.3 index 578b63d87345..aa3386ad9771 100644 --- a/lib/libufs/libufs.3 +++ b/lib/libufs/libufs.3 @@ -5,8 +5,6 @@ .\" .\" This file is in the public domain. .\" -.\" $FreeBSD$ -.\" .Dd September 2, 2020 .Dt LIBUFS 3 .Os @@ -72,7 +70,7 @@ to a string describing the error. .Xr ufs_disk_fillout 3 , .Xr ufs_disk_fillout_blank 3 , .Xr ufs_disk_write 3 , -.Xr ffs 7 +.Xr ffs 4 .Sh HISTORY The .Xr libufs 3 diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h index 63a8dc170997..bb92e082a875 100644 --- a/lib/libufs/libufs.h +++ b/lib/libufs/libufs.h @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Juli Mallett. All rights reserved. * @@ -25,57 +25,69 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ #ifndef __LIBUFS_H__ #define __LIBUFS_H__ +#include <stdbool.h> /* - * libufs structures. + * Various disk controllers require their buffers to be aligned to the size + * of a cache line. The LIBUFS_BUFALIGN defines the required alignment size. + * The alignment must be a power of 2. */ -union dinodep { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; -}; +#define LIBUFS_BUFALIGN 128 /* * userland ufs disk. */ struct uufsd { - const char *d_name; /* disk name */ - int d_ufs; /* decimal UFS version */ - int d_fd; /* raw device file descriptor */ - long d_bsize; /* device bsize */ - ufs2_daddr_t d_sblock; /* superblock location */ - struct fs_summary_info *d_si; /* Superblock summary info */ - caddr_t d_inoblock; /* inode block */ - uint32_t d_inomin; /* low ino, not ino_t for ABI compat */ - uint32_t d_inomax; /* high ino, not ino_t for ABI compat */ - union dinodep d_dp; /* pointer to currently active inode */ union { struct fs d_fs; /* filesystem information */ - char d_sb[MAXBSIZE]; /* superblock as buffer */ - } d_sbunion; + char d_sb[SBLOCKSIZE]; /* superblock as buffer */ + } d_sbunion __aligned(LIBUFS_BUFALIGN); union { struct cg d_cg; /* cylinder group */ char d_buf[MAXBSIZE]; /* cylinder group storage */ - } d_cgunion; - int d_ccg; /* current cylinder group */ - int d_lcg; /* last cylinder group (in d_cg) */ + } d_cgunion __aligned(LIBUFS_BUFALIGN); + union { + union dinodep d_ino[1]; /* inode block */ + char d_inos[MAXBSIZE]; /* inode block as buffer */ + } d_inosunion __aligned(LIBUFS_BUFALIGN); + const char *d_name; /* disk name */ const char *d_error; /* human readable disk error */ - int d_mine; /* internal flags */ + ufs2_daddr_t d_sblock; /* superblock location */ + struct fs_summary_info *d_si; /* Superblock summary info */ + union dinodep d_dp; /* pointer to currently active inode */ + ino_t d_inomin; /* low ino */ + ino_t d_inomax; /* high ino */ + off_t d_sblockloc; /* where to look for the superblock */ + int64_t d_bsize; /* device bsize */ + int64_t d_lookupflags; /* flags to superblock lookup */ + int64_t d_mine; /* internal flags */ + int32_t d_ccg; /* current cylinder group */ + int32_t d_ufs; /* decimal UFS version */ + int32_t d_fd; /* raw device file descriptor */ + int32_t d_lcg; /* last cylinder group (in d_cg) */ +}; +#define d_inos d_inosunion.d_inos #define d_fs d_sbunion.d_fs -#define d_sb d_sbunion.d_sb #define d_cg d_cgunion.d_cg -}; /* * libufs macros (internal, non-exported). */ #ifdef _LIBUFS /* + * Ensure that the buffer is aligned to the I/O subsystem requirements. + */ +#define BUF_MALLOC(newbufpp, data, size) { \ + if (data != NULL && (((intptr_t)data) & (LIBUFS_BUFALIGN - 1)) == 0) \ + *newbufpp = (void *)data; \ + else \ + *newbufpp = aligned_alloc(LIBUFS_BUFALIGN, size); \ +} +/* * Trace steps through libufs, to be used at entry and erroneous return. */ static inline void @@ -109,8 +121,11 @@ 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); +bool ffs_oldfscompat_inode_read(struct fs *, union dinodep, time_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, char *, +int ffs_sbget(void *, struct fs **, off_t, int, char *, int (*)(void *, off_t, void **, int)); int ffs_sbput(void *, struct fs *, off_t, int (*)(void *, off_t, void *, int)); @@ -147,9 +162,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 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 3b65e79b02b5..09d478bfe71e 100644 --- a/lib/libufs/sblock.c +++ b/lib/libufs/sblock.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Juli Mallett. All rights reserved. * @@ -27,9 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/mount.h> #include <sys/disklabel.h> @@ -49,21 +46,70 @@ __FBSDID("$FreeBSD$"); #include <libufs.h> +static int handle_disk_read(struct uufsd *, struct fs *, int); + +/* + * Read the standard superblock. + * + * The following option flags can be or'ed into disk->d_lookupflags: + * + * 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 sbread(struct uufsd *disk) { struct fs *fs; + int error; - ERROR(disk, NULL); + error = sbget(disk->d_fd, &fs, disk->d_sblockloc, disk->d_lookupflags); + return (handle_disk_read(disk, fs, error)); +} - if ((errno = sbget(disk->d_fd, &fs, STDSB)) != 0) { - switch (errno) { +/* + * 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) +{ + + 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"); @@ -133,14 +179,43 @@ static int use_pread(void *devfd, off_t loc, void **bufp, int size); static int use_pwrite(void *devfd, off_t loc, void *buf, int size); /* + * The following two functions read a superblock. Their flags + * parameter are 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. + * * Read a superblock from the devfd device allocating memory returned - * in fsp. Also read the superblock summary information. + * in fsp. */ int -sbget(int devfd, struct fs **fsp, off_t sblockloc) +sbget(int devfd, struct fs **fsp, off_t sblockloc, int flags) { + int error; - return (ffs_sbget(&devfd, fsp, sblockloc, "user", use_pread)); + 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; + + error = ffs_sbsearch(&devfd, fsp, flags, "user", use_pread); + fflush(NULL); /* flush any messages */ + return (error); } /* @@ -152,7 +227,8 @@ use_pread(void *devfd, off_t loc, void **bufp, int size) int fd; fd = *(int *)devfd; - if ((*bufp = malloc(size)) == NULL) + BUF_MALLOC(bufp, NULL, size); + if (*bufp == NULL) return (ENOSPC); if (pread(fd, *bufp, size, loc) != size) return (EIO); @@ -174,25 +250,29 @@ 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; - savedcsp = fs->fs_csp; - fs->fs_csp = NULL; + if (fs->fs_si != NULL) { + savedcsp = fs->fs_csp; + fs->fs_csp = NULL; + } for (i = 0; i < numaltwrite; i++) { 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); } } fs->fs_sblockactualloc = savedactualloc; - fs->fs_csp = savedcsp; + 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 e97469f86873..47c32ce029ae 100644 --- a/lib/libufs/sbread.3 +++ b/lib/libufs/sbread.3 @@ -3,19 +3,19 @@ .\" 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 @@ -27,18 +27,24 @@ .In ufs/ffs/fs.h .In libufs.h .Ft int -.Fn sbget "int devfd" "struct fs **fsp" "off_t sblockloc" +.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 +58,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, @@ -60,11 +68,43 @@ file descriptor that references the filesystem disk, reads the superblock located at the byte offset specified by .Va sblockloc into the allocated buffer. -If successful, it returns a pointer to the buffer containing the superblock in +The value +.Cm UFS_STDSB +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_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. +.El +.Pp +If successful, +.Fn sbget +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 @@ -93,7 +133,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 @@ -111,16 +163,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 diff --git a/lib/libufs/type.c b/lib/libufs/type.c index a060f8ec5abf..557e6cdead63 100644 --- a/lib/libufs/type.c +++ b/lib/libufs/type.c @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Juli Mallett. All rights reserved. * @@ -27,9 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/mount.h> #include <sys/disklabel.h> @@ -63,10 +60,6 @@ ufs_disk_close(struct uufsd *disk) ERROR(disk, NULL); close(disk->d_fd); disk->d_fd = -1; - if (disk->d_inoblock != NULL) { - free(disk->d_inoblock); - disk->d_inoblock = NULL; - } if (disk->d_mine & MINE_NAME) { free((char *)(uintptr_t)disk->d_name); disk->d_name = NULL; @@ -157,10 +150,16 @@ again: if ((ret = stat(name, &st)) < 0) { return (-1); } + if (((uintptr_t)disk & ~(LIBUFS_BUFALIGN - 1)) != (uintptr_t)disk) { + ERROR(disk, "uufsd structure must be aligned to " + "LIBUFS_BUFALIGN byte boundry, see ufs_disk_fillout(3)"); + close(fd); + return (-1); + } + disk->d_bsize = 1; disk->d_ccg = 0; disk->d_fd = fd; - disk->d_inoblock = NULL; disk->d_inomin = 0; disk->d_inomax = 0; disk->d_lcg = 0; @@ -168,6 +167,8 @@ again: if ((ret = stat(name, &st)) < 0) { disk->d_ufs = 0; disk->d_error = NULL; disk->d_si = NULL; + disk->d_sblockloc = UFS_STDSB; + disk->d_lookupflags = 0; if (oname != name) { name = strdup(name); diff --git a/lib/libufs/ufs_disk_close.3 b/lib/libufs/ufs_disk_close.3 index d01e302d98df..f332a9bb5de9 100644 --- a/lib/libufs/ufs_disk_close.3 +++ b/lib/libufs/ufs_disk_close.3 @@ -9,9 +9,7 @@ .\" .\" This file is in the public domain. .\" -.\" $FreeBSD$ -.\" -.Dd June 4, 2003 +.Dd November 17, 2023 .Dt UFS_DISK_CLOSE 3 .Os .Sh NAME @@ -53,6 +51,13 @@ functions open a disk specified by .Fa name and populate the structure pointed to by .Fa disk . +The structure referenced by the +.Fa disk +pointer must be aligned to at least the alignment specified by +.Dv LIBUFS_ALIGN +that is defined in the +.Lb libufs.h +header file. The disk is opened read-only. The specified .Fa name |