[Midnightbsd-cvs] src [11222] trunk/sbin/fsck_ffs: sync iwth frebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jul 1 17:06:49 EDT 2018


Revision: 11222
          http://svnweb.midnightbsd.org/src/?rev=11222
Author:   laffer1
Date:     2018-07-01 17:06:48 -0400 (Sun, 01 Jul 2018)
Log Message:
-----------
sync iwth frebsd

Modified Paths:
--------------
    trunk/sbin/fsck_ffs/Makefile
    trunk/sbin/fsck_ffs/dir.c
    trunk/sbin/fsck_ffs/ea.c
    trunk/sbin/fsck_ffs/fsck.h
    trunk/sbin/fsck_ffs/fsck_ffs.8
    trunk/sbin/fsck_ffs/fsutil.c
    trunk/sbin/fsck_ffs/gjournal.c
    trunk/sbin/fsck_ffs/inode.c
    trunk/sbin/fsck_ffs/main.c
    trunk/sbin/fsck_ffs/pass1.c
    trunk/sbin/fsck_ffs/pass1b.c
    trunk/sbin/fsck_ffs/pass2.c
    trunk/sbin/fsck_ffs/pass3.c
    trunk/sbin/fsck_ffs/pass4.c
    trunk/sbin/fsck_ffs/pass5.c
    trunk/sbin/fsck_ffs/setup.c
    trunk/sbin/fsck_ffs/suj.c
    trunk/sbin/fsck_ffs/utilities.c

Added Paths:
-----------
    trunk/sbin/fsck_ffs/globs.c

Property Changed:
----------------
    trunk/sbin/fsck_ffs/fsck_ffs.8

Modified: trunk/sbin/fsck_ffs/Makefile
===================================================================
--- trunk/sbin/fsck_ffs/Makefile	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/Makefile	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,4 +1,5 @@
 # $MidnightBSD$
+# $FreeBSD: stable/10/sbin/fsck_ffs/Makefile 260178 2014-01-02 01:44:14Z scottl $
 #	@(#)Makefile	8.2 (Berkeley) 4/27/95
 
 PROG=	fsck_ffs
@@ -7,7 +8,8 @@
 MAN=	fsck_ffs.8
 MLINKS=	fsck_ffs.8 fsck_ufs.8 fsck_ffs.8 fsck_4.2bsd.8
 SRCS=	dir.c ea.c fsutil.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c \
-	pass4.c pass5.c setup.c suj.c utilities.c gjournal.c getmntopts.c
+	pass4.c pass5.c setup.c suj.c utilities.c gjournal.c getmntopts.c \
+	globs.c
 DPADD=	${LIBUFS}
 LDADD=	-lufs
 WARNS?=	2

Modified: trunk/sbin/fsck_ffs/dir.c
===================================================================
--- trunk/sbin/fsck_ffs/dir.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/dir.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/dir.c 260178 2014-01-02 01:44:14Z scottl $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -48,20 +49,14 @@
 
 #include "fsck.h"
 
-const char	*lfname = "lost+found";
-int	lfmode = 0700;
-struct	dirtemplate emptydir = {
+static struct	dirtemplate emptydir = {
 	0, DIRBLKSIZ, DT_UNKNOWN, 0, "",
 	0, 0, DT_UNKNOWN, 0, ""
 };
-struct	dirtemplate dirhead = {
+static struct	dirtemplate dirhead = {
 	0, 12, DT_DIR, 1, ".",
 	0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
 };
-struct	odirtemplate odirhead = {
-	0, 12, 1, ".",
-	0, DIRBLKSIZ - 12, 2, ".."
-};
 
 static int chgino(struct inodesc *);
 static int dircheck(struct inodesc *, struct direct *);
@@ -133,6 +128,7 @@
 			    (size_t)dsize);
 			dirty(bp);
 			sbdirty();
+			rerun = 1;
 		}
 		if (n & STOP)
 			return (n);

Modified: trunk/sbin/fsck_ffs/ea.c
===================================================================
--- trunk/sbin/fsck_ffs/ea.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/ea.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2002 Poul-Henning Kamp
  * Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -34,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/ea.c 259223 2013-12-11 19:25:17Z pfg $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -65,7 +66,7 @@
 	char dbuf[DIRBLKSIZ];
 
 	printf("Inode %ju extsize %ju\n",
-	   (intmax_t)idesc->id_number, (intmax_t)dp->di_extsize);
+	   (intmax_t)idesc->id_number, (uintmax_t)dp->di_extsize);
 	if (dp->di_extsize == 0)
 		return 0;
 	if (dp->di_extsize <= sblock.fs_fsize)

Modified: trunk/sbin/fsck_ffs/fsck.h
===================================================================
--- trunk/sbin/fsck_ffs/fsck.h	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/fsck.h	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2002 Networks Associates Technology, Inc.
  * All rights reserved.
@@ -57,7 +58,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)fsck.h	8.4 (Berkeley) 5/9/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/fsck_ffs/fsck.h 307536 2016-10-17 22:34:41Z mckusick $
  */
 
 #ifndef _FSCK_H_
@@ -74,6 +75,7 @@
 #define	MINBUFS		10	/* minimum number of buffers required */
 #define	MAXBUFS		40	/* maximum space to allocate to buffers */
 #define	INOBUFSIZE	64*1024	/* size of buffer to read inodes in pass1 */
+#define	ZEROBUFSIZE	(dev_bsize * 128) /* size of zero buffer used by -Z */
 
 union dinode {
 	struct ufs1_dinode dp1;
@@ -191,15 +193,15 @@
 	"Inode Block",			\
 	"Directory Contents",		\
 	"User Data" }
-long readcnt[BT_NUMBUFTYPES];
-long totalreadcnt[BT_NUMBUFTYPES];
-struct timespec readtime[BT_NUMBUFTYPES];
-struct timespec totalreadtime[BT_NUMBUFTYPES];
-struct timespec startprog;
+extern long readcnt[BT_NUMBUFTYPES];
+extern long totalreadcnt[BT_NUMBUFTYPES];
+extern struct timespec readtime[BT_NUMBUFTYPES];
+extern struct timespec totalreadtime[BT_NUMBUFTYPES];
+extern struct timespec startprog;
 
-struct bufarea sblk;		/* file system superblock */
-struct bufarea *pdirbp;		/* current directory contents */
-struct bufarea *pbp;		/* current inode block */
+extern struct bufarea sblk;		/* file system superblock */
+extern struct bufarea *pdirbp;		/* current directory contents */
+extern struct bufarea *pbp;		/* current inode block */
 
 #define	dirty(bp) do { \
 	if (fswritefd < 0) \
@@ -218,7 +220,7 @@
 #define	sblock		(*sblk.b_un.b_fs)
 
 enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
-ino_t cursnapshot;
+extern ino_t cursnapshot;
 
 struct inodesc {
 	enum fixstate id_fix;	/* policy on fixing errors */
@@ -252,7 +254,7 @@
  * To check if a block has been found as a duplicate it is only
  * necessary to search from duplist through muldup. To find the
  * total number of times that a block has been found as a duplicate
- * the entire list must be searched for occurences of the block
+ * the entire list must be searched for occurrences of the block
  * in question. The following diagram shows a sample list where
  * w (found twice), x (found once), y (found three times), and z
  * (found once) are duplicate block numbers:
@@ -281,61 +283,64 @@
 	u_int	i_numblks;		/* size of block array in bytes */
 	ufs2_daddr_t i_blks[1];		/* actually longer */
 } **inphead, **inpsort;
-long numdirs, dirhash, listmax, inplast;
-long countdirs;			/* number of directories we actually found */
+extern long numdirs, dirhash, listmax, inplast;
+extern long countdirs;		/* number of directories we actually found */
 
 #define MIBSIZE	3		/* size of fsck sysctl MIBs */
-int	adjrefcnt[MIBSIZE];	/* MIB command to adjust inode reference cnt */
-int	adjblkcnt[MIBSIZE];	/* MIB command to adjust inode block count */
-int	adjndir[MIBSIZE];	/* MIB command to adjust number of directories */
-int	adjnbfree[MIBSIZE];	/* MIB command to adjust number of free blocks */
-int	adjnifree[MIBSIZE];	/* MIB command to adjust number of free inodes */
-int	adjnffree[MIBSIZE];	/* MIB command to adjust number of free frags */
-int	adjnumclusters[MIBSIZE];	/* MIB command to adjust number of free clusters */
-int	freefiles[MIBSIZE];	/* MIB command to free a set of files */
-int	freedirs[MIBSIZE];	/* MIB command to free a set of directories */
-int	freeblks[MIBSIZE];	/* MIB command to free a set of data blocks */
-struct	fsck_cmd cmd;		/* sysctl file system update commands */
-char	snapname[BUFSIZ];	/* when doing snapshots, the name of the file */
-char	*cdevname;		/* name of device being checked */
-long	dev_bsize;		/* computed value of DEV_BSIZE */
-long	secsize;		/* actual disk sector size */
-u_int	real_dev_bsize;		/* actual disk sector size, not overriden */
-char	nflag;			/* assume a no response */
-char	yflag;			/* assume a yes response */
-int	bkgrdflag;		/* use a snapshot to run on an active system */
-int	bflag;			/* location of alternate super block */
-int	debug;			/* output debugging info */
-int	Eflag;			/* zero out empty data blocks */
-int	inoopt;			/* trim out unused inodes */
-char	ckclean;		/* only do work if not cleanly unmounted */
-int	cvtlevel;		/* convert to newer file system format */
-int	bkgrdcheck;		/* determine if background check is possible */
-int	bkgrdsumadj;		/* whether the kernel have ability to adjust superblock summary */
-char	usedsoftdep;		/* just fix soft dependency inconsistencies */
-char	preen;			/* just fix normal inconsistencies */
-char	rerun;			/* rerun fsck. Only used in non-preen mode */
-int	returntosingle;		/* 1 => return to single user mode on exit */
-char	resolved;		/* cleared if unresolved changes => not clean */
-char	havesb;			/* superblock has been read */
-char	skipclean;		/* skip clean file systems if preening */
-int	fsmodified;		/* 1 => write done to file system */
-int	fsreadfd;		/* file descriptor for reading file system */
-int	fswritefd;		/* file descriptor for writing file system */
+extern int	adjrefcnt[MIBSIZE];	/* MIB command to adjust inode reference cnt */
+extern int	adjblkcnt[MIBSIZE];	/* MIB command to adjust inode block count */
+extern int	adjndir[MIBSIZE];	/* MIB command to adjust number of directories */
+extern int	adjnbfree[MIBSIZE];	/* MIB command to adjust number of free blocks */
+extern int	adjnifree[MIBSIZE];	/* MIB command to adjust number of free inodes */
+extern int	adjnffree[MIBSIZE];	/* MIB command to adjust number of free frags */
+extern int	adjnumclusters[MIBSIZE];	/* MIB command to adjust number of free clusters */
+extern int	freefiles[MIBSIZE];	/* MIB command to free a set of files */
+extern int	freedirs[MIBSIZE];	/* MIB command to free a set of directories */
+extern int	freeblks[MIBSIZE];	/* MIB command to free a set of data blocks */
+extern struct	fsck_cmd cmd;		/* sysctl file system update commands */
+extern char	snapname[BUFSIZ];	/* when doing snapshots, the name of the file */
+extern char	*cdevname;		/* name of device being checked */
+extern long	dev_bsize;		/* computed value of DEV_BSIZE */
+extern long	secsize;		/* actual disk sector size */
+extern u_int	real_dev_bsize;		/* actual disk sector size, not overridden */
+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 int	debug;			/* output debugging info */
+extern int	Eflag;			/* delete empty data blocks */
+extern int	Zflag;			/* zero empty data blocks */
+extern int	inoopt;			/* trim out unused inodes */
+extern char	ckclean;		/* only do work if not cleanly unmounted */
+extern int	cvtlevel;		/* convert to newer file system format */
+extern int	bkgrdcheck;		/* determine if background check is possible */
+extern int	bkgrdsumadj;		/* whether the kernel have ability to adjust superblock summary */
+extern char	usedsoftdep;		/* just fix soft dependency inconsistencies */
+extern char	preen;			/* just fix normal inconsistencies */
+extern char	rerun;			/* rerun fsck. Only used in non-preen mode */
+extern int	returntosingle;		/* 1 => return to single user mode on exit */
+extern char	resolved;		/* cleared if unresolved changes => not clean */
+extern char	havesb;			/* superblock has been read */
+extern char	skipclean;		/* skip clean file systems if preening */
+extern int	fsmodified;		/* 1 => write done to file system */
+extern int	fsreadfd;		/* file descriptor for reading file system */
+extern int	fswritefd;		/* file descriptor for writing file system */
+extern int	surrender;		/* Give up if reads fail */
+extern int	wantrestart;		/* Restart fsck on early termination */
 
