Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 04 Dec 2007 18:15:55 +0100
From:      julien.bellang@free.fr
To:        freebsd-fs@freebsd.org
Subject:   FSCK failed does'nt corrected file size when INCORRECT BLOCK COUNT is found
Message-ID:  <1196788555.47558b4bab0ab@imp.free.fr>

next in thread | raw e-mail | index | archive | help

Hi,

I'm working on a system installed in an environnement where power is cut off
many time a week. This system is based on i386 FreeBSD 6.2 OS.

I'm using FS UFS2 with SoftUpdate Activated.

After such power shutdown, when I restart I've got some corrupted files that
FSCK_UFS doesn't entirely resolve.

For these files FSCK resolves the following error :
 /dev/ad0s1f: INCORRECT BLOCK COUNT I=3132417 (512992 should be 459392)
(CORRECTED)

But actually these file still inconsistency in my point of view as the file size
field doesn't reflect the number of block reference in its inode.

Regards to fsck_ffs sources, It seems that FSCK checks the validity of block
pointer (!= 0) in the inode block list only for directory inode but not for
regular file.
In my case, as the number of block adress to check in the inode is deduced from
the file size, and the file size is greater than the number of really allocated
blocks I obtain many NULL block pointer.

Does anyone have an idea why the NULL pointer are accepted by FSCK for regular
file and it doesn't try to adjust the file size ?

file fsck_ffs/inode.c, iblocks(), line 208

line 153: static int
     154: iblock(struct inodesc *idesc, long ilevel, off_t isize)
{
      .
      .
      .
197: if (IBLK(bp, i)) {
                        idesc->id_blkno = IBLK(bp, i);
                        if (ilevel == 0)
                                n = (*func)(idesc);
                        else
                                n = iblock(idesc, ilevel, isize);
                        if (n & STOP) {
                                bp->b_flags &= ~B_INUSE;
                                return (n);
                        }
                } else {
208:                        if (idesc->id_type == DATA && isize > 0) {
                                /* An empty block in a directory XXX */
                                getpathname(pathbuf, idesc->id_number,
                                                idesc->id_number);
                                pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
                                        pathbuf);
                                if (reply("ADJUST LENGTH") == 1) {
                                        dp = ginode(idesc->id_number);
                                        DIP_SET(dp, di_size,
                                            DIP(dp, di_size) - isize);
                                        isize = 0;
                                        printf(
                                            "YOU MUST RERUN FSCK AFTERWARDS\n");
                                        rerun = 1;
                                        inodirty();
                                        bp->b_flags &= ~B_INUSE;
                                        return(STOP);
                                }
                        }
                }
      .
      .
      .
}

Thanks,

Julien





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1196788555.47558b4bab0ab>