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