-ufs2_daddr_t maxfsblock;	/* number of blocks in the file system */
-char	*blockmap;		/* ptr to primary blk allocation map */
-ino_t	maxino;			/* number of inodes in file system */
+extern ufs2_daddr_t maxfsblock;	/* number of blocks in the file system */
+extern char	*blockmap;		/* ptr to primary blk allocation map */
+extern ino_t	maxino;			/* number of inodes in file system */
 
-ino_t	lfdir;			/* lost & found directory inode number */
-const char *lfname;		/* lost & found directory name */
-int	lfmode;			/* lost & found directory creation mode */
+extern ino_t	lfdir;			/* lost & found directory inode number */
+extern const char *lfname;		/* lost & found directory name */
+extern int	lfmode;			/* lost & found directory creation mode */
 
-ufs2_daddr_t n_blks;		/* number of blocks in use */
-ino_t n_files;			/* number of files in use */
+extern ufs2_daddr_t n_blks;		/* number of blocks in use */
+extern ino_t n_files;			/* number of files in use */
 
-volatile sig_atomic_t	got_siginfo;	/* received a SIGINFO */
-volatile sig_atomic_t	got_sigalarm;	/* received a SIGALRM */
+extern volatile sig_atomic_t	got_siginfo;	/* received a SIGINFO */
+extern volatile sig_atomic_t	got_sigalarm;	/* received a SIGALRM */
 
 #define	clearinode(dp) \
 	if (sblock.fs_magic == FS_UFS1_MAGIC) { \
@@ -343,8 +348,8 @@
 	} else { \
 		(dp)->dp2 = ufs2_zino; \
 	}
-struct	ufs1_dinode ufs1_zino;
-struct	ufs2_dinode ufs2_zino;
+extern struct	ufs1_dinode ufs1_zino;
+extern struct	ufs2_dinode ufs2_zino;
 
 #define	setbmap(blkno)	setbit(blockmap, blkno)
 #define	testbmap(blkno)	isset(blockmap, blkno)
@@ -357,6 +362,7 @@
 #define	FOUND	0x10
 
 #define	EEXIT	8		/* Standard error exit. */
+#define	ERESTART -1
 
 int flushentry(void);
 /*
@@ -364,7 +370,7 @@
  * to get space.
  */
 static inline void*
