diff options
author | Paul Lawrence <paullawrence@google.com> | 2014-01-21 08:26:21 -0800 |
---|---|---|
committer | JP Abgrall <jpa@google.com> | 2014-01-29 22:33:10 +0000 |
commit | ee2bba62529ce544a60d141ca10a37407c03ab1e (patch) | |
tree | 39d46aa404b7bb1f7397ec98635066e50b92a537 /ext4_utils | |
parent | 547cdb36b8adfd5f55f8f2be4abe1ce7a2786567 (diff) | |
download | extras-ee2bba62529ce544a60d141ca10a37407c03ab1e.tar.gz |
ext4 utils: Refactor read_ext, and expose some of the functions
Make read_ext an externally useable function. Use case is to
enable fast encryption by being able to look at whether each block
is in use or not.
Bug: 11985952
Change-Id: Ief71f408a55db7261c75ebe974620415ed8cfd29
Diffstat (limited to 'ext4_utils')
-rw-r--r-- | ext4_utils/ext2simg.c | 62 | ||||
-rw-r--r-- | ext4_utils/ext4_utils.c | 92 | ||||
-rw-r--r-- | ext4_utils/ext4_utils.h | 6 | ||||
-rw-r--r-- | ext4_utils/ext4fixup.c | 134 |
4 files changed, 123 insertions, 171 deletions
diff --git a/ext4_utils/ext2simg.c b/ext4_utils/ext2simg.c index 7b63836c..64067292 100644 --- a/ext4_utils/ext2simg.c +++ b/ext4_utils/ext2simg.c @@ -53,66 +53,6 @@ static void usage(char *path) fprintf(stderr, " -S don't use sparse output format\n"); } -static int read_ext(int fd) -{ - off64_t ret; - struct ext4_super_block sb; - - ret = lseek64(fd, 1024, SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to superblock"); - - ret = read(fd, &sb, sizeof(sb)); - if (ret < 0) - critical_error_errno("failed to read superblock"); - if (ret != sizeof(sb)) - critical_error("failed to read all of superblock"); - - ext4_parse_sb(&sb); - - ret = lseek64(fd, info.len, SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to end of input image"); - - ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to block group descriptors"); - - ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks); - if (ret < 0) - critical_error_errno("failed to read block group descriptors"); - if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks) - critical_error("failed to read all of block group descriptors"); - - if (verbose) { - printf("Found filesystem with parameters:\n"); - printf(" Size: %llu\n", info.len); - printf(" Block size: %d\n", info.block_size); - printf(" Blocks per group: %d\n", info.blocks_per_group); - printf(" Inodes per group: %d\n", info.inodes_per_group); - printf(" Inode size: %d\n", info.inode_size); - printf(" Label: %s\n", info.label); - printf(" Blocks: %llu\n", aux_info.len_blocks); - printf(" Block groups: %d\n", aux_info.groups); - printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks); - printf(" Used %d/%d inodes and %d/%d blocks\n", - aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count, - aux_info.sb->s_inodes_count, - aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo, - aux_info.sb->s_blocks_count_lo); - } - - return 0; -} - -static int bitmap_get_bit(u8 *bitmap, u32 bit) -{ - if (bitmap[bit / 8] & 1 << (bit % 8)) - return 1; - - return 0; -} - static int build_sparse_ext(int fd, const char *filename) { unsigned int i; @@ -228,7 +168,7 @@ int main(int argc, char **argv) if (infd < 0) critical_error_errno("failed to open input image"); - read_ext(infd); + read_ext(infd, verbose); info.sparse_file = sparse_file_new(info.block_size, info.len); diff --git a/ext4_utils/ext4_utils.c b/ext4_utils/ext4_utils.c index d4fbc7c8..1b70afee 100644 --- a/ext4_utils/ext4_utils.c +++ b/ext4_utils/ext4_utils.c @@ -62,6 +62,21 @@ static int is_power_of(int a, int b) return (a == b) ? 1 : 0; } +int bitmap_get_bit(u8 *bitmap, u32 bit) +{ + if (bitmap[bit / 8] & (1 << (bit % 8))) + return 1; + + return 0; +} + +void bitmap_clear_bit(u8 *bitmap, u32 bit) +{ + bitmap[bit / 8] &= ~(1 << (bit % 8)); + + return; +} + /* Returns 1 if the bg contains a backup superblock. On filesystems with the sparse_super feature, only block groups 0, 1, and powers of 3, 5, and 7 have backup superblocks. Otherwise, all block groups have backup @@ -81,6 +96,38 @@ int ext4_bg_has_super_block(int bg) return 0; } +/* Function to read the primary superblock */ +void read_sb(int fd, struct ext4_super_block *sb) +{ + off64_t ret; + + ret = lseek64(fd, 1024, SEEK_SET); + if (ret < 0) + critical_error_errno("failed to seek to superblock"); + + ret = read(fd, sb, sizeof(*sb)); + if (ret < 0) + critical_error_errno("failed to read superblock"); + if (ret != sizeof(*sb)) + critical_error("failed to read all of superblock"); +} + +/* Function to write a primary or backup superblock at a given offset */ +void write_sb(int fd, unsigned long long offset, struct ext4_super_block *sb) +{ + off64_t ret; + + ret = lseek64(fd, offset, SEEK_SET); + if (ret < 0) + critical_error_errno("failed to seek to superblock"); + + ret = write(fd, sb, sizeof(*sb)); + if (ret < 0) + critical_error_errno("failed to write superblock"); + if (ret != sizeof(*sb)) + critical_error("failed to write all of superblock"); +} + /* Write the filesystem image to a file */ void write_ext4_image(int fd, int gz, int sparse, int crc) { @@ -450,3 +497,48 @@ u64 parse_num(const char *arg) return num; } + +int read_ext(int fd, int verbose) +{ + off64_t ret; + struct ext4_super_block sb; + + read_sb(fd, &sb); + + ext4_parse_sb(&sb); + + ret = lseek64(fd, info.len, SEEK_SET); + if (ret < 0) + critical_error_errno("failed to seek to end of input image"); + + ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET); + if (ret < 0) + critical_error_errno("failed to seek to block group descriptors"); + + ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks); + if (ret < 0) + critical_error_errno("failed to read block group descriptors"); + if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks) + critical_error("failed to read all of block group descriptors"); + + if (verbose) { + printf("Found filesystem with parameters:\n"); + printf(" Size: %llu\n", info.len); + printf(" Block size: %d\n", info.block_size); + printf(" Blocks per group: %d\n", info.blocks_per_group); + printf(" Inodes per group: %d\n", info.inodes_per_group); + printf(" Inode size: %d\n", info.inode_size); + printf(" Label: %s\n", info.label); + printf(" Blocks: %llu\n", aux_info.len_blocks); + printf(" Block groups: %d\n", aux_info.groups); + printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks); + printf(" Used %d/%d inodes and %d/%d blocks\n", + aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count, + aux_info.sb->s_inodes_count, + aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo, + aux_info.sb->s_blocks_count_lo); + } + + return 0; +} + diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h index 1e13a90c..7f96ac28 100644 --- a/ext4_utils/ext4_utils.h +++ b/ext4_utils/ext4_utils.h @@ -156,7 +156,11 @@ static inline int log_2(int j) return i - 1; } +int bitmap_get_bit(u8 *bitmap, u32 bit); +void bitmap_clear_bit(u8 *bitmap, u32 bit); int ext4_bg_has_super_block(int bg); +void read_sb(int fd, struct ext4_super_block *sb); +void write_sb(int fd, unsigned long long offset, struct ext4_super_block *sb); void write_ext4_image(int fd, int gz, int sparse, int crc); void ext4_create_fs_aux_info(void); void ext4_free_fs_aux_info(void); @@ -181,6 +185,8 @@ int make_ext4fs_internal(int fd, const char *directory, int sparse, int crc, int wipe, struct selabel_handle *sehnd, int verbose, time_t fixed_time); +int read_ext(int fd, int verbose); + #ifdef __cplusplus } #endif diff --git a/ext4_utils/ext4fixup.c b/ext4_utils/ext4fixup.c index d271116c..0e517655 100644 --- a/ext4_utils/ext4fixup.c +++ b/ext4_utils/ext4fixup.c @@ -83,42 +83,6 @@ static int compute_new_inum(unsigned int old_inum) return (group * new_inodes_per_group) + offset + 1; } -/* Function to read the primary superblock */ -static void read_sb(int fd, struct ext4_super_block *sb) -{ - off64_t ret; - - ret = lseek64(fd, 1024, SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to superblock"); - - ret = read(fd, sb, sizeof(*sb)); - if (ret < 0) - critical_error_errno("failed to read superblock"); - if (ret != sizeof(*sb)) - critical_error("failed to read all of superblock"); -} - -/* Function to write a primary or backup superblock at a given offset */ -static void write_sb(int fd, unsigned long long offset, struct ext4_super_block *sb) -{ - off64_t ret; - - if (no_write) { - return; - } - - ret = lseek64(fd, offset, SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to superblock"); - - ret = write(fd, sb, sizeof(*sb)); - if (ret < 0) - critical_error_errno("failed to write superblock"); - if (ret != sizeof(*sb)) - critical_error("failed to write all of superblock"); -} - static int get_fs_fixup_state(int fd) { unsigned long long magic; @@ -191,64 +155,9 @@ static int set_fs_fixup_state(int fd, int state) /* we are done, so make the filesystem mountable again */ sb.s_desc_size &= ~1; } - write_sb(fd, 1024, &sb); - - return 0; -} - -static int read_ext(int fd) -{ - off64_t ret; - struct ext4_super_block sb; - - read_sb(fd, &sb); - - ext4_parse_sb(&sb); - - if (info.feat_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) { - critical_error("Filesystem needs recovery first, mount and unmount to do that\n"); - } - - /* Clear the low bit which is set while this tool is in progress. - * If the tool crashes, it will still be set when we restart. - * The low bit is set to make the filesystem unmountable while - * it is being fixed up. Also allow 0, which means the old ext2 - * size is in use. - */ - if (((sb.s_desc_size & ~1) != sizeof(struct ext2_group_desc)) && - ((sb.s_desc_size & ~1) != 0)) - critical_error("error: bg_desc_size != sizeof(struct ext2_group_desc)\n"); - - ret = lseek64(fd, info.len, SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to end of input image"); - - ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET); - if (ret < 0) - critical_error_errno("failed to seek to block group descriptors"); - - ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks); - if (ret < 0) - critical_error_errno("failed to read block group descriptors"); - if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks) - critical_error("failed to read all of block group descriptors"); - if (verbose) { - printf("Found filesystem with parameters:\n"); - printf(" Size: %llu\n", info.len); - printf(" Block size: %d\n", info.block_size); - printf(" Blocks per group: %d\n", info.blocks_per_group); - printf(" Inodes per group: %d\n", info.inodes_per_group); - printf(" Inode size: %d\n", info.inode_size); - printf(" Label: %s\n", info.label); - printf(" Blocks: %llu\n", aux_info.len_blocks); - printf(" Block groups: %d\n", aux_info.groups); - printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks); - printf(" Used %d/%d inodes and %d/%d blocks\n", - aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count, - aux_info.sb->s_inodes_count, - aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo, - aux_info.sb->s_blocks_count_lo); + if (!no_write) { + write_sb(fd, 1024, &sb); } return 0; @@ -320,21 +229,6 @@ static int write_block(int fd, unsigned long long block_num, void *block) return 0; } -static int bitmap_get_bit(u8 *bitmap, u32 bit) -{ - if (bitmap[bit / 8] & (1 << (bit % 8))) - return 1; - - return 0; -} - -static void bitmap_clear_bit(u8 *bitmap, u32 bit) -{ - bitmap[bit / 8] &= ~(1 << (bit % 8)); - - return; -} - static void check_inode_bitmap(int fd, unsigned int bg_num) { unsigned int inode_bitmap_block_num; @@ -425,7 +319,13 @@ static int update_superblocks_and_bg_desc(int fd, int state) sb.s_desc_size &= ~1; } - write_sb(fd, (unsigned long long)i * info.blocks_per_group * info.block_size + sb_offset, &sb); + if (!no_write) { + write_sb(fd, + (unsigned long long)i + * info.blocks_per_group * info.block_size + + sb_offset, + &sb); + } ret = lseek64(fd, ((unsigned long long)i * info.blocks_per_group * info.block_size) + (info.block_size * (aux_info.first_data_block + 1)), SEEK_SET); @@ -805,7 +705,21 @@ int ext4fixup_internal(char *fsdev, int v_flag, int n_flag, if (fd < 0) critical_error_errno("failed to open filesystem image"); - read_ext(fd); + read_ext(fd, verbose); + + if (info.feat_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) { + critical_error("Filesystem needs recovery first, mount and unmount to do that\n"); + } + + /* Clear the low bit which is set while this tool is in progress. + * If the tool crashes, it will still be set when we restart. + * The low bit is set to make the filesystem unmountable while + * it is being fixed up. Also allow 0, which means the old ext2 + * size is in use. + */ + if (((aux_info.sb->s_desc_size & ~1) != sizeof(struct ext2_group_desc)) && + ((aux_info.sb->s_desc_size & ~1) != 0)) + critical_error("error: bg_desc_size != sizeof(struct ext2_group_desc)\n"); if ((info.feat_incompat & EXT4_FEATURE_INCOMPAT_FILETYPE) == 0) { critical_error("Expected filesystem to have filetype flag set\n"); |