2 * Copyright (c) 2014 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/types.h>
31 #include <sys/endian.h>
32 #include <sys/errno.h>
43 /* Default cluster sizes. */
44 #define QCOW1_CLSTR_LOG2SZ 12 /* 4KB */
45 #define QCOW2_CLSTR_LOG2SZ 16 /* 64KB */
47 /* Flag bits in cluster offsets */
48 #define QCOW_CLSTR_COMPRESSED (1ULL << 62)
49 #define QCOW_CLSTR_COPIED (1ULL << 63)
53 #define QCOW_MAGIC 0x514649fb
55 #define QCOW_VERSION_1 1
56 #define QCOW_VERSION_2 2
59 uint32_t clstr_log2sz; /* v2 only */
73 uint64_t refcnt_offset;
74 uint32_t refcnt_clstrs;
75 uint32_t snapshot_count;
76 uint64_t snapshot_offset;
81 static u_int clstr_log2sz;
84 round_clstr(uint64_t ofs)
88 clstrsz = 1UL << clstr_log2sz;
89 return ((ofs + clstrsz - 1) & ~(clstrsz - 1));
93 qcow_resize(lba_t imgsz, u_int version)
99 clstr_log2sz = QCOW1_CLSTR_LOG2SZ;
102 clstr_log2sz = QCOW2_CLSTR_LOG2SZ;
108 imagesz = round_clstr(imgsz * secsz);
111 fprintf(stderr, "QCOW: image size = %ju, cluster size = %u\n",
112 (uintmax_t)imagesz, (u_int)(1U << clstr_log2sz));
114 return (image_set_size(imagesz / secsz));
118 qcow1_resize(lba_t imgsz)
121 return (qcow_resize(imgsz, QCOW_VERSION_1));
125 qcow2_resize(lba_t imgsz)
128 return (qcow_resize(imgsz, QCOW_VERSION_2));
132 qcow_write(int fd, u_int version)
134 struct qcow_header *hdr;
135 uint64_t *l1tbl, *l2tbl, *rctbl;
137 uint64_t clstr_imgsz, clstr_l2tbls, clstr_l1tblsz;
138 uint64_t clstr_rcblks, clstr_rctblsz;
139 uint64_t n, imagesz, nclstrs, ofs, ofsflags;
140 lba_t blk, blkofs, blk_imgsz;
141 u_int l1clno, l2clno, rcclno;
142 u_int blk_clstrsz, refcnt_clstrs;
143 u_int clstrsz, l1idx, l2idx;
146 if (clstr_log2sz == 0)
149 clstrsz = 1U << clstr_log2sz;
150 blk_clstrsz = clstrsz / secsz;
151 blk_imgsz = image_get_size();
152 imagesz = blk_imgsz * secsz;
153 clstr_imgsz = imagesz >> clstr_log2sz;
154 clstr_l2tbls = round_clstr(clstr_imgsz * 8) >> clstr_log2sz;
155 clstr_l1tblsz = round_clstr(clstr_l2tbls * 8) >> clstr_log2sz;
156 nclstrs = clstr_imgsz + clstr_l2tbls + clstr_l1tblsz + 1;
157 clstr_rcblks = clstr_rctblsz = 0;
159 n = clstr_rcblks + clstr_rctblsz;
160 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz;
161 clstr_rctblsz = round_clstr(clstr_rcblks * 8) >> clstr_log2sz;
162 } while (n < (clstr_rcblks + clstr_rctblsz));
165 * We got all the sizes in clusters. Start the layout.
168 * 2 - RC table (v2 only)
170 * 4 - RC block (v2 only)
176 rctbl = l2tbl = l1tbl = NULL;
179 hdr = calloc(1, clstrsz);
183 be32enc(&hdr->magic, QCOW_MAGIC);
184 be32enc(&hdr->version, version);
185 be64enc(&hdr->disk_size, imagesz);
189 l2clno = l1clno + clstr_l1tblsz;
190 hdr->u.v1.clstr_log2sz = clstr_log2sz;
191 hdr->u.v1.l2_log2sz = clstr_log2sz - 3;
192 be64enc(&hdr->u.v1.l1_offset, clstrsz * l1clno);
195 ofsflags = QCOW_CLSTR_COPIED;
196 rcclno = l1clno + clstr_l1tblsz;
197 l2clno = rcclno + clstr_rctblsz;
198 be32enc(&hdr->clstr_log2sz, clstr_log2sz);
199 be32enc(&hdr->u.v2.l1_entries, clstr_l2tbls);
200 be64enc(&hdr->u.v2.l1_offset, clstrsz * l1clno);
201 be64enc(&hdr->u.v2.refcnt_offset, clstrsz * rcclno);
202 refcnt_clstrs = round_clstr(clstr_rcblks * 8) >> clstr_log2sz;
203 be32enc(&hdr->u.v2.refcnt_clstrs, refcnt_clstrs);
209 if (sparse_write(fd, hdr, clstrsz) < 0) {
217 ofs = clstrsz * l2clno;
218 nclstrs = 1 + clstr_l1tblsz + clstr_rctblsz;
220 l1tbl = calloc(1, clstrsz * clstr_l1tblsz);
226 for (n = 0; n < clstr_imgsz; n++) {
227 blk = n * blk_clstrsz;
228 if (image_data(blk, blk_clstrsz)) {
230 l1idx = n >> (clstr_log2sz - 3);
231 if (l1tbl[l1idx] == 0) {
232 be64enc(l1tbl + l1idx, ofs + ofsflags);
239 if (sparse_write(fd, l1tbl, clstrsz * clstr_l1tblsz) < 0) {
247 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz;
248 } while (n < clstr_rcblks);
251 rctbl = calloc(1, clstrsz * clstr_rctblsz);
256 for (n = 0; n < clstr_rcblks; n++) {
257 be64enc(rctbl + n, ofs);
261 if (sparse_write(fd, rctbl, clstrsz * clstr_rctblsz) < 0) {
269 l2tbl = malloc(clstrsz);
275 for (l1idx = 0; l1idx < clstr_l2tbls; l1idx++) {
276 if (l1tbl[l1idx] == 0)
278 memset(l2tbl, 0, clstrsz);
279 blkofs = (lba_t)l1idx * blk_clstrsz * (clstrsz >> 3);
280 for (l2idx = 0; l2idx < (clstrsz >> 3); l2idx++) {
281 blk = blkofs + (lba_t)l2idx * blk_clstrsz;
282 if (blk >= blk_imgsz)
284 if (image_data(blk, blk_clstrsz)) {
285 be64enc(l2tbl + l2idx, ofs + ofsflags);
289 if (sparse_write(fd, l2tbl, clstrsz) < 0) {
301 rcblk = calloc(1, clstrsz * clstr_rcblks);
306 for (n = 0; n < nclstrs; n++)
307 be16enc(rcblk + n, 1);
308 if (sparse_write(fd, rcblk, clstrsz * clstr_rcblks) < 0) {
317 for (n = 0; n < clstr_imgsz; n++) {
318 blk = n * blk_clstrsz;
319 if (image_data(blk, blk_clstrsz)) {
320 error = image_copyout_region(fd, blk, blk_clstrsz);
326 error = image_copyout_done(fd);
346 return (qcow_write(fd, QCOW_VERSION_1));
353 return (qcow_write(fd, QCOW_VERSION_2));
356 static struct mkimg_format qcow1_format = {
358 .description = "QEMU Copy-On-Write, version 1",
359 .resize = qcow1_resize,
360 .write = qcow1_write,
362 FORMAT_DEFINE(qcow1_format);
364 static struct mkimg_format qcow2_format = {
366 .description = "QEMU Copy-On-Write, version 2",
367 .resize = qcow2_resize,
368 .write = qcow2_write,
370 FORMAT_DEFINE(qcow2_format);