-Malloc(int size)
+Malloc(size_t size)
 {
 	void *retval;
 
@@ -379,7 +385,7 @@
  * to get space.
  */
 static inline void*
-Calloc(int cnt, int size)
+Calloc(size_t cnt, size_t size)
 {
 	void *retval;
 
@@ -400,8 +406,9 @@
 char	       *blockcheck(char *name);
 int		blread(int fd, char *buf, ufs2_daddr_t blk, long size);
 void		bufinit(void);
-void		blwrite(int fd, char *buf, ufs2_daddr_t blk, long size);
+void		blwrite(int fd, char *buf, ufs2_daddr_t blk, ssize_t size);
 void		blerase(int fd, ufs2_daddr_t blk, long size);
+void		blzero(int fd, ufs2_daddr_t blk, long size);
 void		cacheino(union dinode *dp, ino_t inumber);
 void		catch(int);
 void		catchquit(int);
@@ -424,6 +431,7 @@
 void		freeblk(ufs2_daddr_t blkno, long frags);
 void		freeino(ino_t ino);
 void		freeinodebuf(void);
+void		fsutilinit(void);
 int		ftypeok(union dinode *dp);
 void		getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
 struct bufarea *cgget(int cg);
@@ -462,5 +470,6 @@
 void		gjournal_check(const char *filesys);
 int		suj_check(const char *filesys);
 void		update_maps(struct cg *, struct cg*, int);
+void		fsckinit(void);
 
 #endif	/* !_FSCK_H_ */

Modified: trunk/sbin/fsck_ffs/fsck_ffs.8
===================================================================
--- trunk/sbin/fsck_ffs/fsck_ffs.8	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/fsck_ffs.8	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\"
 .\" Copyright (c) 1980, 1989, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -27,9 +28,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"	@(#)fsck.8	8.4 (Berkeley) 5/9/95
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/sbin/fsck_ffs/fsck_ffs.8 307441 2016-10-16 23:49:09Z sevan $
 .\"
-.Dd April 27, 2011
+.Dd October 5, 2016
 .Dt FSCK_FFS 8
 .Os
 .Sh NAME
@@ -38,7 +39,7 @@
 .Nd file system consistency check and interactive repair
 .Sh SYNOPSIS
 .Nm
-.Op Fl BEFfnpry
+.Op Fl BEFfnpRryZ
 .Op Fl b Ar block
 .Op Fl c Ar level
 .Op Fl m Ar mode
@@ -193,6 +194,11 @@
 the super block for the file system.
 An alternate super block is usually located at block 32 for UFS1,
 and block 160 for UFS2.
+.Pp
+See the
+.Fl N
+flag of
+.Xr newfs 8 .
 .It Fl C
 Check if file system was dismounted cleanly.
 If so, skip file system checks (like "preen").
@@ -261,6 +267,11 @@
 do not open the file system for writing.
 .It Fl p
 Preen file systems (see above).
+.It Fl R
+Instruct fsck_ffs to restart itself if it encounters certain errors that
+warrant another run.
+It will limit itself to a maximum of 10 restarts in a given run in order
+to avoid an endless loop with extremely corrupted filesystems.
 .It Fl r
 Free up excess unused inodes.
 Decreasing the number of preallocated inodes reduces the
@@ -270,11 +281,25 @@
 The
 .Fl r
 option is ignored when running in preen mode.
+.It Fl S
+Surrender on error.
+With this flag enabled, a hard error returned on disk i/o will cause
+.Nm
+to abort instead of continuing on and possibly tripping over more i/o errors.
 .It Fl y
 Assume a yes response to all questions asked by
 .Nm ;
 this should be used with great caution as this is a free license
 to continue after essentially unlimited trouble has been encountered.
+.It Fl Z
+Similar to
+.Fl E ,
+but overwrites unused blocks with zeroes.
+If both
+.Fl E
+and
+.Fl Z
+are specified, blocks are first zeroed and then erased.
 .El
 .Pp
 Inconsistencies checked are as follows:
@@ -369,3 +394,14 @@
 .Xr fsdb 8 ,
 .Xr newfs 8 ,
 .Xr reboot 8
+.Sh HISTORY
+A
+.Nm fsck
+utility appeared in
+.Bx 4.0 .
+It became
+.Nm
+in
+.Fx 5.0
+with the introduction of the filesystem independent wrapper as
+.Nm fsck .


Property changes on: trunk/sbin/fsck_ffs/fsck_ffs.8
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sbin/fsck_ffs/fsutil.c
===================================================================
--- trunk/sbin/fsck_ffs/fsutil.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/fsutil.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/fsutil.c 263629 2014-03-22 11:43:35Z mckusick $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -74,7 +75,26 @@
 static TAILQ_HEAD(buflist, bufarea) bufhead;	/* head of buffer cache list */
 static int numbufs;				/* size of buffer cache */
 static char *buftype[BT_NUMBUFTYPES] = BT_NAMES;
+static struct bufarea *cgbufs;	/* header for cylinder group cache */
+static int flushtries;		/* number of tries to reclaim memory */
 
+void
+fsutilinit(void)
+{
+	diskreads = totaldiskreads = totalreads = 0;
+	bzero(&startpass, sizeof(struct timespec));
+	bzero(&finishpass, sizeof(struct timespec));
+	bzero(&slowio_starttime, sizeof(struct timeval));
+	slowio_delay_usec = 10000;
+	slowio_pollcnt = 0;
+	bzero(&cgblk, sizeof(struct bufarea));
+	TAILQ_INIT(&bufhead);
+	numbufs = 0;
+	/* buftype ? */
+	cgbufs = NULL;
+	flushtries = 0;
+}
+
 int
 ftypeok(union dinode *dp)
 {
@@ -144,7 +164,8 @@
 	int iloff;
 
 	if (inum > maxino)
-		errx(EEXIT, "inoinfo: inumber %d out of range", inum);
+		errx(EEXIT, "inoinfo: inumber %ju out of range",
+		    (uintmax_t)inum);
 	ilp = &inostathead[inum / sblock.fs_ipg];
 	iloff = inum % sblock.fs_ipg;
 	if (iloff >= ilp->il_numalloced)
@@ -205,7 +226,7 @@
 	struct cg *cgp;
 
 	if (cgbufs == NULL) {
-		cgbufs = Calloc(sblock.fs_ncg, sizeof(struct bufarea));
+		cgbufs = calloc(sblock.fs_ncg, sizeof(struct bufarea));
 		if (cgbufs == NULL)
 			errx(EEXIT, "cannot allocate cylinder group buffers");
 	}
@@ -234,6 +255,8 @@
 {
 	struct bufarea *cgbp;
 
+	if (flushtries == sblock.fs_ncg || cgbufs == NULL)
+		return (0);
 	cgbp = &cgbufs[flushtries++];
 	if (cgbp->b_un.b_cg == NULL)
 		return (0);
@@ -337,7 +360,7 @@
 		    (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
 		    (long long)bp->b_bno);
 	bp->b_errs = 0;
-	blwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
+	blwrite(fd, bp->b_un.b_buf, bp->b_bno, bp->b_size);
 	if (bp != &sblk)
 		return;
 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
@@ -414,13 +437,15 @@
 	}
 	if (numbufs != cnt)
 		errx(EEXIT, "panic: lost %d buffers", numbufs - cnt);
-	for (cnt = 0; cnt < sblock.fs_ncg; cnt++) {
-		if (cgbufs[cnt].b_un.b_cg == NULL)
-			continue;
-		flush(fswritefd, &cgbufs[cnt]);
-		free(cgbufs[cnt].b_un.b_cg);
+	if (cgbufs != NULL) {
+		for (cnt = 0; cnt < sblock.fs_ncg; cnt++) {
+			if (cgbufs[cnt].b_un.b_cg == NULL)
+				continue;
+			flush(fswritefd, &cgbufs[cnt]);
+			free(cgbufs[cnt].b_un.b_cg);
+		}
+		free(cgbufs);
 	}
-	free(cgbufs);
 	pbp = pdirbp = (struct bufarea *)0;
 	if (cursnapshot == 0 && sblock.fs_clean != markclean) {
 		if ((sblock.fs_clean = markclean) != 0) {
@@ -548,7 +573,18 @@
 			slowio_end();
 		return (0);
 	}
-	rwerror("READ BLK", blk);
+
+	/*
+	 * This is handled specially here instead of in rwerror because
+	 * rwerror is used for all sorts of errors, not just true read/write
+	 * errors.  It should be refactored and fixed.
+	 */
+	if (surrender) {
+		pfatal("CANNOT READ_BLK: %ld", (long)blk);
+		errx(EEXIT, "ABORTING DUE TO READ ERRORS");
+	} else
+		rwerror("READ BLK", blk);
+
 	if (lseek(fd, offset, 0) < 0)
 		rwerror("SEEK BLK", blk);
 	errs = 0;
@@ -573,7 +609,7 @@
 }
 
 void
-blwrite(int fd, char *buf, ufs2_daddr_t blk, long size)
+blwrite(int fd, char *buf, ufs2_daddr_t blk, ssize_t size)
 {
 	int i;
 	char *cp;
@@ -585,7 +621,7 @@
 	offset *= dev_bsize;
 	if (lseek(fd, offset, 0) < 0)
 		rwerror("SEEK BLK", blk);
-	else if (write(fd, buf, (int)size) == size) {
+	else if (write(fd, buf, size) == size) {
 		fsmodified = 1;
 		return;
 	}
@@ -595,7 +631,7 @@
 		rwerror("SEEK BLK", blk);
 	printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
 	for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
-		if (write(fd, cp, (int)dev_bsize) != dev_bsize) {
+		if (write(fd, cp, dev_bsize) != dev_bsize) {
 			(void)lseek(fd, offset + i + dev_bsize, 0);
 			printf(" %jd,", (intmax_t)blk + i / dev_bsize);
 		}
@@ -618,6 +654,35 @@
 }
 
 /*
+ * Fill a contiguous region with all-zeroes.  Note ZEROBUFSIZE is by
+ * definition a multiple of dev_bsize.
+ */
+void
+blzero(int fd, ufs2_daddr_t blk, long size)
+{
+	static char *zero;
+	off_t offset, len;
+
+	if (fd < 0)
+		return;
+	if (zero == NULL) {
+		zero = calloc(ZEROBUFSIZE, 1);
+		if (zero == NULL)
+			errx(EEXIT, "cannot allocate buffer pool");
+	}
+	offset = blk * dev_bsize;
+	if (lseek(fd, offset, 0) < 0)
+		rwerror("SEEK BLK", blk);
+	while (size > 0) {
+		len = size > ZEROBUFSIZE ? ZEROBUFSIZE : size;
+		if (write(fd, zero, len) != len)
+			rwerror("WRITE BLK", blk);
+		blk += len / dev_bsize;
+		size -= len;
+	}
+}
+
+/*
  * Verify cylinder group's magic number and other parameters.  If the
  * test fails, offer an option to rebuild the whole cylinder group.
  */
@@ -901,7 +966,7 @@
 #include <stdarg.h>
 
 /*
- * An unexpected inconsistency occured.
+ * An unexpected inconsistency occurred.
  * Die if preening or file system is running with soft dependency protocol,
  * otherwise just print message and continue.
  */

Modified: trunk/sbin/fsck_ffs/gjournal.c
===================================================================
--- trunk/sbin/fsck_ffs/gjournal.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/gjournal.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
  * All rights reserved.
@@ -52,7 +53,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/gjournal.c 241012 2012-09-27 23:30:58Z mdf $");
 
 #include <sys/param.h>
 #include <sys/disklabel.h>
@@ -448,7 +449,8 @@
 			if (isclr(inosused, cino))
 				continue;
 			if (getino(disk, &p, ino, &mode) == -1)
-				err(1, "getino(cg=%d ino=%d)", cg, ino);
+				err(1, "getino(cg=%d ino=%ju)",
+				    cg, (uintmax_t)ino);
 			dino = p;
 			/* Not a regular file nor directory? Skip it. */
 			if (!S_ISREG(dino->di_mode) && !S_ISDIR(dino->di_mode))
@@ -480,7 +482,8 @@
 			*dino = ufs2_zino;
 			/* Write the inode back. */
 			if (putino(disk) == -1)
-				err(1, "putino(cg=%d ino=%d)", cg, ino);
+				err(1, "putino(cg=%d ino=%ju)",
+				    cg, (uintmax_t)ino);
 			if (cgp->cg_unrefs == 0) {
 				//printf("No more unreferenced inodes in cg=%d.\n", cg);
 				break;

Added: trunk/sbin/fsck_ffs/globs.c
===================================================================
--- trunk/sbin/fsck_ffs/globs.c	                        (rev 0)
+++ trunk/sbin/fsck_ffs/globs.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -0,0 +1,166 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 1980, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1980, 1986, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c	8.6 (Berkeley) 5/14/95";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/globs.c 307536 2016-10-17 22:34:41Z mckusick $");
+
+#include <sys/param.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#include <string.h>
+#include "fsck.h"
+ 
+long readcnt[BT_NUMBUFTYPES];
+long totalreadcnt[BT_NUMBUFTYPES];
+struct timespec readtime[BT_NUMBUFTYPES];
+struct timespec totalreadtime[BT_NUMBUFTYPES];
+struct timespec startprog;
+struct bufarea sblk;		/* file system superblock */
+struct bufarea *pdirbp;		/* current directory contents */
+struct bufarea *pbp;		/* current inode block */
+ino_t cursnapshot;
+long numdirs, dirhash, listmax, inplast;
+long countdirs;		/* number of directories we actually found */
+int	adjrefcnt[MIBSIZE];	/* MIB command to adjust inode reference cnt */
+int	adjblkcnt[MIBSIZE];	/* MIB command to adjust inode block count */
+int	adjndir[MIBSIZE];	/* MIB command to adjust number of directories */
+int	adjnbfree[MIBSIZE];	/* MIB command to adjust number of free blocks */
+int	adjnifree[MIBSIZE];	/* MIB command to adjust number of free inodes */
+int	adjnffree[MIBSIZE];	/* MIB command to adjust number of free frags */
+int	adjnumclusters[MIBSIZE];	/* MIB command to adjust number of free clusters */
+int	freefiles[MIBSIZE];	/* MIB command to free a set of files */
+int	freedirs[MIBSIZE];	/* MIB command to free a set of directories */
+int	freeblks[MIBSIZE];	/* MIB command to free a set of data blocks */
+struct	fsck_cmd cmd;		/* sysctl file system update commands */
+char	snapname[BUFSIZ];	/* when doing snapshots, the name of the file */
+char	*cdevname;		/* name of device being checked */
+long	dev_bsize;		/* computed value of DEV_BSIZE */
+long	secsize;		/* actual disk sector size */
+u_int	real_dev_bsize;		/* actual disk sector size, not overridden */
+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 */
+int	debug;			/* output debugging info */
+int	Eflag;			/* delete empty data blocks */
+int	Zflag;			/* zero empty data blocks */
+int	inoopt;			/* trim out unused inodes */
+char	ckclean;		/* only do work if not cleanly unmounted */
+int	cvtlevel;		/* convert to newer file system format */
+int	bkgrdcheck;		/* determine if background check is possible */
+int	bkgrdsumadj;		/* whether the kernel have ability to adjust superblock summary */
+char	usedsoftdep;		/* just fix soft dependency inconsistencies */
+char	preen;			/* just fix normal inconsistencies */
+char	rerun;			/* rerun fsck. Only used in non-preen mode */
+int	returntosingle;		/* 1 => return to single user mode on exit */
+char	resolved;		/* cleared if unresolved changes => not clean */
+char	havesb;			/* superblock has been read */
+char	skipclean;		/* skip clean file systems if preening */
+int	fsmodified;		/* 1 => write done to file system */
+int	fsreadfd;		/* file descriptor for reading file system */
+int	fswritefd;		/* file descriptor for writing file system */
+int	surrender;		/* Give up if reads fail */
+int	wantrestart;		/* Restart fsck on early termination */
+ufs2_daddr_t maxfsblock;	/* number of blocks in the file system */
+char	*blockmap;		/* ptr to primary blk allocation map */
+ino_t	maxino;			/* number of inodes in file system */
+ino_t	lfdir;			/* lost & found directory inode number */
+const char *lfname;		/* lost & found directory name */
+int	lfmode;			/* lost & found directory creation mode */
+ufs2_daddr_t n_blks;		/* number of blocks in use */
+ino_t n_files;			/* number of files in use */
+volatile sig_atomic_t	got_siginfo;	/* received a SIGINFO */
+volatile sig_atomic_t	got_sigalarm;	/* received a SIGALRM */
+struct	ufs1_dinode ufs1_zino;
+struct	ufs2_dinode ufs2_zino;
+
+void
+fsckinit(void)
+{
+	bzero(readcnt, sizeof(long) * BT_NUMBUFTYPES);
+	bzero(totalreadcnt, sizeof(long) * BT_NUMBUFTYPES);
+	bzero(readtime, sizeof(struct timespec) * BT_NUMBUFTYPES);
+	bzero(totalreadtime, sizeof(struct timespec) * BT_NUMBUFTYPES);
+	bzero(&startprog, sizeof(struct timespec));;
+	bzero(&sblk, sizeof(struct bufarea));
+	pdirbp = NULL;
+	pbp = NULL;
+	cursnapshot = 0;
+	numdirs = dirhash = listmax = inplast = 0;
+	countdirs = 0;
+	bzero(adjrefcnt, sizeof(int) * MIBSIZE);
+	bzero(adjblkcnt, sizeof(int) * MIBSIZE);
+	bzero(adjndir, sizeof(int) * MIBSIZE);
+	bzero(adjnbfree, sizeof(int) * MIBSIZE);
+	bzero(adjnifree, sizeof(int) * MIBSIZE);
+	bzero(adjnffree, sizeof(int) * MIBSIZE);
+	bzero(adjnumclusters, sizeof(int) * MIBSIZE);
+	bzero(freefiles, sizeof(int) * MIBSIZE);
+	bzero(freedirs, sizeof(int) * MIBSIZE);
+	bzero(freeblks, sizeof(int) * MIBSIZE);
+	bzero(&cmd, sizeof(struct fsck_cmd));
+	bzero(snapname, sizeof(char) * BUFSIZ);
+	cdevname = NULL;
+	dev_bsize = 0;
+	secsize = 0;
+	real_dev_bsize = 0;	
+	bkgrdsumadj = 0;
+	usedsoftdep = 0;
+	rerun = 0;
+	returntosingle = 0;
+	resolved = 0;
+	havesb = 0;
+	fsmodified = 0;
+	fsreadfd = 0;
+	fswritefd = 0;
+	maxfsblock = 0;
+	blockmap = NULL;
+	maxino = 0;
+	lfdir = 0;
+	lfname = "lost+found";
+	lfmode = 0700;
+	n_blks = 0;
+	n_files = 0;
+	got_siginfo = 0;
+	got_sigalarm = 0;
+	bzero(&ufs1_zino, sizeof(struct ufs1_dinode));
+	bzero(&ufs2_zino, sizeof(struct ufs2_dinode));
+}


Property changes on: trunk/sbin/fsck_ffs/globs.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sbin/fsck_ffs/inode.c
===================================================================
--- trunk/sbin/fsck_ffs/inode.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/inode.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/inode.c 329883 2018-02-23 23:07:41Z mckusick $");
 
 #include <sys/param.h>
 #include <sys/stdint.h>
@@ -285,7 +286,8 @@
 	ufs2_daddr_t iblk;
 
 	if (inumber < ROOTINO || inumber > maxino)
-		errx(EEXIT, "bad inode number %d to ginode", inumber);
+		errx(EEXIT, "bad inode number %ju to ginode",
+		    (uintmax_t)inumber);
 	if (startinum == 0 ||
 	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
 		iblk = ino_to_fsba(&sblock, inumber);
@@ -319,7 +321,8 @@
 	static caddr_t nextinop;
 
 	if (inumber != nextino++ || inumber > lastvalidinum)
-		errx(EEXIT, "bad inode number %d to nextinode", inumber);
+		errx(EEXIT, "bad inode number %ju to nextinode",
+		    (uintmax_t)inumber);
 	if (inumber >= lastinum) {
 		readcount++;
 		blk = ino_to_fsba(&sblock, lastinum);
@@ -398,7 +401,8 @@
 {
 
 	if (inum % sblock.fs_ipg != 0)
-		errx(EEXIT, "bad inode number %d to setinodebuf", inum);
+		errx(EEXIT, "bad inode number %ju to setinodebuf",
+		    (uintmax_t)inum);
 	lastvalidinum = inum + sblock.fs_ipg - 1;
 	startinum = 0;
 	nextino = inum;
@@ -448,8 +452,10 @@
 
 	if (howmany(DIP(dp, di_size), sblock.fs_bsize) > NDADDR)
 		blks = NDADDR + NIADDR;
+	else if (DIP(dp, di_size) > 0)
+		blks = howmany(DIP(dp, di_size), sblock.fs_bsize);
 	else
-		blks = howmany(DIP(dp, di_size), sblock.fs_bsize);
+		blks = 1;
 	inp = (struct inoinfo *)
 		Malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t));
 	if (inp == NULL)
@@ -490,7 +496,7 @@
 			continue;
 		return (inp);
 	}
-	errx(EEXIT, "cannot find inode %d", inumber);
+	errx(EEXIT, "cannot find inode %ju", (uintmax_t)inumber);
 	return ((struct inoinfo *)0);
 }
 

Modified: trunk/sbin/fsck_ffs/main.c
===================================================================
--- trunk/sbin/fsck_ffs/main.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/main.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -39,7 +40,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/main.c 324675 2017-10-16 21:55:31Z mckusick $");
 
 #include <sys/param.h>
 #include <sys/file.h>
@@ -57,6 +58,7 @@
 #include <errno.h>
 #include <fstab.h>
 #include <grp.h>
+#include <inttypes.h>
 #include <mntopts.h>
 #include <paths.h>
 #include <stdint.h>
@@ -65,8 +67,10 @@
 
 #include "fsck.h"
 
+int	restarts;
+
 static void usage(void) __dead2;
-static int argtoi(int flag, const char *req, const char *str, int base);
+static intmax_t argtoimax(int flag, const char *req, const char *str, int base);
 static int checkfilesys(char *filesys);
 static int chkdoreload(struct statfs *mntp);
 static struct statfs *getmntpt(const char *);
@@ -82,12 +86,12 @@
 	sync();
 	skipclean = 1;
 	inoopt = 0;
-	while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npry")) != -1) {
+	while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npRrSyZ")) != -1) {
 		switch (ch) {
 		case 'b':
 			skipclean = 0;
-			bflag = argtoi('b', "number", optarg, 10);
-			printf("Alternate super block location: %d\n", bflag);
+			bflag = argtoimax('b', "number", optarg, 10);
+			printf("Alternate super block location: %jd\n", bflag);
 			break;
 
 		case 'B':
@@ -96,7 +100,8 @@
 
 		case 'c':
 			skipclean = 0;
-			cvtlevel = argtoi('c', "conversion level", optarg, 10);
+			cvtlevel = argtoimax('c', "conversion level", optarg,
+			    10);
 			if (cvtlevel < 3)
 				errx(EEXIT, "cannot do level %d conversion",
 				    cvtlevel);
@@ -119,7 +124,7 @@
 			break;
 
 		case 'm':
-			lfmode = argtoi('m', "mode", optarg, 8);
+			lfmode = argtoimax('m', "mode", optarg, 8);
 			if (lfmode &~ 07777)
 				errx(EEXIT, "bad mode to -m: %o", lfmode);
 			printf("** lost+found creation mode %o\n", lfmode);
@@ -138,15 +143,26 @@
 			ckclean++;
 			break;
 
+		case 'R':
+			wantrestart = 1;
+			break;
 		case 'r':
 			inoopt++;
 			break;
 
+		case 'S':
+			surrender = 1;
+			break;
+
 		case 'y':
 			yflag++;
 			nflag = 0;
 			break;
 
+		case 'Z':
+			Zflag++;
+			break;
+
 		default:
 			usage();
 		}
@@ -178,8 +194,12 @@
 		rlimit.rlim_cur = rlimit.rlim_max;
 		(void)setrlimit(RLIMIT_DATA, &rlimit);
 	}
-	while (argc-- > 0)
-		(void)checkfilesys(*argv++);
+	while (argc > 0) {
+		if (checkfilesys(*argv) == ERESTART)
+			continue;
+		argc--;
+		argv++;
+	}
 
 	if (returntosingle)
 		ret = 2;
@@ -186,13 +206,13 @@
 	exit(ret);
 }
 
-static int
-argtoi(int flag, const char *req, const char *str, int base)
+static intmax_t
+argtoimax(int flag, const char *req, const char *str, int base)
 {
 	char *cp;
-	int ret;
+	intmax_t ret;
 
-	ret = (int)strtol(str, &cp, base);
+	ret = strtoimax(str, &cp, base);
 	if (cp == str || *cp)
 		errx(EEXIT, "-%c flag requires a %s", flag, req);
 	return (ret);
@@ -210,17 +230,19 @@
 	struct statfs *mntp;
 	struct stat snapdir;
 	struct group *grp;
-	ufs2_daddr_t blks;
 	struct iovec *iov;
 	char errmsg[255];
+	int ofsmodified;
 	int iovlen;
 	int cylno;
-	ino_t files;
+	intmax_t blks, files;
 	size_t size;
 
 	iov = NULL;
 	iovlen = 0;
 	errmsg[0] = '\0';
+	fsutilinit();
+	fsckinit();
 
 	cdevname = filesys;
 	if (debug && ckclean)
@@ -279,8 +301,8 @@
 					exit(0);
 				exit(4);
 			} else {
-				pfatal("UNEXPECTED INCONSISTENCY, %s\n",
-				    "CANNOT RUN FAST FSCK\n");
+				pfatal(
+			    "UNEXPECTED INCONSISTENCY, CANNOT RUN FAST FSCK\n");
 			}
 		}
 	}
@@ -297,8 +319,8 @@
 			pfatal("NOT MOUNTED, CANNOT RUN IN BACKGROUND\n");
 		} else if ((mntp->f_flags & MNT_SOFTDEP) == 0) {
 			bkgrdflag = 0;
-			pfatal("NOT USING SOFT UPDATES, %s\n",
-			    "CANNOT RUN IN BACKGROUND");
+			pfatal(
+			  "NOT USING SOFT UPDATES, CANNOT RUN IN BACKGROUND\n");
 		} else if ((mntp->f_flags & MNT_RDONLY) != 0) {
 			bkgrdflag = 0;
 			pfatal("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
@@ -306,8 +328,8 @@
 			if (readsb(0) != 0) {
 				if (sblock.fs_flags & (FS_NEEDSFSCK | FS_SUJ)) {
 					bkgrdflag = 0;
-					pfatal("UNEXPECTED INCONSISTENCY, %s\n",
-					    "CANNOT RUN IN BACKGROUND\n");
+					pfatal(
+			"UNEXPECTED INCONSISTENCY, CANNOT RUN IN BACKGROUND\n");
 				}
 				if ((sblock.fs_flags & FS_UNCLEAN) == 0 &&
 				    skipclean && ckclean) {
@@ -315,8 +337,8 @@
 					 * file system is clean;
 					 * skip snapshot and report it clean
 					 */
-					pwarn("FILE SYSTEM CLEAN; %s\n",
-					    "SKIPPING CHECKS");
+					pwarn(
+					"FILE SYSTEM CLEAN; SKIPPING CHECKS\n");
 					goto clean;
 				}
 			}
@@ -328,24 +350,23 @@
 			if (stat(snapname, &snapdir) < 0) {
 				if (errno != ENOENT) {
 					bkgrdflag = 0;
-					pfatal("CANNOT FIND %s %s: %s, %s\n",
-					    "SNAPSHOT DIRECTORY",
-					    snapname, strerror(errno),
-					    "CANNOT RUN IN BACKGROUND");
+					pfatal(
+	"CANNOT FIND SNAPSHOT DIRECTORY %s: %s, CANNOT RUN IN BACKGROUND\n",
+					    snapname, strerror(errno));
 				} else if ((grp = getgrnam("operator")) == 0 ||
 				    mkdir(snapname, 0770) < 0 ||
 				    chown(snapname, -1, grp->gr_gid) < 0 ||
 				    chmod(snapname, 0770) < 0) {
 					bkgrdflag = 0;
-					pfatal("CANNOT CREATE %s %s: %s, %s\n",
-					    "SNAPSHOT DIRECTORY",
-					    snapname, strerror(errno),
-					    "CANNOT RUN IN BACKGROUND");
+					pfatal(
+	"CANNOT CREATE SNAPSHOT DIRECTORY %s: %s, CANNOT RUN IN BACKGROUND\n",
+					    snapname, strerror(errno));
 				}
 			} else if (!S_ISDIR(snapdir.st_mode)) {
 				bkgrdflag = 0;
-				pfatal("%s IS NOT A DIRECTORY, %s\n", snapname,
-				    "CANNOT RUN IN BACKGROUND");
+				pfatal(
+			"%s IS NOT A DIRECTORY, CANNOT RUN IN BACKGROUND\n",
+				    snapname);
 			}
 		}
 		if (bkgrdflag) {
@@ -383,9 +404,9 @@
 	clean:
 		pwarn("clean, %ld free ", (long)(sblock.fs_cstotal.cs_nffree +
 		    sblock.fs_frag * sblock.fs_cstotal.cs_nbfree));
-		printf("(%lld frags, %lld blocks, %.1f%% fragmentation)\n",
-		    (long long)sblock.fs_cstotal.cs_nffree,
-		    (long long)sblock.fs_cstotal.cs_nbfree,
+		printf("(%jd frags, %jd blocks, %.1f%% fragmentation)\n",
+		    (intmax_t)sblock.fs_cstotal.cs_nffree,
+		    (intmax_t)sblock.fs_cstotal.cs_nbfree,
 		    sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize);
 		return (0);
 	}
@@ -406,10 +427,15 @@
 		}
 		/*
 		 * Write the superblock so we don't try to recover the
-		 * journal on another pass.
+		 * journal on another pass. If this is the only change
+		 * to the filesystem, we do not want it to be called
+		 * out as modified.
 		 */
 		sblock.fs_mtime = time(NULL);
 		sbdirty();
+		ofsmodified = fsmodified;
+		flush(fswritefd, &sblk);
+		fsmodified = ofsmodified;
 	}
 
 	/*
@@ -489,8 +515,8 @@
 	blks = maxfsblock - (n_ffree + sblock.fs_frag * n_bfree) - blks;
 	if (bkgrdflag && (files > 0 || blks > 0)) {
 		countdirs = sblock.fs_cstotal.cs_ndir - countdirs;
-		pwarn("Reclaimed: %ld directories, %ld files, %lld fragments\n",
-		    countdirs, (long)files - countdirs, (long long)blks);
+		pwarn("Reclaimed: %ld directories, %jd files, %jd fragments\n",
+		    countdirs, files - countdirs, blks);
 	}
 	pwarn("%ld files, %jd used, %ju free ",
 	    (long)n_files, (intmax_t)n_blks,
@@ -500,13 +526,13 @@
 	    n_ffree * 100.0 / sblock.fs_dsize);
 	if (debug) {
 		if (files < 0)
-			printf("%d inodes missing\n", -files);
+			printf("%jd inodes missing\n", -files);
 		if (blks < 0)
-			printf("%lld blocks missing\n", -(long long)blks);
+			printf("%jd blocks missing\n", -blks);
 		if (duplist != NULL) {
 			printf("The following duplicate blocks remain:");
 			for (dp = duplist; dp; dp = dp->next)
-				printf(" %lld,", (long long)dp->dup);
+				printf(" %jd,", (intmax_t)dp->dup);
 			printf("\n");
 		}
 	}
@@ -544,8 +570,12 @@
 	inostathead = NULL;
 	if (fsmodified && !preen)
 		printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
-	if (rerun)
+	if (rerun) {
+		if (wantrestart && (restarts++ < 10) &&
+		    (preen || reply("RESTART")))
+			return (ERESTART);
 		printf("\n***** PLEASE RERUN FSCK *****\n");
+	}
 	if (chkdoreload(mntp) != 0) {
 		if (!fsmodified)
 			return (0);
@@ -623,6 +653,9 @@
 		statfsp = &mntbuf[i];
 		ddevname = statfsp->f_mntfromname;
 		if (*ddevname != '/') {
+			if (strlen(_PATH_DEV) + strlen(ddevname) + 1 >
+			    sizeof(statfsp->f_mntfromname))
+				continue;
 			strcpy(device, _PATH_DEV);
 			strcat(device, ddevname);
 			strcpy(statfsp->f_mntfromname, device);
@@ -644,8 +677,19 @@
 usage(void)
 {
 	(void) fprintf(stderr,
-	    "usage: %s [-BEFfnpry] [-b block] [-c level] [-m mode] "
-			"filesystem ...\n",
+"usage: %s [-BEFfnpry] [-b block] [-c level] [-m mode] filesystem ...\n",
 	    getprogname());
 	exit(1);
 }
+
+void
+infohandler(int sig __unused)
+{
+	got_siginfo = 1;
+}
+
+void
+alarmhandler(int sig __unused)
+{
+	got_sigalarm = 1;
+}

Modified: trunk/sbin/fsck_ffs/pass1.c
===================================================================
--- trunk/sbin/fsck_ffs/pass1.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass1.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass1.c 317250 2017-04-21 10:16:34Z kib $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -68,6 +69,8 @@
 	u_int8_t *cp;
 	int c, rebuildcg;
 
+	badblk = dupblk = lastino = 0;
+
 	/*
 	 * Set file system reserved blocks in used block map.
 	 */
@@ -102,10 +105,10 @@
 		if (!rebuildcg && sblock.fs_magic == FS_UFS2_MAGIC) {
 			inosused = cgp->cg_initediblk;
 			if (inosused > sblock.fs_ipg) {
-				pfatal("%s (%d > %d) %s %d\nReset to %d\n",
-				    "Too many initialized inodes", inosused,
-				    sblock.fs_ipg, "in cylinder group", c,
-				    sblock.fs_ipg);
+				pfatal(
+"Too many initialized inodes (%ju > %d) in cylinder group %d\nReset to %d\n",
+				    (uintmax_t)inosused,
+				    sblock.fs_ipg, c, sblock.fs_ipg);
 				inosused = sblock.fs_ipg;
 			}
 		} else {
@@ -131,9 +134,14 @@
 		 */
 		if ((preen || inoopt) && usedsoftdep && !rebuildcg) {
 			cp = &cg_inosused(cgp)[(inosused - 1) / CHAR_BIT];
-			for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
-				if (*cp == 0)
+			for ( ; inosused != 0; cp--) {
+				if (*cp == 0) {
+					if (inosused > CHAR_BIT)
+						inosused -= CHAR_BIT;
+					else
+						inosused = 0;
 					continue;
+				}
 				for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
 					if (*cp & i)
 						break;
@@ -141,8 +149,6 @@
 				}
 				break;
 			}
-			if (inosused < 0)
-				inosused = 0;
 		}
 		/*
 		 * Allocate inoinfo structures for the allocated inodes.
@@ -463,6 +469,7 @@
 				ckfini(0);
 				exit(EEXIT);
 			}
+			rerun = 1;
 			return (STOP);
 		}
 	}
@@ -483,6 +490,7 @@
 					ckfini(0);
 					exit(EEXIT);
 				}
+				rerun = 1;
 				return (STOP);
 			}
 			new = (struct dups *)Malloc(sizeof(struct dups));
@@ -492,6 +500,7 @@
 					ckfini(0);
 					exit(EEXIT);
 				}
+				rerun = 1;
 				return (STOP);
 			}
 			new->dup = blkno;

Modified: trunk/sbin/fsck_ffs/pass1b.c
===================================================================
--- trunk/sbin/fsck_ffs/pass1b.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass1b.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass1b.c 260178 2014-01-02 01:44:14Z scottl $");
 
 #include <sys/param.h>
 
@@ -80,8 +81,10 @@
 				continue;
 			idesc.id_number = inumber;
 			if (inoinfo(inumber)->ino_state != USTATE &&
-			    (ckinode(dp, &idesc) & STOP))
+			    (ckinode(dp, &idesc) & STOP)) {
+				rerun = 1;
 				return;
+			}
 		}
 	}
 }
@@ -106,8 +109,10 @@
 			if (dlp == muldup)
 				break;
 		}
-		if (muldup == 0 || duphead == muldup->next)
+		if (muldup == 0 || duphead == muldup->next) {
+			rerun = 1;
 			return (STOP);
+		}
 	}
 	return (res);
 }

Modified: trunk/sbin/fsck_ffs/pass2.c
===================================================================
--- trunk/sbin/fsck_ffs/pass2.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass2.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass2.c 241012 2012-09-27 23:30:58Z mdf $");
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -223,13 +224,14 @@
 		 *    inp->i_parent is directory to which ".." should point.
 		 */
 		getpathname(pathbuf, inp->i_parent, inp->i_number);
-		printf("BAD INODE NUMBER FOR '..' in DIR I=%d (%s)\n",
-		    inp->i_number, pathbuf);
+		printf("BAD INODE NUMBER FOR '..' in DIR I=%ju (%s)\n",
+		    (uintmax_t)inp->i_number, pathbuf);
 		getpathname(pathbuf, inp->i_dotdot, inp->i_dotdot);
-		printf("CURRENTLY POINTS TO I=%d (%s), ", inp->i_dotdot,
-		    pathbuf);
+		printf("CURRENTLY POINTS TO I=%ju (%s), ",
+		    (uintmax_t)inp->i_dotdot, pathbuf);
 		getpathname(pathbuf, inp->i_parent, inp->i_parent);
-		printf("SHOULD POINT TO I=%d (%s)", inp->i_parent, pathbuf);
+		printf("SHOULD POINT TO I=%ju (%s)",
+		    (uintmax_t)inp->i_parent, pathbuf);
 		if (cursnapshot != 0) {
 			/*
 			 * We need to:
@@ -443,8 +445,8 @@
 			} else {
 				getpathname(dirname, idesc->id_number,
 				    dirp->d_ino);
-				pwarn("ZERO LENGTH DIRECTORY %s I=%d",
-					dirname, dirp->d_ino);
+				pwarn("ZERO LENGTH DIRECTORY %s I=%ju",
+				    dirname, (uintmax_t)dirp->d_ino);
 				/*
 				 * We need to:
 				 *    setcwd(idesc->id_parent);
@@ -507,8 +509,9 @@
 			break;
 
 		default:
-			errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
-			    inoinfo(dirp->d_ino)->ino_state, dirp->d_ino);
+			errx(EEXIT, "BAD STATE %d FOR INODE I=%ju",
+			    inoinfo(dirp->d_ino)->ino_state,
+			    (uintmax_t)dirp->d_ino);
 		}
 	}
 	if (n == 0)
@@ -613,7 +616,7 @@
 			printf(" (IGNORED)\n");
 			return (0);
 		}
-		if ((cp = rindex(oldname, '/')) == NULL) {
+		if ((cp = strchr(oldname, '/')) == NULL) {
 			printf(" (IGNORED)\n");
 			return (0);
 		}

Modified: trunk/sbin/fsck_ffs/pass3.c
===================================================================
--- trunk/sbin/fsck_ffs/pass3.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass3.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass3.c 136281 2004-10-08 20:44:47Z truckman $");
 
 #include <sys/param.h>
 

Modified: trunk/sbin/fsck_ffs/pass4.c
===================================================================
--- trunk/sbin/fsck_ffs/pass4.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass4.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass4.c 241012 2012-09-27 23:30:58Z mdf $");
 
 #include <sys/param.h>
 
@@ -41,6 +42,7 @@
 #include <ufs/ffs/fs.h>
 
 #include <err.h>
+#include <stdint.h>
 #include <string.h>
 
 #include "fsck.h"
@@ -114,8 +116,9 @@
 				break;
 
 			default:
-				errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
-				    inoinfo(inumber)->ino_state, inumber);
+				errx(EEXIT, "BAD STATE %d FOR INODE I=%ju",
+				    inoinfo(inumber)->ino_state,
+				    (uintmax_t)inumber);
 			}
 		}
 	}

Modified: trunk/sbin/fsck_ffs/pass5.c
===================================================================
--- trunk/sbin/fsck_ffs/pass5.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/pass5.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/pass5.c 250057 2013-04-29 20:14:11Z des $");
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -252,7 +253,7 @@
 			frags = 0;
 			for (j = 0; j < fs->fs_frag; j++) {
 				if (testbmap(d + j)) {
-					if (Eflag && start != -1) {
+					if ((Eflag || Zflag) && start != -1) {
 						clear_blocks(start, d + j - 1);
 						start = -1;
 					}
@@ -274,7 +275,7 @@
 				ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
 			}
 		}
-		if (Eflag && start != -1)
+		if ((Eflag || Zflag) && start != -1)
 			clear_blocks(start, d - 1);
 		if (fs->fs_contigsumsize > 0) {
 			int32_t *sump = cg_clustersum(newcg);
@@ -581,11 +582,16 @@
 	}
 }
 
-static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end)
+static void
+clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end)
 {
 
 	if (debug)
 		printf("Zero frags %jd to %jd\n", start, end);
-	blerase(fswritefd, fsbtodb(&sblock, start),
-	    lfragtosize(&sblock, end - start + 1));
+	if (Zflag)
+		blzero(fswritefd, fsbtodb(&sblock, start),
+		    lfragtosize(&sblock, end - start + 1));
+	if (Eflag)
+		blerase(fswritefd, fsbtodb(&sblock, start),
+		    lfragtosize(&sblock, end - start + 1));
 }

Modified: trunk/sbin/fsck_ffs/setup.c
===================================================================
--- trunk/sbin/fsck_ffs/setup.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/setup.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/setup.c 322860 2017-08-24 21:44:23Z mckusick $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -58,9 +59,9 @@
 #define altsblock (*asblk.b_un.b_fs)
 #define POWEROF2(num)	(((num) & ((num) - 1)) == 0)
 
-static void badsb(int listerr, const char *s);
 static int calcsb(char *dev, int devfd, struct fs *fs);
-static struct disklabel *getdisklabel(char *s, int fd);
+static void saverecovery(int readfd, int writefd);
+static int chkrecovery(int devfd);
 
 /*
  * Read in a superblock finding an alternate if necessary.
@@ -194,11 +195,11 @@
 				"-b OPTION TO FSCK TO SPECIFY THE",
 				"LOCATION OF AN ALTERNATE",
 				"SUPER-BLOCK TO SUPPLY NEEDED",
-				"INFORMATION; SEE fsck(8).");
+				"INFORMATION; SEE fsck_ffs(8).");
 			bflag = 0;
 			return(0);
 		}
-		pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
+		pwarn("USING ALTERNATE SUPERBLOCK AT %jd\n", bflag);
 		bflag = 0;
 	}
 	if (skipclean && ckclean && sblock.fs_clean) {
@@ -236,6 +237,10 @@
 		memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
 		flush(fswritefd, &asblk);
 	}
+	if (preen == 0 && yflag == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
+	    fswritefd != -1 && chkrecovery(fsreadfd) == 0 &&
+	    reply("SAVE DATA TO FIND ALTERNATE SUPERBLOCKS") != 0)
+		saverecovery(fsreadfd, fswritefd);
 	/*
 	 * read in the summary info.
 	 */
@@ -319,7 +324,7 @@
 readsb(int listerr)
 {
 	ufs2_daddr_t super;
-	int i;
+	int i, bad;
 
 	if (bflag) {
 		super = bflag;
@@ -332,7 +337,7 @@
 		}
 		if (sblock.fs_magic != FS_UFS1_MAGIC &&
 		    sblock.fs_magic != FS_UFS2_MAGIC) {
-			fprintf(stderr, "%d is not a file system superblock\n",
+			fprintf(stderr, "%jd is not a file system superblock\n",
 			    bflag);
 			return (0);
 		}
@@ -369,40 +374,57 @@
 	dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
 	sblk.b_bno = super / dev_bsize;
 	sblk.b_size = SBLOCKSIZE;
-	if (bflag)
-		goto out;
 	/*
 	 * Compare all fields that should not differ in alternate super block.
 	 * When an alternate super-block is specified this check is skipped.
 	 */
+	if (bflag)
+		goto out;
 	getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
 	if (asblk.b_errs)
 		return (0);
-	if (altsblock.fs_sblkno != sblock.fs_sblkno ||
-	    altsblock.fs_cblkno != sblock.fs_cblkno ||
-	    altsblock.fs_iblkno != sblock.fs_iblkno ||
-	    altsblock.fs_dblkno != sblock.fs_dblkno ||
-	    altsblock.fs_ncg != sblock.fs_ncg ||
-	    altsblock.fs_bsize != sblock.fs_bsize ||
-	    altsblock.fs_fsize != sblock.fs_fsize ||
-	    altsblock.fs_frag != sblock.fs_frag ||
-	    altsblock.fs_bmask != sblock.fs_bmask ||
-	    altsblock.fs_fmask != sblock.fs_fmask ||
-	    altsblock.fs_bshift != sblock.fs_bshift ||
-	    altsblock.fs_fshift != sblock.fs_fshift ||
-	    altsblock.fs_fragshift != sblock.fs_fragshift ||
-	    altsblock.fs_fsbtodb != sblock.fs_fsbtodb ||
-	    altsblock.fs_sbsize != sblock.fs_sbsize ||
-	    altsblock.fs_nindir != sblock.fs_nindir ||
-	    altsblock.fs_inopb != sblock.fs_inopb ||
-	    altsblock.fs_cssize != sblock.fs_cssize ||
-	    altsblock.fs_ipg != sblock.fs_ipg ||
-	    altsblock.fs_fpg != sblock.fs_fpg ||
-	    altsblock.fs_magic != sblock.fs_magic) {
-		badsb(listerr,
-		"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
-		return (0);
+	bad = 0;
+#define CHK(x, y)				\
+	if (altsblock.x != sblock.x) {		\
+		bad++;				\
+		if (listerr && debug)		\
+			printf("SUPER BLOCK VS ALTERNATE MISMATCH %s: " y " vs " y "\n", \
+			    #x, (intmax_t)sblock.x, (intmax_t)altsblock.x); \
 	}
+	CHK(fs_sblkno, "%jd");
+	CHK(fs_cblkno, "%jd");
+	CHK(fs_iblkno, "%jd");
+	CHK(fs_dblkno, "%jd");
+	CHK(fs_ncg, "%jd");
+	CHK(fs_bsize, "%jd");
+	CHK(fs_fsize, "%jd");
+	CHK(fs_frag, "%jd");
+	CHK(fs_bmask, "%#jx");
+	CHK(fs_fmask, "%#jx");
+	CHK(fs_bshift, "%jd");
+	CHK(fs_fshift, "%jd");
+	CHK(fs_fragshift, "%jd");
+	CHK(fs_fsbtodb, "%jd");
+	CHK(fs_sbsize, "%jd");
+	CHK(fs_nindir, "%jd");
+	CHK(fs_inopb, "%jd");
+	CHK(fs_cssize, "%jd");
+	CHK(fs_ipg, "%jd");
+	CHK(fs_fpg, "%jd");
+	CHK(fs_magic, "%#jx");
+#undef CHK
+	if (bad) {
+		if (listerr == 0)
+			return (0);
+		if (preen)
+			printf("%s: ", cdevname);
+		printf(
+		    "VALUES IN SUPER BLOCK LSB=%jd DISAGREE WITH THOSE IN\n"
+		    "LAST ALTERNATE LSB=%jd\n",
+		    sblk.b_bno, asblk.b_bno);
+		if (reply("IGNORE ALTERNATE SUPER BLOCK") == 0)
+			return (0);
+	}
 out:
 	/*
 	 * If not yet done, update UFS1 superblock with new wider fields.
@@ -423,21 +445,9 @@
 	return (1);
 }
 
-static void
-badsb(int listerr, const char *s)
-{
-
-	if (!listerr)
-		return;
-	if (preen)
-		printf("%s: ", cdevname);
-	pfatal("BAD SUPER BLOCK: %s\n", s);
-}
-
 void
 sblock_init(void)
 {
-	struct disklabel *lp;
 
 	fswritefd = -1;
 	fsmodified = 0;
@@ -448,14 +458,11 @@
 	asblk.b_un.b_buf = Malloc(SBLOCKSIZE);
 	if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
 		errx(EEXIT, "cannot allocate space for superblock");
-	if ((lp = getdisklabel(NULL, fsreadfd)))
-		real_dev_bsize = dev_bsize = secsize = lp->d_secsize;
-	else
-		dev_bsize = secsize = DEV_BSIZE;
+	dev_bsize = secsize = DEV_BSIZE;
 }
 
 /*
- * Calculate a prototype superblock based on information in the disk label.
+ * Calculate a prototype superblock based on information in the boot area.
  * When done the cgsblock macro can be calculated and the fs_ncg field
  * can be used. Do NOT attempt to use other macros without verifying that
  * their needed information is available!
@@ -463,74 +470,63 @@
 static int
 calcsb(char *dev, int devfd, struct fs *fs)
 {
-	struct disklabel *lp;
-	struct partition *pp;
-	char *cp;
-	int i, nspf;
+	struct fsrecovery fsr;
 
-	cp = strchr(dev, '\0') - 1;
-	if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
-		pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
+	/*
+	 * We need fragments-per-group and the partition-size.
+	 *
+	 * Newfs stores these details at the end of the boot block area
+	 * at the start of the filesystem partition. If they have been
+	 * overwritten by a boot block, we fail. But usually they are
+	 * there and we can use them.
+	 */
+	if (blread(devfd, (char *)&fsr,
+	    (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)) ||
+	    fsr.fsr_magic != FS_UFS2_MAGIC)
 		return (0);
-	}
-	lp = getdisklabel(dev, devfd);
-	if (isdigit(*cp))
-		pp = &lp->d_partitions[0];
-	else
-		pp = &lp->d_partitions[*cp - 'a'];
-	if (pp->p_fstype != FS_BSDFFS) {
-		pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n",
-			dev, pp->p_fstype < FSMAXTYPES ?
-			fstypenames[pp->p_fstype] : "unknown");
-		return (0);
-	}
-	if (pp->p_fsize == 0 || pp->p_frag == 0 ||
-	    pp->p_cpg == 0 || pp->p_size == 0) {
-		pfatal("%s: %s: type %s fsize %d, frag %d, cpg %d, size %d\n",
-		    dev, "INCOMPLETE LABEL", fstypenames[pp->p_fstype],
-		    pp->p_fsize, pp->p_frag, pp->p_cpg, pp->p_size);
-		return (0);
-	}
 	memset(fs, 0, sizeof(struct fs));
-	fs->fs_fsize = pp->p_fsize;
-	fs->fs_frag = pp->p_frag;
-	fs->fs_size = pp->p_size;
-	fs->fs_sblkno = roundup(
-		howmany(lp->d_bbsize + lp->d_sbsize, fs->fs_fsize),
-		fs->fs_frag);
-	nspf = fs->fs_fsize / lp->d_secsize;
-	for (fs->fs_fsbtodb = 0, i = nspf; i > 1; i >>= 1)
-		fs->fs_fsbtodb++;
-	dev_bsize = lp->d_secsize;
-	if (fs->fs_magic == FS_UFS2_MAGIC) {
-		fs->fs_fpg = pp->p_cpg;
-		fs->fs_ncg = howmany(fs->fs_size, fs->fs_fpg);
-	} else /* if (fs->fs_magic == FS_UFS1_MAGIC) */ {
-		fs->fs_old_cpg = pp->p_cpg;
-		fs->fs_old_cgmask = 0xffffffff;
-		for (i = lp->d_ntracks; i > 1; i >>= 1)
-			fs->fs_old_cgmask <<= 1;
-		if (!POWEROF2(lp->d_ntracks))
-			fs->fs_old_cgmask <<= 1;
-		fs->fs_old_cgoffset = roundup(howmany(lp->d_nsectors, nspf),
-		    fs->fs_frag);
-		fs->fs_fpg = (fs->fs_old_cpg * lp->d_secpercyl) / nspf;
-		fs->fs_ncg = howmany(fs->fs_size / lp->d_secpercyl,
-		    fs->fs_old_cpg);
-	}
+	fs->fs_fpg = fsr.fsr_fpg;
+	fs->fs_fsbtodb = fsr.fsr_fsbtodb;
+	fs->fs_sblkno = fsr.fsr_sblkno;
+	fs->fs_magic = fsr.fsr_magic;
+	fs->fs_ncg = fsr.fsr_ncg;
 	return (1);
 }
 
-static struct disklabel *
-getdisklabel(char *s, int fd)
+/*
+ * Check to see if recovery information exists.
+ */
+static int
+chkrecovery(int devfd)
 {
-	static struct disklabel lab;
+	struct fsrecovery fsr;
 
-	if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
-		if (s == NULL)
-			return ((struct disklabel *)NULL);
-		pwarn("ioctl (GCINFO): %s\n", strerror(errno));
-		errx(EEXIT, "%s: can't read disk label", s);
-	}
-	return (&lab);
+	if (blread(devfd, (char *)&fsr,
+	    (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)) ||
+	    fsr.fsr_magic != FS_UFS2_MAGIC)
+		return (0);
+	return (1);
 }
+
+/*
+ * Read the last sector of the boot block, replace the last
+ * 20 bytes with the recovery information, then write it back.
+ * The recovery information only works for UFS2 filesystems.
+ */
+static void
+saverecovery(int readfd, int writefd)
+{
+	struct fsrecovery fsr;
+
+	if (sblock.fs_magic != FS_UFS2_MAGIC ||
+	    blread(readfd, (char *)&fsr,
+	    (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)))
+		return;
+	fsr.fsr_magic = sblock.fs_magic;
+	fsr.fsr_fpg = sblock.fs_fpg;
+	fsr.fsr_fsbtodb = sblock.fs_fsbtodb;
+	fsr.fsr_sblkno = sblock.fs_sblkno;
+	fsr.fsr_ncg = sblock.fs_ncg;
+	blwrite(writefd, (char *)&fsr, (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize,
+	    sizeof(fsr));
+}

Modified: trunk/sbin/fsck_ffs/suj.c
===================================================================
--- trunk/sbin/fsck_ffs/suj.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/suj.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright 2009, 2010 Jeffrey W. Roberson <jeff at FreeBSD.org>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/suj.c 298764 2016-04-29 03:04:56Z pfg $");
 
 #include <sys/param.h>
 #include <sys/disk.h>
@@ -125,26 +126,26 @@
 	int			sc_cgx;
 };
 
-LIST_HEAD(cghd, suj_cg) cghash[SUJ_HASHSIZE];
-LIST_HEAD(dblkhd, data_blk) dbhash[SUJ_HASHSIZE];
-struct suj_cg *lastcg;
-struct data_blk *lastblk;
+static LIST_HEAD(cghd, suj_cg) cghash[SUJ_HASHSIZE];
+static LIST_HEAD(dblkhd, data_blk) dbhash[SUJ_HASHSIZE];
+static struct suj_cg *lastcg;
+static struct data_blk *lastblk;
 
-TAILQ_HEAD(seghd, suj_seg) allsegs;
-uint64_t oldseq;
+static TAILQ_HEAD(seghd, suj_seg) allsegs;
+static uint64_t oldseq;
 static struct uufsd *disk = NULL;
 static struct fs *fs = NULL;
-ino_t sujino;
+static ino_t sujino;
 
 /*
  * Summary statistics.
  */
-uint64_t freefrags;
-uint64_t freeblocks;
-uint64_t freeinos;
-uint64_t freedir;
-uint64_t jbytes;
-uint64_t jrecs;
+static uint64_t freefrags;
+static uint64_t freeblocks;
+static uint64_t freeinos;
+static uint64_t freedir;
+static uint64_t jbytes;
+static uint64_t jrecs;
 
 static jmp_buf	jmpbuf;
 
@@ -155,6 +156,7 @@
 static void ino_adjust(struct suj_ino *);
 static void ino_build(struct suj_ino *);
 static int blk_isfree(ufs2_daddr_t);
+static void initsuj(void);
 
 static void *
 errmalloc(size_t n)
@@ -216,7 +218,7 @@
 closedisk(const char *devnam)
 {
 	struct csum *cgsum;
-	int i;
+	uint32_t i;
 
 	/*
 	 * Recompute the fs summary info from correct cs summaries.
@@ -831,8 +833,8 @@
 	int doff;
 
 	if (debug)
-		printf("Clearing inode %d from parent %d at offset %jd\n",
-		    child, parent, diroff);
+		printf("Clearing inode %ju from parent %ju at offset %jd\n",
+		    (uintmax_t)child, (uintmax_t)parent, diroff);
 
 	lbn = lblkno(fs, diroff);
 	doff = blkoff(fs, diroff);
@@ -842,8 +844,8 @@
 	block = dblk_read(blk, blksize);
 	dp = (struct direct *)&block[doff];
 	if (dp->d_ino != child)
-		errx(1, "Inode %d does not exist in %d at %jd",
-		    child, parent, diroff);
+		errx(1, "Inode %ju does not exist in %ju at %jd",
+		    (uintmax_t)child, (uintmax_t)parent, diroff);
 	dp->d_ino = 0;
 	dblk_dirty(blk);
 	/*
@@ -879,10 +881,11 @@
 			 * was reallocated.
 			 */
 			if (*mode != 0)
-				printf("Directory %d has bad mode %o\n",
-				    parent, *mode);
+				printf("Directory %ju has bad mode %o\n",
+				    (uintmax_t)parent, *mode);
 			else
-				printf("Directory %d has zero mode\n", parent);
+				printf("Directory %ju has zero mode\n",
+				    (uintmax_t)parent);
 		}
 		return (0);
 	}
@@ -891,15 +894,16 @@
 	blksize = sblksize(fs, DIP(dip, di_size), lbn);
 	if (diroff + DIRECTSIZ(1) > DIP(dip, di_size) || doff >= blksize) {
 		if (debug)
-			printf("ino %d absent from %d due to offset %jd"
+			printf("ino %ju absent from %ju due to offset %jd"
 			    " exceeding size %jd\n",
-			    child, parent, diroff, DIP(dip, di_size));
+			    (uintmax_t)child, (uintmax_t)parent, diroff,
+			    DIP(dip, di_size));
 		return (0);
 	}
 	blk = ino_blkatoff(dip, parent, lbn, &frags);
 	if (blk <= 0) {
 		if (debug)
-			printf("Sparse directory %d", parent);
+			printf("Sparse directory %ju", (uintmax_t)parent);
 		return (0);
 	}
 	block = dblk_read(blk, blksize);
@@ -918,12 +922,13 @@
 		dpoff += dp->d_reclen;
 	} while (dpoff <= doff);
 	if (dpoff > fs->fs_bsize)
-		err_suj("Corrupt directory block in dir ino %d\n", parent);
+		err_suj("Corrupt directory block in dir ino %ju\n",
+		    (uintmax_t)parent);
 	/* Not found. */
 	if (dpoff != doff) {
 		if (debug)
-			printf("ino %d not found in %d, lbn %jd, dpoff %d\n",
-			    child, parent, lbn, dpoff);
+			printf("ino %ju not found in %ju, lbn %jd, dpoff %d\n",
+			    (uintmax_t)child, (uintmax_t)parent, lbn, dpoff);
 		return (0);
 	}
 	/*
@@ -940,8 +945,8 @@
 		return (1);
 	}
 	if (debug)
-		printf("ino %d doesn't match dirent ino %d in parent %d\n",
-		    child, dp->d_ino, parent);
+		printf("ino %ju doesn't match dirent ino %ju in parent %ju\n",
+		    (uintmax_t)child, (uintmax_t)dp->d_ino, (uintmax_t)parent);
 	return (0);
 }
 
@@ -977,8 +982,8 @@
 		err_suj("Invalid level for lbn %jd\n", lbn);
 	if ((flags & VISIT_ROOT) == 0 && blk_isindir(blk, ino, lbn) == 0) {
 		if (debug)
-			printf("blk %jd ino %d lbn %jd(%d) is not indir.\n",
-			    blk, ino, lbn, level);
+			printf("blk %jd ino %ju lbn %jd(%d) is not indir.\n",
+			    blk, (uintmax_t)ino, lbn, level);
 		goto out;
 	}
 	lbnadd = 1;
@@ -1131,8 +1136,8 @@
 	if (blocks == DIP(ip, di_blocks))
 		return;
 	if (debug)
-		printf("ino %d adjusting block count from %jd to %jd\n",
-		    ino, DIP(ip, di_blocks), blocks);
+		printf("ino %ju adjusting block count from %jd to %jd\n",
+		    (uintmax_t)ino, DIP(ip, di_blocks), blocks);
 	DIP_SET(ip, di_blocks, blocks);
 	ino_dirty(ino);
 }
@@ -1258,8 +1263,8 @@
 		if (isdotdot && skipparent == 1)
 			continue;
 		if (debug)
-			printf("Directory %d removing ino %d name %s\n",
-			    ino, dp->d_ino, dp->d_name);
+			printf("Directory %ju removing ino %ju name %s\n",
+			    (uintmax_t)ino, (uintmax_t)dp->d_ino, dp->d_name);
 		diroff = lblktosize(fs, lbn) + dpoff;
 		ino_remref(ino, dp->d_ino, diroff, isdotdot);
 	}
@@ -1277,8 +1282,8 @@
 	if (ino == ROOTINO)
 		err_suj("Attempting to free ROOTINO\n");
 	if (debug)
-		printf("Truncating and freeing ino %d, nlink %d, mode %o\n",
-		    ino, DIP(ip, di_nlink), DIP(ip, di_mode));
+		printf("Truncating and freeing ino %ju, nlink %d, mode %o\n",
+		    (uintmax_t)ino, DIP(ip, di_nlink), DIP(ip, di_mode));
 
 	/* We are freeing an inode or directory. */
 	if ((DIP(ip, di_mode) & IFMT) == IFDIR)
@@ -1322,8 +1327,8 @@
 		reqlink = 1;
 	if (nlink < reqlink) {
 		if (debug)
-			printf("ino %d not enough links to live %d < %d\n",
-			    ino, nlink, reqlink);
+			printf("ino %ju not enough links to live %d < %d\n",
+			    (uintmax_t)ino, nlink, reqlink);
 		ino_reclaim(ip, ino, mode);
 		return;
 	}
@@ -1368,7 +1373,7 @@
 			break;
 		}
 		if (srec == NULL)
