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