static int get_target_device_size(int fd, const char *blk_device, uint64_t *device_size) { int data_device; struct ext4_super_block sb; struct fs_info info; info.len = 0; /* Only len is set to 0 to ask the device for real size. */ data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC); if (data_device < 0) { write_console(fd, "Error opening block device (%s)\n", strerror(errno)); return -1; } if (lseek64(data_device, 1024, SEEK_SET) < 0) { write_console(fd, "Error seeking to superblock\n"); adb_close(data_device); return -1; } if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { write_console(fd, "Error reading superblock\n"); adb_close(data_device); return -1; } ext4_parse_sb(&sb, &info); *device_size = info.len; adb_close(data_device); return 0; }
int ext4_part_size(const char *blk_device, uint64_t *device_size) { int data_device; struct ext4_super_block sb; data_device = open(blk_device, O_RDONLY); if (data_device < 0) { fprintf(stderr, "Error opening block device (%s)", strerror(errno)); return -1; } if (1024 != lseek64(data_device, 1024, SEEK_SET)) { close(data_device); fprintf(stderr, "Error seeking to superblock in %s\n", blk_device); return -1; } if (read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { close(data_device); fprintf(stderr, "Error reading superblock in %s\n", blk_device); return -1; } ext4_parse_sb(&sb, &info); *device_size = info.len; close(data_device); return 0; }
static int read_ext(int fd) { off64_t ret; struct ext4_super_block sb; unsigned int i; 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; }
void ext4_parse_sb_info(struct ext4_super_block *sb) { if (sb->s_magic != EXT4_SUPER_MAGIC) error("superblock magic incorrect"); if ((sb->s_state & EXT4_VALID_FS) != EXT4_VALID_FS) error("filesystem state not valid"); ext4_parse_sb(sb, &info); ext4_create_fs_aux_info(); memcpy(aux_info.sb, sb, sizeof(*sb)); if (aux_info.first_data_block != sb->s_first_data_block) critical_error("first data block does not match"); }
/* reads the ext4 superblock and returns the size of the file system in `offset' */ static int get_ext4_size(fec_handle *f, uint64_t *offset) { check(f); check(f->size > 1024 + sizeof(ext4_super_block)); check(offset); ext4_super_block sb; if (fec_pread(f, &sb, sizeof(sb), 1024) != sizeof(sb)) { error("failed to read superblock: %s", strerror(errno)); return -1; } fs_info info; info.len = 0; /* only len is set to 0 to ask the device for real size. */ if (ext4_parse_sb(&sb, &info) != 0) { errno = EINVAL; return -1; } *offset = info.len; return 0; }