-			errx(1, "Directory %d name not found", ino);
+			errx(1, "Directory %ju name not found", (uintmax_t)ino);
 	}
 	/*
 	 * If it's a directory with no real names pointing to it go ahead
@@ -1392,21 +1397,22 @@
 	ip = ino_read(ino);
 	mode = DIP(ip, di_mode) & IFMT;
 	if (nlink > LINK_MAX)
-		err_suj(
-		    "ino %d nlink manipulation error, new link %d, old link %d\n",
-		    ino, nlink, DIP(ip, di_nlink));
+		err_suj("ino %ju nlink manipulation error, new %d, old %d\n",
+		    (uintmax_t)ino, nlink, DIP(ip, di_nlink));
 	if (debug)
-		printf("Adjusting ino %d, nlink %d, old link %d lastmode %o\n",
-		    ino, nlink, DIP(ip, di_nlink), sino->si_mode);
+		printf("Adjusting ino %ju, nlink %d, old link %d lastmode %o\n",
+		    (uintmax_t)ino, nlink, DIP(ip, di_nlink), sino->si_mode);
 	if (mode == 0) {
 		if (debug)
-			printf("ino %d, zero inode freeing bitmap\n", ino);
+			printf("ino %ju, zero inode freeing bitmap\n",
+			    (uintmax_t)ino);
 		ino_free(ino, sino->si_mode);
 		return;
 	}
 	/* XXX Should be an assert? */
 	if (mode != sino->si_mode && debug)
