Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Jan 2009 00:39:22 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r187069 - stable/7/sbin/fsck_ffs
Message-ID:  <200901120039.n0C0dMKX043214@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Mon Jan 12 00:39:22 2009
New Revision: 187069
URL: http://svn.freebsd.org/changeset/base/187069

Log:
  MFC revisions 178088 and 179656: Catastrophic recovery mode.

Modified:
  stable/7/sbin/fsck_ffs/   (props changed)
  stable/7/sbin/fsck_ffs/fsck.h
  stable/7/sbin/fsck_ffs/fsck_ffs.8
  stable/7/sbin/fsck_ffs/fsutil.c
  stable/7/sbin/fsck_ffs/inode.c
  stable/7/sbin/fsck_ffs/main.c

Modified: stable/7/sbin/fsck_ffs/fsck.h
==============================================================================
--- stable/7/sbin/fsck_ffs/fsck.h	Sun Jan 11 23:19:17 2009	(r187068)
+++ stable/7/sbin/fsck_ffs/fsck.h	Mon Jan 12 00:39:22 2009	(r187069)
@@ -270,6 +270,7 @@ 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 */
+char	catastrophicflag;	/* run in catastrophic mode */
 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 */
@@ -335,6 +336,7 @@ void		cacheino(union dinode *dp, ino_t i
 void		catch(int);
 void		catchquit(int);
 int		changeino(ino_t dir, const char *name, ino_t newnum);
+void		check_cgmagic(int cg, struct cg *cgp);
 int		chkrange(ufs2_daddr_t blk, int cnt);
 void		ckfini(int markclean);
 int		ckinode(union dinode *dp, struct inodesc *);

Modified: stable/7/sbin/fsck_ffs/fsck_ffs.8
==============================================================================
--- stable/7/sbin/fsck_ffs/fsck_ffs.8	Sun Jan 11 23:19:17 2009	(r187068)
+++ stable/7/sbin/fsck_ffs/fsck_ffs.8	Mon Jan 12 00:39:22 2009	(r187069)
@@ -29,7 +29,7 @@
 .\"	@(#)fsck.8	8.4 (Berkeley) 5/9/95
 .\" $FreeBSD$
 .\"
-.Dd April 24, 2001
+.Dd April 10, 2008
 .Dt FSCK_FFS 8
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 .Nd file system consistency check and interactive repair
 .Sh SYNOPSIS
 .Nm
-.Op Fl BFpfny
+.Op Fl BCFpfny
 .Op Fl b Ar block
 .Op Fl c Ar level
 .Op Fl m Ar mode
@@ -175,6 +175,26 @@ Use the block specified immediately afte
 the super block for the file system.
 An alternate super block is usually located at block 32 for UFS1,
 and block 160 for UFS2.
+.It Fl C
+Run
+.Nm
+in 'catastrophic recovery' mode, which will enable certain aggressive
+operations that can make
+.Nm
+to survive with file systems that has very serious data damage, which
+is an useful last resort when on disk data damage is very serious
+and causes
+.Nm
+to crash otherwise.  Be
+.Em very careful
+using this flag, is dangerous if there are data transmission hazards
+because a false positive cylinder group magic number mismatch could
+cause
+.Em irrevertible data loss!
+.Pp
+This option implies the
+.Fl f
+flag.
 .It Fl c
 Convert the file system to the specified level.
 Note that the level of a file system can only be raised.

Modified: stable/7/sbin/fsck_ffs/fsutil.c
==============================================================================
--- stable/7/sbin/fsck_ffs/fsutil.c	Sun Jan 11 23:19:17 2009	(r187068)
+++ stable/7/sbin/fsck_ffs/fsutil.c	Mon Jan 12 00:39:22 2009	(r187069)
@@ -418,6 +418,35 @@ blwrite(int fd, char *buf, ufs2_daddr_t 
 }
 
 /*
+ * Check cg's magic number.  If catastrophic mode is enabled and the cg's
+ * magic number is bad, offer an option to clear the whole cg.
+ */
+void
+check_cgmagic(int cg, struct cg *cgp)
+{
+
+	if (!cg_chkmagic(cgp)) {
+	    pwarn("CG %d: BAD MAGIC NUMBER\n", cg);
+	    if (catastrophicflag) {
+		if (reply("CLEAR CG")) {
+			memset(cgp, 0, (size_t)sblock.fs_cgsize);
+			cgp->cg_initediblk = sblock.fs_ipg;
+			cgp->cg_old_niblk = sblock.fs_ipg;
+			cgp->cg_old_ncyl = sblock.fs_old_cpg;
+			cgp->cg_cgx = cg;
+			cgp->cg_niblk = sblock.fs_ipg;
+			cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
+			cgp->cg_magic = CG_MAGIC;
+			cgdirty();
+			printf("PLEASE RERUN FSCK.\n");
+			rerun = 1;
+		}
+	    } else
+		printf("YOU MAY NEED TO RERUN FSCK WITH -C IF IT CRASHED.\n");
+	}
+}
+
+/*
  * allocate a data block with the specified number of fragments
  */
 ufs2_daddr_t
@@ -441,8 +470,7 @@ allocblk(long frags)
 			}
 			cg = dtog(&sblock, i + j);
 			getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
-			if (!cg_chkmagic(cgp))
-				pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
+			check_cgmagic(cg, cgp);
 			baseblk = dtogd(&sblock, i + j);
 			for (k = 0; k < frags; k++) {
 				setbmap(i + j + k);

Modified: stable/7/sbin/fsck_ffs/inode.c
==============================================================================
--- stable/7/sbin/fsck_ffs/inode.c	Sun Jan 11 23:19:17 2009	(r187068)
+++ stable/7/sbin/fsck_ffs/inode.c	Mon Jan 12 00:39:22 2009	(r187069)
@@ -617,8 +617,7 @@ allocino(ino_t request, int type)
 		return (0);
 	cg = ino_to_cg(&sblock, ino);
 	getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
-	if (!cg_chkmagic(cgp))
-		pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
+	check_cgmagic(cg, cgp);
 	setbit(cg_inosused(cgp), ino % sblock.fs_ipg);
 	cgp->cg_cs.cs_nifree--;
 	switch (type & IFMT) {

Modified: stable/7/sbin/fsck_ffs/main.c
==============================================================================
--- stable/7/sbin/fsck_ffs/main.c	Sun Jan 11 23:19:17 2009	(r187068)
+++ stable/7/sbin/fsck_ffs/main.c	Mon Jan 12 00:39:22 2009	(r187069)
@@ -81,7 +81,8 @@ main(int argc, char *argv[])
 
 	sync();
 	skipclean = 1;
-	while ((ch = getopt(argc, argv, "b:Bc:dfFm:npy")) != -1) {
+	catastrophicflag = 0;
+	while ((ch = getopt(argc, argv, "b:Bc:CdfFm:npy")) != -1) {
 		switch (ch) {
 		case 'b':
 			skipclean = 0;
@@ -105,6 +106,10 @@ main(int argc, char *argv[])
 			debug++;
 			break;
 
+		case 'C':
+			catastrophicflag = 1;
+			/* FALLTHROUGH */
+
 		case 'f':
 			skipclean = 0;
 			break;
@@ -610,7 +615,7 @@ static void
 usage(void)
 {
         (void) fprintf(stderr,
-            "usage: %s [-BFpfny] [-b block] [-c level] [-m mode] "
+            "usage: %s [-BCFpfny] [-b block] [-c level] [-m mode] "
                         "filesystem ...\n",
             getprogname());
         exit(1);



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