svn commit: r328426 - in head: lib/libufs sbin/clri sbin/dump sbin/fsck_ffs sbin/fsirand sbin/growfs sbin/newfs sbin/quotacheck stand/libsa sys/geom sys/geom/journal sys/geom/label sys/ufs/ffs usr....

Kirk McKusick mckusick at FreeBSD.org
Fri Jan 26 00:58:35 UTC 2018


Author: mckusick
Date: Fri Jan 26 00:58:32 2018
New Revision: 328426
URL: https://svnweb.freebsd.org/changeset/base/328426

Log:
  Refactoring of reading and writing of the UFS/FFS superblock.
  Specifically reading is done if ffs_sbget() and writing is done
  in ffs_sbput(). These functions are exported to libufs via the
  sbget() and sbput() functions which then used in the various
  filesystem utilities. This work is in preparation for adding
  subperblock check hashes.
  
  No functional change intended.
  
  Reviewed by: kib

Modified:
  head/lib/libufs/Makefile
  head/lib/libufs/libufs.h
  head/lib/libufs/sblock.c
  head/lib/libufs/sbread.3
  head/sbin/clri/Makefile
  head/sbin/clri/clri.c
  head/sbin/dump/Makefile
  head/sbin/dump/dump.h
  head/sbin/dump/main.c
  head/sbin/fsck_ffs/fsck.h
  head/sbin/fsck_ffs/fsutil.c
  head/sbin/fsck_ffs/globs.c
  head/sbin/fsck_ffs/setup.c
  head/sbin/fsirand/Makefile
  head/sbin/fsirand/fsirand.c
  head/sbin/growfs/growfs.c
  head/sbin/newfs/mkfs.c
  head/sbin/quotacheck/Makefile
  head/sbin/quotacheck/quotacheck.c
  head/stand/libsa/Makefile
  head/stand/libsa/ufs.c
  head/sys/geom/geom.h
  head/sys/geom/geom_io.c
  head/sys/geom/journal/g_journal_ufs.c
  head/sys/geom/label/g_label_ufs.c
  head/sys/ufs/ffs/ffs_extern.h
  head/sys/ufs/ffs/ffs_subr.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/ufs/ffs/fs.h
  head/usr.sbin/fstyp/Makefile
  head/usr.sbin/fstyp/ufs.c
  head/usr.sbin/quot/Makefile
  head/usr.sbin/quot/quot.c

Modified: head/lib/libufs/Makefile
==============================================================================
--- head/lib/libufs/Makefile	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/lib/libufs/Makefile	Fri Jan 26 00:58:32 2018	(r328426)
@@ -17,6 +17,8 @@ MLINKS+= cgread.3 cgwrite.3
 MLINKS+= cgread.3 cgwrite1.3
 MLINKS+= cgread.3 cgput.3
 MLINKS+= sbread.3 sbwrite.3
+MLINKS+= sbread.3 sbget.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
 MLINKS+= ufs_disk_close.3 ufs_disk_write.3

Modified: head/lib/libufs/libufs.h
==============================================================================
--- head/lib/libufs/libufs.h	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/lib/libufs/libufs.h	Fri Jan 26 00:58:32 2018	(r328426)
@@ -99,6 +99,20 @@ __BEGIN_DECLS
  */
 
 /*
+ * ffs_subr.c
+ */
+void	ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
+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);
+void	ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
+int	ffs_sbget(void *, struct fs **, off_t, char *,
+	    int (*)(void *, off_t, void **, int));
+int	ffs_sbput(void *, struct fs *, off_t,
+	    int (*)(void *, off_t, void *, int));
+
+/*
  * block.c
  */
 ssize_t bread(struct uufsd *, ufs2_daddr_t, void *, size_t);
@@ -129,6 +143,9 @@ int putino(struct uufsd *);
  */
 int sbread(struct uufsd *);
 int sbwrite(struct uufsd *, int);
