problems with fsck_ffs
Simson L. Garfinkel
simsong at csail.mit.edu
Thu Aug 26 07:57:05 PDT 2004
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
-------------- next part --------------
#include <stdio.h>
#include <err.h>
#include <sys/types.h>
#include <sys/time.h>
#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++;
}
}
-------------- next part --------------
#include <stdio.h>
#include <err.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#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);
}
-------------- next part --------------
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
>
More information about the freebsd-fs
mailing list