#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
-#include <linux/sort.h>
#include "qcow2.h"
#include "tools-util.h"
if (img->l1_index != -1) {
img->l1_table[img->l1_index] =
cpu_to_be64(img->offset|QCOW_OFLAG_COPIED);
- xpwrite(img->fd, img->l2_table, img->block_size, img->offset);
+ xpwrite(img->fd, img->l2_table, img->block_size, img->offset,
+ "qcow2 l2 table");
img->offset += img->block_size;
memset(img->l2_table, 0, img->block_size);
img->l2_table[l2_index] = cpu_to_be64(dst_offset|QCOW_OFLAG_COPIED);
}
-static int range_cmp(const void *_l, const void *_r)
-{
- const struct range *l = _l, *r = _r;
-
- if (l->start < r->start)
- return -1;
- if (l->start > r->start)
- return 1;
- return 0;
-}
-
-void qcow2_write_image(int infd, int outfd, sparse_data *data,
+void qcow2_write_image(int infd, int outfd, ranges *data,
unsigned block_size)
{
- u64 image_size = get_size(NULL, infd);
+ u64 image_size = get_size(infd);
unsigned l2_size = block_size / sizeof(u64);
unsigned l1_size = DIV_ROUND_UP(image_size, (u64) block_size * l2_size);
struct qcow2_hdr hdr = { 0 };
struct range *r;
char *buf = xmalloc(block_size);
u64 src_offset, dst_offset;
- sparse_data m;
assert(is_power_of_2(block_size));
- sort(&darray_item(*data, 0),
- darray_size(*data),
- sizeof(darray_item(*data, 0)),
- range_cmp, NULL);
-
- /* Round to blocksize, merge contiguous ranges: */
- darray_init(m);
- darray_foreach(r, *data) {
- struct range *l = m.size ? &m.item[m.size - 1] : NULL;
-
- r->start = round_down(r->start, block_size);
- r->end = round_up(r->end, block_size);
-
- if (l && l->end >= r->start)
- l->end = max(l->end, r->end);
- else
- darray_append(m, *r);
- }
- darray_free(*data);
- *data = m;
+ ranges_roundup(data, block_size);
+ ranges_sort_merge(data);
/* Write data: */
- darray_foreach(r, *data)
+ darray_for_each(*data, r)
for (src_offset = r->start;
src_offset < r->end;
src_offset += block_size) {
img.offset += img.block_size;
xpread(infd, buf, block_size, src_offset);
- xpwrite(outfd, buf, block_size, dst_offset);
+ xpwrite(outfd, buf, block_size, dst_offset,
+ "qcow2 data");
add_l2(&img, src_offset / block_size, dst_offset);
}
/* Write L1 table: */
dst_offset = img.offset;
img.offset += round_up(l1_size * sizeof(u64), block_size);
- xpwrite(img.fd, img.l1_table, l1_size * sizeof(u64), dst_offset);
+ xpwrite(img.fd, img.l1_table, l1_size * sizeof(u64), dst_offset,
+ "qcow2 l1 table");
/* Write header: */
hdr.magic = cpu_to_be32(QCOW_MAGIC);
memset(buf, 0, block_size);
memcpy(buf, &hdr, sizeof(hdr));
- xpwrite(img.fd, buf, block_size, 0);
+ xpwrite(img.fd, buf, block_size, 0,
+ "qcow2 header");
free(img.l2_table);
free(img.l1_table);