if (retval)
return retval;
ext2fs_group_desc_csum_set(fs, i);
+ fs->flags |= EXT2_FLAG_DIRTY;
blk = ext2fs_block_bitmap_loc(fs, i);
if (blk) {
if (retval)
goto errout;
ext2fs_group_desc_csum_set(fs, i);
+ fs->flags |= EXT2_FLAG_DIRTY;
blk = ext2fs_inode_bitmap_loc(fs, i);
if (blk) {
return 0;
}
+static int bitmap_tail_verify(unsigned char *bitmap, int first, int last)
+{
+ int i;
+
+ for (i = first; i <= last; i++)
+ if (bitmap[i] != 0xff)
+ return 0;
+ return 1;
+}
+
static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
{
dgrp_t i;
errcode_t retval;
int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+ int tail_flags = 0;
int csum_flag;
unsigned int cnt;
blk64_t blk;
ext2fs_free_mem(&buf);
if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
- blk = (fs->image_header->offset_inodemap / fs->blocksize);
+ blk = (ext2fs_le32_to_cpu(fs->image_header->offset_inodemap) / fs->blocksize);
ino_cnt = fs->super->s_inodes_count;
- while (inode_nbytes > 0) {
+ while (inode_bitmap && ino_cnt > 0) {
retval = io_channel_read_blk64(fs->image_io, blk++,
1, inode_bitmap);
if (retval)
ino_itr, cnt, inode_bitmap);
if (retval)
goto cleanup;
- ino_itr += fs->blocksize << 3;
- ino_cnt -= fs->blocksize << 3;
- inode_nbytes -= fs->blocksize;
+ ino_itr += cnt;
+ ino_cnt -= cnt;
}
- blk = (fs->image_header->offset_blockmap /
+ blk = (ext2fs_le32_to_cpu(fs->image_header->offset_blockmap) /
fs->blocksize);
- blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
- fs->group_desc_count;
- while (block_nbytes > 0) {
+ blk_cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super,
+ fs->group_desc_count);
+ while (block_bitmap && blk_cnt > 0) {
retval = io_channel_read_blk64(fs->image_io, blk++,
1, block_bitmap);
if (retval)
blk_itr, cnt, block_bitmap);
if (retval)
goto cleanup;
- blk_itr += fs->blocksize << 3;
- blk_cnt -= fs->blocksize << 3;
- block_nbytes -= fs->blocksize;
+ blk_itr += cnt;
+ blk_cnt -= cnt;
}
goto success_cleanup;
}
for (i = 0; i < fs->group_desc_count; i++) {
if (block_bitmap) {
blk = ext2fs_block_bitmap_loc(fs, i);
- if (csum_flag &&
- ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
- ext2fs_group_desc_csum_verify(fs, i))
+ if ((csum_flag &&
+ ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
+ ext2fs_group_desc_csum_verify(fs, i)) ||
+ (blk >= ext2fs_blocks_count(fs->super)))
blk = 0;
if (blk) {
retval = io_channel_read_blk64(fs->io, blk,
EXT2_ET_BLOCK_BITMAP_CSUM_INVALID;
goto cleanup;
}
+ if (!bitmap_tail_verify((unsigned char *) block_bitmap,
+ block_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
} else
memset(block_bitmap, 0, block_nbytes);
cnt = block_nbytes << 3;
}
if (inode_bitmap) {
blk = ext2fs_inode_bitmap_loc(fs, i);
- if (csum_flag &&
- ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
- ext2fs_group_desc_csum_verify(fs, i))
+ if ((csum_flag &&
+ ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
+ ext2fs_group_desc_csum_verify(fs, i)) ||
+ (blk >= ext2fs_blocks_count(fs->super)))
blk = 0;
if (blk) {
retval = io_channel_read_blk64(fs->io, blk,
EXT2_ET_INODE_BITMAP_CSUM_INVALID;
goto cleanup;
}
+ if (!bitmap_tail_verify((unsigned char *) inode_bitmap,
+ inode_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
} else
memset(inode_bitmap, 0, inode_nbytes);
cnt = inode_nbytes << 3;
}
success_cleanup:
- if (inode_bitmap)
+ if (inode_bitmap) {
ext2fs_free_mem(&inode_bitmap);
- if (block_bitmap)
+ fs->flags &= ~EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
+ }
+ if (block_bitmap) {
ext2fs_free_mem(&block_bitmap);
+ fs->flags &= ~EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
+ }
+ fs->flags |= tail_flags;
return 0;
cleanup:
if (do_block) {
- ext2fs_free_mem(&fs->block_map);
+ ext2fs_free_block_bitmap(fs->block_map);
fs->block_map = 0;
}
if (do_inode) {
- ext2fs_free_mem(&fs->inode_map);
+ ext2fs_free_inode_bitmap(fs->inode_map);
fs->inode_map = 0;
}
if (inode_bitmap)