Home | History | Annotate | Download | only in misc
      1 /*
      2  * e2image.c --- Program which writes an image file backing up
      3  * critical metadata for the filesystem.
      4  *
      5  * Copyright 2000, 2001 by Theodore Ts'o.
      6  *
      7  * %Begin-Header%
      8  * This file may be redistributed under the terms of the GNU Public
      9  * License.
     10  * %End-Header%
     11  */
     12 
     13 #define _LARGEFILE_SOURCE
     14 #define _LARGEFILE64_SOURCE
     15 
     16 #include <fcntl.h>
     17 #include <grp.h>
     18 #ifdef HAVE_GETOPT_H
     19 #include <getopt.h>
     20 #else
     21 extern char *optarg;
     22 extern int optind;
     23 #endif
     24 #include <pwd.h>
     25 #include <stdio.h>
     26 #ifdef HAVE_STDLIB_H
     27 #include <stdlib.h>
     28 #endif
     29 #include <string.h>
     30 #include <time.h>
     31 #include <unistd.h>
     32 #include <fcntl.h>
     33 #include <errno.h>
     34 #include <sys/stat.h>
     35 #include <sys/types.h>
     36 #include <assert.h>
     37 #include <signal.h>
     38 
     39 #include "ext2fs/ext2_fs.h"
     40 #include "ext2fs/ext2fs.h"
     41 #include "et/com_err.h"
     42 #include "uuid/uuid.h"
     43 #include "e2p/e2p.h"
     44 #include "ext2fs/e2image.h"
     45 #include "ext2fs/qcow2.h"
     46 
     47 #include "../version.h"
     48 #include "nls-enable.h"
     49 
     50 #define QCOW_OFLAG_COPIED     (1LL << 63)
     51 #define NO_BLK ((blk64_t) -1)
     52 
     53 /* Image types */
     54 #define E2IMAGE_RAW	1
     55 #define E2IMAGE_QCOW2	2
     56 
     57 /* Image flags */
     58 #define E2IMAGE_INSTALL_FLAG	1
     59 #define E2IMAGE_SCRAMBLE_FLAG	2
     60 #define E2IMAGE_IS_QCOW2_FLAG	4
     61 #define E2IMAGE_CHECK_ZERO_FLAG	8
     62 
     63 static const char * program_name = "e2image";
     64 static char * device_name = NULL;
     65 static char all_data;
     66 static char output_is_blk;
     67 static char nop_flag;
     68 /* writing to blk device: don't skip zeroed blocks */
     69 static blk64_t source_offset, dest_offset;
     70 static char move_mode;
     71 static char show_progress;
     72 static char *check_buf;
     73 static int skipped_blocks;
     74 
     75 static blk64_t align_offset(blk64_t offset, unsigned int n)
     76 {
     77 	return (offset + n - 1) & ~((blk64_t) n - 1);
     78 }
     79 
     80 static int get_bits_from_size(size_t size)
     81 {
     82 	int res = 0;
     83 
     84 	if (size == 0)
     85 		return -1;
     86 
     87 	while (size != 1) {
     88 		/* Not a power of two */
     89 		if (size & 1)
     90 			return -1;
     91 
     92 		size >>= 1;
     93 		res++;
     94 	}
     95 	return res;
     96 }
     97 
     98 static void usage(void)
     99 {
    100 	fprintf(stderr, _("Usage: %s [ -r|Q ] [ -fr ] device image-file\n"),
    101 		program_name);
    102 	fprintf(stderr, _("       %s -I device image-file\n"), program_name);
    103 	fprintf(stderr, _("       %s -ra  [  -cfnp  ] [ -o src_offset ] "
    104 			  "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
    105 		program_name);
    106 	exit (1);
    107 }
    108 
    109 static ext2_loff_t seek_relative(int fd, int offset)
    110 {
    111 	ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
    112 	if (ret < 0) {
    113 		perror("seek_relative");
    114 		exit(1);
    115 	}
    116 	return ret;
    117 }
    118 
    119 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
    120 {
    121 	ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
    122 	if (ret < 0) {
    123 		perror("seek_set");
    124 		exit(1);
    125 	}
    126 	return ret;
    127 }
    128 
    129 /*
    130  * Returns true if the block we are about to write is identical to
    131  * what is already on the disk.
    132  */
    133 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
    134 {
    135 	char *cp = cbuf;
    136 	int count = blocksize, ret;
    137 
    138 	if (cbuf == NULL)
    139 		return 0;
    140 
    141 	while (count > 0) {
    142 		ret = read(fd, cp, count);
    143 		if (ret < 0) {
    144 			perror("check_block");
    145 			exit(1);
    146 		}
    147 		count -= ret;
    148 		cp += ret;
    149 	}
    150 	ret = memcmp(buf, cbuf, blocksize);
    151 	seek_relative(fd, -blocksize);
    152 	return (ret == 0) ? 1 : 0;
    153 }
    154 
    155 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
    156 {
    157 	int count, free_buf = 0;
    158 	errcode_t err;
    159 
    160 	if (!blocksize)
    161 		return;
    162 
    163 	if (!buf) {
    164 		free_buf = 1;
    165 		err = ext2fs_get_arrayzero(1, blocksize, &buf);
    166 		if (err) {
    167 			com_err(program_name, err,
    168 				_("while allocating buffer"));
    169 			exit(1);
    170 		}
    171 	}
    172 	if (nop_flag) {
    173 		printf(_("Writing block %llu\n"), (unsigned long long) block);
    174 		if (fd != 1)
    175 			seek_relative(fd, blocksize);
    176 		return;
    177 	}
    178 	count = write(fd, buf, blocksize);
    179 	if (count != blocksize) {
    180 		if (count == -1)
    181 			err = errno;
    182 		else
    183 			err = 0;
    184 
    185 		if (block)
    186 			com_err(program_name, err,
    187 				_("error writing block %llu"), block);
    188 		else
    189 			com_err(program_name, err, _("error in write()"));
    190 
    191 		exit(1);
    192 	}
    193 	if (free_buf)
    194 		ext2fs_free_mem(&buf);
    195 }
    196 
    197 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
    198 {
    199 	char *header_buf;
    200 	int ret;
    201 
    202 	/* Sanity check */
    203 	if (hdr_size > wrt_size) {
    204 		fprintf(stderr, "%s",
    205 			_("Error: header size is bigger than wrt_size\n"));
    206 	}
    207 
    208 	ret = ext2fs_get_mem(wrt_size, &header_buf);
    209 	if (ret) {
    210 		fputs(_("Couldn't allocate header buffer\n"), stderr);
    211 		exit(1);
    212 	}
    213 
    214 	seek_set(fd, 0);
    215 	memset(header_buf, 0, wrt_size);
    216 
    217 	if (hdr)
    218 		memcpy(header_buf, hdr, hdr_size);
    219 
    220 	generic_write(fd, header_buf, wrt_size, NO_BLK);
    221 
    222 	ext2fs_free_mem(&header_buf);
    223 }
    224 
    225 static void write_image_file(ext2_filsys fs, int fd)
    226 {
    227 	struct ext2_image_hdr	hdr;
    228 	struct stat		st;
    229 	errcode_t		retval;
    230 
    231 	write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
    232 	memset(&hdr, 0, sizeof(struct ext2_image_hdr));
    233 
    234 	hdr.offset_super = seek_relative(fd, 0);
    235 	retval = ext2fs_image_super_write(fs, fd, 0);
    236 	if (retval) {
    237 		com_err(program_name, retval, "%s",
    238 			_("while writing superblock"));
    239 		exit(1);
    240 	}
    241 
    242 	hdr.offset_inode = seek_relative(fd, 0);
    243 	retval = ext2fs_image_inode_write(fs, fd,
    244 				  (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
    245 	if (retval) {
    246 		com_err(program_name, retval, "%s",
    247 			_("while writing inode table"));
    248 		exit(1);
    249 	}
    250 
    251 	hdr.offset_blockmap = seek_relative(fd, 0);
    252 	retval = ext2fs_image_bitmap_write(fs, fd, 0);
    253 	if (retval) {
    254 		com_err(program_name, retval, "%s",
    255 			_("while writing block bitmap"));
    256 		exit(1);
    257 	}
    258 
    259 	hdr.offset_inodemap = seek_relative(fd, 0);
    260 	retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
    261 	if (retval) {
    262 		com_err(program_name, retval, "%s",
    263 			_("while writing inode bitmap"));
    264 		exit(1);
    265 	}
    266 
    267 	hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
    268 	strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
    269 	gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
    270 	strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
    271 	hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
    272 	hdr.fs_blocksize = fs->blocksize;
    273 
    274 	if (stat(device_name, &st) == 0)
    275 		hdr.fs_device = st.st_rdev;
    276 
    277 	if (fstat(fd, &st) == 0) {
    278 		hdr.image_device = st.st_dev;
    279 		hdr.image_inode = st.st_ino;
    280 	}
    281 	memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
    282 
    283 	hdr.image_time = time(0);
    284 	write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
    285 }
    286 
    287 /*
    288  * These set of functions are used to write a RAW image file.
    289  */
    290 static ext2fs_block_bitmap meta_block_map;
    291 static ext2fs_block_bitmap scramble_block_map;	/* Directory blocks to be scrambled */
    292 static blk64_t meta_blocks_count;
    293 
    294 struct process_block_struct {
    295 	ext2_ino_t	ino;
    296 	int		is_dir;
    297 };
    298 
    299 /*
    300  * These subroutines short circuits ext2fs_get_blocks and
    301  * ext2fs_check_directory; we use them since we already have the inode
    302  * structure, so there's no point in letting the ext2fs library read
    303  * the inode again.
    304  */
    305 static ino_t stashed_ino = 0;
    306 static struct ext2_inode *stashed_inode;
    307 
    308 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
    309 				 ext2_ino_t ino,
    310 				 blk_t *blocks)
    311 {
    312 	int	i;
    313 
    314 	if ((ino != stashed_ino) || !stashed_inode)
    315 		return EXT2_ET_CALLBACK_NOTHANDLED;
    316 
    317 	for (i=0; i < EXT2_N_BLOCKS; i++)
    318 		blocks[i] = stashed_inode->i_block[i];
    319 	return 0;
    320 }
    321 
    322 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
    323 				      ext2_ino_t ino)
    324 {
    325 	if ((ino != stashed_ino) || !stashed_inode)
    326 		return EXT2_ET_CALLBACK_NOTHANDLED;
    327 
    328 	if (!LINUX_S_ISDIR(stashed_inode->i_mode))
    329 		return EXT2_ET_NO_DIRECTORY;
    330 	return 0;
    331 }
    332 
    333 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
    334 				 ext2_ino_t ino,
    335 				 struct ext2_inode *inode)
    336 {
    337 	if ((ino != stashed_ino) || !stashed_inode)
    338 		return EXT2_ET_CALLBACK_NOTHANDLED;
    339 	*inode = *stashed_inode;
    340 	return 0;
    341 }
    342 
    343 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
    344 {
    345 	if (use_shortcuts) {
    346 		fs->get_blocks = meta_get_blocks;
    347 		fs->check_directory = meta_check_directory;
    348 		fs->read_inode = meta_read_inode;
    349 		stashed_ino = 0;
    350 	} else {
    351 		fs->get_blocks = 0;
    352 		fs->check_directory = 0;
    353 		fs->read_inode = 0;
    354 	}
    355 }
    356 
    357 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
    358 			     blk64_t *block_nr,
    359 			     e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
    360 			     blk64_t ref_block EXT2FS_ATTR((unused)),
    361 			     int ref_offset EXT2FS_ATTR((unused)),
    362 			     void *priv_data EXT2FS_ATTR((unused)))
    363 {
    364 	struct process_block_struct *p;
    365 
    366 	p = (struct process_block_struct *) priv_data;
    367 
    368 	ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
    369 	meta_blocks_count++;
    370 	if (scramble_block_map && p->is_dir && blockcnt >= 0)
    371 		ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
    372 	return 0;
    373 }
    374 
    375 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
    376 			      blk64_t *block_nr,
    377 			      e2_blkcnt_t blockcnt,
    378 			      blk64_t ref_block EXT2FS_ATTR((unused)),
    379 			      int ref_offset EXT2FS_ATTR((unused)),
    380 			      void *priv_data EXT2FS_ATTR((unused)))
    381 {
    382 	if (blockcnt < 0 || all_data) {
    383 		ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
    384 		meta_blocks_count++;
    385 	}
    386 	return 0;
    387 }
    388 
    389 static void mark_table_blocks(ext2_filsys fs)
    390 {
    391 	blk64_t	first_block, b;
    392 	unsigned int	i,j;
    393 
    394 	first_block = fs->super->s_first_data_block;
    395 	/*
    396 	 * Mark primary superblock
    397 	 */
    398 	ext2fs_mark_block_bitmap2(meta_block_map, first_block);
    399 	meta_blocks_count++;
    400 
    401 	/*
    402 	 * Mark the primary superblock descriptors
    403 	 */
    404 	for (j = 0; j < fs->desc_blocks; j++) {
    405 		ext2fs_mark_block_bitmap2(meta_block_map,
    406 			 ext2fs_descriptor_block_loc2(fs, first_block, j));
    407 	}
    408 	meta_blocks_count += fs->desc_blocks;
    409 
    410 	for (i = 0; i < fs->group_desc_count; i++) {
    411 		/*
    412 		 * Mark the blocks used for the inode table
    413 		 */
    414 		if ((output_is_blk ||
    415 		     !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
    416 		    ext2fs_inode_table_loc(fs, i)) {
    417 			unsigned int end = (unsigned) fs->inode_blocks_per_group;
    418 			/* skip unused blocks */
    419 			if (!output_is_blk &&
    420 			    EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
    421 						       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
    422 				end -= (ext2fs_bg_itable_unused(fs, i) /
    423 					EXT2_INODES_PER_BLOCK(fs->super));
    424 			for (j = 0, b = ext2fs_inode_table_loc(fs, i);
    425 			     j < end;
    426 			     j++, b++) {
    427 				ext2fs_mark_block_bitmap2(meta_block_map, b);
    428 				meta_blocks_count++;
    429 			}
    430 		}
    431 
    432 		/*
    433 		 * Mark block used for the block bitmap
    434 		 */
    435 		if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
    436 		    ext2fs_block_bitmap_loc(fs, i)) {
    437 			ext2fs_mark_block_bitmap2(meta_block_map,
    438 				     ext2fs_block_bitmap_loc(fs, i));
    439 			meta_blocks_count++;
    440 		}
    441 
    442 		/*
    443 		 * Mark block used for the inode bitmap
    444 		 */
    445 		if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
    446 		    ext2fs_inode_bitmap_loc(fs, i)) {
    447 			ext2fs_mark_block_bitmap2(meta_block_map,
    448 				 ext2fs_inode_bitmap_loc(fs, i));
    449 			meta_blocks_count++;
    450 		}
    451 	}
    452 }
    453 
    454 /*
    455  * This function returns 1 if the specified block is all zeros
    456  */
    457 static int check_zero_block(char *buf, int blocksize)
    458 {
    459 	char	*cp = buf;
    460 	int	left = blocksize;
    461 
    462 	if (output_is_blk)
    463 		return 0;
    464 	while (left > 0) {
    465 		if (*cp++)
    466 			return 0;
    467 		left--;
    468 	}
    469 	return 1;
    470 }
    471 
    472 static int name_id[256];
    473 
    474 #define EXT4_MAX_REC_LEN		((1<<16)-1)
    475 
    476 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
    477 {
    478 	char *p, *end, *cp;
    479 	struct ext2_dir_entry_2 *dirent;
    480 	unsigned int rec_len;
    481 	int id, len;
    482 
    483 	end = buf + fs->blocksize;
    484 	for (p = buf; p < end-8; p += rec_len) {
    485 		dirent = (struct ext2_dir_entry_2 *) p;
    486 		rec_len = dirent->rec_len;
    487 #ifdef WORDS_BIGENDIAN
    488 		rec_len = ext2fs_swab16(rec_len);
    489 #endif
    490 		if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
    491 			rec_len = fs->blocksize;
    492 		else
    493 			rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
    494 #if 0
    495 		printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
    496 #endif
    497 		if (rec_len < 8 || (rec_len % 4) ||
    498 		    (p+rec_len > end)) {
    499 			printf(_("Corrupt directory block %llu: "
    500 				 "bad rec_len (%d)\n"),
    501 			       (unsigned long long) blk, rec_len);
    502 			rec_len = end - p;
    503 			(void) ext2fs_set_rec_len(fs, rec_len,
    504 					(struct ext2_dir_entry *) dirent);
    505 #ifdef WORDS_BIGENDIAN
    506 			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
    507 #endif
    508 			continue;
    509 		}
    510 		if (dirent->name_len + 8U > rec_len) {
    511 			printf(_("Corrupt directory block %llu: "
    512 				 "bad name_len (%d)\n"),
    513 			       (unsigned long long) blk, dirent->name_len);
    514 			dirent->name_len = rec_len - 8;
    515 			continue;
    516 		}
    517 		cp = p+8;
    518 		len = rec_len - dirent->name_len - 8;
    519 		if (len > 0)
    520 			memset(cp+dirent->name_len, 0, len);
    521 		if (dirent->name_len==1 && cp[0] == '.')
    522 			continue;
    523 		if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
    524 			continue;
    525 
    526 		memset(cp, 'A', dirent->name_len);
    527 		len = dirent->name_len;
    528 		id = name_id[len]++;
    529 		while ((len > 0) && (id > 0)) {
    530 			*cp += id % 26;
    531 			id = id / 26;
    532 			cp++;
    533 			len--;
    534 		}
    535 	}
    536 }
    537 
    538 static char got_sigint;
    539 
    540 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
    541 {
    542 	got_sigint = 1;
    543 	signal (SIGINT, SIG_DFL);
    544 }
    545 
    546 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
    547 					     ((float) (b)))) + 0.5))
    548 #define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d))
    549 
    550 static int print_progress(blk64_t num, blk64_t total)
    551 {
    552 	return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total,
    553 		      calc_percent(num, total));
    554 }
    555 
    556 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
    557 {
    558 	errcode_t	retval;
    559 	blk64_t		blk;
    560 	char		*buf, *zero_buf;
    561 	int		sparse = 0;
    562 	blk64_t		start = 0;
    563 	blk64_t		distance = 0;
    564 	blk64_t		end = ext2fs_blocks_count(fs->super);
    565 	time_t		last_update = 0;
    566 	time_t		start_time = 0;
    567 	blk64_t		total_written = 0;
    568 	int		bscount = 0;
    569 
    570 	retval = ext2fs_get_mem(fs->blocksize, &buf);
    571 	if (retval) {
    572 		com_err(program_name, retval, _("while allocating buffer"));
    573 		exit(1);
    574 	}
    575 	retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
    576 	if (retval) {
    577 		com_err(program_name, retval, _("while allocating buffer"));
    578 		exit(1);
    579 	}
    580 	if (show_progress) {
    581 		fprintf(stderr, _("Copying "));
    582 		bscount = print_progress(total_written, meta_blocks_count);
    583 		fflush(stderr);
    584 		last_update = time(NULL);
    585 		start_time = time(NULL);
    586 	}
    587 	/* when doing an in place move to the right, you can't start
    588 	   at the beginning or you will overwrite data, so instead
    589 	   divide the fs up into distance size chunks and write them
    590 	   in reverse. */
    591 	if (move_mode && dest_offset > source_offset) {
    592 		distance = (dest_offset - source_offset) / fs->blocksize;
    593 		if (distance < ext2fs_blocks_count(fs->super))
    594 			start = ext2fs_blocks_count(fs->super) - distance;
    595 	}
    596 	if (move_mode)
    597 		signal (SIGINT, sigint_handler);
    598 more_blocks:
    599 	if (distance)
    600 		seek_set(fd, (start * fs->blocksize) + dest_offset);
    601 	for (blk = start; blk < end; blk++) {
    602 		if (got_sigint) {
    603 			if (distance) {
    604 				/* moving to the right */
    605 				if (distance >= ext2fs_blocks_count(fs->super) ||
    606 				    start == ext2fs_blocks_count(fs->super) - distance)
    607 					kill (getpid(), SIGINT);
    608 			} else {
    609 				/* moving to the left */
    610 				if (blk < (source_offset - dest_offset) / fs->blocksize)
    611 					kill (getpid(), SIGINT);
    612 			}
    613 			if (show_progress)
    614 				fputc('\r', stderr);
    615 			fprintf(stderr,
    616 				_("Stopping now will destroy the filesystem, "
    617 				 "interrupt again if you are sure\n"));
    618 			if (show_progress) {
    619 				fprintf(stderr, _("Copying "));
    620 				bscount = print_progress(total_written,
    621 							 meta_blocks_count);
    622 				fflush(stderr);
    623 			}
    624 
    625 			got_sigint = 0;
    626 		}
    627 		if (show_progress && last_update != time(NULL)) {
    628 			time_t duration;
    629 			last_update = time(NULL);
    630 			while (bscount--)
    631 				fputc('\b', stderr);
    632 			bscount = print_progress(total_written,
    633 						 meta_blocks_count);
    634 			duration = time(NULL) - start_time;
    635 			if (duration > 5) {
    636 				time_t est = (duration * meta_blocks_count /
    637 					      total_written) - duration;
    638 				char buff[30];
    639 				strftime(buff, 30, "%T", gmtime(&est));
    640 				bscount += fprintf(stderr,
    641 						   _(" %s remaining at %.2f MB/s"),
    642 						   buff, calc_rate(total_written,
    643 								   fs->blocksize,
    644 								   duration));
    645 			}
    646 			fflush (stderr);
    647 		}
    648 		if ((blk >= fs->super->s_first_data_block) &&
    649 		    ext2fs_test_block_bitmap2(meta_block_map, blk)) {
    650 			retval = io_channel_read_blk64(fs->io, blk, 1, buf);
    651 			if (retval) {
    652 				com_err(program_name, retval,
    653 					_("error reading block %llu"), blk);
    654 			}
    655 			total_written++;
    656 			if (scramble_block_map &&
    657 			    ext2fs_test_block_bitmap2(scramble_block_map, blk))
    658 				scramble_dir_block(fs, blk, buf);
    659 			if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
    660 			    check_zero_block(buf, fs->blocksize))
    661 				goto sparse_write;
    662 			if (sparse)
    663 				seek_relative(fd, sparse);
    664 			sparse = 0;
    665 			if (check_block(fd, buf, check_buf, fs->blocksize)) {
    666 				seek_relative(fd, fs->blocksize);
    667 				skipped_blocks++;
    668 			} else
    669 				generic_write(fd, buf, fs->blocksize, blk);
    670 		} else {
    671 		sparse_write:
    672 			if (fd == 1) {
    673 				if (!nop_flag)
    674 					generic_write(fd, zero_buf,
    675 						      fs->blocksize, blk);
    676 				continue;
    677 			}
    678 			sparse += fs->blocksize;
    679 			if (sparse > 1024*1024) {
    680 				seek_relative(fd, 1024*1024);
    681 				sparse -= 1024*1024;
    682 			}
    683 		}
    684 	}
    685 	if (distance && start) {
    686 		if (start < distance) {
    687 			end = start;
    688 			start = 0;
    689 		} else {
    690 			end -= distance;
    691 			start -= distance;
    692 			if (end < distance) {
    693 				/* past overlap, do rest in one go */
    694 				end = start;
    695 				start = 0;
    696 			}
    697 		}
    698 		sparse = 0;
    699 		goto more_blocks;
    700 	}
    701 	signal (SIGINT, SIG_DFL);
    702 	if (show_progress) {
    703 		time_t duration = time(NULL) - start_time;
    704 		char buff[30];
    705 		while (bscount--)
    706 			fputc('\b', stderr);
    707 		strftime(buff, 30, "%T", gmtime(&duration));
    708 		fprintf(stderr, _("\b\b\b\b\b\b\b\bCopied %llu / %llu "
    709 			 "blocks (%llu%%) in %s at %.2f MB/s       \n"),
    710 		       total_written, meta_blocks_count,
    711 		       calc_percent(total_written, meta_blocks_count), buff,
    712 		       calc_rate(total_written, fs->blocksize, duration));
    713 	}
    714 #ifdef HAVE_FTRUNCATE64
    715 	if (sparse) {
    716 		ext2_loff_t offset;
    717 		if (distance)
    718 			offset = seek_set(fd,
    719 					  fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
    720 		else
    721 			offset = seek_relative(fd, sparse);
    722 
    723 		if (ftruncate64(fd, offset) < 0) {
    724 			seek_relative(fd, -1);
    725 			generic_write(fd, zero_buf, 1, NO_BLK);
    726 		}
    727 	}
    728 #else
    729 	if (sparse && !distance) {
    730 		seek_relative(fd, sparse-1);
    731 		generic_write(fd, zero_buf, 1, NO_BLK);
    732 	}
    733 #endif
    734 	ext2fs_free_mem(&zero_buf);
    735 	ext2fs_free_mem(&buf);
    736 }
    737 
    738 static void init_l1_table(struct ext2_qcow2_image *image)
    739 {
    740 	__u64 *l1_table;
    741 	errcode_t ret;
    742 
    743 	ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
    744 	if (ret) {
    745 		com_err(program_name, ret, _("while allocating l1 table"));
    746 		exit(1);
    747 	}
    748 
    749 	image->l1_table = l1_table;
    750 }
    751 
    752 static void init_l2_cache(struct ext2_qcow2_image *image)
    753 {
    754 	unsigned int count, i;
    755 	struct ext2_qcow2_l2_cache *cache;
    756 	struct ext2_qcow2_l2_table *table;
    757 	errcode_t ret;
    758 
    759 	ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
    760 				   &cache);
    761 	if (ret)
    762 		goto alloc_err;
    763 
    764 	count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
    765 		 image->l1_size;
    766 
    767 	cache->count = count;
    768 	cache->free = count;
    769 	cache->next_offset = image->l2_offset;
    770 
    771 	for (i = 0; i < count; i++) {
    772 		ret = ext2fs_get_arrayzero(1,
    773 				sizeof(struct ext2_qcow2_l2_table), &table);
    774 		if (ret)
    775 			goto alloc_err;
    776 
    777 		ret = ext2fs_get_arrayzero(image->l2_size,
    778 						   sizeof(__u64), &table->data);
    779 		if (ret)
    780 			goto alloc_err;
    781 
    782 		table->next = cache->free_head;
    783 		cache->free_head = table;
    784 	}
    785 
    786 	image->l2_cache = cache;
    787 	return;
    788 
    789 alloc_err:
    790 	com_err(program_name, ret, _("while allocating l2 cache"));
    791 	exit(1);
    792 }
    793 
    794 static void put_l2_cache(struct ext2_qcow2_image *image)
    795 {
    796 	struct ext2_qcow2_l2_cache *cache = image->l2_cache;
    797 	struct ext2_qcow2_l2_table *tmp, *table;
    798 
    799 	if (!cache)
    800 		return;
    801 
    802 	table = cache->free_head;
    803 	cache->free_head = NULL;
    804 again:
    805 	while (table) {
    806 		tmp = table;
    807 		table = table->next;
    808 		ext2fs_free_mem(&tmp->data);
    809 		ext2fs_free_mem(&tmp);
    810 	}
    811 
    812 	if (cache->free != cache->count) {
    813 		fprintf(stderr, _("Warning: There are still tables in the "
    814 				  "cache while putting the cache, data will "
    815 				  "be lost so the image may not be valid.\n"));
    816 		table = cache->used_head;
    817 		cache->used_head = NULL;
    818 		goto again;
    819 	}
    820 
    821 	ext2fs_free_mem(&cache);
    822 }
    823 
    824 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
    825 {
    826 	struct	ext2_qcow2_refcount	*ref;
    827 	blk64_t table_clusters;
    828 	errcode_t ret;
    829 
    830 	ref = &(img->refcount);
    831 
    832 	/*
    833 	 * One refcount block addresses 2048 clusters, one refcount table
    834 	 * addresses cluster/sizeof(__u64) refcount blocks, and we need
    835 	 * to address meta_blocks_count clusters + qcow2 metadata clusters
    836 	 * in the worst case.
    837 	 */
    838 	table_clusters = meta_blocks_count + (table_offset >>
    839 					      img->cluster_bits);
    840 	table_clusters >>= (img->cluster_bits + 6 - 1);
    841 	table_clusters = (table_clusters == 0) ? 1 : table_clusters;
    842 
    843 	ref->refcount_table_offset = table_offset;
    844 	ref->refcount_table_clusters = table_clusters;
    845 	ref->refcount_table_index = 0;
    846 	ref->refcount_block_index = 0;
    847 
    848 	/* Allocate refcount table */
    849 	ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
    850 				   img->cluster_size, &ref->refcount_table);
    851 	if (ret)
    852 		return ret;
    853 
    854 	/* Allocate refcount block */
    855 	ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
    856 	if (ret)
    857 		ext2fs_free_mem(&ref->refcount_table);
    858 
    859 	return ret;
    860 }
    861 
    862 static int initialize_qcow2_image(int fd, ext2_filsys fs,
    863 			    struct ext2_qcow2_image *image)
    864 {
    865 	struct ext2_qcow2_hdr *header;
    866 	blk64_t total_size, offset;
    867 	int shift, l2_bits, header_size, l1_size, ret;
    868 	int cluster_bits = get_bits_from_size(fs->blocksize);
    869 	struct ext2_super_block *sb = fs->super;
    870 
    871 	/* Allocate header */
    872 	ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
    873 	if (ret)
    874 		return ret;
    875 
    876 	total_size = ext2fs_blocks_count(sb) << cluster_bits;
    877 	image->cluster_size = fs->blocksize;
    878 	image->l2_size = 1 << (cluster_bits - 3);
    879 	image->cluster_bits = cluster_bits;
    880 	image->fd = fd;
    881 
    882 	header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
    883 	header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
    884 	header->size = ext2fs_cpu_to_be64(total_size);
    885 	header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
    886 
    887 	header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
    888 	offset = align_offset(header_size, image->cluster_size);
    889 
    890 	header->l1_table_offset = ext2fs_cpu_to_be64(offset);
    891 	image->l1_offset = offset;
    892 
    893 	l2_bits = cluster_bits - 3;
    894 	shift = cluster_bits + l2_bits;
    895 	l1_size = ((total_size + (1LL << shift) - 1) >> shift);
    896 	header->l1_size = ext2fs_cpu_to_be32(l1_size);
    897 	image->l1_size = l1_size;
    898 
    899 	/* Make space for L1 table */
    900 	offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
    901 
    902 	/* Initialize refcounting */
    903 	ret = init_refcount(image, offset);
    904 	if (ret) {
    905 		ext2fs_free_mem(&header);
    906 		return ret;
    907 	}
    908 	header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
    909 	header->refcount_table_clusters =
    910 		ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
    911 	offset += image->cluster_size;
    912 	offset += image->refcount.refcount_table_clusters <<
    913 		image->cluster_bits;
    914 
    915 	/* Make space for L2 tables */
    916 	image->l2_offset = offset;
    917 	offset += image->cluster_size;
    918 
    919 	/* Make space for first refcount block */
    920 	image->refcount.refcount_block_offset = offset;
    921 
    922 	image->hdr = header;
    923 	/* Initialize l1 and l2 tables */
    924 	init_l1_table(image);
    925 	init_l2_cache(image);
    926 
    927 	return 0;
    928 }
    929 
    930 static void free_qcow2_image(struct ext2_qcow2_image *img)
    931 {
    932 	if (!img)
    933 		return;
    934 
    935 	if (img->hdr)
    936 		ext2fs_free_mem(&img->hdr);
    937 
    938 	if (img->l1_table)
    939 		ext2fs_free_mem(&img->l1_table);
    940 
    941 	if (img->refcount.refcount_table)
    942 		ext2fs_free_mem(&img->refcount.refcount_table);
    943 	if (img->refcount.refcount_block)
    944 		ext2fs_free_mem(&img->refcount.refcount_block);
    945 
    946 	put_l2_cache(img);
    947 
    948 	ext2fs_free_mem(&img);
    949 }
    950 
    951 /**
    952  * Put table from used list (used_head) into free list (free_head).
    953  * l2_table is used to return pointer to the next used table (used_head).
    954  */
    955 static void put_used_table(struct ext2_qcow2_image *img,
    956 			  struct ext2_qcow2_l2_table **l2_table)
    957 {
    958 	struct ext2_qcow2_l2_cache *cache = img->l2_cache;
    959 	struct ext2_qcow2_l2_table *table;
    960 
    961 	table = cache->used_head;
    962 	cache->used_head = table->next;
    963 
    964 	assert(table);
    965 	if (!table->next)
    966 		cache->used_tail = NULL;
    967 
    968 	/* Clean the table for case we will need to use it again */
    969 	memset(table->data, 0, img->cluster_size);
    970 	table->next = cache->free_head;
    971 	cache->free_head = table;
    972 
    973 	cache->free++;
    974 
    975 	*l2_table = cache->used_head;
    976 }
    977 
    978 static void flush_l2_cache(struct ext2_qcow2_image *image)
    979 {
    980 	blk64_t seek = 0;
    981 	ext2_loff_t offset;
    982 	struct ext2_qcow2_l2_cache *cache = image->l2_cache;
    983 	struct ext2_qcow2_l2_table *table = cache->used_head;
    984 	int fd = image->fd;
    985 
    986 	/* Store current position */
    987 	offset = seek_relative(fd, 0);
    988 
    989 	assert(table);
    990 	while (cache->free < cache->count) {
    991 		if (seek != table->offset) {
    992 			seek_set(fd, table->offset);
    993 			seek = table->offset;
    994 		}
    995 
    996 		generic_write(fd, (char *)table->data, image->cluster_size,
    997 			      NO_BLK);
    998 		put_used_table(image, &table);
    999 		seek += image->cluster_size;
   1000 	}
   1001 
   1002 	/* Restore previous position */
   1003 	seek_set(fd, offset);
   1004 }
   1005 
   1006 /**
   1007  * Get first free table (from free_head) and put it into tail of used list
   1008  * (to used_tail).
   1009  * l2_table is used to return pointer to moved table.
   1010  * Returns 1 if the cache is full, 0 otherwise.
   1011  */
   1012 static void get_free_table(struct ext2_qcow2_image *image,
   1013 			  struct ext2_qcow2_l2_table **l2_table)
   1014 {
   1015 	struct ext2_qcow2_l2_table *table;
   1016 	struct ext2_qcow2_l2_cache *cache = image->l2_cache;
   1017 
   1018 	if (0 == cache->free)
   1019 		flush_l2_cache(image);
   1020 
   1021 	table = cache->free_head;
   1022 	assert(table);
   1023 	cache->free_head = table->next;
   1024 
   1025 	if (cache->used_tail)
   1026 		cache->used_tail->next = table;
   1027 	else
   1028 		/* First item in the used list */
   1029 		cache->used_head = table;
   1030 
   1031 	cache->used_tail = table;
   1032 	cache->free--;
   1033 
   1034 	*l2_table = table;
   1035 }
   1036 
   1037 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
   1038 		       blk64_t data, blk64_t next)
   1039 {
   1040 	struct ext2_qcow2_l2_cache *cache = img->l2_cache;
   1041 	struct ext2_qcow2_l2_table *table = cache->used_tail;
   1042 	blk64_t l1_index = blk / img->l2_size;
   1043 	blk64_t l2_index = blk & (img->l2_size - 1);
   1044 	int ret = 0;
   1045 
   1046 	/*
   1047 	 * Need to create new table if it does not exist,
   1048 	 * or if it is full
   1049 	 */
   1050 	if (!table || (table->l1_index != l1_index)) {
   1051 		get_free_table(img, &table);
   1052 		table->l1_index = l1_index;
   1053 		table->offset = cache->next_offset;
   1054 		cache->next_offset = next;
   1055 		img->l1_table[l1_index] =
   1056 			ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
   1057 		ret++;
   1058 	}
   1059 
   1060 	table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
   1061 	return ret;
   1062 }
   1063 
   1064 static int update_refcount(int fd, struct ext2_qcow2_image *img,
   1065 			   blk64_t offset, blk64_t rfblk_pos)
   1066 {
   1067 	struct	ext2_qcow2_refcount	*ref;
   1068 	__u32	table_index;
   1069 	int ret = 0;
   1070 
   1071 	ref = &(img->refcount);
   1072 	table_index = offset >> (2 * img->cluster_bits - 1);
   1073 
   1074 	/*
   1075 	 * Need to create new refcount block when the offset addresses
   1076 	 * another item in the refcount table
   1077 	 */
   1078 	if (table_index != ref->refcount_table_index) {
   1079 
   1080 		seek_set(fd, ref->refcount_block_offset);
   1081 
   1082 		generic_write(fd, (char *)ref->refcount_block,
   1083 			      img->cluster_size, NO_BLK);
   1084 		memset(ref->refcount_block, 0, img->cluster_size);
   1085 
   1086 		ref->refcount_table[ref->refcount_table_index] =
   1087 			ext2fs_cpu_to_be64(ref->refcount_block_offset);
   1088 		ref->refcount_block_offset = rfblk_pos;
   1089 		ref->refcount_block_index = 0;
   1090 		ref->refcount_table_index = table_index;
   1091 		ret++;
   1092 	}
   1093 
   1094 	/*
   1095 	 * We are relying on the fact that we are creating the qcow2
   1096 	 * image sequentially, hence we will always allocate refcount
   1097 	 * block items sequentialy.
   1098 	 */
   1099 	ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
   1100 	ref->refcount_block_index++;
   1101 	return ret;
   1102 }
   1103 
   1104 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
   1105 {
   1106 	struct	ext2_qcow2_refcount	*ref;
   1107 
   1108 	ref = &(img->refcount);
   1109 
   1110 	ref->refcount_table[ref->refcount_table_index] =
   1111 		ext2fs_cpu_to_be64(ref->refcount_block_offset);
   1112 	seek_set(fd, ref->refcount_table_offset);
   1113 	generic_write(fd, (char *)ref->refcount_table,
   1114 		ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
   1115 
   1116 	seek_set(fd, ref->refcount_block_offset);
   1117 	generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
   1118 		      NO_BLK);
   1119 	return 0;
   1120 }
   1121 
   1122 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
   1123 {
   1124 	errcode_t		retval;
   1125 	blk64_t			blk, offset, size, end;
   1126 	char			*buf;
   1127 	struct ext2_qcow2_image	*img;
   1128 	unsigned int		header_size;
   1129 
   1130 	/* allocate  struct ext2_qcow2_image */
   1131 	retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
   1132 	if (retval) {
   1133 		com_err(program_name, retval,
   1134 			_("while allocating ext2_qcow2_image"));
   1135 		exit(1);
   1136 	}
   1137 
   1138 	retval = initialize_qcow2_image(fd, fs, img);
   1139 	if (retval) {
   1140 		com_err(program_name, retval,
   1141 			_("while initializing ext2_qcow2_image"));
   1142 		exit(1);
   1143 	}
   1144 	header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
   1145 				   img->cluster_size);
   1146 	write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
   1147 
   1148 	/* Refcount all qcow2 related metadata up to refcount_block_offset */
   1149 	end = img->refcount.refcount_block_offset;
   1150 	seek_set(fd, end);
   1151 	blk = end + img->cluster_size;
   1152 	for (offset = 0; offset <= end; offset += img->cluster_size) {
   1153 		if (update_refcount(fd, img, offset, blk)) {
   1154 			blk += img->cluster_size;
   1155 			/*
   1156 			 * If we create new refcount block, we need to refcount
   1157 			 * it as well.
   1158 			 */
   1159 			end += img->cluster_size;
   1160 		}
   1161 	}
   1162 	seek_set(fd, offset);
   1163 
   1164 	retval = ext2fs_get_mem(fs->blocksize, &buf);
   1165 	if (retval) {
   1166 		com_err(program_name, retval, _("while allocating buffer"));
   1167 		exit(1);
   1168 	}
   1169 	/* Write qcow2 data blocks */
   1170 	for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
   1171 		if ((blk >= fs->super->s_first_data_block) &&
   1172 		    ext2fs_test_block_bitmap2(meta_block_map, blk)) {
   1173 			retval = io_channel_read_blk64(fs->io, blk, 1, buf);
   1174 			if (retval) {
   1175 				com_err(program_name, retval,
   1176 					_("error reading block %llu"), blk);
   1177 				continue;
   1178 			}
   1179 			if (scramble_block_map &&
   1180 			    ext2fs_test_block_bitmap2(scramble_block_map, blk))
   1181 				scramble_dir_block(fs, blk, buf);
   1182 			if (check_zero_block(buf, fs->blocksize))
   1183 				continue;
   1184 
   1185 			if (update_refcount(fd, img, offset, offset)) {
   1186 				/* Make space for another refcount block */
   1187 				offset += img->cluster_size;
   1188 				seek_set(fd, offset);
   1189 				/*
   1190 				 * We have created the new refcount block, this
   1191 				 * means that we need to refcount it as well.
   1192 				 * So the previous update_refcount refcounted
   1193 				 * the block itself and now we are going to
   1194 				 * create refcount for data. New refcount
   1195 				 * block should not be created!
   1196 				 */
   1197 				if (update_refcount(fd, img, offset, offset)) {
   1198 					fprintf(stderr, _("Programming error: "
   1199 						"multiple sequential refcount "
   1200 						"blocks created!\n"));
   1201 					exit(1);
   1202 				}
   1203 			}
   1204 
   1205 			generic_write(fd, buf, fs->blocksize, blk);
   1206 
   1207 			if (add_l2_item(img, blk, offset,
   1208 					offset + img->cluster_size)) {
   1209 				offset += img->cluster_size;
   1210 				if (update_refcount(fd, img, offset,
   1211 					offset + img->cluster_size)) {
   1212 					offset += img->cluster_size;
   1213 					if (update_refcount(fd, img, offset,
   1214 							    offset)) {
   1215 						fprintf(stderr,
   1216 			_("Programming error: multiple sequential refcount "
   1217 			  "blocks created!\n"));
   1218 						exit(1);
   1219 					}
   1220 				}
   1221 				offset += img->cluster_size;
   1222 				seek_set(fd, offset);
   1223 				continue;
   1224 			}
   1225 
   1226 			offset += img->cluster_size;
   1227 		}
   1228 	}
   1229 	update_refcount(fd, img, offset, offset);
   1230 	flush_l2_cache(img);
   1231 	sync_refcount(fd, img);
   1232 
   1233 	/* Write l1_table*/
   1234 	seek_set(fd, img->l1_offset);
   1235 	size = img->l1_size * sizeof(__u64);
   1236 	generic_write(fd, (char *)img->l1_table, size, NO_BLK);
   1237 
   1238 	ext2fs_free_mem(&buf);
   1239 	free_qcow2_image(img);
   1240 }
   1241 
   1242 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
   1243 {
   1244 	struct process_block_struct	pb;
   1245 	struct ext2_inode		inode;
   1246 	ext2_inode_scan			scan;
   1247 	ext2_ino_t			ino;
   1248 	errcode_t			retval;
   1249 	char *				block_buf;
   1250 
   1251 	meta_blocks_count = 0;
   1252 	retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
   1253 					      &meta_block_map);
   1254 	if (retval) {
   1255 		com_err(program_name, retval,
   1256 			_("while allocating block bitmap"));
   1257 		exit(1);
   1258 	}
   1259 
   1260 	if (flags & E2IMAGE_SCRAMBLE_FLAG) {
   1261 		retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
   1262 						      &scramble_block_map);
   1263 		if (retval) {
   1264 			com_err(program_name, retval,
   1265 				_("while allocating scramble block bitmap"));
   1266 			exit(1);
   1267 		}
   1268 	}
   1269 
   1270 	mark_table_blocks(fs);
   1271 	if (show_progress)
   1272 		printf(_("Scanning inodes...\n"));
   1273 
   1274 	retval = ext2fs_open_inode_scan(fs, 0, &scan);
   1275 	if (retval) {
   1276 		com_err(program_name, retval,"%s",
   1277 			_("while opening inode scan"));
   1278 		exit(1);
   1279 	}
   1280 
   1281 	retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
   1282 	if (retval) {
   1283 		com_err(program_name, 0, "%s",
   1284 			_("Can't allocate block buffer"));
   1285 		exit(1);
   1286 	}
   1287 
   1288 	use_inode_shortcuts(fs, 1);
   1289 	stashed_inode = &inode;
   1290 	while (1) {
   1291 		retval = ext2fs_get_next_inode(scan, &ino, &inode);
   1292 		if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
   1293 			continue;
   1294 		if (retval) {
   1295 			com_err(program_name, retval, "%s",
   1296 				_("while getting next inode"));
   1297 			exit(1);
   1298 		}
   1299 		if (ino == 0)
   1300 			break;
   1301 		if (!inode.i_links_count)
   1302 			continue;
   1303 		if (ext2fs_file_acl_block(fs, &inode)) {
   1304 			ext2fs_mark_block_bitmap2(meta_block_map,
   1305 					ext2fs_file_acl_block(fs, &inode));
   1306 			meta_blocks_count++;
   1307 		}
   1308 		if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
   1309 			continue;
   1310 
   1311 		stashed_ino = ino;
   1312 		pb.ino = ino;
   1313 		pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
   1314 		if (LINUX_S_ISDIR(inode.i_mode) ||
   1315 		    (LINUX_S_ISLNK(inode.i_mode) &&
   1316 		     ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
   1317 		    ino == fs->super->s_journal_inum) {
   1318 			retval = ext2fs_block_iterate3(fs, ino,
   1319 					BLOCK_FLAG_READ_ONLY, block_buf,
   1320 					process_dir_block, &pb);
   1321 			if (retval) {
   1322 				com_err(program_name, retval,
   1323 					_("while iterating over inode %u"),
   1324 					ino);
   1325 				exit(1);
   1326 			}
   1327 		} else {
   1328 			if ((inode.i_flags & EXT4_EXTENTS_FL) ||
   1329 			    inode.i_block[EXT2_IND_BLOCK] ||
   1330 			    inode.i_block[EXT2_DIND_BLOCK] ||
   1331 			    inode.i_block[EXT2_TIND_BLOCK] || all_data) {
   1332 				retval = ext2fs_block_iterate3(fs,
   1333 				       ino, BLOCK_FLAG_READ_ONLY, block_buf,
   1334 				       process_file_block, &pb);
   1335 				if (retval) {
   1336 					com_err(program_name, retval,
   1337 					_("while iterating over inode %u"), ino);
   1338 					exit(1);
   1339 				}
   1340 			}
   1341 		}
   1342 	}
   1343 	use_inode_shortcuts(fs, 0);
   1344 
   1345 	if (type & E2IMAGE_QCOW2)
   1346 		output_qcow2_meta_data_blocks(fs, fd);
   1347 	else
   1348 		output_meta_data_blocks(fs, fd, flags);
   1349 
   1350 	ext2fs_free_mem(&block_buf);
   1351 	ext2fs_close_inode_scan(scan);
   1352 	ext2fs_free_block_bitmap(meta_block_map);
   1353 	if (type & E2IMAGE_SCRAMBLE_FLAG)
   1354 		ext2fs_free_block_bitmap(scramble_block_map);
   1355 }
   1356 
   1357 static void install_image(char *device, char *image_fn, int type)
   1358 {
   1359 	errcode_t retval;
   1360 	ext2_filsys fs;
   1361 	int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS;
   1362 	int fd = 0;
   1363 	io_manager	io_ptr;
   1364 	io_channel	io;
   1365 
   1366 	if (type) {
   1367 		com_err(program_name, 0, _("Raw and qcow2 images cannot"
   1368 					   "be installed"));
   1369 		exit(1);
   1370 	}
   1371 
   1372 #ifdef CONFIG_TESTIO_DEBUG
   1373 	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
   1374 		io_ptr = test_io_manager;
   1375 		test_io_backing_manager = unix_io_manager;
   1376 	} else
   1377 #endif
   1378 		io_ptr = unix_io_manager;
   1379 
   1380 	retval = ext2fs_open (image_fn, open_flag, 0, 0,
   1381 			      io_ptr, &fs);
   1382         if (retval) {
   1383 		com_err (program_name, retval, _("while trying to open %s"),
   1384 			 image_fn);
   1385 		exit(1);
   1386 	}
   1387 
   1388 	retval = ext2fs_read_bitmaps (fs);
   1389 	if (retval) {
   1390 		com_err(program_name, retval, _("error reading bitmaps"));
   1391 		exit(1);
   1392 	}
   1393 
   1394 	fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
   1395 	if (fd < 0) {
   1396 		perror(image_fn);
   1397 		exit(1);
   1398 	}
   1399 
   1400 	retval = io_ptr->open(device, IO_FLAG_RW, &io);
   1401 	if (retval) {
   1402 		com_err(device, 0, _("while opening device file"));
   1403 		exit(1);
   1404 	}
   1405 
   1406 	ext2fs_rewrite_to_io(fs, io);
   1407 
   1408 	seek_set(fd, fs->image_header->offset_inode);
   1409 
   1410 	retval = ext2fs_image_inode_read(fs, fd, 0);
   1411 	if (retval) {
   1412 		com_err(image_fn, 0, "while restoring the image table");
   1413 		exit(1);
   1414 	}
   1415 
   1416 	close(fd);
   1417 	ext2fs_close (fs);
   1418 }
   1419 
   1420 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
   1421 {
   1422 
   1423 	*fd = ext2fs_open_file(name, O_RDONLY, 0600);
   1424 	if (*fd < 0)
   1425 		return NULL;
   1426 
   1427 	return qcow2_read_header(*fd);
   1428 }
   1429 
   1430 int main (int argc, char ** argv)
   1431 {
   1432 	int c;
   1433 	errcode_t retval;
   1434 	ext2_filsys fs;
   1435 	char *image_fn, offset_opt[64];
   1436 	struct ext2_qcow2_hdr *header = NULL;
   1437 	int open_flag = EXT2_FLAG_64BITS;
   1438 	int img_type = 0;
   1439 	int flags = 0;
   1440 	int mount_flags = 0;
   1441 	int qcow2_fd = 0;
   1442 	int fd = 0;
   1443 	int ret = 0;
   1444 	int ignore_rw_mount = 0;
   1445 	int check = 0;
   1446 	struct stat st;
   1447 
   1448 #ifdef ENABLE_NLS
   1449 	setlocale(LC_MESSAGES, "");
   1450 	setlocale(LC_CTYPE, "");
   1451 	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
   1452 	textdomain(NLS_CAT_NAME);
   1453 	set_com_err_gettext(gettext);
   1454 #endif
   1455 	fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
   1456 		 E2FSPROGS_DATE);
   1457 	if (argc && *argv)
   1458 		program_name = *argv;
   1459 	add_error_table(&et_ext2_error_table);
   1460 	while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
   1461 		switch (c) {
   1462 		case 'I':
   1463 			flags |= E2IMAGE_INSTALL_FLAG;
   1464 			break;
   1465 		case 'Q':
   1466 			if (img_type)
   1467 				usage();
   1468 			img_type |= E2IMAGE_QCOW2;
   1469 			break;
   1470 		case 'r':
   1471 			if (img_type)
   1472 				usage();
   1473 			img_type |= E2IMAGE_RAW;
   1474 			break;
   1475 		case 's':
   1476 			flags |= E2IMAGE_SCRAMBLE_FLAG;
   1477 			break;
   1478 		case 'a':
   1479 			all_data = 1;
   1480 			break;
   1481 		case 'f':
   1482 			ignore_rw_mount = 1;
   1483 			break;
   1484 		case 'n':
   1485 			nop_flag = 1;
   1486 			break;
   1487 		case 'o':
   1488 			source_offset = strtoull(optarg, NULL, 0);
   1489 			break;
   1490 		case 'O':
   1491 			dest_offset = strtoull(optarg, NULL, 0);
   1492 			break;
   1493 		case 'p':
   1494 			show_progress = 1;
   1495 			break;
   1496 		case 'c':
   1497 			check = 1;
   1498 			break;
   1499 		default:
   1500 			usage();
   1501 		}
   1502 	if (optind == argc - 1 &&
   1503 	    (source_offset || dest_offset))
   1504 		    move_mode = 1;
   1505 	else if (optind != argc - 2 )
   1506 		usage();
   1507 
   1508 	if (all_data && !img_type) {
   1509 		com_err(program_name, 0, _("-a option can only be used "
   1510 					   "with raw or QCOW2 images."));
   1511 		exit(1);
   1512 	}
   1513 	if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
   1514 		com_err(program_name, 0,
   1515 			_("Offsets are only allowed with raw images."));
   1516 		exit(1);
   1517 	}
   1518 	if (move_mode && img_type != E2IMAGE_RAW) {
   1519 		com_err(program_name, 0,
   1520 			_("Move mode is only allowed with raw images."));
   1521 		exit(1);
   1522 	}
   1523 	if (move_mode && !all_data) {
   1524 		com_err(program_name, 0,
   1525 			_("Move mode requires all data mode."));
   1526 		exit(1);
   1527 	}
   1528 	device_name = argv[optind];
   1529 	if (move_mode)
   1530 		image_fn = device_name;
   1531 	else image_fn = argv[optind+1];
   1532 
   1533 	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
   1534 	if (retval) {
   1535 		com_err(program_name, retval, _("checking if mounted"));
   1536 		exit(1);
   1537 	}
   1538 
   1539 	if (img_type && !ignore_rw_mount &&
   1540 	    (mount_flags & EXT2_MF_MOUNTED) &&
   1541 	   !(mount_flags & EXT2_MF_READONLY)) {
   1542 		fprintf(stderr, _("\nRunning e2image on a R/W mounted "
   1543 			"filesystem can result in an\n"
   1544 			"inconsistent image which will not be useful "
   1545 			"for debugging purposes.\n"
   1546 			"Use -f option if you really want to do that.\n"));
   1547 		exit(1);
   1548 	}
   1549 
   1550 	if (flags & E2IMAGE_INSTALL_FLAG) {
   1551 		install_image(device_name, image_fn, img_type);
   1552 		exit (0);
   1553 	}
   1554 
   1555 	if (img_type & E2IMAGE_RAW) {
   1556 		header = check_qcow2_image(&qcow2_fd, device_name);
   1557 		if (header) {
   1558 			flags |= E2IMAGE_IS_QCOW2_FLAG;
   1559 			goto skip_device;
   1560 		}
   1561 	}
   1562 	sprintf(offset_opt, "offset=%llu", source_offset);
   1563 	retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
   1564 			      unix_io_manager, &fs);
   1565         if (retval) {
   1566 		com_err (program_name, retval, _("while trying to open %s"),
   1567 			 device_name);
   1568 		fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
   1569 		exit(1);
   1570 	}
   1571 
   1572 skip_device:
   1573 	if (strcmp(image_fn, "-") == 0)
   1574 		fd = 1;
   1575 	else {
   1576 		int o_flags = O_CREAT|O_RDWR;
   1577 
   1578 		if (img_type != E2IMAGE_RAW)
   1579 			o_flags |= O_TRUNC;
   1580 		if (access(image_fn, F_OK) != 0)
   1581 			flags |= E2IMAGE_CHECK_ZERO_FLAG;
   1582 		fd = ext2fs_open_file(image_fn, o_flags, 0600);
   1583 		if (fd < 0) {
   1584 			com_err(program_name, errno,
   1585 				_("while trying to open %s"), image_fn);
   1586 			exit(1);
   1587 		}
   1588 	}
   1589 	if (dest_offset)
   1590 		seek_set(fd, dest_offset);
   1591 
   1592 	if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
   1593 		com_err(program_name, 0, _("QCOW2 image can not be written to "
   1594 					   "the stdout!\n"));
   1595 		exit(1);
   1596 	}
   1597 	if (fd != 1) {
   1598 		if (fstat(fd, &st)) {
   1599 			com_err(program_name, 0, "Can not stat output\n");
   1600 			exit(1);
   1601 		}
   1602 		if (S_ISBLK(st.st_mode))
   1603 			output_is_blk = 1;
   1604 	}
   1605 	if (flags & E2IMAGE_IS_QCOW2_FLAG) {
   1606 		ret = qcow2_write_raw_image(qcow2_fd, fd, header);
   1607 		if (ret) {
   1608 			if (ret == -QCOW_COMPRESSED)
   1609 				fprintf(stderr, _("Image (%s) is compressed\n"),
   1610 					image_fn);
   1611 			if (ret == -QCOW_ENCRYPTED)
   1612 				fprintf(stderr, _("Image (%s) is encrypted\n"),
   1613 					image_fn);
   1614 			com_err(program_name, ret,
   1615 				_("while trying to convert qcow2 image"
   1616 				  " (%s) into raw image (%s)"),
   1617 				device_name, image_fn);
   1618 		}
   1619 		goto out;
   1620 	}
   1621 
   1622 	if (check) {
   1623 		if (img_type != E2IMAGE_RAW) {
   1624 			fprintf(stderr, _("The -c option only supported "
   1625 					  "in raw mode\n"));
   1626 			exit(1);
   1627 		}
   1628 		if (fd == 1) {
   1629 			fprintf(stderr, _("The -c option is not supported "
   1630 					  "when writing to stdout\n"));
   1631 			exit(1);
   1632 		}
   1633 		retval = ext2fs_get_mem(fs->blocksize, &check_buf);
   1634 		if (retval) {
   1635 			com_err(program_name, retval,
   1636 				_("while allocating check_buf"));
   1637 			exit(1);
   1638 		}
   1639 	}
   1640 	if (show_progress && (img_type != E2IMAGE_RAW)) {
   1641 		fprintf(stderr, _("The -p option only supported "
   1642 				  "in raw mode\n"));
   1643 		exit(1);
   1644 	}
   1645 	if (img_type)
   1646 		write_raw_image_file(fs, fd, img_type, flags);
   1647 	else
   1648 		write_image_file(fs, fd);
   1649 
   1650 	ext2fs_close (fs);
   1651 	if (check)
   1652 		printf(_("%d blocks already contained the data to be copied.\n"),
   1653 		       skipped_blocks);
   1654 
   1655 out:
   1656 	if (header)
   1657 		free(header);
   1658 	if (qcow2_fd)
   1659 		close(qcow2_fd);
   1660 	remove_error_table(&et_ext2_error_table);
   1661 	return ret;
   1662 }
   1663