Date: Thu, 26 Jul 2001 15:14:09 +0100 From: Ian Dowse <iedowse@maths.tcd.ie> To: Michael Harnois <mdharnois@home.com> Cc: freebsd-current@freebsd.org, mckusick@mckusick.com Subject: Re: filesystem errors Message-ID: <200107261514.aa46454@salmon.maths.tcd.ie> In-Reply-To: Your message of "Wed, 25 Jul 2001 23:14:16 CDT." <8666cgfht3.fsf@mharnois.workgroup.net>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <8666cgfht3.fsf@mharnois.workgroup.net>, Michael Harnois writes: >I'm tearing my hair out trying to find a filesystem error that's >causing me a panic: ufsdirhash_checkblock: bad dir inode. > >When I run fsck from a single user boot, it finds no errors. > >When I run it on the same filesystem mounted, it finds errors: but, of >course, it then can't correct them [Kirk, I'm cc'ing you because here the dirhash code sanity checks found a directory entry with d_ino == 0 that was not at the start of a DIRBLKSIZ block. This doesn't happen normally, but it seems from this report that fsck does not correct this. Is it a basic filesystem assumption that d_ino == 0 can only happen at the start of a directory block, or is it something the code should tolerate?] Interesting - this is an error reported by the UFS_DIRHASH code that you enabled in your kernel config. A sanity check that the dirhash code is performing is failing. These checks are designed to catch bugs in the dirhash code, but in this case I think it may be a bug that fsck is not finding this problem, or else my sanity tests are too strict. A workaround is to turn off the sanity checks with: sysctl vfs.ufs.dirhash_docheck=0 or to remove UFS_DIRHASH from your kernel config. You could also try to find the directory that is causing the problems. Copy the following script to a file called dircheck.pl, and try running: chmod 755 dircheck.pl find / -fstype ufs -type d -print0 | xargs ./dircheck.pl That should show up any directories that would fail that dirhash sanity check - there will probably just be one or two that resulted from some old filesystem corruption. Ian #!/usr/local/bin/perl while (defined($dir = shift)) { unless (open(DIR, "$dir")) { print STDERR "$dir: $!\n"; next; } $b = 0; my(%dir) = (); while (sysread(DIR, $dat, 512) == 512) { $off = 0; while (length($dat) > 0) { ($dir{'d_ino'}, $dir{'d_reclen'}, $dir{'d_type'}, $dir{'d_namlen'}) = unpack("LSCC", $dat); $dir{'d_name'} = substr($dat, 8, $dir{'d_namlen'}); $minreclen = (8 + $dir{'d_namlen'} + 1 + 3) & (~3); $gapinfo = ($dir{'d_reclen'} == $minreclen) ? "" : sprintf("[%d]", $dir{'d_reclen'} - $minreclen); if ($dir{'d_ino'} == 0 && $off != 0) { printf("%s off %d ino %d reclen 0x%x type 0%o" . " namelen %d name '%s' %s\n", $dir, $off, $dir{'d_ino'}, $dir{'d_reclen'}, $dir{'d_type'}, $dir{'d_namlen'}, $dir{'d_name'}, $gapinfo); } if ($dir{'d_reclen'} > length($dat)) { die "reclen too long!\n"; } $dat = substr($dat, $dir{'d_reclen'}); $off += $dir{'d_reclen'}; } $b++; } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <200107261514.aa46454>