-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Here is a patch that will help fsck_ffs(8) to recover from certain types of damages which is caused by some catastrophic damage seen in some disk arrays that does not detect data errors in time. Change summary: fsutil.c: - Really update standard superblock. fsck_ffs -b used to update the backup superblock which does not recover file systems which have bad master superblocks. - Instead of coredump, zero out whole cg if its signature is bad. inode.c: - Instead of coredump, zero out whole cg if its signature is bad. pass1.c: - If cg gives insane initediblk, use a fallback one which will not cause allocation failure. setup.c: - Really sanity check the superblock's fs_sbsize. With these changes, fsck_ffs will be able to check file systems with heavily damaged cylinder group information, and have a better chance surviving. Comments? Cheers, - -- Xin LI <delphij_at_delphij.net> http://www.delphij.net/ FreeBSD - The Power to Serve! -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4 (FreeBSD) iD8DBQFHu9hji+vbBBjt66ARAqSyAJ49q4uEIANxr4/ccaVKeLTDomiFVQCfVB0i kLZsrSPTifwvItwC3WMq40E= =vvkQ -----END PGP SIGNATURE----- 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 20 Feb 2008 07:15:56 -0000 _at__at_ -301,7 +301,7 _at__at_ 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); } _at__at_ -441,8 +441,13 _at__at_ 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); + if (!cg_chkmagic(cgp)) { + pwarn("CG %d: BAD MAGIC NUMBER\n", cg); + memset(cgp, 0, (size_t)sblock.fs_cgsize); + cgp->cg_niblk = sblock.fs_ipg; + cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg); + cgp->cg_magic = CG_MAGIC; + } 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 20 Feb 2008 07:15:22 -0000 _at__at_ -617,8 +617,13 _at__at_ 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); + if (!cg_chkmagic(cgp)) { + pwarn("CG %d: BAD MAGIC NUMBER\n", cg); + memset(cgp, 0, (size_t)sblock.fs_cgsize); + cgp->cg_niblk = sblock.fs_ipg; + cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg); + cgp->cg_magic = CG_MAGIC; + } setbit(cg_inosused(cgp), ino % sblock.fs_ipg); cgp->cg_cs.cs_nifree--; switch (type & IFMT) { 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 _at__at_ -93,9 +93,11 _at__at_ 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: 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 _at__at_ -349,7 +349,7 _at__at_ 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) {Received on Wed Feb 20 2008 - 06:37:10 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:27 UTC