Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Jan 2014 01:44:14 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r260178 - in stable/10/sbin: fsck_ffs fsdb
Message-ID:  <201401020144.s021iE6N040838@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Thu Jan  2 01:44:14 2014
New Revision: 260178
URL: http://svnweb.freebsd.org/changeset/base/260178

Log:
  MFC r260068, r260069, r260076
  
   Add the -R option to allow fsck_ffs to restart itself when too many critical
   errors have been detected in a particular run.
  
   Clean up the global state variables so that a restart can happen correctly.
  
   Separate the global variables in fsck_ffs and fsdb to their own file.  This
   fixes header sharing with fscd.
  
   Correctly initialize, static-ize, and remove global variables as needed in
   dir.c.  This fixes a problem with lost+found directories that was causing
   a segfault.
  
   Correctly initialize, static-ize, and remove global variables as needed in
   suj.c.
  
   Initialize the suj globals before allocating the disk object, not after.
   Also ensure that 'preen' mode doesn't conflict with 'restart' mode
  
  Obtained from:	Netflix

Added:
  stable/10/sbin/fsck_ffs/globs.c
     - copied unchanged from r260076, head/sbin/fsck_ffs/globs.c
Modified:
  stable/10/sbin/fsck_ffs/Makefile
  stable/10/sbin/fsck_ffs/dir.c
  stable/10/sbin/fsck_ffs/fsck.h
  stable/10/sbin/fsck_ffs/fsck_ffs.8
  stable/10/sbin/fsck_ffs/fsutil.c
  stable/10/sbin/fsck_ffs/main.c
  stable/10/sbin/fsck_ffs/pass1.c
  stable/10/sbin/fsck_ffs/pass1b.c
  stable/10/sbin/fsck_ffs/suj.c
  stable/10/sbin/fsck_ffs/utilities.c
  stable/10/sbin/fsdb/Makefile

Modified: stable/10/sbin/fsck_ffs/Makefile
==============================================================================
--- stable/10/sbin/fsck_ffs/Makefile	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/Makefile	Thu Jan  2 01:44:14 2014	(r260178)
@@ -7,7 +7,8 @@ LINKS+=	${BINDIR}/fsck_ffs ${BINDIR}/fsc
 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: stable/10/sbin/fsck_ffs/dir.c
==============================================================================
--- stable/10/sbin/fsck_ffs/dir.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/dir.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -48,20 +48,14 @@ __FBSDID("$FreeBSD$");
 
 #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 +127,7 @@ dirscan(struct inodesc *idesc)
 			    (size_t)dsize);
 			dirty(bp);
 			sbdirty();
+			rerun = 1;
 		}
 		if (n & STOP)
 			return (n);

Modified: stable/10/sbin/fsck_ffs/fsck.h
==============================================================================
--- stable/10/sbin/fsck_ffs/fsck.h	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/fsck.h	Thu Jan  2 01:44:14 2014	(r260178)
@@ -192,15 +192,15 @@ struct bufarea {
 	"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;
-
-struct bufarea sblk;		/* file system superblock */
-struct bufarea *pdirbp;		/* current directory contents */
-struct bufarea *pbp;		/* current inode block */
+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;
+
+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) \
@@ -219,7 +219,7 @@ struct bufarea *pbp;		/* current inode b
 #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 */
@@ -282,63 +282,64 @@ struct inoinfo {
 	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;			/* 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 */
-
-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 */
+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 overriden */
+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 int	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 */
+
+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 */
+
+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) { \
@@ -346,8 +347,8 @@ volatile sig_atomic_t	got_sigalarm;	/* r
 	} 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)
@@ -360,6 +361,7 @@ struct	ufs2_dinode ufs2_zino;
 #define	FOUND	0x10
 
 #define	EEXIT	8		/* Standard error exit. */
+#define	ERESTART -1
 
 int flushentry(void);
 /*
@@ -428,6 +430,7 @@ void		flush(int fd, struct bufarea *bp);
 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);
@@ -466,5 +469,6 @@ int		setup(char *dev);
 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: stable/10/sbin/fsck_ffs/fsck_ffs.8
==============================================================================
--- stable/10/sbin/fsck_ffs/fsck_ffs.8	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/fsck_ffs.8	Thu Jan  2 01:44:14 2014	(r260178)
@@ -38,7 +38,7 @@
 .Nd file system consistency check and interactive repair
 .Sh SYNOPSIS
 .Nm
-.Op Fl BEFfnpryZ
+.Op Fl BEFfnpRryZ
 .Op Fl b Ar block
 .Op Fl c Ar level
 .Op Fl m Ar mode
@@ -266,6 +266,11 @@ which is assumed to be affirmative;
 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

Modified: stable/10/sbin/fsck_ffs/fsutil.c
==============================================================================
--- stable/10/sbin/fsck_ffs/fsutil.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/fsutil.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -74,6 +74,25 @@ static struct bufarea cgblk;	/* backup b
 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)

Copied: stable/10/sbin/fsck_ffs/globs.c (from r260076, head/sbin/fsck_ffs/globs.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/sbin/fsck_ffs/globs.c	Thu Jan  2 01:44:14 2014	(r260178, copy of r260076, head/sbin/fsck_ffs/globs.c)
@@ -0,0 +1,165 @@
+/*
+ * 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$");
+
+#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 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;			/* 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));
+}

Modified: stable/10/sbin/fsck_ffs/main.c
==============================================================================
--- stable/10/sbin/fsck_ffs/main.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/main.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$");
 
 #include "fsck.h"
 
+int	restarts;
+
 static void usage(void) __dead2;
 static int argtoi(int flag, const char *req, const char *str, int base);
 static int checkfilesys(char *filesys);
@@ -82,7 +84,7 @@ main(int argc, char *argv[])
 	sync();
 	skipclean = 1;
 	inoopt = 0;
-	while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:nprSyZ")) != -1) {
+	while ((ch = getopt(argc, argv, "b:Bc:CdEfFm:npRrSyZ")) != -1) {
 		switch (ch) {
 		case 'b':
 			skipclean = 0;
@@ -138,6 +140,9 @@ main(int argc, char *argv[])
 			ckclean++;
 			break;
 
+		case 'R':
+			wantrestart = 1;
+			break;
 		case 'r':
 			inoopt++;
 			break;
@@ -186,8 +191,12 @@ main(int argc, char *argv[])
 		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;
@@ -228,6 +237,8 @@ checkfilesys(char *filesys)
 	iov = NULL;
 	iovlen = 0;
 	errmsg[0] = '\0';
+	fsutilinit();
+	fsckinit();
 
 	cdevname = filesys;
 	if (debug && ckclean)
@@ -550,8 +561,12 @@ checkfilesys(char *filesys)
 	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);
@@ -654,3 +669,15 @@ usage(void)
 	    getprogname());
 	exit(1);
 }
+
+void
+infohandler(int sig __unused)
+{
+	got_siginfo = 1;
+}
+
+void
+alarmhandler(int sig __unused)
+{
+	got_sigalarm = 1;
+}

Modified: stable/10/sbin/fsck_ffs/pass1.c
==============================================================================
--- stable/10/sbin/fsck_ffs/pass1.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/pass1.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -68,6 +68,8 @@ pass1(void)
 	u_int8_t *cp;
 	int c, rebuildcg;
 
+	badblk = dupblk = lastino = 0;
+
 	/*
 	 * Set file system reserved blocks in used block map.
 	 */
@@ -463,6 +465,7 @@ pass1check(struct inodesc *idesc)
 				ckfini(0);
 				exit(EEXIT);
 			}