+/* low level superblock read/write functions */
+int sbget(int, struct fs **, off_t);
+int sbput(int, struct fs *, int);
 
 /*
  * type.c
@@ -137,16 +154,6 @@ int ufs_disk_close(struct uufsd *);
 int ufs_disk_fillout(struct uufsd *, const char *);
 int ufs_disk_fillout_blank(struct uufsd *, const char *);
 int ufs_disk_write(struct uufsd *);
-
-/*
- * ffs_subr.c
- */
-void	ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
-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);
-void	ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
 
 /*
  * crc32c.c

Modified: head/lib/libufs/sblock.c
==============================================================================
--- head/lib/libufs/sblock.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/lib/libufs/sblock.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -47,79 +47,48 @@ __FBSDID("$FreeBSD$");
 
 #include <libufs.h>
 
-static int superblocks[] = SBLOCKSEARCH;
-
 int
 sbread(struct uufsd *disk)
 {
-	uint8_t block[MAXBSIZE];
 	struct fs *fs;
-	int sb, superblock;
-	int i, size, blks;
-	uint8_t *space;
 
 	ERROR(disk, NULL);
 
-	fs = &disk->d_fs;
-	superblock = superblocks[0];
-
-	for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) {
-		if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) {
+	if ((errno = sbget(disk->d_fd, &fs, -1)) != 0) {
+		switch (errno) {
+		case EIO:
 			ERROR(disk, "non-existent or truncated superblock");
-			return (-1);
+			break;
+		case ENOENT:
+			ERROR(disk, "no usable known superblock found");
+			break;
+		case ENOSPC:
+			ERROR(disk, "failed to allocate space for superblock "
+			    "information");
+			break;
+		case EINVAL:
+			ERROR(disk, "The previous newfs operation on this "
+			    "volume did not complete.\nYou must complete "
+			    "newfs before using this volume.");
+			break;
+		default:
+			ERROR(disk, "unknown superblock read error");
+			errno = EIO;
+			break;
 		}
-		if (fs->fs_magic == FS_UFS1_MAGIC)
-			disk->d_ufs = 1;
-		if (fs->fs_magic == FS_UFS2_MAGIC &&
-		    fs->fs_sblockloc == superblock)
-			disk->d_ufs = 2;
-		if (fs->fs_bsize <= MAXBSIZE &&
-		    (size_t)fs->fs_bsize >= sizeof(*fs)) {
-			if (disk->d_ufs)
-				break;
-		}
 		disk->d_ufs = 0;
-	}
-	if (superblock == -1 || disk->d_ufs == 0) {
-		/*
-		 * Other error cases will result in errno being set, here we
-		 * must set it to indicate no superblock could be found with
-		 * which to associate this disk/filesystem.
-		 */
-		ERROR(disk, "no usable known superblock found");
-		errno = ENOENT;
 		return (-1);
 	}
+	memcpy(&disk->d_fs, fs, fs->fs_sbsize);
+	free(fs);
+	fs = &disk->d_fs;
+	if (fs->fs_magic == FS_UFS1_MAGIC)
+		disk->d_ufs = 1;
+	if (fs->fs_magic == FS_UFS2_MAGIC)
+		disk->d_ufs = 2;
 	disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1);
-	disk->d_sblock = superblock / disk->d_bsize;
-	/*
-	 * Read in the superblock summary information.
-	 */
-	size = fs->fs_cssize;
-	blks = howmany(size, fs->fs_fsize);
-	size += fs->fs_ncg * sizeof(int32_t);
-	space = malloc(size);
-	if (space == NULL) {
-		ERROR(disk, "failed to allocate space for summary information");
-		return (-1);
-	}
-	fs->fs_csp = (struct csum *)space;
-	for (i = 0; i < blks; i += fs->fs_frag) {
-		size = fs->fs_bsize;
-		if (i + fs->fs_frag > blks)
-			size = (blks - i) * fs->fs_fsize;
-		if (bread(disk, fsbtodb(fs, fs->fs_csaddr + i), block, size)
-		    == -1) {
-			ERROR(disk, "Failed to read sb summary information");
-			free(fs->fs_csp);
-			return (-1);
-		}
-		bcopy(block, space, size);
-		space += size;
-	}
-	fs->fs_maxcluster = (uint32_t *)space;
+	disk->d_sblock = fs->fs_sblockloc / disk->d_bsize;
 	disk->d_sbcsum = fs->fs_csp;
-
 	return (0);
 }
 
