Whamcloud - gitweb
3f91f64f9d9cb9417fc2d598d721bc070787bf31
[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 <fcntl.h>
17 #include <grp.h>
18 #ifdef HAVE_GETOPT_H
19 #include <getopt.h>
20 #else
21 extern char *optarg;
22 extern int optind;
23 #endif
24 #include <pwd.h>
25 #include <stdio.h>
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #include <string.h>
30 #include <time.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <assert.h>
37
38 #include "ext2fs/ext2_fs.h"
39 #include "ext2fs/ext2fs.h"
40 #include "et/com_err.h"
41 #include "uuid/uuid.h"
42 #include "e2p/e2p.h"
43 #include "ext2fs/e2image.h"
44 #include "ext2fs/qcow2.h"
45
46 #include "../version.h"
47 #include "nls-enable.h"
48
49 #define QCOW_OFLAG_COPIED     (1LL << 63)
50
51
52 const char * program_name = "e2image";
53 char * device_name = NULL;
54
55 static void lseek_error_and_exit(int errnum)
56 {
57         perror("seek");
58         exit(1);
59 }
60
61 static blk64_t align_offset(blk64_t offset, int n)
62 {
63         return (offset + n - 1) & ~(n - 1);
64 }
65
66 static int get_bits_from_size(size_t size)
67 {
68         int res = 0;
69
70         if (size == 0)
71                 return -1;
72
73         while (size != 1) {
74                 /* Not a power of two */
75                 if (size & 1)
76                         return -1;
77
78                 size >>= 1;
79                 res++;
80         }
81         return res;
82 }
83
84 static void usage(void)
85 {
86         fprintf(stderr, _("Usage: %s [-rsIQ] device image_file\n"),
87                 program_name);
88         exit (1);
89 }
90
91 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
92 {
93         int count, free_buf = 0;
94         errcode_t err;
95         blk64_t offset;
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 actual, 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         unsigned int i;
716
717         if (!img)
718                 return;
719
720         if (img->hdr)
721                 ext2fs_free_mem(&img->hdr);
722
723         if (img->l1_table)
724                 ext2fs_free_mem(&img->l1_table);
725
726         if (img->refcount.refcount_table)
727                 ext2fs_free_mem(&img->refcount.refcount_table);
728         if (img->refcount.refcount_block)
729                 ext2fs_free_mem(&img->refcount.refcount_block);
730
731         put_l2_cache(img);
732
733         ext2fs_free_mem(&img);
734 }
735
736 /**
737  * Put table from used list (used_head) into free list (free_head).
738  * l2_table is used to return pointer to the next used table (used_head).
739  */
740 static void put_used_table(struct ext2_qcow2_image *img,
741                           struct ext2_qcow2_l2_table **l2_table)
742 {
743         struct ext2_qcow2_l2_cache *cache = img->l2_cache;
744         struct ext2_qcow2_l2_table *table;
745
746         table = cache->used_head;
747         cache->used_head = table->next;
748
749         assert(table);
750         if (!table->next)
751                 cache->used_tail = NULL;
752
753         /* Clean the table for case we will need to use it again */
754         memset(table->data, 0, img->cluster_size);
755         table->next = cache->free_head;
756         cache->free_head = table;
757
758         cache->free++;
759
760         *l2_table = cache->used_head;
761 }
762
763 static void flush_l2_cache(struct ext2_qcow2_image *image)
764 {
765         blk64_t offset, seek = 0;
766         struct ext2_qcow2_l2_cache *cache = image->l2_cache;
767         struct ext2_qcow2_l2_table *table = cache->used_head;
768         int fd = image->fd;
769
770         /* Store current position */
771         if ((offset = ext2fs_llseek(fd, 0, SEEK_CUR)) < 0)
772                 lseek_error_and_exit(errno);
773
774         assert(table);
775         while (cache->free < cache->count) {
776                 if (seek != table->offset) {
777                         if (ext2fs_llseek(fd, table->offset, SEEK_SET) < 0)
778                                 lseek_error_and_exit(errno);
779                         seek = table->offset;
780                 }
781
782                 generic_write(fd, (char *)table->data, image->cluster_size , 0);
783                 put_used_table(image, &table);
784                 seek += image->cluster_size;
785         }
786
787         /* Restore previous position */
788         if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
789                 lseek_error_and_exit(errno);
790 }
791
792 /**
793  * Get first free table (from free_head) and put it into tail of used list
794  * (to used_tail).
795  * l2_table is used to return pointer to moved table.
796  * Returns 1 if the cache is full, 0 otherwise.
797  */
798 static void get_free_table(struct ext2_qcow2_image *image,
799                           struct ext2_qcow2_l2_table **l2_table)
800 {
801         struct ext2_qcow2_l2_table *table;
802         struct ext2_qcow2_l2_cache *cache = image->l2_cache;
803
804         if (0 == cache->free)
805                 flush_l2_cache(image);
806
807         table = cache->free_head;
808         assert(table);
809         cache->free_head = table->next;
810
811         if (cache->used_tail)
812                 cache->used_tail->next = table;
813         else
814                 /* First item in the used list */
815                 cache->used_head = table;
816
817         cache->used_tail = table;
818         cache->free--;
819
820         *l2_table = table;
821 }
822
823 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
824                        blk64_t data, blk64_t next)
825 {
826         struct ext2_qcow2_l2_cache *cache = img->l2_cache;
827         struct ext2_qcow2_l2_table *table = cache->used_tail;
828         blk64_t l1_index = blk / img->l2_size;
829         blk64_t l2_index = blk & (img->l2_size - 1);
830         int ret = 0;
831
832         /*
833          * Need to create new table if it does not exist,
834          * or if it is full
835          */
836         if (!table || (table->l1_index != l1_index)) {
837                 get_free_table(img, &table);
838                 table->l1_index = l1_index;
839                 table->offset = cache->next_offset;
840                 cache->next_offset = next;
841                 img->l1_table[l1_index] =
842                         ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
843                 ret++;
844         }
845
846         table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
847         return ret;
848 }
849
850 static int update_refcount(int fd, struct ext2_qcow2_image *img,
851                            blk64_t offset, blk64_t rfblk_pos)
852 {
853         struct  ext2_qcow2_refcount     *ref;
854         __u32   table_index;
855         int ret = 0;
856
857         ref = &(img->refcount);
858         table_index = offset >> (2 * img->cluster_bits - 1);
859
860         /*
861          * Need to create new refcount block when the offset addresses
862          * another item in the refcount table
863          */
864         if (table_index != ref->refcount_table_index) {
865
866                 if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0)
867                         lseek_error_and_exit(errno);
868
869                 generic_write(fd, (char *)ref->refcount_block,
870                               img->cluster_size, 0);
871                 memset(ref->refcount_block, 0, img->cluster_size);
872
873                 ref->refcount_table[ref->refcount_table_index] =
874                         ext2fs_cpu_to_be64(ref->refcount_block_offset);
875                 ref->refcount_block_offset = rfblk_pos;
876                 ref->refcount_block_index = 0;
877                 ref->refcount_table_index = table_index;
878                 ret++;
879         }
880
881         /*
882          * We are relying on the fact that we are creating the qcow2
883          * image sequentially, hence we will always allocate refcount
884          * block items sequentialy.
885          */
886         ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
887         ref->refcount_block_index++;
888         return ret;
889 }
890
891 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
892 {
893         struct  ext2_qcow2_refcount     *ref;
894
895         ref = &(img->refcount);
896
897         ref->refcount_table[ref->refcount_table_index] =
898                 ext2fs_cpu_to_be64(ref->refcount_block_offset);
899         if (ext2fs_llseek(fd, ref->refcount_table_offset, SEEK_SET) < 0)
900                 lseek_error_and_exit(errno);
901         generic_write(fd, (char *)ref->refcount_table,
902                 ref->refcount_table_clusters << img->cluster_bits, 0);
903
904         if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0)
905                 lseek_error_and_exit(errno);
906         generic_write(fd, (char *)ref->refcount_block, img->cluster_size, 0);
907         return 0;
908 }
909
910 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
911 {
912         errcode_t               retval;
913         blk64_t                 blk, datablk, offset, size, actual, end;
914         char                    *buf;
915         int                     sparse = 0;
916         struct ext2_qcow2_image *img;
917         unsigned int            header_size, i;
918         blk64_t                 l1_index, l2_offset, l2_index;
919         char                    *buffer;
920         __u64                   *l2_table;
921
922         /* allocate  struct ext2_qcow2_image */
923         retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
924         if (retval) {
925                 com_err(program_name, retval,
926                         "while allocating ext2_qcow2_image");
927                 exit(1);
928         }
929
930         retval = initialize_qcow2_image(fd, fs, img);
931         if (retval) {
932                 com_err(program_name, retval,
933                         "while initializing ext2_qcow2_image");
934                 exit(1);
935         }
936         header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
937                                    img->cluster_size);
938         write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
939
940         /* Refcount all qcow2 related metadata up to refcount_block_offset */
941         end = img->refcount.refcount_block_offset;
942         if (ext2fs_llseek(fd, end, SEEK_SET) < 0)
943                 lseek_error_and_exit(errno);
944         blk = end + img->cluster_size;
945         for (offset = 0; offset <= end; offset += img->cluster_size) {
946                 if (update_refcount(fd, img, offset, blk)) {
947                         blk += img->cluster_size;
948                         /*
949                          * If we create new refcount block, we need to refcount
950                          * it as well.
951                          */
952                         end += img->cluster_size;
953                 }
954         }
955         if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
956                 lseek_error_and_exit(errno);
957
958         retval = ext2fs_get_mem(fs->blocksize, &buf);
959         if (retval) {
960                 com_err(program_name, retval, "while allocating buffer");
961                 exit(1);
962         }
963         /* Write qcow2 data blocks */
964         for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
965                 if ((blk >= fs->super->s_first_data_block) &&
966                     ext2fs_test_block_bitmap2(meta_block_map, blk)) {
967                         retval = io_channel_read_blk64(fs->io, blk, 1, buf);
968                         if (retval) {
969                                 com_err(program_name, retval,
970                                         "error reading block %llu", blk);
971                                 continue;
972                         }
973                         if (scramble_block_map &&
974                             ext2fs_test_block_bitmap2(scramble_block_map, blk))
975                                 scramble_dir_block(fs, blk, buf);
976                         if (check_zero_block(buf, fs->blocksize))
977                                 continue;
978
979                         if (update_refcount(fd, img, offset, offset)) {
980                                 /* Make space for another refcount block */
981                                 offset += img->cluster_size;
982                                 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
983                                         lseek_error_and_exit(errno);
984                                 /*
985                                  * We have created the new refcount block, this
986                                  * means that we need to refcount it as well.
987                                  * So the previous update_refcount refcounted
988                                  * the block itself and now we are going to
989                                  * create refcount for data. New refcount
990                                  * block should not be created!
991                                  */
992                                 if (update_refcount(fd, img, offset, offset)) {
993                                         fprintf(stderr, "Programming error: "
994                                                 "multiple sequential refcount "
995                                                 "blocks created!\n");
996                                         exit(1);
997                                 }
998                         }
999
1000                         generic_write(fd, buf, fs->blocksize, 0);
1001
1002                         if (add_l2_item(img, blk, offset,
1003                                         offset + img->cluster_size)) {
1004                                 offset += img->cluster_size;
1005                                 if (update_refcount(fd, img, offset,
1006                                         offset + img->cluster_size)) {
1007                                         offset += img->cluster_size;
1008                                         if (update_refcount(fd, img, offset,
1009                                                             offset)) {
1010                                                 fprintf(stderr,
1011                         "Programming error: multiple sequential refcount "
1012                         "blocks created!\n");
1013                                                 exit(1);
1014                                         }
1015                                 }
1016                                 offset += img->cluster_size;
1017                                 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
1018                                         lseek_error_and_exit(errno);
1019                                 continue;
1020                         }
1021
1022                         offset += img->cluster_size;
1023                 }
1024         }
1025         update_refcount(fd, img, offset, offset);
1026         flush_l2_cache(img);
1027         sync_refcount(fd, img);
1028
1029         /* Write l1_table*/
1030         if (ext2fs_llseek(fd, img->l1_offset, SEEK_SET) < 0)
1031                 lseek_error_and_exit(errno);
1032         size = img->l1_size * sizeof(__u64);
1033         generic_write(fd, (char *)img->l1_table, size, 0);
1034
1035         ext2fs_free_mem(&buf);
1036         free_qcow2_image(img);
1037 }
1038
1039 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
1040 {
1041         struct process_block_struct     pb;
1042         struct ext2_inode               inode;
1043         ext2_inode_scan                 scan;
1044         ext2_ino_t                      ino;
1045         errcode_t                       retval;
1046         char *                          block_buf;
1047
1048         meta_blocks_count = 0;
1049         retval = ext2fs_allocate_block_bitmap(fs, "in-use block map",
1050                                               &meta_block_map);
1051         if (retval) {
1052                 com_err(program_name, retval, "while allocating block bitmap");
1053                 exit(1);
1054         }
1055
1056         if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1057                 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1058                                                       &scramble_block_map);
1059                 if (retval) {
1060                         com_err(program_name, retval,
1061                                 "while allocating scramble block bitmap");
1062                         exit(1);
1063                 }
1064         }
1065
1066         mark_table_blocks(fs);
1067
1068         retval = ext2fs_open_inode_scan(fs, 0, &scan);
1069         if (retval) {
1070                 com_err(program_name, retval, _("while opening inode scan"));
1071                 exit(1);
1072         }
1073
1074         retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1075         if (retval) {
1076                 com_err(program_name, 0, "Can't allocate block buffer");
1077                 exit(1);
1078         }
1079
1080         use_inode_shortcuts(fs, 1);
1081         stashed_inode = &inode;
1082         while (1) {
1083                 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1084                 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1085                         continue;
1086                 if (retval) {
1087                         com_err(program_name, retval,
1088                                 _("while getting next inode"));
1089                         exit(1);
1090                 }
1091                 if (ino == 0)
1092                         break;
1093                 if (!inode.i_links_count)
1094                         continue;
1095                 if (ext2fs_file_acl_block(&inode)) {
1096                         ext2fs_mark_block_bitmap2(meta_block_map,
1097                                                  ext2fs_file_acl_block(&inode));
1098                         meta_blocks_count++;
1099                 }
1100                 if (!ext2fs_inode_has_valid_blocks(&inode))
1101                         continue;
1102
1103                 stashed_ino = ino;
1104                 pb.ino = ino;
1105                 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1106                 if (LINUX_S_ISDIR(inode.i_mode) ||
1107                     (LINUX_S_ISLNK(inode.i_mode) &&
1108                      ext2fs_inode_has_valid_blocks(&inode)) ||
1109                     ino == fs->super->s_journal_inum) {
1110                         retval = ext2fs_block_iterate3(fs, ino,
1111                                         BLOCK_FLAG_READ_ONLY, block_buf,
1112                                         process_dir_block, &pb);
1113                         if (retval) {
1114                                 com_err(program_name, retval,
1115                                         "while iterating over inode %u",
1116                                         ino);
1117                                 exit(1);
1118                         }
1119                 } else {
1120                         if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1121                             inode.i_block[EXT2_IND_BLOCK] ||
1122                             inode.i_block[EXT2_DIND_BLOCK] ||
1123                             inode.i_block[EXT2_TIND_BLOCK]) {
1124                                 retval = ext2fs_block_iterate3(fs,
1125                                        ino, BLOCK_FLAG_READ_ONLY, block_buf,
1126                                        process_file_block, &pb);
1127                                 if (retval) {
1128                                         com_err(program_name, retval,
1129                                         "while iterating over inode %u", ino);
1130                                         exit(1);
1131                                 }
1132                         }
1133                 }
1134         }
1135         use_inode_shortcuts(fs, 0);
1136
1137         if (type & E2IMAGE_QCOW2)
1138                 output_qcow2_meta_data_blocks(fs, fd);
1139         else
1140                 output_meta_data_blocks(fs, fd);
1141
1142         ext2fs_free_mem(&block_buf);
1143         ext2fs_close_inode_scan(scan);
1144         ext2fs_free_block_bitmap(meta_block_map);
1145         if (type & E2IMAGE_SCRAMBLE_FLAG)
1146                 ext2fs_free_block_bitmap(scramble_block_map);
1147 }
1148
1149 static void install_image(char *device, char *image_fn, int type)
1150 {
1151         errcode_t retval;
1152         ext2_filsys fs;
1153         int open_flag = EXT2_FLAG_IMAGE_FILE;
1154         int fd = 0;
1155         io_manager      io_ptr;
1156         io_channel      io;
1157
1158         if (type) {
1159                 com_err(program_name, 0, "Raw and qcow2 images cannot"
1160                         "be installed");
1161                 exit(1);
1162         }
1163
1164 #ifdef CONFIG_TESTIO_DEBUG
1165         if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1166                 io_ptr = test_io_manager;
1167                 test_io_backing_manager = unix_io_manager;
1168         } else
1169 #endif
1170                 io_ptr = unix_io_manager;
1171
1172         retval = ext2fs_open (image_fn, open_flag, 0, 0,
1173                               io_ptr, &fs);
1174         if (retval) {
1175                 com_err (program_name, retval, _("while trying to open %s"),
1176                          image_fn);
1177                 exit(1);
1178         }
1179
1180         retval = ext2fs_read_bitmaps (fs);
1181         if (retval) {
1182                 com_err(program_name, retval, "error reading bitmaps");
1183                 exit(1);
1184         }
1185
1186 #ifdef HAVE_OPEN64
1187         fd = open64(image_fn, O_RDONLY);
1188 #else
1189         fd = open(image_fn, O_RDONLY);
1190 #endif
1191         if (fd < 0) {
1192                 perror(image_fn);
1193                 exit(1);
1194         }
1195
1196         retval = io_ptr->open(device, IO_FLAG_RW, &io);
1197         if (retval) {
1198                 com_err(device, 0, "while opening device file");
1199                 exit(1);
1200         }
1201
1202         ext2fs_rewrite_to_io(fs, io);
1203
1204         if (ext2fs_llseek(fd, fs->image_header->offset_inode, SEEK_SET) < 0) {
1205                 perror("ext2fs_llseek");
1206                 exit(1);
1207         }
1208
1209         retval = ext2fs_image_inode_read(fs, fd, 0);
1210         if (retval) {
1211                 com_err(image_fn, 0, "while restoring the image table");
1212                 exit(1);
1213         }
1214
1215         ext2fs_close (fs);
1216         exit (0);
1217 }
1218
1219 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1220 {
1221
1222 #ifdef HAVE_OPEN64
1223         *fd = open64(name, O_RDONLY, 0600);
1224 #else
1225         *fd = open(name, O_RDONLY, 0600);
1226 #endif
1227         if (*fd < 0)
1228                 return NULL;
1229
1230         return qcow2_read_header(*fd);
1231 }
1232
1233 int main (int argc, char ** argv)
1234 {
1235         int c;
1236         errcode_t retval;
1237         ext2_filsys fs;
1238         char *image_fn;
1239         struct ext2_qcow2_hdr *header = NULL;
1240         int open_flag = EXT2_FLAG_64BITS;
1241         int img_type = 0;
1242         int flags = 0;
1243         int qcow2_fd = 0;
1244         int fd = 0;
1245         int ret = 0;
1246
1247 #ifdef ENABLE_NLS
1248         setlocale(LC_MESSAGES, "");
1249         setlocale(LC_CTYPE, "");
1250         bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1251         textdomain(NLS_CAT_NAME);
1252 #endif
1253         fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1254                  E2FSPROGS_DATE);
1255         if (argc && *argv)
1256                 program_name = *argv;
1257         add_error_table(&et_ext2_error_table);
1258         while ((c = getopt(argc, argv, "rsIQ")) != EOF)
1259                 switch (c) {
1260                 case 'I':
1261                         flags |= E2IMAGE_INSTALL_FLAG;
1262                         break;
1263                 case 'Q':
1264                         if (img_type)
1265                                 usage();
1266                         img_type |= E2IMAGE_QCOW2;
1267                         break;
1268                 case 'r':
1269                         if (img_type)
1270                                 usage();
1271                         img_type |= E2IMAGE_RAW;
1272                         break;
1273                 case 's':
1274                         flags |= E2IMAGE_SCRAMBLE_FLAG;
1275                         break;
1276                 default:
1277                         usage();
1278                 }
1279         if (optind != argc - 2 )
1280                 usage();
1281         device_name = argv[optind];
1282         image_fn = argv[optind+1];
1283
1284         if (flags & E2IMAGE_INSTALL_FLAG) {
1285                 install_image(device_name, image_fn, img_type);
1286                 exit (0);
1287         }
1288
1289         if (img_type & E2IMAGE_RAW) {
1290                 header = check_qcow2_image(&qcow2_fd, device_name);
1291                 if (header) {
1292                         flags |= E2IMAGE_IS_QCOW2_FLAG;
1293                         goto skip_device;
1294                 }
1295         }
1296
1297         retval = ext2fs_open (device_name, open_flag, 0, 0,
1298                               unix_io_manager, &fs);
1299         if (retval) {
1300                 com_err (program_name, retval, _("while trying to open %s"),
1301                          device_name);
1302                 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1303                 exit(1);
1304         }
1305
1306 skip_device:
1307         if (strcmp(image_fn, "-") == 0)
1308                 fd = 1;
1309         else {
1310 #ifdef HAVE_OPEN64
1311                 fd = open64(image_fn, O_CREAT|O_TRUNC|O_WRONLY, 0600);
1312 #else
1313                 fd = open(image_fn, O_CREAT|O_TRUNC|O_WRONLY, 0600);
1314 #endif
1315                 if (fd < 0) {
1316                         com_err(program_name, errno,
1317                                 _("while trying to open %s"), argv[optind+1]);
1318                         exit(1);
1319                 }
1320         }
1321
1322         if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1323                 com_err(program_name, 0, "QCOW2 image can not be written to "
1324                                          "the stdout!\n");
1325                 exit(1);
1326         }
1327
1328         if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1329                 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1330                 if (ret) {
1331                         if (ret == -QCOW_COMPRESSED)
1332                                 fprintf(stderr, "Image (%s) is compressed\n",
1333                                         image_fn);
1334                         if (ret == -QCOW_ENCRYPTED)
1335                                 fprintf(stderr, "Image (%s) is encrypted\n",
1336                                         image_fn);
1337                         com_err(program_name, ret,
1338                                 _("while trying to convert qcow2 image"
1339                                 " (%s) into raw image (%s)"),
1340                                 device_name, image_fn);
1341                 }
1342                 goto out;
1343         }
1344
1345
1346         if (img_type)
1347                 write_raw_image_file(fs, fd, img_type, flags);
1348         else
1349                 write_image_file(fs, fd);
1350
1351         ext2fs_close (fs);
1352 out:
1353         if (header)
1354                 free(header);
1355         if (qcow2_fd)
1356                 close(qcow2_fd);
1357         remove_error_table(&et_ext2_error_table);
1358         return ret;
1359 }