qcow2-util.c revision 1c7dd82563ff2e71a067aea20d2acb2d0553644b
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe This file is part of systemd.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Copyright 2015 Lennart Poettering
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe systemd is free software; you can redistribute it and/or modify it
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe under the terms of the GNU Lesser General Public License as published by
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe the Free Software Foundation; either version 2.1 of the License, or
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe (at your option) any later version.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe systemd is distributed in the hope that it will be useful, but
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Lesser General Public License for more details.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe You should have received a copy of the GNU Lesser General Public License
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe along with systemd; If not, see <http://www.gnu.org/licenses/>.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe /* The remainder is only present on QCOW3 */
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_MAGIC(header) be32toh((header)->magic)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_VERSION(header) be32toh((header)->version)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_CLUSTER_BITS(header) be32toh((header)->cluster_bits)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_CLUSTER_SIZE(header) (1ULL << HEADER_CLUSTER_BITS(header))
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_L2_BITS(header) (HEADER_CLUSTER_BITS(header) - 3)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_SIZE(header) be64toh((header)->size)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_CRYPT_METHOD(header) be32toh((header)->crypt_method)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_L1_SIZE(header) be32toh((header)->l1_size)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_L2_SIZE(header) (HEADER_CLUSTER_SIZE(header)/sizeof(uint64_t))
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define HEADER_L1_TABLE_OFFSET(header) be64toh((header)->l1_table_offset)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowestatic uint32_t HEADER_HEADER_LENGTH(const Header *h) {
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe return offsetof(Header, incompatible_features);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe r = btrfs_clone_range(sfd, soffset, dfd, doffset, cluster_size);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe l = pwrite(dfd, buffer, cluster_size, doffset);
void *buffer1,
void *buffer2) {
z_stream s = {};
ssize_t l;
if (!large_buffer)
return -ENOMEM;
return -errno;
return -EIO;
if (r != Z_OK)
return -EIO;
inflateEnd(&s);
return -EIO;
return -errno;
return -EIO;
static int normalize_offset(
uint64_t p,
bool *compressed,
uint64_t q;
q = be64toh(p);
if (q & QCOW2_COMPRESSED) {
if (!compressed)
return -ENOTSUP;
if (compressed_size)
*compressed = true;
if (compressed) {
*compressed = false;
*compressed_size = 0;
if (q & QCOW2_ZERO) {
*ret = 0;
q &= ~QCOW2_COPIED;
*ret = q;
return -EBADMSG;
return -ENOTSUP;
return -ENOTSUP;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
return -ENOTSUP;
return -EBADMSG;
ssize_t l;
return -errno;
if (l != sizeof(header))
return -EIO;
if (!l1_table)
return -ENOMEM;
if (!l2_table)
return -ENOMEM;
if (!buffer1)
return -ENOMEM;
if (!buffer2)
return -ENOMEM;
return -errno;
return -errno;
return -errno;
return -EIO;
return -errno;
return -EIO;
bool compressed;
if (compressed)
r = decompress_cluster(
raw_fd, p,
r = copy_cluster(
raw_fd, p,
ssize_t l;
return -errno;
if (l != sizeof(id))
return -EIO;