@@ -127,45 +96,107 @@ int
 sbwrite(struct uufsd *disk, int all)
 {
 	struct fs *fs;
-	int blks, size;
-	uint8_t *space;
-	unsigned i;
 
 	ERROR(disk, NULL);
 
 	fs = &disk->d_fs;
-
-	if (!disk->d_sblock) {
-		disk->d_sblock = disk->d_fs.fs_sblockloc / disk->d_bsize;
-	}
-
-	if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) {
-		ERROR(disk, "failed to write superblock");
+	if ((errno = sbput(disk->d_fd, fs, all ? fs->fs_ncg : 0)) != 0) {
+		switch (errno) {
+		case EIO:
+			ERROR(disk, "failed to write superblock");
+			break;
+		default:
+			ERROR(disk, "unknown superblock write error");
+			errno = EIO;
+			break;
+		}
 		return (-1);
 	}
-	/*
-	 * Write superblock summary information.
-	 */
-	blks = howmany(fs->fs_cssize, fs->fs_fsize);
-	space = (uint8_t *)disk->d_sbcsum;
-	for (i = 0; i < blks; i += fs->fs_frag) {
-		size = fs->fs_bsize;
-		if (i + fs->fs_frag > blks)
-			size = (blks - i) * fs->fs_fsize;
-		if (bwrite(disk, fsbtodb(fs, fs->fs_csaddr + i), space, size)
-		    == -1) {
-			ERROR(disk, "Failed to write sb summary information");
+	return (0);
+}
+
+/*
+ * These are the low-level functions that actually read and write
+ * the superblock and its associated data. The actual work is done by
+ * the functions ffs_sbget and ffs_sbput in /sys/ufs/ffs/ffs_subr.c.
+ */
+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);
+
+/*
+ * Read a superblock from the devfd device allocating memory returned
+ * in fsp. Also read the superblock summary information.
+ */
+int
+sbget(int devfd, struct fs **fsp, off_t sblockloc)
+{
+
+	return (ffs_sbget(&devfd, fsp, sblockloc, "user", use_pread));
+}
+
+/*
+ * A read function for use by user-level programs using libufs.
+ */
+static int
+use_pread(void *devfd, off_t loc, void **bufp, int size)
+{
+	int fd;
+
+	fd = *(int *)devfd;
+	if ((*bufp = malloc(size)) == NULL)
+		return (ENOSPC);
+	if (pread(fd, *bufp, size, loc) != size)
+		return (EIO);
+	return (0);
+}
+
+/*
+ * Write a superblock to the devfd device from the memory pointed to by fs.
+ * Also write out the superblock summary information but do not free the
+ * summary information memory.
+ *
+ * Additionally write out numaltwrite of the alternate superblocks. Use
+ * fs->fs_ncg to write out all of the alternate superblocks.
+ */
+int
+sbput(int devfd, struct fs *fs, int numaltwrite)
+{
+	struct csum *savedcsp;
+	off_t savedactualloc;
+	int i, error;
+
+	if ((error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc,
+	     use_pwrite)) != 0)
+		return (error);
+	if (numaltwrite == 0)
+		return (0);
+	savedactualloc = fs->fs_sblockactualloc;
+	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) {
+			fs->fs_sblockactualloc = savedactualloc;
+			fs->fs_csp = savedcsp;
 			return (-1);
 		}
-		space += size;
 	}
-	if (all) {
-		for (i = 0; i < fs->fs_ncg; i++)
-			if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)),
-			    fs, SBLOCKSIZE) == -1) {
-				ERROR(disk, "failed to update a superblock");
-				return (-1);
-			}
-	}
+	fs->fs_sblockactualloc = savedactualloc;
+	fs->fs_csp = savedcsp;
+	return (0);
+}
+
+/*
+ * A write function for use by user-level programs using sbput in libufs.
+ */
+static int
+use_pwrite(void *devfd, off_t loc, void *buf, int size)
+{
+	int fd;
+
+	fd = *(int *)devfd;
+	if (pwrite(fd, buf, size, loc) != size)
+		return (EIO);
 	return (0);
 }

Modified: head/lib/libufs/sbread.3
==============================================================================
--- head/lib/libufs/sbread.3	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/lib/libufs/sbread.3	Fri Jan 26 00:58:32 2018	(r328426)
@@ -2,6 +2,8 @@
 .\" Date:	June 04, 2003
 .\" Description:
 .\" 	Manual page for libufs functions:
+.\"		sbget(3)
+.\"		sbput(3)
 .\"		sbread(3)
 .\"		sbwrite(3)
 .\"
@@ -9,11 +11,11 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 4, 2003
+.Dd January 19, 2018
 .Dt SBREAD 3
 .Os
 .Sh NAME
-.Nm sbread , sbwrite
+.Nm sbget , sbput , sbread , sbwrite
 .Nd read and write superblocks of a UFS file system
 .Sh LIBRARY
 .Lb libufs
@@ -25,35 +27,95 @@
 .In ufs/ffs/fs.h
 .In libufs.h
 .Ft int
+.Fn sbget "int devfd" "struct fs **fsp" "off_t sblockloc"
+.Ft int
+.Fn sbput "int devfd" "struct fs *fs" "int numaltwrite"
+.Ft int
 .Fn sbread "struct uufsd *disk"
 .Ft int
 .Fn sbwrite "struct uufsd *disk" "int all"
 .Sh DESCRIPTION
 The
+.Fn sbget
+and
 .Fn sbread
+functions provide superblock reads for
+.Xr libufs 3
+consumers.
+The
+.Fn sbput
 and
 .Fn sbwrite
-functions provide superblock reads and writes for
+functions provide superblock writes for
 .Xr libufs 3
 consumers.
+.Pp
 The
+.Fn sbget
+function first allocates a buffer to hold the superblock.
+Using the
+.Va devfd
+file descriptor that references the filesystem disk,
+.Fn sbget
+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
+.Va fsp .
+The
+.Fn sbget
+function is safe to use in threaded applications.
+.Pp
+The
+.Fn sbput
+function writes the superblock specified by
+.Va fs
+to the location from which it was read on the disk referenced by the
+.Va devfd
+file descriptor.
+Additionally, the
+.Fn sbput
+function will update the first
+.Va numaltwrite
+alternate superblock locations.
+To update all the alternate superblocks,
+specify a
+.Va numaltwrite
+value of
+.Va fs->fs_ncg .
+The
+.Fn sbput
+function is safe to use in threaded applications.
+Note that the
+.Fn sbput
+function needs to be called only if the superblock has been
+modified and the on-disk copy needs to be updated.
+.Pp
+The
 .Fn sbread
