xref: /kvmtool/disk/qcow.c (revision e94cdf08a394fb1b3fabd0beba31f09ad674cd78)
186835cedSPrasad Joshi #include "kvm/qcow.h"
286835cedSPrasad Joshi 
386835cedSPrasad Joshi #include "kvm/disk-image.h"
486835cedSPrasad Joshi #include "kvm/read-write.h"
5c0799eb9SPekka Enberg #include "kvm/mutex.h"
686835cedSPrasad Joshi #include "kvm/util.h"
786835cedSPrasad Joshi 
886835cedSPrasad Joshi #include <sys/types.h>
986835cedSPrasad Joshi #include <sys/stat.h>
1086835cedSPrasad Joshi #include <stdbool.h>
1186835cedSPrasad Joshi #include <stdlib.h>
1286835cedSPrasad Joshi #include <string.h>
1386835cedSPrasad Joshi #include <unistd.h>
1486835cedSPrasad Joshi #include <fcntl.h>
1586835cedSPrasad Joshi 
1686835cedSPrasad Joshi #include <linux/byteorder.h>
17865c675fSPrasad Joshi #include <linux/kernel.h>
180df6b4d9SPekka Enberg #include <linux/types.h>
1986835cedSPrasad Joshi 
20*e94cdf08SPekka Enberg static int l2_table_insert(struct rb_root *root, struct qcow_l2_table *new)
213309045fSPrasad Joshi {
223309045fSPrasad Joshi 	struct rb_node **link = &(root->rb_node), *parent = NULL;
233309045fSPrasad Joshi 	u64 offset = new->offset;
243309045fSPrasad Joshi 
253309045fSPrasad Joshi 	/* search the tree */
263309045fSPrasad Joshi 	while (*link) {
27473d58ffSPekka Enberg 		struct qcow_l2_table *t;
283309045fSPrasad Joshi 
29473d58ffSPekka Enberg 		t = rb_entry(*link, struct qcow_l2_table, node);
303309045fSPrasad Joshi 		if (!t)
313309045fSPrasad Joshi 			goto error;
323309045fSPrasad Joshi 
333309045fSPrasad Joshi 		parent = *link;
343309045fSPrasad Joshi 
353309045fSPrasad Joshi 		if (t->offset > offset)
363309045fSPrasad Joshi 			link = &(*link)->rb_left;
373309045fSPrasad Joshi 		else if (t->offset < offset)
383309045fSPrasad Joshi 			link = &(*link)->rb_right;
393309045fSPrasad Joshi 		else
403309045fSPrasad Joshi 			goto out;
413309045fSPrasad Joshi 	}
423309045fSPrasad Joshi 
433309045fSPrasad Joshi 	/* add new node */
443309045fSPrasad Joshi 	rb_link_node(&new->node, parent, link);
453309045fSPrasad Joshi 	rb_insert_color(&new->node, root);
463309045fSPrasad Joshi out:
473309045fSPrasad Joshi 	return 0;
483309045fSPrasad Joshi error:
493309045fSPrasad Joshi 	return -1;
503309045fSPrasad Joshi }
513309045fSPrasad Joshi 
52*e94cdf08SPekka Enberg static struct qcow_l2_table *l2_table_lookup(struct rb_root *root, u64 offset)
533309045fSPrasad Joshi {
543309045fSPrasad Joshi 	struct rb_node *link = root->rb_node;
553309045fSPrasad Joshi 
563309045fSPrasad Joshi 	while (link) {
57473d58ffSPekka Enberg 		struct qcow_l2_table *t;
583309045fSPrasad Joshi 
59473d58ffSPekka Enberg 		t = rb_entry(link, struct qcow_l2_table, node);
603309045fSPrasad Joshi 		if (!t)
613309045fSPrasad Joshi 			goto out;
623309045fSPrasad Joshi 
633309045fSPrasad Joshi 		if (t->offset > offset)
643309045fSPrasad Joshi 			link = link->rb_left;
653309045fSPrasad Joshi 		else if (t->offset < offset)
663309045fSPrasad Joshi 			link = link->rb_right;
673309045fSPrasad Joshi 		else
683309045fSPrasad Joshi 			return t;
693309045fSPrasad Joshi 	}
703309045fSPrasad Joshi out:
713309045fSPrasad Joshi 	return NULL;
723309045fSPrasad Joshi }
733309045fSPrasad Joshi 
74*e94cdf08SPekka Enberg static void l1_table_free_cache(struct qcow_l1_table *l1t)
753309045fSPrasad Joshi {
767b4eb530SPekka Enberg 	struct rb_root *r = &l1t->root;
773309045fSPrasad Joshi 	struct list_head *pos, *n;
78473d58ffSPekka Enberg 	struct qcow_l2_table *t;
793309045fSPrasad Joshi 
807b4eb530SPekka Enberg 	list_for_each_safe(pos, n, &l1t->lru_list) {
813309045fSPrasad Joshi 		/* Remove cache table from the list and RB tree */
823309045fSPrasad Joshi 		list_del(pos);
83473d58ffSPekka Enberg 		t = list_entry(pos, struct qcow_l2_table, list);
843309045fSPrasad Joshi 		rb_erase(&t->node, r);
853309045fSPrasad Joshi 
863309045fSPrasad Joshi 		/* Free the cached node */
873309045fSPrasad Joshi 		free(t);
883309045fSPrasad Joshi 	}
893309045fSPrasad Joshi }
903309045fSPrasad Joshi 
91a4e46515SPekka Enberg static int qcow_l2_cache_write(struct qcow *q, struct qcow_l2_table *c)
92a4e46515SPekka Enberg {
93a4e46515SPekka Enberg 	struct qcow_header *header = q->header;
94a4e46515SPekka Enberg 	u64 size;
95a4e46515SPekka Enberg 
96aff88976SPekka Enberg 	if (!c->dirty)
97aff88976SPekka Enberg 		return 0;
98aff88976SPekka Enberg 
99a4e46515SPekka Enberg 	size = 1 << header->l2_bits;
100a4e46515SPekka Enberg 
101aff88976SPekka Enberg 	if (pwrite_in_full(q->fd, c->table, size * sizeof(u64), c->offset) < 0)
102aff88976SPekka Enberg 		return -1;
103aff88976SPekka Enberg 
104aff88976SPekka Enberg 	c->dirty = 0;
105aff88976SPekka Enberg 
106aff88976SPekka Enberg 	return 0;
107a4e46515SPekka Enberg }
108a4e46515SPekka Enberg 
109473d58ffSPekka Enberg static int cache_table(struct qcow *q, struct qcow_l2_table *c)
1103309045fSPrasad Joshi {
1117b4eb530SPekka Enberg 	struct qcow_l1_table *l1t = &q->table;
1127b4eb530SPekka Enberg 	struct rb_root *r = &l1t->root;
113473d58ffSPekka Enberg 	struct qcow_l2_table *lru;
1143309045fSPrasad Joshi 
1157b4eb530SPekka Enberg 	if (l1t->nr_cached == MAX_CACHE_NODES) {
1163309045fSPrasad Joshi 		/*
1173309045fSPrasad Joshi 		 * The node at the head of the list is least recently used
1183309045fSPrasad Joshi 		 * node. Remove it from the list and replaced with a new node.
1193309045fSPrasad Joshi 		 */
1207b4eb530SPekka Enberg 		lru = list_first_entry(&l1t->lru_list, struct qcow_l2_table, list);
1213309045fSPrasad Joshi 
122a4e46515SPekka Enberg 		if (qcow_l2_cache_write(q, lru) < 0)
123a4e46515SPekka Enberg 			goto error;
124a4e46515SPekka Enberg 
1253309045fSPrasad Joshi 		/* Remove the node from the cache */
1263309045fSPrasad Joshi 		rb_erase(&lru->node, r);
1273309045fSPrasad Joshi 		list_del_init(&lru->list);
1287b4eb530SPekka Enberg 		l1t->nr_cached--;
1293309045fSPrasad Joshi 
1303309045fSPrasad Joshi 		/* Free the LRUed node */
1313309045fSPrasad Joshi 		free(lru);
1323309045fSPrasad Joshi 	}
1333309045fSPrasad Joshi 
1343309045fSPrasad Joshi 	/* Add new node in RB Tree: Helps in searching faster */
135*e94cdf08SPekka Enberg 	if (l2_table_insert(r, c) < 0)
1363309045fSPrasad Joshi 		goto error;
1373309045fSPrasad Joshi 
1383309045fSPrasad Joshi 	/* Add in LRU replacement list */
1397b4eb530SPekka Enberg 	list_add_tail(&c->list, &l1t->lru_list);
1407b4eb530SPekka Enberg 	l1t->nr_cached++;
1413309045fSPrasad Joshi 
1423309045fSPrasad Joshi 	return 0;
1433309045fSPrasad Joshi error:
1443309045fSPrasad Joshi 	return -1;
1453309045fSPrasad Joshi }
1463309045fSPrasad Joshi 
147*e94cdf08SPekka Enberg static struct qcow_l2_table *l2_table_search(struct qcow *q, u64 offset)
1483309045fSPrasad Joshi {
1497b4eb530SPekka Enberg 	struct qcow_l1_table *l1t = &q->table;
150fe8bdde0SPekka Enberg 	struct qcow_l2_table *l2t;
1513309045fSPrasad Joshi 
152*e94cdf08SPekka Enberg 	l2t = l2_table_lookup(&l1t->root, offset);
153fe8bdde0SPekka Enberg 	if (!l2t)
154fe8bdde0SPekka Enberg 		return NULL;
1553309045fSPrasad Joshi 
1563309045fSPrasad Joshi 	/* Update the LRU state, by moving the searched node to list tail */
1577b4eb530SPekka Enberg 	list_move_tail(&l2t->list, &l1t->lru_list);
1583309045fSPrasad Joshi 
159fe8bdde0SPekka Enberg 	return l2t;
1603309045fSPrasad Joshi }
1613309045fSPrasad Joshi 
1623309045fSPrasad Joshi /* Allocates a new node for caching L2 table */
163473d58ffSPekka Enberg static struct qcow_l2_table *new_cache_table(struct qcow *q, u64 offset)
1643309045fSPrasad Joshi {
1653309045fSPrasad Joshi 	struct qcow_header *header = q->header;
166473d58ffSPekka Enberg 	struct qcow_l2_table *c;
1673309045fSPrasad Joshi 	u64 l2t_sz;
1683309045fSPrasad Joshi 	u64 size;
1693309045fSPrasad Joshi 
1703309045fSPrasad Joshi 	l2t_sz = 1 << header->l2_bits;
1713309045fSPrasad Joshi 	size   = sizeof(*c) + l2t_sz * sizeof(u64);
1723309045fSPrasad Joshi 	c      = calloc(1, size);
1733309045fSPrasad Joshi 	if (!c)
1743309045fSPrasad Joshi 		goto out;
1753309045fSPrasad Joshi 
1763309045fSPrasad Joshi 	c->offset = offset;
1773309045fSPrasad Joshi 	RB_CLEAR_NODE(&c->node);
1783309045fSPrasad Joshi 	INIT_LIST_HEAD(&c->list);
1793309045fSPrasad Joshi out:
1803309045fSPrasad Joshi 	return c;
1813309045fSPrasad Joshi }
1823309045fSPrasad Joshi 
183742fce76SPrasad Joshi static inline u64 get_l1_index(struct qcow *q, u64 offset)
18486835cedSPrasad Joshi {
185ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
18686835cedSPrasad Joshi 
18786835cedSPrasad Joshi 	return offset >> (header->l2_bits + header->cluster_bits);
18886835cedSPrasad Joshi }
18986835cedSPrasad Joshi 
190742fce76SPrasad Joshi static inline u64 get_l2_index(struct qcow *q, u64 offset)
19186835cedSPrasad Joshi {
192ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
19386835cedSPrasad Joshi 
19486835cedSPrasad Joshi 	return (offset >> (header->cluster_bits)) & ((1 << header->l2_bits)-1);
19586835cedSPrasad Joshi }
19686835cedSPrasad Joshi 
197742fce76SPrasad Joshi static inline u64 get_cluster_offset(struct qcow *q, u64 offset)
19886835cedSPrasad Joshi {
199ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
20086835cedSPrasad Joshi 
20186835cedSPrasad Joshi 	return offset & ((1 << header->cluster_bits)-1);
20286835cedSPrasad Joshi }
20386835cedSPrasad Joshi 
204fe8bdde0SPekka Enberg static struct qcow_l2_table *qcow_read_l2_table(struct qcow *q, u64 offset)
2053309045fSPrasad Joshi {
2063309045fSPrasad Joshi 	struct qcow_header *header = q->header;
207fe8bdde0SPekka Enberg 	struct qcow_l2_table *l2t;
2083309045fSPrasad Joshi 	u64 size;
2093309045fSPrasad Joshi 
2103309045fSPrasad Joshi 	size = 1 << header->l2_bits;
2113309045fSPrasad Joshi 
2123309045fSPrasad Joshi 	/* search an entry for offset in cache */
213*e94cdf08SPekka Enberg 	l2t = l2_table_search(q, offset);
214fe8bdde0SPekka Enberg 	if (l2t)
215fe8bdde0SPekka Enberg 		return l2t;
2163309045fSPrasad Joshi 
2173309045fSPrasad Joshi 	/* allocate new node for caching l2 table */
218fe8bdde0SPekka Enberg 	l2t = new_cache_table(q, offset);
219fe8bdde0SPekka Enberg 	if (!l2t)
2203309045fSPrasad Joshi 		goto error;
2213309045fSPrasad Joshi 
2223309045fSPrasad Joshi 	/* table not cached: read from the disk */
223fe8bdde0SPekka Enberg 	if (pread_in_full(q->fd, l2t->table, size * sizeof(u64), offset) < 0)
2243309045fSPrasad Joshi 		goto error;
2253309045fSPrasad Joshi 
2263309045fSPrasad Joshi 	/* cache the table */
227fe8bdde0SPekka Enberg 	if (cache_table(q, l2t) < 0)
2283309045fSPrasad Joshi 		goto error;
2293309045fSPrasad Joshi 
230fe8bdde0SPekka Enberg 	return l2t;
2313309045fSPrasad Joshi error:
232fe8bdde0SPekka Enberg 	free(l2t);
233fe8bdde0SPekka Enberg 	return NULL;
2343309045fSPrasad Joshi }
2353309045fSPrasad Joshi 
236b1c84095SPekka Enberg static ssize_t qcow_read_cluster(struct qcow *q, u64 offset, void *dst, u32 dst_len)
23786835cedSPrasad Joshi {
238ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
2393fb67b93SPekka Enberg 	struct qcow_l1_table *l1t = &q->table;
2403fb67b93SPekka Enberg 	struct qcow_l2_table *l2t;
2413dac48d4SPrasad Joshi 	u64 cluster_size;
242742fce76SPrasad Joshi 	u64 clust_offset;
243742fce76SPrasad Joshi 	u64 clust_start;
2443fb67b93SPekka Enberg 	u64 l2t_offset;
245a51948ceSPekka Enberg 	size_t length;
2463fb67b93SPekka Enberg 	u64 l2t_size;
247742fce76SPrasad Joshi 	u64 l1_idx;
248742fce76SPrasad Joshi 	u64 l2_idx;
24986835cedSPrasad Joshi 
250dae803fbSPekka Enberg 	cluster_size = 1 << header->cluster_bits;
25186835cedSPrasad Joshi 
252c5e0624bSPrasad Joshi 	l1_idx = get_l1_index(q, offset);
2533fb67b93SPekka Enberg 	if (l1_idx >= l1t->table_size)
254c0799eb9SPekka Enberg 		return -1;
25586835cedSPrasad Joshi 
2563dac48d4SPrasad Joshi 	clust_offset = get_cluster_offset(q, offset);
2573dac48d4SPrasad Joshi 	if (clust_offset >= cluster_size)
258c0799eb9SPekka Enberg 		return -1;
2593dac48d4SPrasad Joshi 
2603dac48d4SPrasad Joshi 	length = cluster_size - clust_offset;
2613dac48d4SPrasad Joshi 	if (length > dst_len)
2623dac48d4SPrasad Joshi 		length = dst_len;
2633dac48d4SPrasad Joshi 
264c0799eb9SPekka Enberg 	mutex_lock(&q->mutex);
265b2ebe61bSPekka Enberg 
2663fb67b93SPekka Enberg 	l2t_offset = be64_to_cpu(l1t->l1_table[l1_idx]);
2673fb67b93SPekka Enberg 	if (l2t_offset & QCOW_OFLAG_COMPRESSED) {
268b2ebe61bSPekka Enberg 		pr_warning("compressed sectors are not supported");
269b2ebe61bSPekka Enberg 		goto out_error;
270b2ebe61bSPekka Enberg 	}
271b2ebe61bSPekka Enberg 
2723fb67b93SPekka Enberg 	l2t_offset &= QCOW_OFFSET_MASK;
2733fb67b93SPekka Enberg 	if (!l2t_offset)
2743dac48d4SPrasad Joshi 		goto zero_cluster;
27586835cedSPrasad Joshi 
2763fb67b93SPekka Enberg 	l2t_size = 1 << header->l2_bits;
27786835cedSPrasad Joshi 
2783309045fSPrasad Joshi 	/* read and cache level 2 table */
2793fb67b93SPekka Enberg 	l2t = qcow_read_l2_table(q, l2t_offset);
2803fb67b93SPekka Enberg 	if (!l2t)
281b6edb0ecSSasha Levin 		goto out_error;
28286835cedSPrasad Joshi 
283c5e0624bSPrasad Joshi 	l2_idx = get_l2_index(q, offset);
2843fb67b93SPekka Enberg 	if (l2_idx >= l2t_size)
285b6edb0ecSSasha Levin 		goto out_error;
28686835cedSPrasad Joshi 
2873fb67b93SPekka Enberg 	clust_start = be64_to_cpu(l2t->table[l2_idx]);
288b2ebe61bSPekka Enberg 	if (clust_start & QCOW_OFLAG_COMPRESSED) {
289b2ebe61bSPekka Enberg 		pr_warning("compressed sectors are not supported");
290b2ebe61bSPekka Enberg 		goto out_error;
291b2ebe61bSPekka Enberg 	}
292b2ebe61bSPekka Enberg 
293b2ebe61bSPekka Enberg 	clust_start &= QCOW_OFFSET_MASK;
29486835cedSPrasad Joshi 	if (!clust_start)
2953dac48d4SPrasad Joshi 		goto zero_cluster;
29686835cedSPrasad Joshi 
297c0799eb9SPekka Enberg 	mutex_unlock(&q->mutex);
29886835cedSPrasad Joshi 
299c0799eb9SPekka Enberg 	if (pread_in_full(q->fd, dst, length, clust_start + clust_offset) < 0)
300c0799eb9SPekka Enberg 		return -1;
301c0799eb9SPekka Enberg 
3023dac48d4SPrasad Joshi 	return length;
30386835cedSPrasad Joshi 
304179b71f0SPekka Enberg zero_cluster:
305c0799eb9SPekka Enberg 	mutex_unlock(&q->mutex);
306179b71f0SPekka Enberg 	memset(dst, 0, length);
307c0799eb9SPekka Enberg 	return length;
308179b71f0SPekka Enberg 
30986835cedSPrasad Joshi out_error:
310c0799eb9SPekka Enberg 	mutex_unlock(&q->mutex);
311179b71f0SPekka Enberg 	length = -1;
312c0799eb9SPekka Enberg 	return -1;
3133dac48d4SPrasad Joshi }
314b6edb0ecSSasha Levin 
315b1c84095SPekka Enberg static ssize_t qcow_read_sector(struct disk_image *disk, u64 sector, void *dst, u32 dst_len)
3163dac48d4SPrasad Joshi {
31743835ac9SSasha Levin 	struct qcow *q = disk->priv;
318ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
319d8eea993SPekka Enberg 	u32 nr_read;
3200df6b4d9SPekka Enberg 	u64 offset;
3210df6b4d9SPekka Enberg 	char *buf;
3223dac48d4SPrasad Joshi 	u32 nr;
3233dac48d4SPrasad Joshi 
3240df6b4d9SPekka Enberg 	buf		= dst;
325d8eea993SPekka Enberg 	nr_read		= 0;
3260df6b4d9SPekka Enberg 
327d8eea993SPekka Enberg 	while (nr_read < dst_len) {
3283dac48d4SPrasad Joshi 		offset		= sector << SECTOR_SHIFT;
3293dac48d4SPrasad Joshi 		if (offset >= header->size)
3300df6b4d9SPekka Enberg 			return -1;
3313dac48d4SPrasad Joshi 
332b1c84095SPekka Enberg 		nr = qcow_read_cluster(q, offset, buf, dst_len - nr_read);
333a51948ceSPekka Enberg 		if (nr <= 0)
3340df6b4d9SPekka Enberg 			return -1;
3353dac48d4SPrasad Joshi 
336d8eea993SPekka Enberg 		nr_read		+= nr;
3373dac48d4SPrasad Joshi 		buf		+= nr;
3383dac48d4SPrasad Joshi 		sector		+= (nr >> SECTOR_SHIFT);
3393dac48d4SPrasad Joshi 	}
3400df6b4d9SPekka Enberg 
34172133dd2SAsias He 	return dst_len;
34286835cedSPrasad Joshi }
34386835cedSPrasad Joshi 
344865c675fSPrasad Joshi static inline u64 file_size(int fd)
345865c675fSPrasad Joshi {
346865c675fSPrasad Joshi 	struct stat st;
3470df6b4d9SPekka Enberg 
348865c675fSPrasad Joshi 	if (fstat(fd, &st) < 0)
349865c675fSPrasad Joshi 		return 0;
3500df6b4d9SPekka Enberg 
351865c675fSPrasad Joshi 	return st.st_size;
352865c675fSPrasad Joshi }
353865c675fSPrasad Joshi 
3540df6b4d9SPekka Enberg static inline int qcow_pwrite_sync(int fd, void *buf, size_t count, off_t offset)
355865c675fSPrasad Joshi {
356865c675fSPrasad Joshi 	if (pwrite_in_full(fd, buf, count, offset) < 0)
357865c675fSPrasad Joshi 		return -1;
3580df6b4d9SPekka Enberg 
3597d94a719SPekka Enberg 	return fdatasync(fd);
360865c675fSPrasad Joshi }
361865c675fSPrasad Joshi 
362865c675fSPrasad Joshi /* Writes a level 2 table at the end of the file. */
363b1c84095SPekka Enberg static u64 qcow_write_l2_table(struct qcow *q, u64 *table)
364865c675fSPrasad Joshi {
365865c675fSPrasad Joshi 	struct qcow_header *header = q->header;
366865c675fSPrasad Joshi 	u64 clust_sz;
367865c675fSPrasad Joshi 	u64 f_sz;
3680df6b4d9SPekka Enberg 	u64 off;
3690df6b4d9SPekka Enberg 	u64 sz;
370865c675fSPrasad Joshi 
371865c675fSPrasad Joshi 	f_sz		= file_size(q->fd);
372865c675fSPrasad Joshi 	if (!f_sz)
373865c675fSPrasad Joshi 		return 0;
374865c675fSPrasad Joshi 
375865c675fSPrasad Joshi 	sz		= 1 << header->l2_bits;
376865c675fSPrasad Joshi 	clust_sz	= 1 << header->cluster_bits;
377865c675fSPrasad Joshi 	off		= ALIGN(f_sz, clust_sz);
378865c675fSPrasad Joshi 
3796fe151aeSPekka Enberg 	if (pwrite_in_full(q->fd, table, sz * sizeof(u64), off) < 0)
380865c675fSPrasad Joshi 		return 0;
3810df6b4d9SPekka Enberg 
382865c675fSPrasad Joshi 	return off;
383865c675fSPrasad Joshi }
384865c675fSPrasad Joshi 
385865c675fSPrasad Joshi /*
386865c675fSPrasad Joshi  * QCOW file might grow during a write operation. Not only data but metadata is
387865c675fSPrasad Joshi  * also written at the end of the file. Therefore it is necessary to ensure
3880df6b4d9SPekka Enberg  * every write is committed to disk. Hence we use uses qcow_pwrite_sync() to
389865c675fSPrasad Joshi  * synchronize the in-core state of QCOW image to disk.
390865c675fSPrasad Joshi  *
391865c675fSPrasad Joshi  * We also try to restore the image to a consistent state if the metdata
392865c675fSPrasad Joshi  * operation fails. The two metadat operations are: level 1 and level 2 table
393865c675fSPrasad Joshi  * update. If either of them fails the image is truncated to a consistent state.
394865c675fSPrasad Joshi  */
395b1c84095SPekka Enberg static ssize_t qcow_write_cluster(struct qcow *q, u64 offset, void *buf, u32 src_len)
396865c675fSPrasad Joshi {
397865c675fSPrasad Joshi 	struct qcow_header *header = q->header;
3983fb67b93SPekka Enberg 	struct qcow_l1_table *l1t = &q->table;
399fe8bdde0SPekka Enberg 	struct qcow_l2_table *l2t;
4000df6b4d9SPekka Enberg 	u64 clust_start;
4013fb67b93SPekka Enberg 	u64 l2t_offset;
4020df6b4d9SPekka Enberg 	u64 clust_off;
4033fb67b93SPekka Enberg 	u64 l2t_size;
404865c675fSPrasad Joshi 	u64 clust_sz;
405865c675fSPrasad Joshi 	u64 l1t_idx;
406865c675fSPrasad Joshi 	u64 l2t_idx;
407865c675fSPrasad Joshi 	u64 f_sz;
4080df6b4d9SPekka Enberg 	u64 len;
409865c675fSPrasad Joshi 
410fe8bdde0SPekka Enberg 	l2t		= NULL;
4113fb67b93SPekka Enberg 	l2t_size	= 1 << header->l2_bits;
412865c675fSPrasad Joshi 	clust_sz	= 1 << header->cluster_bits;
413865c675fSPrasad Joshi 
414865c675fSPrasad Joshi 	l1t_idx = get_l1_index(q, offset);
4153fb67b93SPekka Enberg 	if (l1t_idx >= l1t->table_size)
416c0799eb9SPekka Enberg 		return -1;
417865c675fSPrasad Joshi 
418865c675fSPrasad Joshi 	l2t_idx = get_l2_index(q, offset);
4193fb67b93SPekka Enberg 	if (l2t_idx >= l2t_size)
420c0799eb9SPekka Enberg 		return -1;
421865c675fSPrasad Joshi 
422865c675fSPrasad Joshi 	clust_off = get_cluster_offset(q, offset);
423865c675fSPrasad Joshi 	if (clust_off >= clust_sz)
424c0799eb9SPekka Enberg 		return -1;
425865c675fSPrasad Joshi 
426865c675fSPrasad Joshi 	len = clust_sz - clust_off;
427865c675fSPrasad Joshi 	if (len > src_len)
428865c675fSPrasad Joshi 		len = src_len;
429865c675fSPrasad Joshi 
430c0799eb9SPekka Enberg 	mutex_lock(&q->mutex);
431c0799eb9SPekka Enberg 
4323fb67b93SPekka Enberg 	l2t_offset = be64_to_cpu(l1t->l1_table[l1t_idx]);
4333fb67b93SPekka Enberg 	if (l2t_offset & QCOW_OFLAG_COMPRESSED) {
434121dd76eSPekka Enberg 		pr_warning("compressed clusters are not supported");
435121dd76eSPekka Enberg 		goto error;
436121dd76eSPekka Enberg 	}
4373fb67b93SPekka Enberg 	if (!(l2t_offset & QCOW_OFLAG_COPIED)) {
438121dd76eSPekka Enberg 		pr_warning("copy-on-write clusters are not supported");
439b2ebe61bSPekka Enberg 		goto error;
440b2ebe61bSPekka Enberg 	}
441b2ebe61bSPekka Enberg 
4423fb67b93SPekka Enberg 	l2t_offset &= QCOW_OFFSET_MASK;
4433fb67b93SPekka Enberg 	if (l2t_offset) {
4443309045fSPrasad Joshi 		/* read and cache l2 table */
4453fb67b93SPekka Enberg 		l2t = qcow_read_l2_table(q, l2t_offset);
446fe8bdde0SPekka Enberg 		if (!l2t)
4473309045fSPrasad Joshi 			goto error;
448865c675fSPrasad Joshi 	} else {
4493fb67b93SPekka Enberg 		l2t = new_cache_table(q, l2t_offset);
450fe8bdde0SPekka Enberg 		if (!l2t)
4513309045fSPrasad Joshi 			goto error;
4523309045fSPrasad Joshi 
4530df6b4d9SPekka Enberg 		/* Capture the state of the consistent QCOW image */
454865c675fSPrasad Joshi 		f_sz = file_size(q->fd);
455865c675fSPrasad Joshi 		if (!f_sz)
4563309045fSPrasad Joshi 			goto free_cache;
457865c675fSPrasad Joshi 
458865c675fSPrasad Joshi 		/* Write the l2 table of 0's at the end of the file */
4593fb67b93SPekka Enberg 		l2t_offset = qcow_write_l2_table(q, l2t->table);
4603fb67b93SPekka Enberg 		if (!l2t_offset)
4613309045fSPrasad Joshi 			goto free_cache;
462865c675fSPrasad Joshi 
463fe8bdde0SPekka Enberg 		if (cache_table(q, l2t) < 0) {
4643309045fSPrasad Joshi 			if (ftruncate(q->fd, f_sz) < 0)
4653309045fSPrasad Joshi 				goto free_cache;
4663309045fSPrasad Joshi 
4673309045fSPrasad Joshi 			goto free_cache;
468865c675fSPrasad Joshi 		}
469865c675fSPrasad Joshi 
4700df6b4d9SPekka Enberg 		/* Update the in-core entry */
4713fb67b93SPekka Enberg 		l1t->l1_table[l1t_idx] = cpu_to_be64(l2t_offset);
472865c675fSPrasad Joshi 	}
473865c675fSPrasad Joshi 
4740df6b4d9SPekka Enberg 	/* Capture the state of the consistent QCOW image */
475865c675fSPrasad Joshi 	f_sz		= file_size(q->fd);
476865c675fSPrasad Joshi 	if (!f_sz)
4773309045fSPrasad Joshi 		goto error;
478865c675fSPrasad Joshi 
479b2ebe61bSPekka Enberg 	clust_start	= be64_to_cpu(l2t->table[l2t_idx]);
480b2ebe61bSPekka Enberg 	if (clust_start & QCOW_OFLAG_COMPRESSED) {
481121dd76eSPekka Enberg 		pr_warning("compressed clusters are not supported");
482121dd76eSPekka Enberg 		goto error;
483121dd76eSPekka Enberg 	}
484121dd76eSPekka Enberg 	if (!(clust_start & QCOW_OFLAG_COPIED)) {
485121dd76eSPekka Enberg 		pr_warning("copy-on-write clusters are not supported");
486b2ebe61bSPekka Enberg 		goto error;
487b2ebe61bSPekka Enberg 	}
488b2ebe61bSPekka Enberg 
489b2ebe61bSPekka Enberg 	clust_start &= QCOW_OFFSET_MASK;
490865c675fSPrasad Joshi 	if (!clust_start) {
491865c675fSPrasad Joshi 		clust_start		= ALIGN(f_sz, clust_sz);
4924bd7e48bSPekka Enberg 		l2t->table[l2t_idx]	= cpu_to_be64(clust_start);
493aff88976SPekka Enberg 		l2t->dirty		= 1;
494865c675fSPrasad Joshi 	}
4950df6b4d9SPekka Enberg 
496c0799eb9SPekka Enberg 	mutex_unlock(&q->mutex);
497c0799eb9SPekka Enberg 
498a4e46515SPekka Enberg 	/* Write actual data */
499a4e46515SPekka Enberg 	if (pwrite_in_full(q->fd, buf, len, clust_start + clust_off) < 0)
500a4e46515SPekka Enberg 		return -1;
501a4e46515SPekka Enberg 
502865c675fSPrasad Joshi 	return len;
5033309045fSPrasad Joshi 
5043309045fSPrasad Joshi free_cache:
505fe8bdde0SPekka Enberg 	free(l2t);
506865c675fSPrasad Joshi error:
507c0799eb9SPekka Enberg 	mutex_unlock(&q->mutex);
508865c675fSPrasad Joshi 	return -1;
509865c675fSPrasad Joshi }
510865c675fSPrasad Joshi 
511b1c84095SPekka Enberg static ssize_t qcow_write_sector(struct disk_image *disk, u64 sector, void *src, u32 src_len)
51286835cedSPrasad Joshi {
513865c675fSPrasad Joshi 	struct qcow *q = disk->priv;
514865c675fSPrasad Joshi 	struct qcow_header *header = q->header;
515c4acb611SIngo Molnar 	u32 nr_written;
5160df6b4d9SPekka Enberg 	char *buf;
517865c675fSPrasad Joshi 	u64 offset;
518865c675fSPrasad Joshi 	ssize_t nr;
519865c675fSPrasad Joshi 
5200df6b4d9SPekka Enberg 	buf		= src;
5210df6b4d9SPekka Enberg 	nr_written	= 0;
522865c675fSPrasad Joshi 	offset		= sector << SECTOR_SHIFT;
5230df6b4d9SPekka Enberg 
5240df6b4d9SPekka Enberg 	while (nr_written < src_len) {
525865c675fSPrasad Joshi 		if (offset >= header->size)
5260df6b4d9SPekka Enberg 			return -1;
527865c675fSPrasad Joshi 
528b1c84095SPekka Enberg 		nr = qcow_write_cluster(q, offset, buf, src_len - nr_written);
529865c675fSPrasad Joshi 		if (nr < 0)
5300df6b4d9SPekka Enberg 			return -1;
531865c675fSPrasad Joshi 
5320df6b4d9SPekka Enberg 		nr_written	+= nr;
533865c675fSPrasad Joshi 		buf		+= nr;
534865c675fSPrasad Joshi 		offset		+= nr;
535865c675fSPrasad Joshi 	}
5360df6b4d9SPekka Enberg 
53772133dd2SAsias He 	return nr_written;
53886835cedSPrasad Joshi }
53986835cedSPrasad Joshi 
540b1c84095SPekka Enberg static ssize_t qcow_nowrite_sector(struct disk_image *disk, u64 sector, void *src, u32 src_len)
541f10860caSPekka Enberg {
542f10860caSPekka Enberg 	/* I/O error */
543b1c84095SPekka Enberg 	pr_info("%s: no write support\n", __func__);
544f10860caSPekka Enberg 	return -1;
545f10860caSPekka Enberg }
546f10860caSPekka Enberg 
547659f4186SPekka Enberg static int qcow_disk_flush(struct disk_image *disk)
548659f4186SPekka Enberg {
54973984b11SPekka Enberg 	struct qcow *q = disk->priv;
55073984b11SPekka Enberg 	struct qcow_header *header;
551a4e46515SPekka Enberg 	struct list_head *pos, *n;
5527b4eb530SPekka Enberg 	struct qcow_l1_table *l1t;
55373984b11SPekka Enberg 
55473984b11SPekka Enberg 	header = q->header;
5557b4eb530SPekka Enberg 	l1t = &q->table;
55673984b11SPekka Enberg 
557a4e46515SPekka Enberg 	mutex_lock(&q->mutex);
558a4e46515SPekka Enberg 
5597b4eb530SPekka Enberg 	list_for_each_safe(pos, n, &l1t->lru_list) {
560a4e46515SPekka Enberg 		struct qcow_l2_table *c = list_entry(pos, struct qcow_l2_table, list);
561a4e46515SPekka Enberg 
562a4e46515SPekka Enberg 		if (qcow_l2_cache_write(q, c) < 0)
563a4e46515SPekka Enberg 			goto error_unlock;
564a4e46515SPekka Enberg 	}
565a4e46515SPekka Enberg 
566a4e46515SPekka Enberg 	if (fdatasync(disk->fd) < 0)
567a4e46515SPekka Enberg 		goto error_unlock;
568a4e46515SPekka Enberg 
5697b4eb530SPekka Enberg 	if (pwrite_in_full(disk->fd, l1t->l1_table, l1t->table_size * sizeof(u64), header->l1_table_offset) < 0)
570a4e46515SPekka Enberg 		goto error_unlock;
571a4e46515SPekka Enberg 
572a4e46515SPekka Enberg 	mutex_unlock(&q->mutex);
57373984b11SPekka Enberg 
574659f4186SPekka Enberg 	return fsync(disk->fd);
575a4e46515SPekka Enberg 
576a4e46515SPekka Enberg error_unlock:
577a4e46515SPekka Enberg 	mutex_unlock(&q->mutex);
578a4e46515SPekka Enberg 	return -1;
579659f4186SPekka Enberg }
580659f4186SPekka Enberg 
581b1c84095SPekka Enberg static int qcow_disk_close(struct disk_image *disk)
58286835cedSPrasad Joshi {
58386835cedSPrasad Joshi 	struct qcow *q;
58486835cedSPrasad Joshi 
58543835ac9SSasha Levin 	if (!disk)
58672133dd2SAsias He 		return 0;
58786835cedSPrasad Joshi 
58843835ac9SSasha Levin 	q = disk->priv;
58986835cedSPrasad Joshi 
590*e94cdf08SPekka Enberg 	l1_table_free_cache(&q->table);
5916c6f79b6SPrasad Joshi 	free(q->table.l1_table);
59286835cedSPrasad Joshi 	free(q->header);
59386835cedSPrasad Joshi 	free(q);
59472133dd2SAsias He 
59572133dd2SAsias He 	return 0;
59686835cedSPrasad Joshi }
59786835cedSPrasad Joshi 
598b1c84095SPekka Enberg static struct disk_image_operations qcow_disk_readonly_ops = {
599b1c84095SPekka Enberg 	.read_sector		= qcow_read_sector,
600b1c84095SPekka Enberg 	.write_sector		= qcow_nowrite_sector,
601b1c84095SPekka Enberg 	.close			= qcow_disk_close,
602f10860caSPekka Enberg };
603f10860caSPekka Enberg 
604b1c84095SPekka Enberg static struct disk_image_operations qcow_disk_ops = {
605b1c84095SPekka Enberg 	.read_sector		= qcow_read_sector,
606b1c84095SPekka Enberg 	.write_sector		= qcow_write_sector,
607659f4186SPekka Enberg 	.flush			= qcow_disk_flush,
608b1c84095SPekka Enberg 	.close			= qcow_disk_close,
60986835cedSPrasad Joshi };
61086835cedSPrasad Joshi 
61186835cedSPrasad Joshi static int qcow_read_l1_table(struct qcow *q)
61286835cedSPrasad Joshi {
613ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
614473aaa2dSPekka Enberg 	struct qcow_l1_table *table = &q->table;
61586835cedSPrasad Joshi 
616ad627d62SPekka Enberg 	table->table_size	= header->l1_size;
61786835cedSPrasad Joshi 
61800adcc1bSPrasad Joshi 	table->l1_table	= calloc(table->table_size, sizeof(u64));
61900adcc1bSPrasad Joshi 	if (!table->l1_table)
62086835cedSPrasad Joshi 		return -1;
62186835cedSPrasad Joshi 
622659f4186SPekka Enberg 	return pread_in_full(q->fd, table->l1_table, sizeof(u64) * table->table_size, header->l1_table_offset);
62386835cedSPrasad Joshi }
62486835cedSPrasad Joshi 
625ad627d62SPekka Enberg static void *qcow2_read_header(int fd)
62686835cedSPrasad Joshi {
627ad627d62SPekka Enberg 	struct qcow2_header_disk f_header;
628ad627d62SPekka Enberg 	struct qcow_header *header;
62986835cedSPrasad Joshi 
630ad627d62SPekka Enberg 	header = malloc(sizeof(struct qcow_header));
63186835cedSPrasad Joshi 	if (!header)
63286835cedSPrasad Joshi 		return NULL;
63386835cedSPrasad Joshi 
6340657f33dSPrasad Joshi 	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0) {
6350657f33dSPrasad Joshi 		free(header);
63686835cedSPrasad Joshi 		return NULL;
6370657f33dSPrasad Joshi 	}
63886835cedSPrasad Joshi 
639ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
640ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
641ad627d62SPekka Enberg 	be64_to_cpus(&f_header.backing_file_offset);
642ad627d62SPekka Enberg 	be32_to_cpus(&f_header.backing_file_size);
643ad627d62SPekka Enberg 	be32_to_cpus(&f_header.cluster_bits);
644ad627d62SPekka Enberg 	be64_to_cpus(&f_header.size);
645ad627d62SPekka Enberg 	be32_to_cpus(&f_header.crypt_method);
646ad627d62SPekka Enberg 	be32_to_cpus(&f_header.l1_size);
647ad627d62SPekka Enberg 	be64_to_cpus(&f_header.l1_table_offset);
648ad627d62SPekka Enberg 	be64_to_cpus(&f_header.refcount_table_offset);
649ad627d62SPekka Enberg 	be32_to_cpus(&f_header.refcount_table_clusters);
650ad627d62SPekka Enberg 	be32_to_cpus(&f_header.nb_snapshots);
651ad627d62SPekka Enberg 	be64_to_cpus(&f_header.snapshots_offset);
652ad627d62SPekka Enberg 
653ad627d62SPekka Enberg 	*header		= (struct qcow_header) {
654ad627d62SPekka Enberg 		.size			= f_header.size,
655ad627d62SPekka Enberg 		.l1_table_offset	= f_header.l1_table_offset,
656ad627d62SPekka Enberg 		.l1_size		= f_header.l1_size,
657ad627d62SPekka Enberg 		.cluster_bits		= f_header.cluster_bits,
658ad627d62SPekka Enberg 		.l2_bits		= f_header.cluster_bits - 3,
659ad627d62SPekka Enberg 	};
660ad627d62SPekka Enberg 
661ad627d62SPekka Enberg 	return header;
662ad627d62SPekka Enberg }
663ad627d62SPekka Enberg 
664f10860caSPekka Enberg static struct disk_image *qcow2_probe(int fd, bool readonly)
665ad627d62SPekka Enberg {
666ad627d62SPekka Enberg 	struct disk_image *disk_image;
6677b4eb530SPekka Enberg 	struct qcow_l1_table *l1t;
6687b4eb530SPekka Enberg 	struct qcow_header *h;
6697b4eb530SPekka Enberg 	struct qcow *q;
670ad627d62SPekka Enberg 
671ad627d62SPekka Enberg 	q = calloc(1, sizeof(struct qcow));
672ad627d62SPekka Enberg 	if (!q)
673ad627d62SPekka Enberg 		goto error;
674ad627d62SPekka Enberg 
675c0799eb9SPekka Enberg 	mutex_init(&q->mutex);
676ad627d62SPekka Enberg 	q->fd = fd;
6777b4eb530SPekka Enberg 
6787b4eb530SPekka Enberg 	l1t = &q->table;
6797b4eb530SPekka Enberg 
6807b4eb530SPekka Enberg 	l1t->root = RB_ROOT;
6817b4eb530SPekka Enberg 	INIT_LIST_HEAD(&l1t->lru_list);
682ad627d62SPekka Enberg 
683ad627d62SPekka Enberg 	h = q->header = qcow2_read_header(fd);
684ad627d62SPekka Enberg 	if (!h)
685ad627d62SPekka Enberg 		goto error;
686ad627d62SPekka Enberg 
687ad627d62SPekka Enberg 	if (qcow_read_l1_table(q) < 0)
688ad627d62SPekka Enberg 		goto error;
689ad627d62SPekka Enberg 
6907d22135fSAsias He 	/*
6917d22135fSAsias He 	 * Do not use mmap use read/write instead
6927d22135fSAsias He 	 */
693f10860caSPekka Enberg 	if (readonly)
694b1c84095SPekka Enberg 		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_NOMMAP);
695f10860caSPekka Enberg 	else
696b1c84095SPekka Enberg 		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_NOMMAP);
697f10860caSPekka Enberg 
698ad627d62SPekka Enberg 	if (!disk_image)
699ad627d62SPekka Enberg 		goto error;
700ad627d62SPekka Enberg 	disk_image->priv = q;
701ad627d62SPekka Enberg 
702ad627d62SPekka Enberg 	return disk_image;
703ad627d62SPekka Enberg error:
704ad627d62SPekka Enberg 	if (!q)
705ad627d62SPekka Enberg 		return NULL;
706ad627d62SPekka Enberg 
707ad627d62SPekka Enberg 	free(q->table.l1_table);
708ad627d62SPekka Enberg 	free(q->header);
709ad627d62SPekka Enberg 	free(q);
710ad627d62SPekka Enberg 
711ad627d62SPekka Enberg 	return NULL;
712ad627d62SPekka Enberg }
713ad627d62SPekka Enberg 
714ad627d62SPekka Enberg static bool qcow2_check_image(int fd)
715ad627d62SPekka Enberg {
716ad627d62SPekka Enberg 	struct qcow2_header_disk f_header;
717ad627d62SPekka Enberg 
718ad627d62SPekka Enberg 	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0)
719ad627d62SPekka Enberg 		return false;
720ad627d62SPekka Enberg 
721ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
722ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
723ad627d62SPekka Enberg 
724ad627d62SPekka Enberg 	if (f_header.magic != QCOW_MAGIC)
725ad627d62SPekka Enberg 		return false;
726ad627d62SPekka Enberg 
727ad627d62SPekka Enberg 	if (f_header.version != QCOW2_VERSION)
728ad627d62SPekka Enberg 		return false;
729ad627d62SPekka Enberg 
730ad627d62SPekka Enberg 	return true;
731ad627d62SPekka Enberg }
732ad627d62SPekka Enberg 
733ad627d62SPekka Enberg static void *qcow1_read_header(int fd)
734ad627d62SPekka Enberg {
735ad627d62SPekka Enberg 	struct qcow1_header_disk f_header;
736ad627d62SPekka Enberg 	struct qcow_header *header;
737ad627d62SPekka Enberg 
738ad627d62SPekka Enberg 	header = malloc(sizeof(struct qcow_header));
739ad627d62SPekka Enberg 	if (!header)
740ad627d62SPekka Enberg 		return NULL;
741ad627d62SPekka Enberg 
742d39cefd2SSasha Levin 	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0) {
743d39cefd2SSasha Levin 		free(header);
744ad627d62SPekka Enberg 		return NULL;
745d39cefd2SSasha Levin 	}
746ad627d62SPekka Enberg 
747ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
748ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
749ad627d62SPekka Enberg 	be64_to_cpus(&f_header.backing_file_offset);
750ad627d62SPekka Enberg 	be32_to_cpus(&f_header.backing_file_size);
751ad627d62SPekka Enberg 	be32_to_cpus(&f_header.mtime);
752ad627d62SPekka Enberg 	be64_to_cpus(&f_header.size);
753ad627d62SPekka Enberg 	be32_to_cpus(&f_header.crypt_method);
754ad627d62SPekka Enberg 	be64_to_cpus(&f_header.l1_table_offset);
755ad627d62SPekka Enberg 
756ad627d62SPekka Enberg 	*header		= (struct qcow_header) {
757ad627d62SPekka Enberg 		.size			= f_header.size,
758ad627d62SPekka Enberg 		.l1_table_offset	= f_header.l1_table_offset,
759ad627d62SPekka Enberg 		.l1_size		= f_header.size / ((1 << f_header.l2_bits) * (1 << f_header.cluster_bits)),
760ad627d62SPekka Enberg 		.cluster_bits		= f_header.cluster_bits,
761ad627d62SPekka Enberg 		.l2_bits		= f_header.l2_bits,
762ad627d62SPekka Enberg 	};
76386835cedSPrasad Joshi 
76486835cedSPrasad Joshi 	return header;
76586835cedSPrasad Joshi }
76686835cedSPrasad Joshi 
767f10860caSPekka Enberg static struct disk_image *qcow1_probe(int fd, bool readonly)
76886835cedSPrasad Joshi {
76986835cedSPrasad Joshi 	struct disk_image *disk_image;
7707b4eb530SPekka Enberg 	struct qcow_l1_table *l1t;
7717b4eb530SPekka Enberg 	struct qcow_header *h;
7727b4eb530SPekka Enberg 	struct qcow *q;
77386835cedSPrasad Joshi 
77486835cedSPrasad Joshi 	q = calloc(1, sizeof(struct qcow));
77586835cedSPrasad Joshi 	if (!q)
77686835cedSPrasad Joshi 		goto error;
77786835cedSPrasad Joshi 
778c0799eb9SPekka Enberg 	mutex_init(&q->mutex);
77986835cedSPrasad Joshi 	q->fd = fd;
7807b4eb530SPekka Enberg 
7817b4eb530SPekka Enberg 	l1t = &q->table;
7827b4eb530SPekka Enberg 
7837b4eb530SPekka Enberg 	l1t->root = RB_ROOT;
7847b4eb530SPekka Enberg 	INIT_LIST_HEAD(&l1t->lru_list);
78586835cedSPrasad Joshi 
78686835cedSPrasad Joshi 	h = q->header = qcow1_read_header(fd);
78786835cedSPrasad Joshi 	if (!h)
78886835cedSPrasad Joshi 		goto error;
78986835cedSPrasad Joshi 
79086835cedSPrasad Joshi 	if (qcow_read_l1_table(q) < 0)
79186835cedSPrasad Joshi 		goto error;
79286835cedSPrasad Joshi 
7937d22135fSAsias He 	/*
7947d22135fSAsias He 	 * Do not use mmap use read/write instead
7957d22135fSAsias He 	 */
796f10860caSPekka Enberg 	if (readonly)
797b1c84095SPekka Enberg 		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_NOMMAP);
798f10860caSPekka Enberg 	else
799b1c84095SPekka Enberg 		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_NOMMAP);
800f10860caSPekka Enberg 
80186835cedSPrasad Joshi 	if (!disk_image)
80286835cedSPrasad Joshi 		goto error;
80386835cedSPrasad Joshi 	disk_image->priv = q;
80486835cedSPrasad Joshi 
80586835cedSPrasad Joshi 	return disk_image;
80686835cedSPrasad Joshi error:
80786835cedSPrasad Joshi 	if (!q)
80886835cedSPrasad Joshi 		return NULL;
80986835cedSPrasad Joshi 
8106c6f79b6SPrasad Joshi 	free(q->table.l1_table);
81186835cedSPrasad Joshi 	free(q->header);
81286835cedSPrasad Joshi 	free(q);
81386835cedSPrasad Joshi 
81486835cedSPrasad Joshi 	return NULL;
81586835cedSPrasad Joshi }
81686835cedSPrasad Joshi 
817ad627d62SPekka Enberg static bool qcow1_check_image(int fd)
81886835cedSPrasad Joshi {
819ad627d62SPekka Enberg 	struct qcow1_header_disk f_header;
82086835cedSPrasad Joshi 
821ad627d62SPekka Enberg 	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0)
822ad627d62SPekka Enberg 		return false;
82386835cedSPrasad Joshi 
824ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
825ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
82686835cedSPrasad Joshi 
827ad627d62SPekka Enberg 	if (f_header.magic != QCOW_MAGIC)
828ad627d62SPekka Enberg 		return false;
82986835cedSPrasad Joshi 
830ad627d62SPekka Enberg 	if (f_header.version != QCOW1_VERSION)
831ad627d62SPekka Enberg 		return false;
83286835cedSPrasad Joshi 
833ad627d62SPekka Enberg 	return true;
83486835cedSPrasad Joshi }
83586835cedSPrasad Joshi 
836f10860caSPekka Enberg struct disk_image *qcow_probe(int fd, bool readonly)
83786835cedSPrasad Joshi {
838ad627d62SPekka Enberg 	if (qcow1_check_image(fd))
839f10860caSPekka Enberg 		return qcow1_probe(fd, readonly);
840ad627d62SPekka Enberg 
841ad627d62SPekka Enberg 	if (qcow2_check_image(fd))
842f10860caSPekka Enberg 		return qcow2_probe(fd, readonly);
843ad627d62SPekka Enberg 
844ad627d62SPekka Enberg 	return NULL;
84586835cedSPrasad Joshi }
846