This is a multi-part message in MIME format.
--------------060303000807050602000802
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Xin LI wrote:
> Here is a revised version of patch.


Sorry for replying myself. I found a nit - the clear of cg is beyond
the reach of later phases, so set rerun = 1 to advise the user that a
rerun of fsck is necessary to make a full recover. No other functional
chnages.

Cheers,
- --
Xin LI http://www.delphij.net/
FreeBSD - The Power to Serve!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQFHvh6ii+vbBBjt66ARApvIAKDCTQ13lZCTnP3mHLrJtI s+dsvF2gCeIy3j
lrJcQw30LubvVfiVm8y6cvs=
=Wh3/
-----END PGP SIGNATURE-----

--------------060303000807050602000802
Content-Type: text/plain;
name="fsck.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="fsck.diff"

Index: fsck.h
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/fsck.h,v
retrieving revision 1.37
diff -u -p -r1.37 fsck.h
--- fsck.h 31 Oct 2006 22:06:56 -0000 1.37
+++ fsck.h 21 Feb 2008 22:01:44 -0000
@@ -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 *);
Index: fsck_ffs.8
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/fsck_ffs.8,v
retrieving revision 1.34
diff -u -p -r1.34 fsck_ffs.8
--- fsck_ffs.8 20 Sep 2005 08:02:38 -0000 1.34
+++ fsck_ffs.8 21 Feb 2008 22:26:08 -0000
@@ -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.
Index: fsutil.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/fsutil.c,v
retrieving revision 1.26
diff -u -p -r1.26 fsutil.c
--- fsutil.c 31 Oct 2006 22:06:56 -0000 1.26
+++ fsutil.c 22 Feb 2008 00:50:43 -0000
@@ -301,7 +301,7 @@ ckfini(int markclean)
if (havesb && cursnapshot == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
sblk.b_bno != sblock.fs_sblockloc / dev_bsize &&
!preen && reply("UPDATE STANDARD SUPERBLOCK")) {
- sblk.b_bno = sblock.fs_sblockloc / dev_bsize;
+ sblk.b_bno = SBLOCK_UFS2 / dev_bsize;
sbdirty();
flush(fswritefd, &sblk);
}
@@ -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);
Index: inode.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/inode.c,v
retrieving revision 1.38
diff -u -p -r1.38 inode.c
--- inode.c 31 Oct 2006 22:06:56 -0000 1.38
+++ inode.c 21 Feb 2008 21:56:27 -0000
@@ -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) {
Index: main.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/main.c,v
retrieving revision 1.47
diff -u -p -r1.47 main.c
--- main.c 19 Sep 2007 01:24:19 -0000 1.47
+++ main.c 21 Feb 2008 22:02:42 -0000
@@ -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;
Index: pass1.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/pass1.c,v
retrieving revision 1.43
diff -u -p -r1.43 pass1.c
--- pass1.c 8 Oct 2004 20:44:47 -0000 1.43
+++ pass1.c 20 Feb 2008 07:13:53 -0000
@@ -93,9 +93,11 @@ pass1(void)
inumber = c * sblock.fs_ipg;
setinodebuf(inumber);
getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
- if (sblock.fs_magic == FS_UFS2_MAGIC)
+ if (sblock.fs_magic == FS_UFS2_MAGIC) {
inosused = cgrp.cg_initediblk;
- else
+ if (inosused > sblock.fs_ipg)
+ inosused = sblock.fs_ipg;
+ } else
inosused = sblock.fs_ipg;
if (got_siginfo) {
printf("%s: phase 1: cyl group %d of %d (%d%%)\n",
Index: pass2.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/pass2.c,v
retrieving revision 1.26
diff -u -p -r1.26 pass2.c
--- pass2.c 8 Oct 2004 20:44:47 -0000 1.26
+++ pass2.c 21 Feb 2008 22:31:03 -0000
@@ -242,6 +242,8 @@ pass2check(struct inodesc *idesc)
/*
* check for "."
*/
+ if (dirp->d_ino > maxino)
+ goto chk2;
if (idesc->id_entryno != 0)
goto chk1;
if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) {
Index: setup.c
================================================== =================
RCS file: /home/ncvs/src/sbin/fsck_ffs/setup.c,v
retrieving revision 1.50
diff -u -p -r1.50 setup.c
--- setup.c 31 Oct 2006 22:06:56 -0000 1.50
+++ setup.c 20 Feb 2008 07:13:27 -0000
@@ -349,7 +349,7 @@ readsb(int listerr)
sblock.fs_sblockloc == sblock_try[i])) &&
sblock.fs_ncg >= 1 &&
sblock.fs_bsize >= MINBSIZE &&
- sblock.fs_bsize >= sizeof(struct fs))
+ sblock.fs_sbsize >= roundup(sizeof(struct fs), dev_bsize))
break;
}
if (sblock_try[i] == -1) {

--------------060303000807050602000802
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
freebsd-fs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-fs
To unsubscribe, send any mail to "freebsd-fs-unsubscribe@freebsd.org"

--------------060303000807050602000802--