-and
+function reads the standard filesystem superblock into the
+.Va d_sb ,
+structure embedded in the given user-land UFS disk structure.
+.Pp
+The
 .Fn sbwrite
-functions operate on the superblock field,
+function writes the superblock from the
 .Va d_sb ,
-associated with a given userland UFS disk structure.
+structure embedded in the given user-land UFS disk structure
+to the location from which it was read.
 Additionally, the
 .Fn sbwrite
-function will write to all superblock locations if the
+function will write to all the alternate superblock locations if the
 .Fa all
 value is non-zero.
 .Sh RETURN VALUES
-.Rv -std sbread sbwrite
+.Rv -std sbget sbput sbread sbwrite
 .Sh ERRORS
-The function
+The
+.Fn sbget
+and
 .Fn sbread
-may fail and set
+functions may fail and set
 .Va errno
 for any of the errors specified for the library function
 .Xr bread 3 .
@@ -62,9 +124,11 @@ Additionally, it may follow the
 error methodologies in situations where no usable superblock could be
 found.
 .Pp
-The function
+The
+.Fn sbput
+and
 .Fn sbwrite
-may fail and set
+functions may fail and set
 .Va errno
 for any of the errors specified for the library function
 .Xr bwrite 3 .

Modified: head/sbin/clri/Makefile
==============================================================================
--- head/sbin/clri/Makefile	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/clri/Makefile	Fri Jan 26 00:58:32 2018	(r328426)
@@ -4,6 +4,7 @@
 PACKAGE=runtime
 PROG=	clri
 MAN=	clri.8
+LIBADD=	ufs
 WARNS?=	2
 
 .include <bsd.prog.mk>

Modified: head/sbin/clri/clri.c
==============================================================================
--- head/sbin/clri/clri.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/clri/clri.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -54,17 +54,14 @@ __FBSDID("$FreeBSD$");
 #include <ufs/ffs/fs.h>
 
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <libufs.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
 
-/*
- * Possible superblock locations ordered from most to least likely.
- */
-static int sblock_try[] = SBLOCKSEARCH;
-
 static void
 usage(void)
 {
@@ -75,41 +72,35 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	struct fs *sbp;
+	struct fs *fs;
 	struct ufs1_dinode *dp1;
 	struct ufs2_dinode *dp2;
 	char *ibuf[MAXBSIZE];
 	long generation, bsize;
 	off_t offset;
-	int i, fd, inonum;
-	char *fs, sblock[SBLOCKSIZE];
+	int fd, ret, inonum;
+	char *fsname;
 	void *v = ibuf;
 
 	if (argc < 3)
 		usage();
 
-	fs = *++argv;
-	sbp = NULL;
+	fsname = *++argv;
 
 	/* get the superblock. */
-	if ((fd = open(fs, O_RDWR, 0)) < 0)
-		err(1, "%s", fs);
-	for (i = 0; sblock_try[i] != -1; i++) {
-		if (lseek(fd, (off_t)(sblock_try[i]), SEEK_SET) < 0)
-			err(1, "%s", fs);
-		if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock))
-			errx(1, "%s: can't read superblock", fs);
-		sbp = (struct fs *)sblock;
-		if ((sbp->fs_magic == FS_UFS1_MAGIC ||
-		     (sbp->fs_magic == FS_UFS2_MAGIC &&
-		      sbp->fs_sblockloc == sblock_try[i])) &&
-		    sbp->fs_bsize <= MAXBSIZE &&
-		    sbp->fs_bsize >= (int)sizeof(struct fs))
-			break;
+	if ((fd = open(fsname, O_RDWR, 0)) < 0)
+		err(1, "%s", fsname);
+	if ((ret = sbget(fd, &fs, -1)) != 0) {
+		switch (ret) {
+		case ENOENT:
+			warn("Cannot find file system superblock");
+			return (1);
+		default:
+			warn("Unable to read file system superblock");
+			return (1);
+		}
 	}
