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