From owner-svn-src-all@freebsd.org Fri Jan 26 00:58:35 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DEABBED9682; Fri, 26 Jan 2018 00:58:34 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8B7927B32B; Fri, 26 Jan 2018 00:58:34 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 86423149D3; Fri, 26 Jan 2018 00:58:34 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0Q0wY8I097712; Fri, 26 Jan 2018 00:58:34 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0Q0wXXP097695; Fri, 26 Jan 2018 00:58:33 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <201801260058.w0Q0wXXP097695@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Fri, 26 Jan 2018 00:58:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: 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.... X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: 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.sbin/fstyp usr.sbin/quot X-SVN-Commit-Revision: 328426 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jan 2018 00:58:35 -0000 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 -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 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 #include +#include #include +#include #include #include #include #include -/* - * 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 #include #include +#include #include #include #include @@ -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 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 ***