in lsvmutils/ext2.c [937:1074]
static EXT2Err _LoadBlockNumbersFromInode(
const EXT2* ext2,
const EXT2Inode* inode,
BOOLEAN include_block_blocks,
BufU32 *buf)
{
EXT2_DECLARE_ERR(err);
/* Check parameters */
if (!EXT2Valid(ext2) || !inode || !buf)
{
err = EXT2_ERR_INVALID_PARAMETER;
GOTO(done);
}
/* Handle the direct blocks */
if (EXT2_IFERR(err = _AppendDirectBlockNumbers(
inode->i_block,
EXT2_SINGLE_INDIRECT_BLOCK,
buf)))
{
GOTO(done);
}
/* Handle single-indirect blocks */
if (inode->i_block[EXT2_SINGLE_INDIRECT_BLOCK])
{
EXT2Block block;
UINT32 block_no = inode->i_block[EXT2_SINGLE_INDIRECT_BLOCK];
/* Read the next block */
if (EXT2_IFERR(err = EXT2ReadBlock(ext2, block_no, &block)))
{
GOTO(done);
}
if (include_block_blocks)
{
if (EXT2_IFERR(err = BufU32Append(buf, &block_no, 1)))
{
GOTO(done);
}
}
/* Append the block numbers from this block */
if (EXT2_IFERR(err = _AppendDirectBlockNumbers(
(const UINT32*)block.data,
block.size / sizeof(UINT32),
buf)))
{
GOTO(done);
}
}
/* Handle double-indirect blocks */
if (inode->i_block[EXT2_DOUBLE_INDIRECT_BLOCK])
{
EXT2Block block;
UINT32 block_no = inode->i_block[EXT2_DOUBLE_INDIRECT_BLOCK];
/* Read the next block */
if (EXT2_IFERR(err = EXT2ReadBlock(ext2, block_no, &block)))
{
GOTO(done);
}
if (include_block_blocks)
{
if (EXT2_IFERR(err = BufU32Append(buf, &block_no, 1)))
GOTO(done);
}
if (EXT2_IFERR(err = _AppendIndirectBlockNumbers(
ext2,
(const UINT32*)block.data,
block.size / sizeof(UINT32),
include_block_blocks,
buf)))
{
GOTO(done);
}
}
/* Handle triple-indirect blocks */
if (inode->i_block[EXT2_TRIPLE_INDIRECT_BLOCK])
{
EXT2Block block;
UINT32 block_no = inode->i_block[EXT2_TRIPLE_INDIRECT_BLOCK];
/* Read the next block */
if (EXT2_IFERR(err = EXT2ReadBlock(ext2, block_no, &block)))
{
GOTO(done);
}
if (include_block_blocks)
{
if (EXT2_IFERR(err = BufU32Append(buf, &block_no, 1)))
GOTO(done);
}
if (EXT2_IFERR(err = _AppendDoubleIndirectBlockNumbers(
ext2,
(const UINT32*)block.data,
block.size / sizeof(UINT32),
include_block_blocks,
buf)))
{
GOTO(done);
}
}
/* This is broken */
#if 0
/* Check size expectations */
if (!include_block_blocks)
{
UINT32 expected_size;
expected_size = inode->i_size / ext2->block_size;
if (inode->i_size % ext2->block_size)
expected_size++;
if (buf->size != expected_size)
{
err = EXT2_ERR_SANITY_CHECK_FAILED;
GOTO(done);
}
}
#endif
err = EXT2_ERR_NONE;
done:
return err;
}