From owner-freebsd-fs@FreeBSD.ORG Thu Aug 26 14:57:05 2004 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 11D2A16A4CF for ; Thu, 26 Aug 2004 14:57:05 +0000 (GMT) Received: from fort-point-station.mit.edu (FORT-POINT-STATION.MIT.EDU [18.7.7.76]) by mx1.FreeBSD.org (Postfix) with ESMTP id 85B5D43D55 for ; Thu, 26 Aug 2004 14:57:04 +0000 (GMT) (envelope-from simsong@csail.mit.edu) Received: from grand-central-station.mit.edu (GRAND-CENTRAL-STATION.MIT.EDU [18.7.21.82])i7QEtnuL014164; Thu, 26 Aug 2004 10:57:02 -0400 (EDT) Received: from melbourne-city-street.mit.edu (MELBOURNE-CITY-STREET.MIT.EDU [18.7.21.86])i7QEspCB028629; Thu, 26 Aug 2004 10:54:53 -0400 (EDT) Received: from [192.168.1.21] (ip-64-7-15-235.dsl.bos.megapath.net [64.7.15.235]) )i7QEsmpq016698; Thu, 26 Aug 2004 10:54:48 -0400 (EDT) In-Reply-To: <412DF685.4010505@samsco.org> References: <249AA14A-F6D6-11D8-87E0-000A95DA91E2@csail.mit.edu> <412DF685.4010505@samsco.org> Mime-Version: 1.0 (Apple Message framework v619) Content-Type: multipart/mixed; boundary=Apple-Mail-13--739225341 Message-Id: From: "Simson L. Garfinkel" Date: Thu, 26 Aug 2004 10:54:51 -0400 To: Scott Long X-Mailer: Apple Mail (2.619) cc: freebsd-fs@freebsd.org Subject: Re: problems with fsck_ffs X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Aug 2004 14:57:05 -0000 --Apple-Mail-13--739225341 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed Okay. Thanks for your interest! In fsck_ffs/setup.c, the variable sblock.fs_fsize was 0 because of my disk corruption. As a result, dev_bsize was being set to 0, which was resulting in a divide-by-zero. Here is the code and my fix: /* * Compute block size that the file system is based on, * according to fsbtodb, and adjust superblock block number * so we can tell if this is an alternate later. */ super *= dev_bsize; dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); /* SLG START */ if(dev_bsize==0){ printf("*** dev_bsize==0. This indicates on-disk corruption of the superblock.\n"); return (0); } /* SLG END */ Attached you'll find a program called find_super.c which scans the device for a superblock and fix_super.c which copied the good superblock into the expected superblock location. Ironically, even though fsck_ffs can take a "-b" option and do a full FSCK from any given superblock, mount will not take a superblock argument, so you still need to copy the good superblock into the known location. Both find_super.c and fix_super.c should be integrated into fsck_ffs. I'll do so if you think that this is a good way to proceed and if you seriously consider taking the changes. Th --Apple-Mail-13--739225341 Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0700; name="find_super.c" Content-Disposition: attachment; filename=find_super.c #include #include #include #include #include "/usr/src/sys/ufs/ufs/extattr.h" #include "/usr/src/sys/ufs/ufs/quota.h" #include "/usr/src/sys/ufs/ufs/inode.h" //#include "/usr/src/sys/ufs/ufs/ufsmount.h" #include "/usr/src/sys/ufs/ffs/fs.h" main(int argc,char **argv) { FILE *f = fopen(argv[1],"r"); if(!f) err(1,argv[1]); long block=0; printf("The FS structure is %d bytes large\n",sizeof(struct fs)); while(1){ char buf[8192]; struct fs *fs = (struct fs *)buf; if(fs->fs_magic!=0){ printf("\r%d ",block); } if(fread(buf,1,sizeof(buf),f)!=sizeof(buf)){ err(1,"end of file"); } if(fs->fs_magic==FS_UFS1_MAGIC) printf("UFS1 MAGIC at %d (%d)!\n",block,block*16); if(fs->fs_magic==FS_UFS2_MAGIC) printf("UFS2 MAGIC at %d (%d)!\n",block,block*16); if(fs->fs_magic==FS_BAD2_MAGIC) printf("UFS2 BAD MAGIC at %d (%d)!\n",block,block*16); block++; } } --Apple-Mail-13--739225341 Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0700; name="fix_super.c" Content-Disposition: attachment; filename=fix_super.c #include #include #include #include #include #include #include "/usr/src/sys/ufs/ufs/extattr.h" #include "/usr/src/sys/ufs/ufs/quota.h" #include "/usr/src/sys/ufs/ufs/inode.h" #include "/usr/src/sys/ufs/ffs/fs.h" main(int argc,char **argv) { int fd = open("/dev/da0s1e",O_RDWR); int fd2 = open("oldblock",O_WRONLY | O_CREAT); int buf[SBLOCKSIZE]; struct fs *fs = (struct fs *)buf; int from_block = 376224; //int to_block = SBLOCK_UFS1; int to_block = 128; if(fd<0) err(1,"fd"); if(fd2<0) err(1,"fd2"); lseek(fd,to_block*512,0); read(fd,buf,SBLOCKSIZE); write(fd2,buf,SBLOCKSIZE); /* make a copy */ /* now get the from_block */ lseek(fd,from_block*512,0); read(fd,buf,SBLOCKSIZE); if(fs->fs_magic==FS_UFS1_MAGIC) printf("UFS1 MAGIC at %d\n",from_block); if(fs->fs_magic==FS_UFS2_MAGIC) printf("UFS2 MAGIC at %d\n",from_block); if(fs->fs_magic==FS_BAD2_MAGIC) printf("UFS2 BAD MAGIC at %d\n",from_block); /* Now write it to the to_block */ lseek(fd,to_block*512,0); write(fd,buf,SBLOCKSIZE); printf("wrote to block %d\n",to_block); } --Apple-Mail-13--739225341 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed e good news is that I was able to recover my hard drive with 0 files lost! The bad news is that I had to spend about an hour programming in order to do so, which was kind of, well, unnevering. On Aug 26, 2004, at 10:41 AM, Scott Long wrote: > Simson L. Garfinkel wrote: >> Greetings. I just had a RAID crash which required some recovery with >> fsck_ffs. >> Two problems with fsck_ffs in 5.2 were discovered: >> 1. There is a divide-by-0 error that happens under some conditions >> when the contents of the superblock and the backup superblock are >> partially damaged. >> =>Would you like a fix for this? > > Of course! > >> 2. There is no obvious functionality to scan the whole hard-drive for >> backup superblocks. >> => I've written such a program. If I integrate it into fsck, will >> you take the mods? > > I'd definitely like to see it. > > Scott > --Apple-Mail-13--739225341--