diff options
author | delphij <delphij@FreeBSD.org> | 2008-04-10 23:49:23 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2008-04-10 23:49:23 +0000 |
commit | aff41aab585ea9a4db2a88f4299e3ad8f2f12031 (patch) | |
tree | b5f93f915b454019d2b6ae372ac45f5167ac1c67 /sbin/fsck_ffs/fsutil.c | |
parent | d99d951c1c77a9727f83ca99c52261cc3bc93f76 (diff) | |
download | FreeBSD-src-aff41aab585ea9a4db2a88f4299e3ad8f2f12031.zip FreeBSD-src-aff41aab585ea9a4db2a88f4299e3ad8f2f12031.tar.gz |
Add a new flag, '-C' which enables a special mode that is intended for
catastrophic recovery. Currently, this mode only validates whether a
cylindergroup has good signature data, and prompts the user to decide
whether to clear it as a whole.
This mode is useful when there is data damage on a disk and you are
working on copy of the original disk, as fsck_ffs(8) tends to abnormally
exit in such case, as a last resort to recover data from the disk.
Diffstat (limited to 'sbin/fsck_ffs/fsutil.c')
-rw-r--r-- | sbin/fsck_ffs/fsutil.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index 65f996c..7ca0c44 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -418,6 +418,35 @@ blwrite(int fd, char *buf, ufs2_daddr_t blk, long size) } /* + * 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); |