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