-		printf("ino %d, mode %o != %o\n", ino, mode, sino->si_mode);
+		printf("ino %ju, mode %o != %o\n",
+		    (uintmax_t)ino, mode, sino->si_mode);
 	if ((mode & IFMT) == IFDIR)
 		reqlink = 2;
 	else
@@ -1414,8 +1420,8 @@
 	/* If the inode doesn't have enough links to live, free it. */
 	if (nlink < reqlink) {
 		if (debug)
-			printf("ino %d not enough links to live %d < %d\n",
-			    ino, nlink, reqlink);
+			printf("ino %ju not enough links to live %d < %d\n",
+			    (uintmax_t)ino, nlink, reqlink);
 		ino_reclaim(ip, ino, mode);
 		return;
 	}
@@ -1422,7 +1428,8 @@
 	/* If required write the updated link count. */
 	if (DIP(ip, di_nlink) == nlink) {
 		if (debug)
-			printf("ino %d, link matches, skipping.\n", ino);
+			printf("ino %ju, link matches, skipping.\n",
+			    (uintmax_t)ino);
 		return;
 	}
 	DIP_SET(ip, di_nlink, nlink);
@@ -1521,8 +1528,8 @@
 	mode = DIP(ip, di_mode) & IFMT;
 	cursize = DIP(ip, di_size);
 	if (debug)