+			rerun = 1;
 			return (STOP);
 		}
 	}
@@ -483,6 +486,7 @@ pass1check(struct inodesc *idesc)
 					ckfini(0);
 					exit(EEXIT);
 				}
+				rerun = 1;
 				return (STOP);
 			}
 			new = (struct dups *)Malloc(sizeof(struct dups));
@@ -492,6 +496,7 @@ pass1check(struct inodesc *idesc)
 					ckfini(0);
 					exit(EEXIT);
 				}
+				rerun = 1;
 				return (STOP);
 			}
 			new->dup = blkno;

Modified: stable/10/sbin/fsck_ffs/pass1b.c
==============================================================================
--- stable/10/sbin/fsck_ffs/pass1b.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/pass1b.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -80,8 +80,10 @@ pass1b(void)
 				continue;
 			idesc.id_number = inumber;
 			if (inoinfo(inumber)->ino_state != USTATE &&
-			    (ckinode(dp, &idesc) & STOP))
+			    (ckinode(dp, &idesc) & STOP)) {
+				rerun = 1;
 				return;
+			}
 		}
 	}
 }
@@ -106,8 +108,10 @@ pass1bcheck(struct inodesc *idesc)
 			if (dlp == muldup)
 				break;
 		}
-		if (muldup == 0 || duphead == muldup->next)
+		if (muldup == 0 || duphead == muldup->next) {
+			rerun = 1;
 			return (STOP);
+		}
 	}
 	return (res);
 }

Modified: stable/10/sbin/fsck_ffs/suj.c
==============================================================================
--- stable/10/sbin/fsck_ffs/suj.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/suj.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -125,26 +125,26 @@ struct suj_cg {
 	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 +155,7 @@ static void ino_decr(ino_t);
 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)
@@ -2413,7 +2414,7 @@ struct jextent {
 	int		je_blocks;	/* Disk block count. */
 };
 
-struct jblocks *suj_jblocks;
+static struct jblocks *suj_jblocks;
 
 static struct jblocks *
 jblocks_create(void)
@@ -2673,8 +2674,8 @@ suj_check(const char *filesys)
 	struct suj_seg *seg;
 	struct suj_seg *segn;
 
+	initsuj();
 	opendisk(filesys);
-	TAILQ_INIT(&allsegs);
 
 	/*
 	 * Set an exit point when SUJ check failed
@@ -2763,3 +2764,28 @@ suj_check(const char *filesys)
 
 	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: stable/10/sbin/fsck_ffs/utilities.c
==============================================================================
--- stable/10/sbin/fsck_ffs/utilities.c	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsck_ffs/utilities.c	Thu Jan  2 01:44:14 2014	(r260178)
@@ -108,14 +108,3 @@ retry:
 	return (origname);
 }
 
-void
-infohandler(int sig __unused)
-{
-	got_siginfo = 1;
-}
-
-void
-alarmhandler(int sig __unused)
-{
-	got_sigalarm = 1;
-}

Modified: stable/10/sbin/fsdb/Makefile
==============================================================================
--- stable/10/sbin/fsdb/Makefile	Thu Jan  2 01:40:19 2014	(r260177)
+++ stable/10/sbin/fsdb/Makefile	Thu Jan  2 01:44:14 2014	(r260178)
@@ -6,7 +6,7 @@ PROG=	fsdb
 MAN=	fsdb.8
 SRCS=	fsdb.c fsdbutil.c \
 	dir.c ea.c fsutil.c inode.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
-	pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c
+	pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c globs.c
 CFLAGS+= -I${.CURDIR}/../fsck_ffs
 WARNS?= 2
 LDADD=	-ledit -ltermcap



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401020144.s021iE6N040838>