[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