X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fe2image.c;h=0ee2b1e8338c8bc59e6c72b135d8b03963ef5223;hb=d0a4e54e6a987e03253e03b56a50d50dd37423bc;hp=a6c42fb0319c192e1062a91b4b536459eb583509;hpb=a6d8302b4873527798a77c1ba3106a04b71dfeac;p=tools%2Fe2fsprogs.git diff --git a/misc/e2image.c b/misc/e2image.c index a6c42fb..0ee2b1e 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -23,7 +23,9 @@ extern int optind; #endif #include #include +#ifdef HAVE_STDLIB_H #include +#endif #include #include #include @@ -47,7 +49,7 @@ char * device_name = NULL; static void usage(void) { - fprintf(stderr, _("Usage: %s [-rsI] device image_file\n"), + fprintf(stderr, _("Usage: %s [-rsI] device image_file\n"), program_name); exit (1); } @@ -68,10 +70,10 @@ static void write_header(int fd, struct ext2_image_hdr *hdr, int blocksize) exit(1); } memset(header_buf, 0, blocksize); - + if (hdr) memcpy(header_buf, hdr, sizeof(struct ext2_image_hdr)); - + actual = write(fd, header_buf, blocksize); if (actual < 0) { perror("write header"); @@ -100,7 +102,7 @@ static void write_image_file(ext2_filsys fs, int fd) com_err(program_name, retval, _("while writing superblock")); exit(1); } - + hdr.offset_inode = lseek(fd, 0, SEEK_CUR); retval = ext2fs_image_inode_write(fs, fd, (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0); @@ -108,7 +110,7 @@ static void write_image_file(ext2_filsys fs, int fd) com_err(program_name, retval, _("while writing inode table")); exit(1); } - + hdr.offset_blockmap = lseek(fd, 0, SEEK_CUR); retval = ext2fs_image_bitmap_write(fs, fd, 0); if (retval) { @@ -126,10 +128,10 @@ static void write_image_file(ext2_filsys fs, int fd) hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); - strncat(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)); + strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1); hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0; hdr.fs_blocksize = fs->blocksize; - + if (stat(device_name, &st) == 0) hdr.fs_device = st.st_rdev; @@ -163,12 +165,12 @@ struct process_block_struct { static ino_t stashed_ino = 0; static struct ext2_inode *stashed_inode; -static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), +static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), ext2_ino_t ino, blk_t *blocks) { int i; - + if ((ino != stashed_ino) || !stashed_inode) return EXT2_ET_CALLBACK_NOTHANDLED; @@ -177,7 +179,7 @@ static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), return 0; } -static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)), +static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)), ext2_ino_t ino) { if ((ino != stashed_ino) || !stashed_inode) @@ -188,7 +190,7 @@ static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)), return 0; } -static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)), +static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)), ext2_ino_t ino, struct ext2_inode *inode) { @@ -212,32 +214,32 @@ static void use_inode_shortcuts(ext2_filsys fs, int bool) } } -static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)), +static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t *block_nr, - e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), + e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), blk_t ref_block EXT2FS_ATTR((unused)), - int ref_offset EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), void *priv_data EXT2FS_ATTR((unused))) { struct process_block_struct *p; p = (struct process_block_struct *) priv_data; - ext2fs_mark_block_bitmap(meta_block_map, *block_nr); - if (scramble_block_map && p->is_dir && blockcnt >= 0) - ext2fs_mark_block_bitmap(scramble_block_map, *block_nr); + ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); + if (scramble_block_map && p->is_dir && blockcnt >= 0) + ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr); return 0; } -static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)), +static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t *block_nr, - e2_blkcnt_t blockcnt, + e2_blkcnt_t blockcnt, blk_t ref_block EXT2FS_ATTR((unused)), - int ref_offset EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), void *priv_data EXT2FS_ATTR((unused))) { if (blockcnt < 0) { - ext2fs_mark_block_bitmap(meta_block_map, *block_nr); + ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); } return 0; } @@ -246,18 +248,18 @@ static void mark_table_blocks(ext2_filsys fs) { blk_t first_block, b; unsigned int i,j; - + first_block = fs->super->s_first_data_block; /* * Mark primary superblock */ - ext2fs_mark_block_bitmap(meta_block_map, first_block); - + ext2fs_mark_block_bitmap2(meta_block_map, first_block); + /* * Mark the primary superblock descriptors */ for (j = 0; j < fs->desc_blocks; j++) { - ext2fs_mark_block_bitmap(meta_block_map, + ext2fs_mark_block_bitmap2(meta_block_map, ext2fs_descriptor_block_loc(fs, first_block, j)); } @@ -265,27 +267,27 @@ static void mark_table_blocks(ext2_filsys fs) /* * Mark the blocks used for the inode table */ - if (fs->group_desc[i].bg_inode_table) { - for (j = 0, b = fs->group_desc[i].bg_inode_table; + if (ext2fs_inode_table_loc(fs, i)) { + for (j = 0, b = ext2fs_inode_table_loc(fs, i); j < (unsigned) fs->inode_blocks_per_group; j++, b++) - ext2fs_mark_block_bitmap(meta_block_map, b); + ext2fs_mark_block_bitmap2(meta_block_map, b); } - + /* - * Mark block used for the block bitmap + * Mark block used for the block bitmap */ - if (fs->group_desc[i].bg_block_bitmap) { - ext2fs_mark_block_bitmap(meta_block_map, - fs->group_desc[i].bg_block_bitmap); + if (ext2fs_block_bitmap_loc(fs, i)) { + ext2fs_mark_block_bitmap2(meta_block_map, + ext2fs_block_bitmap_loc(fs, i)); } - + /* - * Mark block used for the inode bitmap + * Mark block used for the inode bitmap */ - if (fs->group_desc[i].bg_inode_bitmap) { - ext2fs_mark_block_bitmap(meta_block_map, - fs->group_desc[i].bg_inode_bitmap); + if (ext2fs_inode_bitmap_loc(fs, i)) { + ext2fs_mark_block_bitmap2(meta_block_map, + ext2fs_inode_bitmap_loc(fs, i)); } } } @@ -330,44 +332,52 @@ static void write_block(int fd, char *buf, int sparse_offset, err = 0; com_err(program_name, err, "error writing block %u", block); + exit(1); } } } int name_id[256]; +#define EXT4_MAX_REC_LEN ((1<<16)-1) + static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf) { char *p, *end, *cp; struct ext2_dir_entry_2 *dirent; - int rec_len, id, len; + unsigned int rec_len; + int id, len; end = buf + fs->blocksize; for (p = buf; p < end-8; p += rec_len) { dirent = (struct ext2_dir_entry_2 *) p; rec_len = dirent->rec_len; -#ifdef EXT2FS_ENABLE_SWAPFS - if (fs->flags & EXT2_FLAG_SWAP_BYTES) - rec_len = ext2fs_swab16(rec_len); +#ifdef WORDS_BIGENDIAN + rec_len = ext2fs_swab16(rec_len); #endif + if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0) + rec_len = fs->blocksize; + else + rec_len = (rec_len & 65532) | ((rec_len & 3) << 16); #if 0 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len); #endif if (rec_len < 8 || (rec_len % 4) || (p+rec_len > end)) { printf("Corrupt directory block %lu: " - "bad rec_len (%d)\n", (unsigned long) blk, + "bad rec_len (%d)\n", (unsigned long) blk, rec_len); rec_len = end - p; -#ifdef EXT2FS_ENABLE_SWAPFS - if (fs->flags & EXT2_FLAG_SWAP_BYTES) - dirent->rec_len = ext2fs_swab16(rec_len); + (void) ext2fs_set_rec_len(fs, rec_len, + (struct ext2_dir_entry *) dirent); +#ifdef WORDS_BIGENDIAN + dirent->rec_len = ext2fs_swab16(dirent->rec_len); #endif continue; } if (dirent->name_len + 8 > rec_len) { printf("Corrupt directory block %lu: " - "bad name_len (%d)\n", (unsigned long) blk, + "bad name_len (%d)\n", (unsigned long) blk, dirent->name_len); dirent->name_len = rec_len - 8; continue; @@ -411,16 +421,16 @@ static void output_meta_data_blocks(ext2_filsys fs, int fd) exit(1); } memset(zero_buf, 0, fs->blocksize); - for (blk = 0; blk < fs->super->s_blocks_count; blk++) { + for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) { if ((blk >= fs->super->s_first_data_block) && - ext2fs_test_block_bitmap(meta_block_map, blk)) { - retval = io_channel_read_blk(fs->io, blk, 1, buf); + ext2fs_test_block_bitmap2(meta_block_map, blk)) { + retval = io_channel_read_blk64(fs->io, blk, 1, buf); if (retval) { com_err(program_name, retval, "error reading block %u", blk); } - if (scramble_block_map && - ext2fs_test_block_bitmap(scramble_block_map, blk)) + if (scramble_block_map && + ext2fs_test_block_bitmap2(scramble_block_map, blk)) scramble_dir_block(fs, blk, buf); if ((fd != 1) && check_zero_block(buf, fs->blocksize)) goto sparse_write; @@ -440,7 +450,10 @@ static void output_meta_data_blocks(ext2_filsys fs, int fd) } } } - write_block(fd, zero_buf, sparse, 1, -1); + if (sparse) + write_block(fd, zero_buf, sparse-1, 1, -1); + free(zero_buf); + free(buf); } static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) @@ -451,7 +464,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) ext2_ino_t ino; errcode_t retval; char * block_buf; - + retval = ext2fs_allocate_block_bitmap(fs, "in-use block map", &meta_block_map); if (retval) { @@ -463,12 +476,12 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) retval = ext2fs_allocate_block_bitmap(fs, "scramble block map", &scramble_block_map); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "while allocating scramble block bitmap"); exit(1); } } - + mark_table_blocks(fs); retval = ext2fs_open_inode_scan(fs, 0, &scan); @@ -482,7 +495,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) com_err(program_name, 0, "Can't allocate block buffer"); exit(1); } - + use_inode_shortcuts(fs, 1); stashed_inode = &inode; while (1) { @@ -498,13 +511,13 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) break; if (!inode.i_links_count) continue; - if (inode.i_file_acl) { - ext2fs_mark_block_bitmap(meta_block_map, - inode.i_file_acl); + if (ext2fs_file_acl_block(&inode)) { + ext2fs_mark_block_bitmap2(meta_block_map, + ext2fs_file_acl_block(&inode)); } if (!ext2fs_inode_has_valid_blocks(&inode)) continue; - + stashed_ino = ino; pb.ino = ino; pb.is_dir = LINUX_S_ISDIR(inode.i_mode); @@ -512,8 +525,9 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) (LINUX_S_ISLNK(inode.i_mode) && ext2fs_inode_has_valid_blocks(&inode)) || ino == fs->super->s_journal_inum) { - retval = ext2fs_block_iterate2(fs, ino, 0, - block_buf, process_dir_block, &pb); + retval = ext2fs_block_iterate2(fs, ino, + BLOCK_FLAG_READ_ONLY, block_buf, + process_dir_block, &pb); if (retval) { com_err(program_name, retval, "while iterating over inode %u", @@ -521,11 +535,12 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) exit(1); } } else { - if (inode.i_block[EXT2_IND_BLOCK] || + if ((inode.i_flags & EXT4_EXTENTS_FL) || + inode.i_block[EXT2_IND_BLOCK] || inode.i_block[EXT2_DIND_BLOCK] || inode.i_block[EXT2_TIND_BLOCK]) { retval = ext2fs_block_iterate2(fs, - ino, 0, block_buf, + ino, BLOCK_FLAG_READ_ONLY, block_buf, process_file_block, &pb); if (retval) { com_err(program_name, retval, @@ -537,6 +552,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag) } use_inode_shortcuts(fs, 0); output_meta_data_blocks(fs, fd); + free(block_buf); } static void install_image(char *device, char *image_fn, int raw_flag) @@ -552,13 +568,14 @@ static void install_image(char *device, char *image_fn, int raw_flag) com_err(program_name, 0, "Raw images cannot be installed"); exit(1); } - + #ifdef CONFIG_TESTIO_DEBUG - io_ptr = test_io_manager; - test_io_backing_manager = unix_io_manager; -#else - io_ptr = unix_io_manager; + if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { + io_ptr = test_io_manager; + test_io_backing_manager = unix_io_manager; + } else #endif + io_ptr = unix_io_manager; retval = ext2fs_open (image_fn, open_flag, 0, 0, io_ptr, &fs); @@ -574,14 +591,17 @@ static void install_image(char *device, char *image_fn, int raw_flag) exit(1); } - +#ifdef HAVE_OPEN64 + fd = open64(image_fn, O_RDONLY); +#else fd = open(image_fn, O_RDONLY); +#endif if (fd < 0) { perror(image_fn); exit(1); } - retval = io_ptr->open(device, IO_FLAG_RW, &io); + retval = io_ptr->open(device, IO_FLAG_RW, &io); if (retval) { com_err(device, 0, "while opening device file"); exit(1);