From owner-freebsd-arch Fri Mar 30 15:38:56 2001 Delivered-To: freebsd-arch@freebsd.org Received: from beastie.mckusick.com (beastie.mckusick.com [209.31.233.184]) by hub.freebsd.org (Postfix) with ESMTP id 781DC37B71A for ; Fri, 30 Mar 2001 15:38:49 -0800 (PST) (envelope-from mckusick@mckusick.com) Received: from beastie.mckusick.com (localhost [127.0.0.1]) by beastie.mckusick.com (8.9.3/8.9.3) with ESMTP id PAA11228; Fri, 30 Mar 2001 15:38:42 -0800 (PST) (envelope-from mckusick@beastie.mckusick.com) Message-Id: <200103302338.PAA11228@beastie.mckusick.com> To: Randell Jesup Subject: Re: Background Fsck Cc: Bakul Shah , arch@FreeBSD.ORG In-Reply-To: Your message of "30 Mar 2001 12:25:50 EST." Date: Fri, 30 Mar 2001 15:38:42 -0800 From: Kirk McKusick Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG As far as I can tell, you have gone through and listed every error exit in fsck... Most of these can only arise if the logic is broken in some fundamental way. For example: errx(EEXIT, "BAD STATE %d FOR INODE I=%d", can only occur if one of the states defined for an inode by fsck is found. The state is derived from a classification made in pass 1. If the inode has had random stuff put into it, then it will be classified as USTATE. Similarly, inode numbers that are out of bounds should have been discovered at a higher level and dealt with (e.g., an out of bounds directory entry should have been found and zapped). I do not disagree that there may be some possibilities that slip through, but going through and wholesale getting rid of error exits is not the right approach. In general `fsck -p' will not fix everything, but `fsck -y' should always succeed (though success may be an empty filesystem). Kirk =-=-=-=-=-=-=-= To: Kirk McKusick Cc: Bakul Shah , arch@FreeBSD.ORG Subject: Re: Background Fsck From: Randell Jesup Date: 30 Mar 2001 12:25:50 -0500 Kirk McKusick writes: > On a somewhat related note, I have always wondered if the > current fsck algorithm can be significantly improved or if it > is about as efficient as it can be (barring any peephole code > improvements). > >Many improvements have been made to fsck over the years. Through >there are undoubtedly more that could be made, there are no big >easy improvements left. Last time I checked, fsck basically calls exit() on a number of types of errors (inode out of range was one of them I think - you had to manually cleari for each one and restart fsck). I munged fsck to try to recover a coworker's files when something went foobar in her 2.2.8 machine and wrote garbage across sectors all over her disk. Does this fix those sorts of "I can't deal with it and won't try no matter how hard you force me" cases? >From the current source - I know that many of these are internal errors that shouldn't happen, and are correct to exit out on. However, some (like inoinfo(), ginode(), maybe getnextinode()) should NOT just cause a blanket exit. utilities.c: (This is the one that caused me the big trouble, I think) ------- /* * Look up state information for an inode. */ struct inostat * inoinfo(inum) ino_t inum; { static struct inostat unallocated = { USTATE, 0, 0 }; struct inostatlist *ilp; int iloff; if (inum > maxino) errx(EEXIT, "inoinfo: inumber %d out of range", inum); inode.c: (this may very well have been it too) ------- /* * General purpose interface for reading inodes. */ struct dinode * ginode(inumber) ino_t inumber; { ufs_daddr_t iblk; if (inumber < ROOTINO || inumber > maxino) errx(EEXIT, "bad inode number %d to ginode", inumber); ... struct dinode * getnextinode(inumber) ino_t inumber; { long size; ufs_daddr_t dblk; static struct dinode *dp; if (inumber != nextino++ || inumber > maxino) errx(EEXIT, "bad inode number %d to nextinode", inumber); ... void setinodebuf(inum) ino_t inum; { if (inum % sblock.fs_ipg != 0) errx(EEXIT, "bad inode number %d to setinodebuf", inum); ... getinoinfo(inumber): errx(EEXIT, "cannot find inode %d", inumber); ... default: errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state); dir.c: ------- if (idesc->id_type != DATA) errx(EEXIT, "wrong type to dirscan %d", idesc->id_type); pass2.c: ------- default: errx(EEXIT, "BAD STATE %d FOR ROOT INODE", inoinfo(ROOTINO)->ino_state); ... default: errx(EEXIT, "BAD STATE %d FOR INODE I=%d", inoinfo(dirp->d_ino)->ino_state, dirp->d_ino); pass4.c: ------- default: errx(EEXIT, "BAD STATE %d FOR INODE I=%d", inoinfo(inumber)->ino_state, inumber); pass5.c: ------- default: inomapsize = blkmapsize = sumsize = 0; /* keep lint happy */ errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d", fs->fs_postblformat); ... default: if (j < ROOTINO) break; errx(EEXIT, "BAD STATE %d FOR INODE I=%ld", inoinfo(j)->ino_state, j); -- Randell Jesup, Worldgate Communications, ex-Scala, ex-Amiga OS team ('88-94) rjesup@wgate.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message