-		printf("Truncating ino %d, mode %o to size %jd from size %jd\n",
-		    ino, mode, size, cursize);
+		printf("Truncating ino %ju, mode %o to size %jd from size %jd\n",
+		    (uintmax_t)ino, mode, size, cursize);
 
 	/* Skip datablocks for short links and devices. */
 	if (mode == 0 || mode == IFBLK || mode == IFCHR ||
@@ -1580,7 +1587,8 @@
 
 		bn = DIP(ip, di_db[visitlbn]);
 		if (bn == 0)
-			err_suj("Bad blk at ino %d lbn %jd\n", ino, visitlbn);
+			err_suj("Bad blk at ino %ju lbn %jd\n",
+			    (uintmax_t)ino, visitlbn);
 		oldspace = sblksize(fs, cursize, visitlbn);
 		newspace = sblksize(fs, size, visitlbn);
 		if (oldspace != newspace) {
@@ -1604,8 +1612,8 @@
 
 		bn = ino_blkatoff(ip, ino, visitlbn, &frags);
 		if (bn == 0)
-			err_suj("Block missing from ino %d at lbn %jd\n",
-			    ino, visitlbn);
+			err_suj("Block missing from ino %ju at lbn %jd\n",
+			    (uintmax_t)ino, visitlbn);
 		clrsize = frags * fs->fs_fsize;
 		buf = dblk_read(bn, clrsize);
 		clrsize -= off;
@@ -1650,11 +1658,11 @@
 			err_suj("Inode mode/directory type mismatch %o != %o\n",
 			    mode, rrec->jr_mode);
 		if (debug)
-			printf("jrefrec: op %d ino %d, nlink %d, parent %d, "
+			printf("jrefrec: op %d ino %ju, nlink %d, parent %d, "
 			    "diroff %jd, mode %o, isat %d, isdot %d\n",
-			    rrec->jr_op, rrec->jr_ino, rrec->jr_nlink,
-			    rrec->jr_parent, rrec->jr_diroff, rrec->jr_mode,
-			    isat, isdot);
+			    rrec->jr_op, (uintmax_t)rrec->jr_ino,
+			    rrec->jr_nlink, rrec->jr_parent, rrec->jr_diroff,
+			    rrec->jr_mode, isat, isdot);
 		mode = rrec->jr_mode & IFMT;
 		if (rrec->jr_op == JOP_REMREF)
 			removes++;
@@ -1670,8 +1678,8 @@
 	 * by one.
 	 */
 	if (debug)
-		printf("ino %d nlink %d newlinks %d removes %d dotlinks %d\n",
-		    ino, nlink, newlinks, removes, dotlinks);
+		printf("ino %ju nlink %d newlinks %d removes %d dotlinks %d\n",
+		    (uintmax_t)ino, nlink, newlinks, removes, dotlinks);
 	nlink += newlinks;
 	nlink -= removes;
 	sino->si_linkadj = 1;
@@ -1712,9 +1720,9 @@
 			sino->si_blkadj = 1;
 		}
 		if (debug)
-			printf("op %d blk %jd ino %d lbn %jd frags %d isat %d (%d)\n",
-			    brec->jb_op, blk, brec->jb_ino, brec->jb_lbn,
-			    brec->jb_frags, isat, frags);
+			printf("op %d blk %jd ino %ju lbn %jd frags %d isat %d (%d)\n",
+			    brec->jb_op, blk, (uintmax_t)brec->jb_ino,
+			    brec->jb_lbn, brec->jb_frags, isat, frags);
 		/*
 		 * If we found the block at this address we still have to
 		 * determine if we need to free the tail end that was
@@ -1931,12 +1939,12 @@
 		 */
 		if (DIP(ip, di_nlink) == 0) {
 			if (debug)
-				printf("Freeing unlinked ino %d mode %o\n",
-				    ino, mode);
+				printf("Freeing unlinked ino %ju mode %o\n",
+				    (uintmax_t)ino, mode);
 			ino_reclaim(ip, ino, mode);
 		} else if (debug)
-			printf("Skipping ino %d mode %o with link %d\n",
-			    ino, mode, DIP(ip, di_nlink));
+			printf("Skipping ino %ju mode %o with link %d\n",
+			    (uintmax_t)ino, mode, DIP(ip, di_nlink));
 		ino = inon;
 	}
 }
