EXT2Err EXT2Check()

in lsvmutils/ext2.c [2956:3098]


EXT2Err EXT2Check(
    const EXT2* ext2)
{
    EXT2_DECLARE_ERR(err);

    /* Check the block bitmaps */
    {
        UINT32 i;
        UINT32 n = 0;
        UINT32 nused = 0;
        UINT32 nfree = 0;

        for (i = 0; i < ext2->group_count; i++)
        {
            EXT2Block bitmap;

            nfree += ext2->groups[i].bg_free_blocks_count;

            if (EXT2_IFERR(err = EXT2ReadBlockBitmap(ext2, i, &bitmap)))
            {
                GOTO(done);
            }

            nused += _CountBitsN(bitmap.data, bitmap.size);
            n += bitmap.size * 8;
        }

        if (ext2->sb.s_free_blocks_count != nfree)
        {
#if !defined(BUILD_EFI)
            printf("s_free_blocks_count{%u}, nfree{%u}\n",
                ext2->sb.s_free_blocks_count, nfree);
#endif /* !defined(BUILD_EFI) */
            GOTO(done);
        }

        if (ext2->sb.s_free_blocks_count != n - nused)
        {
            GOTO(done);
        }
    }

    /* Check the inode bitmaps */
    {
        UINT32 i;
        UINT32 n = 0;
        UINT32 nused = 0;
        UINT32 nfree = 0;

        /* Check the bitmaps for the inodes */
        for (i = 0; i < ext2->group_count; i++)
        {
            EXT2Block bitmap;

            nfree += ext2->groups[i].bg_free_inodes_count;

            if (EXT2_IFERR(err = EXT2readReadInodeBitmap(ext2, i, &bitmap)))
            {
                GOTO(done);
            }

            nused += _CountBitsN(bitmap.data, bitmap.size);
            n += bitmap.size * 8;
        }

        if (ext2->sb.s_free_inodes_count != n - nused)
        {
            GOTO(done);
        }

        if (ext2->sb.s_free_inodes_count != nfree)
        {
            GOTO(done);
        }
    }

    /* Check the inodes */
    {
        UINT32 grpno;
        UINT32 nbits = 0;
        UINT32 mbits = 0;

        /* Check the inode tables */
        for (grpno = 0; grpno < ext2->group_count; grpno++)
        {
            EXT2Block bitmap;
            UINT32 lino;

            /* Get inode bitmap for this group */
            if (EXT2_IFERR(err = EXT2readReadInodeBitmap(ext2, grpno, &bitmap)))
            {
                GOTO(done);
            }

            nbits += _CountBitsN(bitmap.data, bitmap.size);

            /* For each bit set in the bit map */
            for (lino = 0; lino < ext2->sb.s_inodes_per_group; lino++)
            {
                EXT2Inode inode;
                EXT2Ino ino;

                if (!_TestBit(bitmap.data, bitmap.size, lino))
                    continue;

                mbits++;

                if ((lino+1) < EXT2_FIRST_INO && (lino+1) != EXT2_ROOT_INO)
                    continue;

                ino = _MakeIno(ext2, grpno, lino);

                if (EXT2_IFERR(err = EXT2ReadInode(ext2, ino, &inode)))
                {
                    GOTO(done);
                }

                /* Mode can never be zero */
                if (inode.i_mode == 0)
                {
                    GOTO(done);
                }

                /* If file is not zero size but no blocks, then fail */
                if (inode.i_size && !inode.i_block[0])
                {
                    GOTO(done);
                }
            }
        }

        /* The number of bits in bitmap must match number of active inodes */
        if (nbits != mbits)
        {
            GOTO(done);
        }
    }

    err = EXT2_ERR_NONE;

done:
    return err;
}