-	if (sblock_try[i] == -1)
-		errx(2, "cannot find file system superblock");
-	bsize = sbp->fs_bsize;
+	bsize = fs->fs_bsize;
 
 	/* remaining arguments are inode numbers. */
 	while (*++argv) {
@@ -119,20 +110,20 @@ main(int argc, char *argv[])
 		(void)printf("clearing %d\n", inonum);
 
 		/* read in the appropriate block. */
-		offset = ino_to_fsba(sbp, inonum);	/* inode to fs blk */
-		offset = fsbtodb(sbp, offset);		/* fs blk disk blk */
+		offset = ino_to_fsba(fs, inonum);	/* inode to fs blk */
+		offset = fsbtodb(fs, offset);		/* fs blk disk blk */
 		offset *= DEV_BSIZE;			/* disk blk to bytes */
 
 		/* seek and read the block */
 		if (lseek(fd, offset, SEEK_SET) < 0)
-			err(1, "%s", fs);
+			err(1, "%s", fsname);
 		if (read(fd, ibuf, bsize) != bsize)
-			err(1, "%s", fs);
+			err(1, "%s", fsname);
 
-		if (sbp->fs_magic == FS_UFS2_MAGIC) {
+		if (fs->fs_magic == FS_UFS2_MAGIC) {
 			/* get the inode within the block. */
 			dp2 = &(((struct ufs2_dinode *)v)
-			    [ino_to_fsbo(sbp, inonum)]);
+			    [ino_to_fsbo(fs, inonum)]);
 
 			/* clear the inode, and bump the generation count. */
 			generation = dp2->di_gen + 1;
@@ -141,7 +132,7 @@ main(int argc, char *argv[])
 		} else {
 			/* get the inode within the block. */
 			dp1 = &(((struct ufs1_dinode *)v)
-			    [ino_to_fsbo(sbp, inonum)]);
+			    [ino_to_fsbo(fs, inonum)]);
 
 			/* clear the inode, and bump the generation count. */
 			generation = dp1->di_gen + 1;
@@ -151,9 +142,9 @@ main(int argc, char *argv[])
 
 		/* backup and write the block */
 		if (lseek(fd, (off_t)-bsize, SEEK_CUR) < 0)
-			err(1, "%s", fs);
+			err(1, "%s", fsname);
 		if (write(fd, ibuf, bsize) != bsize)
-			err(1, "%s", fs);
+			err(1, "%s", fsname);
 		(void)fsync(fd);
 	}
 	(void)close(fd);

Modified: head/sbin/dump/Makefile
==============================================================================
--- head/sbin/dump/Makefile	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/dump/Makefile	Fri Jan 26 00:58:32 2018	(r328426)
@@ -19,6 +19,7 @@ LINKS=	${BINDIR}/dump ${BINDIR}/rdump
 CFLAGS+=-DRDUMP
 SRCS=	itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c cache.c
 MAN=	dump.8
+LIBADD=	ufs
 MLINKS=	dump.8 rdump.8
 WARNS?=	2
 

Modified: head/sbin/dump/dump.h
==============================================================================
--- head/sbin/dump/dump.h	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/dump/dump.h	Fri Jan 26 00:58:32 2018	(r328426)
@@ -86,7 +86,6 @@ time_t	tstart_writing;	/* when started writing the fir
 time_t	tend_writing;	/* after writing the last tape block */
 int	passno;		/* current dump pass number */
 struct	fs *sblock;	/* the file system super block */
-char	sblock_buf[MAXBSIZE];
 long	dev_bsize;	/* block size of underlying disk device */
 int	dev_bshift;	/* log2(dev_bsize) */
 int	tp_bshift;	/* log2(TP_BSIZE) */

Modified: head/sbin/dump/main.c
==============================================================================
--- head/sbin/dump/main.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/dump/main.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -59,6 +59,7 @@ static const char rcsid[] =
 #include <errno.h>
 #include <fcntl.h>
 #include <fstab.h>
+#include <libufs.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdint.h>
@@ -84,11 +85,6 @@ long	dev_bsize = 1;	/* recalculated below */
 long	blocksperfile;	/* output blocks per file */
 char	*host = NULL;	/* remote host (if any) */
 
-/*
- * Possible superblock locations ordered from most to least likely.
- */
-static int sblock_try[] = SBLOCKSEARCH;
-
 static char *getmntpt(char *, int *);
 static long numarg(const char *, long, long);
 static void obsolete(int *, char **[]);
@@ -104,7 +100,7 @@ main(int argc, char *argv[])
 	struct fstab *dt;
 	char *map, *mntpt;
 	int ch, mode, mntflags;
-	int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
+	int i, ret, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
 	int just_estimate = 0;
 	ino_t maxino;
 	char *tmsg;
@@ -437,19 +433,16 @@ main(int argc, char *argv[])
 		msgtail("to %s\n", tape);
 
 	sync();
