e2image.c revision c859cb1de0d624caa0779fb17d1a53766143136e
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 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 */
796static 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
821static 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
848static 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
889static 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
908static 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
1033static 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
1143static 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
1209static 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
1219int 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
1292skip_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);
1334out:
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}
1342