@@ -2363,27 +2371,27 @@
 {
 
 	if (DIP(ip, di_nlink) != 1) {
-		printf("Invalid link count %d for journal inode %d\n",
-		    DIP(ip, di_nlink), sujino);
+		printf("Invalid link count %d for journal inode %ju\n",
+		    DIP(ip, di_nlink), (uintmax_t)sujino);
 		return (-1);
 	}
 
 	if ((DIP(ip, di_flags) & (SF_IMMUTABLE | SF_NOUNLINK)) !=
 	    (SF_IMMUTABLE | SF_NOUNLINK)) {
-		printf("Invalid flags 0x%X for journal inode %d\n",
-		    DIP(ip, di_flags), sujino);
+		printf("Invalid flags 0x%X for journal inode %ju\n",
+		    DIP(ip, di_flags), (uintmax_t)sujino);
 		return (-1);
 	}
 
 	if (DIP(ip, di_mode) != (IFREG | IREAD)) {
-		printf("Invalid mode %o for journal inode %d\n",
-		    DIP(ip, di_mode), sujino);
+		printf("Invalid mode %o for journal inode %ju\n",
+		    DIP(ip, di_mode), (uintmax_t)sujino);
 		return (-1);
 	}
 
 	if (DIP(ip, di_size) < SUJ_MIN) {
-		printf("Invalid size %jd for journal inode %d\n",
-		    DIP(ip, di_size), sujino);
+		printf("Invalid size %jd for journal inode %ju\n",
+		    DIP(ip, di_size), (uintmax_t)sujino);
 		return (-1);
 	}
 
@@ -2407,7 +2415,7 @@
 	int		je_blocks;	/* Disk block count. */
 };
 
