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