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