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

Reply via email to