-struct jblocks *suj_jblocks;
+static struct jblocks *suj_jblocks;
 
 static struct jblocks *
 jblocks_create(void)
@@ -2667,8 +2675,8 @@
 	struct suj_seg *seg;
 	struct suj_seg *segn;
 
+	initsuj();
 	opendisk(filesys);
-	TAILQ_INIT(&allsegs);
 
 	/*
 	 * Set an exit point when SUJ check failed
@@ -2711,12 +2719,12 @@
 	 * Build a list of journal blocks in jblocks before parsing the
 	 * available journal blocks in with suj_read().
 	 */
-	printf("** Reading %jd byte journal from inode %d.\n",
-	    DIP(jip, di_size), sujino);
+	printf("** Reading %jd byte journal from inode %ju.\n",
+	    DIP(jip, di_size), (uintmax_t)sujino);
 	suj_jblocks = jblocks_create();
 	blocks = ino_visit(jip, sujino, suj_add_block, 0);
 	if (blocks != numfrags(fs, DIP(jip, di_size))) {
-		printf("Sparse journal inode %d.\n", sujino);
+		printf("Sparse journal inode %ju.\n", (uintmax_t)sujino);
 		return (-1);
 	}
 	suj_read();
@@ -2757,3 +2765,28 @@
 
 	return (0);
 }
+
+static void
+initsuj(void)
+{
+	int i;
+
+	for (i = 0; i < SUJ_HASHSIZE; i++) {
+		LIST_INIT(&cghash[i]);
+		LIST_INIT(&dbhash[i]);
+	}
+	lastcg = NULL;
+	lastblk = NULL;
+	TAILQ_INIT(&allsegs);
+	oldseq = 0;
+	disk = NULL;
+	fs = NULL;
+	sujino = 0;
+	freefrags = 0;
+	freeblocks = 0;
+	freeinos = 0;
+	freedir = 0;
+	jbytes = 0;
+	jrecs = 0;
+	suj_jblocks = NULL;
+}

Modified: trunk/sbin/fsck_ffs/utilities.c
===================================================================
--- trunk/sbin/fsck_ffs/utilities.c	2018-07-01 21:06:17 UTC (rev 11221)
+++ trunk/sbin/fsck_ffs/utilities.c	2018-07-01 21:06:48 UTC (rev 11222)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1980, 1986, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
 #endif /* not lint */
 #endif
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sbin/fsck_ffs/utilities.c 260178 2014-01-02 01:44:14Z scottl $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -108,14 +109,3 @@
 	return (origname);
 }
 
-void
-infohandler(int sig __unused)
-{
-	got_siginfo = 1;
-}
-
-void
-alarmhandler(int sig __unused)
-{
-	got_sigalarm = 1;
-}



More information about the Midnightbsd-cvs mailing list