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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to