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>