-	sblock = (struct fs *)sblock_buf;
-	for (i = 0; sblock_try[i] != -1; i++) {
-		sblock->fs_fsize = SBLOCKSIZE; /* needed in blkread */
-		blkread(sblock_try[i]>>dev_bshift, (char *) sblock, SBLOCKSIZE);
-		if ((sblock->fs_magic == FS_UFS1_MAGIC ||
-		     (sblock->fs_magic == FS_UFS2_MAGIC &&
-		      sblock->fs_sblockloc == sblock_try[i])) &&
-		    sblock->fs_bsize <= MAXBSIZE &&
-		    sblock->fs_bsize >= sizeof(struct fs))
-			break;
+	if ((ret = sbget(diskfd, &sblock, -1)) != 0) {
+		switch (ret) {
+		case ENOENT:
+			warn("Cannot find file system superblock");
+			return (1);
+		default:
+			warn("Unable to read file system superblock");
+			return (1);
+		}
 	}
-	if (sblock_try[i] == -1)
-		quit("Cannot find file system superblock\n");
 	dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
 	dev_bshift = ffs(dev_bsize) - 1;
 	if (dev_bsize != (1 << dev_bshift))

Modified: head/sbin/fsck_ffs/fsck.h
==============================================================================
--- head/sbin/fsck_ffs/fsck.h	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsck_ffs/fsck.h	Fri Jan 26 00:58:32 2018	(r328426)
@@ -308,7 +308,7 @@ extern u_int	real_dev_bsize;		/* actual disk sector si
 extern char	nflag;			/* assume a no response */
 extern char	yflag;			/* assume a yes response */
 extern int	bkgrdflag;		/* use a snapshot to run on an active system */
-extern ufs2_daddr_t bflag;		/* location of alternate super block */
+extern off_t	bflag;			/* location of alternate super block */
 extern int	debug;			/* output debugging info */
 extern int	Eflag;			/* delete empty data blocks */
 extern int	Zflag;			/* zero empty data blocks */

Modified: head/sbin/fsck_ffs/fsutil.c
==============================================================================
--- head/sbin/fsck_ffs/fsutil.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsck_ffs/fsutil.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -348,7 +348,6 @@ getblk(struct bufarea *bp, ufs2_daddr_t blk, long size
 void
 flush(int fd, struct bufarea *bp)
 {
-	int i, j;
 
 	if (!bp->b_dirty)
 		return;
@@ -370,14 +369,8 @@ flush(int fd, struct bufarea *bp)
 		if (bp != &sblk)
 			pfatal("BUFFER %p DOES NOT MATCH SBLK %p\n",
 			    bp, &sblk);
-		blwrite(fd, bp->b_un.b_buf, bp->b_bno, bp->b_size);
-		for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize,
-		   j++) {
-			blwrite(fswritefd, (char *)sblock.fs_csp + i,
-			    fsbtodb(&sblock,
-			    sblock.fs_csaddr + j * sblock.fs_frag),
-			    MIN(sblock.fs_cssize - i, sblock.fs_bsize));
-		}
+		if (sbput(fd, (struct fs *)bp->b_un.b_buf, 0) == 0)
+			fsmodified = 1;
 		break;
 	case BT_CYLGRP:
 		if (cgput(&disk, (struct cg *)bp->b_un.b_buf) == 0)
@@ -439,6 +432,8 @@ ckfini(int markclean)
 	if (havesb && cursnapshot == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
 	    sblk.b_bno != sblock.fs_sblockloc / dev_bsize &&
 	    !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
+		/* Change the write destination to standard superblock */
+		sblock.fs_sblockactualloc = sblock.fs_sblockloc;
 		sblk.b_bno = sblock.fs_sblockloc / dev_bsize;
 		sbdirty();
 		flush(fswritefd, &sblk);

Modified: head/sbin/fsck_ffs/globs.c
==============================================================================
--- head/sbin/fsck_ffs/globs.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsck_ffs/globs.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -80,7 +80,7 @@ u_int	real_dev_bsize;		/* actual disk sector size, not
 char	nflag;			/* assume a no response */
 char	yflag;			/* assume a yes response */
 int	bkgrdflag;		/* use a snapshot to run on an active system */
-ufs2_daddr_t bflag;		/* location of alternate super block */
+off_t	bflag;			/* location of alternate super block */
 int	debug;			/* output debugging info */
 int	Eflag;			/* delete empty data blocks */
 int	Zflag;			/* zero empty data blocks */

Modified: head/sbin/fsck_ffs/setup.c
==============================================================================
--- head/sbin/fsck_ffs/setup.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsck_ffs/setup.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -311,70 +311,48 @@ badsb:
 }
 
 /*
- * Possible superblock locations ordered from most to least likely.
- */
-static int sblock_try[] = SBLOCKSEARCH;
-
-#define BAD_MAGIC_MSG \
-"The previous newfs operation on this volume did not complete.\n" \
-"You must complete newfs before mounting this volume.\n"
-
-/*
  * Read in the super block and its summary info.
  */
 int
 readsb(int listerr)
 {
-	ufs2_daddr_t super;
-	int i, bad;
+	off_t super;
+	int bad, ret;
+	struct fs *fs;
 
-	if (bflag) {
-		super = bflag;
-		readcnt[sblk.b_type]++;
-		if ((blread(fsreadfd, (char *)&sblock, super, (long)SBLOCKSIZE)))
-			return (0);
-		if (sblock.fs_magic == FS_BAD_MAGIC) {
-			fprintf(stderr, BAD_MAGIC_MSG);
+	super = bflag ? bflag * dev_bsize : -1;
+	readcnt[sblk.b_type]++;
+	if ((ret = sbget(fsreadfd, &fs, super)) != 0) {
+		switch (ret) {
+		case EINVAL:
+			fprintf(stderr, "The previous newfs operation "
+			    "on this volume did not complete.\nYou must "
+			    "complete newfs before using this volume.\n");
 			exit(11);
-		}
-		if (sblock.fs_magic != FS_UFS1_MAGIC &&
-		    sblock.fs_magic != FS_UFS2_MAGIC) {
-			fprintf(stderr, "%jd is not a file system superblock\n",
-			    bflag);
+		case ENOENT:
+			if (bflag)
+				fprintf(stderr, "%jd is not a file system "
+				    "superblock\n", super / dev_bsize);
+			else
+				fprintf(stderr, "Cannot find file system "
+				    "superblock\n");
 			return (0);
-		}
-	} else {
-		for (i = 0; sblock_try[i] != -1; i++) {
-			super = sblock_try[i] / dev_bsize;
-			readcnt[sblk.b_type]++;
-			if ((blread(fsreadfd, (char *)&sblock, super,
-			    (long)SBLOCKSIZE)))
-				return (0);
-			if (sblock.fs_magic == FS_BAD_MAGIC) {
-				fprintf(stderr, BAD_MAGIC_MSG);
-				exit(11);
-			}
-			if ((sblock.fs_magic == FS_UFS1_MAGIC ||
-			     (sblock.fs_magic == FS_UFS2_MAGIC &&
-			      sblock.fs_sblockloc == sblock_try[i])) &&
-			    sblock.fs_ncg >= 1 &&
-			    sblock.fs_bsize >= MINBSIZE &&
-			    sblock.fs_sbsize >= roundup(sizeof(struct fs), dev_bsize))
-				break;
-		}
-		if (sblock_try[i] == -1) {
-			fprintf(stderr, "Cannot find file system superblock\n");
+		case EIO:
+		default:
+			fprintf(stderr, "I/O error reading %jd\n",
+			    super / dev_bsize);
 			return (0);
 		}
 	}
+	memcpy(&sblock, fs, fs->fs_sbsize);
+	free(fs);
 	/*
 	 * Compute block size that the file system is based on,
 	 * according to fsbtodb, and adjust superblock block number
 	 * so we can tell if this is an alternate later.
 	 */
-	super *= dev_bsize;
 	dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
-	sblk.b_bno = super / dev_bsize;
+	sblk.b_bno = sblock.fs_sblockactualloc / dev_bsize;
 	sblk.b_size = SBLOCKSIZE;
 	/*
 	 * Compare all fields that should not differ in alternate super block.

Modified: head/sbin/fsirand/Makefile
==============================================================================
--- head/sbin/fsirand/Makefile	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsirand/Makefile	Fri Jan 26 00:58:32 2018	(r328426)
@@ -4,6 +4,7 @@
 PACKAGE=runtime
 PROG=	fsirand
 MAN=	fsirand.8
+LIBADD=	ufs
 WARNS?=	3
 
 .include <bsd.prog.mk>

Modified: head/sbin/fsirand/fsirand.c
==============================================================================
--- head/sbin/fsirand/fsirand.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/fsirand/fsirand.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -46,6 +46,7 @@ static const char rcsid[] =
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libufs.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -56,11 +57,6 @@ static const char rcsid[] =
 static void usage(void) __dead2;
 int fsirand(char *);
 
-/*
- * Possible superblock locations ordered from most to least likely.
- */
-static int sblock_try[] = SBLOCKSEARCH;
-
 static int printonly = 0, force = 0, ignorelabel = 0;
 
 int
@@ -117,9 +113,8 @@ fsirand(char *device)
 	ssize_t ibufsize;
 	struct fs *sblock;
 	ino_t inumber;
-	ufs2_daddr_t sblockloc, dblk;
-	char sbuf[SBLOCKSIZE], sbuftmp[SBLOCKSIZE];
-	int i, devfd, n, cg;
+	ufs2_daddr_t dblk;
+	int devfd, n, cg, ret;
 	u_int32_t bsize = DEV_BSIZE;
 
 	if ((devfd = open(device, printonly ? O_RDONLY : O_RDWR)) < 0) {
@@ -131,31 +126,16 @@ fsirand(char *device)
 	dp2 = NULL;
 
 	/* Read in master superblock */
-	(void)memset(&sbuf, 0, sizeof(sbuf));
-	sblock = (struct fs *)&sbuf;
-	for (i = 0; sblock_try[i] != -1; i++) {
-		sblockloc = sblock_try[i];
-		if (lseek(devfd, sblockloc, SEEK_SET) == -1) {
-			warn("can't seek to superblock (%jd) on %s",
-			    (intmax_t)sblockloc, device);
+	if ((ret = sbget(devfd, &sblock, -1)) != 0) {
+		switch (ret) {
+		case ENOENT:
+			warn("Cannot find file system superblock");
 			return (1);
-		}
-		if ((n = read(devfd, (void *)sblock, SBLOCKSIZE))!=SBLOCKSIZE) {
-			warnx("can't read superblock on %s: %s", device,
-			    (n < SBLOCKSIZE) ? "short read" : strerror(errno));
+		default:
+			warn("Unable to read file system superblock");
 			return (1);
 		}
-		if ((sblock->fs_magic == FS_UFS1_MAGIC ||
-		     (sblock->fs_magic == FS_UFS2_MAGIC &&
-		      sblock->fs_sblockloc == sblock_try[i])) &&
-		    sblock->fs_bsize <= MAXBSIZE &&
-		    sblock->fs_bsize >= (ssize_t)sizeof(struct fs))
-			break;
 	}
-	if (sblock_try[i] == -1) {
-		fprintf(stderr, "Cannot find file system superblock\n");
-		return (1);
-	}
 
 	if (sblock->fs_magic == FS_UFS1_MAGIC &&
 	    sblock->fs_old_inodefmt < FS_44INODEFMT) {
@@ -167,33 +147,6 @@ fsirand(char *device)
 		return (1);
 	}
 
-	/* Make sure backup superblocks are sane. */
-	sblock = (struct fs *)&sbuftmp;
-	for (cg = 0; cg < (int)sblock->fs_ncg; cg++) {
-		dblk = fsbtodb(sblock, cgsblock(sblock, cg));
-		if (lseek(devfd, (off_t)dblk * bsize, SEEK_SET) < 0) {
-			warn("can't seek to %jd", (intmax_t)dblk * bsize);
-			return (1);
-		} else if ((n = write(devfd, (void *)sblock, SBLOCKSIZE)) != SBLOCKSIZE) {
-			warn("can't read backup superblock %d on %s: %s",
-			    cg + 1, device, (n < SBLOCKSIZE) ? "short write"
-			    : strerror(errno));
-			return (1);
-		}
-		if (sblock->fs_magic != FS_UFS1_MAGIC &&
-		    sblock->fs_magic != FS_UFS2_MAGIC) {
-			warnx("bad magic number in backup superblock %d on %s",
-			    cg + 1, device);
-			return (1);
-		}
-		if (sblock->fs_sbsize > SBLOCKSIZE) {
-			warnx("size of backup superblock %d on %s is preposterous",
-			    cg + 1, device);
-			return (1);
-		}
-	}
-	sblock = (struct fs *)&sbuf;
-
 	/* XXX - should really cap buffer at 512kb or so */
 	if (sblock->fs_magic == FS_UFS1_MAGIC)
 		ibufsize = sizeof(struct ufs1_dinode) * sblock->fs_ipg;
@@ -215,38 +168,14 @@ fsirand(char *device)
 		/* Randomize fs_id and write out new sblock and backups */
 		sblock->fs_id[0] = (u_int32_t)time(NULL);
 		sblock->fs_id[1] = random();
-
-		if (lseek(devfd, sblockloc, SEEK_SET) == -1) {
-			warn("can't seek to superblock (%jd) on %s",
-			    (intmax_t)sblockloc, device);
+		if (sbput(devfd, sblock, sblock->fs_ncg) != 0) {
+			warn("could not write updated superblock");
 			return (1);
 		}
-		if ((n = write(devfd, (void *)sblock, SBLOCKSIZE)) !=
-		    SBLOCKSIZE) {
-			warn("can't write superblock on %s: %s", device,
-			    (n < SBLOCKSIZE) ? "short write" : strerror(errno));
-			return (1);
-		}
 	}
 
 	/* For each cylinder group, randomize inodes and update backup sblock */
 	for (cg = 0, inumber = 0; cg < (int)sblock->fs_ncg; cg++) {
-		/* Update superblock if appropriate */
-		if (!printonly) {
-			dblk = fsbtodb(sblock, cgsblock(sblock, cg));
-			if (lseek(devfd, (off_t)dblk * bsize, SEEK_SET) < 0) {
-				warn("can't seek to %jd",
-				    (intmax_t)dblk * bsize);
-				return (1);
-			} else if ((n = write(devfd, (void *)sblock,
-			    SBLOCKSIZE)) != SBLOCKSIZE) {
-			      warn("can't write backup superblock %d on %s: %s",
-				    cg + 1, device, (n < SBLOCKSIZE) ?
-				    "short write" : strerror(errno));
-				return (1);
-			}
-		}
-
 		/* Read in inodes, then print or randomize generation nums */
 		dblk = fsbtodb(sblock, ino_to_fsba(sblock, inumber));
 		if (lseek(devfd, (off_t)dblk * bsize, SEEK_SET) < 0) {

Modified: head/sbin/growfs/growfs.c
==============================================================================
--- head/sbin/growfs/growfs.c	Fri Jan 26 00:58:02 2018	(r328425)
+++ head/sbin/growfs/growfs.c	Fri Jan 26 00:58:32 2018	(r328426)
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <paths.h>
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <fstab.h>
 #include <inttypes.h>
@@ -95,12 +96,6 @@ static union {
 #define	sblock	fsun1.fs	/* the new superblock */
 #define	osblock	fsun2.fs	/* the old superblock */
 
-/*
- * Possible superblock locations ordered from most to least likely.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list