1019d6b8fSAnthony Liguori /*
2019d6b8fSAnthony Liguori * Block driver for Parallels disk image format
3019d6b8fSAnthony Liguori *
4019d6b8fSAnthony Liguori * Copyright (c) 2007 Alex Beregszaszi
5cc5690f2SDenis V. Lunev * Copyright (c) 2015 Denis V. Lunev <den@openvz.org>
6019d6b8fSAnthony Liguori *
7cc5690f2SDenis V. Lunev * This code was originally based on comparing different disk images created
8cc5690f2SDenis V. Lunev * by Parallels. Currently it is based on opened OpenVZ sources
9cc5690f2SDenis V. Lunev * available at
10cc5690f2SDenis V. Lunev * http://git.openvz.org/?p=ploop;a=summary
11019d6b8fSAnthony Liguori *
12019d6b8fSAnthony Liguori * Permission is hereby granted, free of charge, to any person obtaining a copy
13019d6b8fSAnthony Liguori * of this software and associated documentation files (the "Software"), to deal
14019d6b8fSAnthony Liguori * in the Software without restriction, including without limitation the rights
15019d6b8fSAnthony Liguori * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16019d6b8fSAnthony Liguori * copies of the Software, and to permit persons to whom the Software is
17019d6b8fSAnthony Liguori * furnished to do so, subject to the following conditions:
18019d6b8fSAnthony Liguori *
19019d6b8fSAnthony Liguori * The above copyright notice and this permission notice shall be included in
20019d6b8fSAnthony Liguori * all copies or substantial portions of the Software.
21019d6b8fSAnthony Liguori *
22019d6b8fSAnthony Liguori * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23019d6b8fSAnthony Liguori * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24019d6b8fSAnthony Liguori * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25019d6b8fSAnthony Liguori * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26019d6b8fSAnthony Liguori * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27019d6b8fSAnthony Liguori * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28019d6b8fSAnthony Liguori * THE SOFTWARE.
29019d6b8fSAnthony Liguori */
30922a01a0SMarkus Armbruster
3180c71a24SPeter Maydell #include "qemu/osdep.h"
32baefd977SVladimir Sementsov-Ogievskiy #include "qemu/error-report.h"
33da34e65cSMarkus Armbruster #include "qapi/error.h"
34737e150eSPaolo Bonzini #include "block/block_int.h"
35609f45eaSMax Reitz #include "block/qdict.h"
368942764fSKevin Wolf #include "sysemu/block-backend.h"
371de7afc9SPaolo Bonzini #include "qemu/module.h"
38922a01a0SMarkus Armbruster #include "qemu/option.h"
391511b490SKevin Wolf #include "qapi/qmp/qdict.h"
401511b490SKevin Wolf #include "qapi/qobject-input-visitor.h"
411511b490SKevin Wolf #include "qapi/qapi-visit-block-core.h"
4258369e22SPaolo Bonzini #include "qemu/bswap.h"
430d31c7c2SDenis V. Lunev #include "qemu/bitmap.h"
445df022cfSPeter Maydell #include "qemu/memalign.h"
451d0f37cfSJeff Cody #include "migration/blocker.h"
4690fe66f0SKlim Kireev #include "parallels.h"
47019d6b8fSAnthony Liguori
48019d6b8fSAnthony Liguori /**************************************************************/
49019d6b8fSAnthony Liguori
50019d6b8fSAnthony Liguori #define HEADER_MAGIC "WithoutFreeSpace"
51d25d5980SDenis V. Lunev #define HEADER_MAGIC2 "WithouFreSpacExt"
52019d6b8fSAnthony Liguori #define HEADER_VERSION 2
536dd6b9f1SDenis V. Lunev #define HEADER_INUSE_MAGIC (0x746F6E59)
54555a608cSKlim Kireev #define MAX_PARALLELS_IMAGE_FACTOR (1ull << 32)
55019d6b8fSAnthony Liguori
56f7abe0ecSMarc-André Lureau static QEnumLookup prealloc_mode_lookup = {
57f7abe0ecSMarc-André Lureau .array = (const char *const[]) {
58d6179011SDenis V. Lunev "falloc",
59d6179011SDenis V. Lunev "truncate",
60f7abe0ecSMarc-André Lureau },
61f7abe0ecSMarc-André Lureau .size = PRL_PREALLOC_MODE__MAX
62d6179011SDenis V. Lunev };
63d6179011SDenis V. Lunev
64d6179011SDenis V. Lunev #define PARALLELS_OPT_PREALLOC_MODE "prealloc-mode"
65d6179011SDenis V. Lunev #define PARALLELS_OPT_PREALLOC_SIZE "prealloc-size"
66d6179011SDenis V. Lunev
67d6179011SDenis V. Lunev static QemuOptsList parallels_runtime_opts = {
68d6179011SDenis V. Lunev .name = "parallels",
69d6179011SDenis V. Lunev .head = QTAILQ_HEAD_INITIALIZER(parallels_runtime_opts.head),
70d6179011SDenis V. Lunev .desc = {
71d6179011SDenis V. Lunev {
72d6179011SDenis V. Lunev .name = PARALLELS_OPT_PREALLOC_SIZE,
73d6179011SDenis V. Lunev .type = QEMU_OPT_SIZE,
74d6179011SDenis V. Lunev .help = "Preallocation size on image expansion",
75ff5bbe56SEdgar Kaziahmedov .def_value_str = "128M",
76d6179011SDenis V. Lunev },
77d6179011SDenis V. Lunev {
78d6179011SDenis V. Lunev .name = PARALLELS_OPT_PREALLOC_MODE,
79d6179011SDenis V. Lunev .type = QEMU_OPT_STRING,
80d6179011SDenis V. Lunev .help = "Preallocation mode on image expansion "
81d6179011SDenis V. Lunev "(allowed values: falloc, truncate)",
82d6179011SDenis V. Lunev .def_value_str = "falloc",
83d6179011SDenis V. Lunev },
84d6179011SDenis V. Lunev { /* end of list */ },
85d6179011SDenis V. Lunev },
86d6179011SDenis V. Lunev };
87d6179011SDenis V. Lunev
881511b490SKevin Wolf static QemuOptsList parallels_create_opts = {
891511b490SKevin Wolf .name = "parallels-create-opts",
901511b490SKevin Wolf .head = QTAILQ_HEAD_INITIALIZER(parallels_create_opts.head),
911511b490SKevin Wolf .desc = {
921511b490SKevin Wolf {
931511b490SKevin Wolf .name = BLOCK_OPT_SIZE,
941511b490SKevin Wolf .type = QEMU_OPT_SIZE,
951511b490SKevin Wolf .help = "Virtual disk size",
961511b490SKevin Wolf },
971511b490SKevin Wolf {
981511b490SKevin Wolf .name = BLOCK_OPT_CLUSTER_SIZE,
991511b490SKevin Wolf .type = QEMU_OPT_SIZE,
1001511b490SKevin Wolf .help = "Parallels image cluster size",
1011511b490SKevin Wolf .def_value_str = stringify(DEFAULT_CLUSTER_SIZE),
1021511b490SKevin Wolf },
1031511b490SKevin Wolf { /* end of list */ }
1041511b490SKevin Wolf }
1051511b490SKevin Wolf };
1061511b490SKevin Wolf
107d6179011SDenis V. Lunev
bat2sect(BDRVParallelsState * s,uint32_t idx)108555cc9d9SDenis V. Lunev static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
109555cc9d9SDenis V. Lunev {
110dd97cdc0SDenis V. Lunev return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier;
111555cc9d9SDenis V. Lunev }
112555cc9d9SDenis V. Lunev
bat_entry_off(uint32_t idx)1132d68e22eSDenis V. Lunev static uint32_t bat_entry_off(uint32_t idx)
1142d68e22eSDenis V. Lunev {
1152d68e22eSDenis V. Lunev return sizeof(ParallelsHeader) + sizeof(uint32_t) * idx;
1162d68e22eSDenis V. Lunev }
1172d68e22eSDenis V. Lunev
seek_to_sector(BDRVParallelsState * s,int64_t sector_num)11829442569SRoman Kagan static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
119019d6b8fSAnthony Liguori {
120c34d2451SDavid Woodhouse uint32_t index, offset;
121019d6b8fSAnthony Liguori
122019d6b8fSAnthony Liguori index = sector_num / s->tracks;
123019d6b8fSAnthony Liguori offset = sector_num % s->tracks;
124019d6b8fSAnthony Liguori
1259d8b88f6SChristoph Hellwig /* not allocated */
126369f7de9SDenis V. Lunev if ((index >= s->bat_size) || (s->bat_bitmap[index] == 0)) {
127019d6b8fSAnthony Liguori return -1;
128369f7de9SDenis V. Lunev }
129555cc9d9SDenis V. Lunev return bat2sect(s, index) + offset;
130019d6b8fSAnthony Liguori }
131019d6b8fSAnthony Liguori
cluster_remainder(BDRVParallelsState * s,int64_t sector_num,int nb_sectors)1329de9da17SRoman Kagan static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
1339de9da17SRoman Kagan int nb_sectors)
1349de9da17SRoman Kagan {
1359de9da17SRoman Kagan int ret = s->tracks - sector_num % s->tracks;
1369de9da17SRoman Kagan return MIN(nb_sectors, ret);
1379de9da17SRoman Kagan }
1389de9da17SRoman Kagan
host_cluster_index(BDRVParallelsState * s,int64_t off)1396bb8bc63SAlexander Ivanov static uint32_t host_cluster_index(BDRVParallelsState *s, int64_t off)
1406bb8bc63SAlexander Ivanov {
1416bb8bc63SAlexander Ivanov off -= s->data_start << BDRV_SECTOR_BITS;
1426bb8bc63SAlexander Ivanov return off / s->cluster_size;
1436bb8bc63SAlexander Ivanov }
1446bb8bc63SAlexander Ivanov
block_status(BDRVParallelsState * s,int64_t sector_num,int nb_sectors,int * pnum)1456953d920SDenis V. Lunev static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
1466953d920SDenis V. Lunev int nb_sectors, int *pnum)
1476953d920SDenis V. Lunev {
1486953d920SDenis V. Lunev int64_t start_off = -2, prev_end_off = -2;
1496953d920SDenis V. Lunev
1506953d920SDenis V. Lunev *pnum = 0;
1516953d920SDenis V. Lunev while (nb_sectors > 0 || start_off == -2) {
1526953d920SDenis V. Lunev int64_t offset = seek_to_sector(s, sector_num);
1536953d920SDenis V. Lunev int to_end;
1546953d920SDenis V. Lunev
1556953d920SDenis V. Lunev if (start_off == -2) {
1566953d920SDenis V. Lunev start_off = offset;
1576953d920SDenis V. Lunev prev_end_off = offset;
1586953d920SDenis V. Lunev } else if (offset != prev_end_off) {
1596953d920SDenis V. Lunev break;
1606953d920SDenis V. Lunev }
1616953d920SDenis V. Lunev
1626953d920SDenis V. Lunev to_end = cluster_remainder(s, sector_num, nb_sectors);
1636953d920SDenis V. Lunev nb_sectors -= to_end;
1646953d920SDenis V. Lunev sector_num += to_end;
1656953d920SDenis V. Lunev *pnum += to_end;
1666953d920SDenis V. Lunev
1676953d920SDenis V. Lunev if (offset > 0) {
1686953d920SDenis V. Lunev prev_end_off += to_end;
1696953d920SDenis V. Lunev }
1706953d920SDenis V. Lunev }
1716953d920SDenis V. Lunev return start_off;
1726953d920SDenis V. Lunev }
1736953d920SDenis V. Lunev
parallels_set_bat_entry(BDRVParallelsState * s,uint32_t index,uint32_t offset)174b64b29b9SAlexander Ivanov static void parallels_set_bat_entry(BDRVParallelsState *s,
175b64b29b9SAlexander Ivanov uint32_t index, uint32_t offset)
176b64b29b9SAlexander Ivanov {
177b64b29b9SAlexander Ivanov s->bat_bitmap[index] = cpu_to_le32(offset);
178b64b29b9SAlexander Ivanov bitmap_set(s->bat_dirty_bmap, bat_entry_off(index) / s->bat_dirty_block, 1);
179b64b29b9SAlexander Ivanov }
180b64b29b9SAlexander Ivanov
mark_used(BlockDriverState * bs,unsigned long * bitmap,uint32_t bitmap_size,int64_t off,uint32_t count)18173194d3fSDenis V. Lunev static int mark_used(BlockDriverState *bs, unsigned long *bitmap,
18273194d3fSDenis V. Lunev uint32_t bitmap_size, int64_t off, uint32_t count)
183a398275eSDenis V. Lunev {
184a398275eSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
185a398275eSDenis V. Lunev uint32_t cluster_index = host_cluster_index(s, off);
18673194d3fSDenis V. Lunev unsigned long next_used;
187*b62e82beSDmitry Frolov if ((uint64_t)cluster_index + count > bitmap_size) {
188a398275eSDenis V. Lunev return -E2BIG;
189a398275eSDenis V. Lunev }
19073194d3fSDenis V. Lunev next_used = find_next_bit(bitmap, bitmap_size, cluster_index);
191*b62e82beSDmitry Frolov if (next_used < (uint64_t)cluster_index + count) {
192a398275eSDenis V. Lunev return -EBUSY;
193a398275eSDenis V. Lunev }
19473194d3fSDenis V. Lunev bitmap_set(bitmap, cluster_index, count);
195a398275eSDenis V. Lunev return 0;
196a398275eSDenis V. Lunev }
197a398275eSDenis V. Lunev
198e185100fSDenis V. Lunev /*
199e185100fSDenis V. Lunev * Collect used bitmap. The image can contain errors, we should fill the
200e185100fSDenis V. Lunev * bitmap anyway, as much as we can. This information will be used for
201e185100fSDenis V. Lunev * error resolution.
202e185100fSDenis V. Lunev */
parallels_fill_used_bitmap(BlockDriverState * bs)2031f051dcbSKevin Wolf static int GRAPH_RDLOCK parallels_fill_used_bitmap(BlockDriverState *bs)
204e185100fSDenis V. Lunev {
205e185100fSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
206e185100fSDenis V. Lunev int64_t payload_bytes;
207e185100fSDenis V. Lunev uint32_t i;
208e185100fSDenis V. Lunev int err = 0;
209e185100fSDenis V. Lunev
210e185100fSDenis V. Lunev payload_bytes = bdrv_getlength(bs->file->bs);
211e185100fSDenis V. Lunev if (payload_bytes < 0) {
212e185100fSDenis V. Lunev return payload_bytes;
213e185100fSDenis V. Lunev }
214e185100fSDenis V. Lunev payload_bytes -= s->data_start * BDRV_SECTOR_SIZE;
215e185100fSDenis V. Lunev if (payload_bytes < 0) {
216e185100fSDenis V. Lunev return -EINVAL;
217e185100fSDenis V. Lunev }
218e185100fSDenis V. Lunev
219e185100fSDenis V. Lunev s->used_bmap_size = DIV_ROUND_UP(payload_bytes, s->cluster_size);
220e185100fSDenis V. Lunev if (s->used_bmap_size == 0) {
221e185100fSDenis V. Lunev return 0;
222e185100fSDenis V. Lunev }
223e185100fSDenis V. Lunev s->used_bmap = bitmap_try_new(s->used_bmap_size);
224e185100fSDenis V. Lunev if (s->used_bmap == NULL) {
225e185100fSDenis V. Lunev return -ENOMEM;
226e185100fSDenis V. Lunev }
227e185100fSDenis V. Lunev
228e185100fSDenis V. Lunev for (i = 0; i < s->bat_size; i++) {
229e185100fSDenis V. Lunev int err2;
230e185100fSDenis V. Lunev int64_t host_off = bat2sect(s, i) << BDRV_SECTOR_BITS;
231e185100fSDenis V. Lunev if (host_off == 0) {
232e185100fSDenis V. Lunev continue;
233e185100fSDenis V. Lunev }
234e185100fSDenis V. Lunev
23573194d3fSDenis V. Lunev err2 = mark_used(bs, s->used_bmap, s->used_bmap_size, host_off, 1);
236e185100fSDenis V. Lunev if (err2 < 0 && err == 0) {
237e185100fSDenis V. Lunev err = err2;
238e185100fSDenis V. Lunev }
239e185100fSDenis V. Lunev }
240e185100fSDenis V. Lunev return err;
241e185100fSDenis V. Lunev }
242e185100fSDenis V. Lunev
parallels_free_used_bitmap(BlockDriverState * bs)243e185100fSDenis V. Lunev static void parallels_free_used_bitmap(BlockDriverState *bs)
244e185100fSDenis V. Lunev {
245e185100fSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
246e185100fSDenis V. Lunev s->used_bmap_size = 0;
247e185100fSDenis V. Lunev g_free(s->used_bmap);
248e185100fSDenis V. Lunev }
249e185100fSDenis V. Lunev
250c2b8e315SKevin Wolf static int64_t coroutine_fn GRAPH_RDLOCK
allocate_clusters(BlockDriverState * bs,int64_t sector_num,int nb_sectors,int * pnum)251c2b8e315SKevin Wolf allocate_clusters(BlockDriverState *bs, int64_t sector_num,
252ddd2ef2cSDenis V. Lunev int nb_sectors, int *pnum)
2535a41e1faSDenis V. Lunev {
254bda4cdcbSEric Blake int ret = 0;
2555a41e1faSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
2563ac10d19SDenis V. Lunev int64_t i, pos, idx, to_allocate, first_free, host_off;
257ddd2ef2cSDenis V. Lunev
258ddd2ef2cSDenis V. Lunev pos = block_status(s, sector_num, nb_sectors, pnum);
259ddd2ef2cSDenis V. Lunev if (pos > 0) {
260ddd2ef2cSDenis V. Lunev return pos;
261ddd2ef2cSDenis V. Lunev }
2625a41e1faSDenis V. Lunev
2635a41e1faSDenis V. Lunev idx = sector_num / s->tracks;
264969401feSLaurent Vivier to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;
26586d1bd70SMax Reitz
266a338dcbbSAlexander Ivanov /*
267a338dcbbSAlexander Ivanov * This function is called only by parallels_co_writev(), which will never
26886d1bd70SMax Reitz * pass a sector_num at or beyond the end of the image (because the block
26986d1bd70SMax Reitz * layer never passes such a sector_num to that function). Therefore, idx
27086d1bd70SMax Reitz * is always below s->bat_size.
27186d1bd70SMax Reitz * block_status() will limit *pnum so that sector_num + *pnum will not
27286d1bd70SMax Reitz * exceed the image end. Therefore, idx + to_allocate cannot exceed
27386d1bd70SMax Reitz * s->bat_size.
27486d1bd70SMax Reitz * Note that s->bat_size is an unsigned int, therefore idx + to_allocate
275a338dcbbSAlexander Ivanov * will always fit into a uint32_t.
276a338dcbbSAlexander Ivanov */
27786d1bd70SMax Reitz assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
27886d1bd70SMax Reitz
2793ac10d19SDenis V. Lunev first_free = find_first_zero_bit(s->used_bmap, s->used_bmap_size);
2803ac10d19SDenis V. Lunev if (first_free == s->used_bmap_size) {
281eeb1e6dcSDenis V. Lunev uint32_t new_usedsize;
28266d201ddSDenis V. Lunev int64_t bytes = to_allocate * s->cluster_size;
28366d201ddSDenis V. Lunev bytes += s->prealloc_size * BDRV_SECTOR_SIZE;
284eeb1e6dcSDenis V. Lunev
2853ac10d19SDenis V. Lunev host_off = s->data_end * BDRV_SECTOR_SIZE;
2863ac10d19SDenis V. Lunev
287bda4cdcbSEric Blake /*
288bda4cdcbSEric Blake * We require the expanded size to read back as zero. If the
289bda4cdcbSEric Blake * user permitted truncation, we try that; but if it fails, we
290bda4cdcbSEric Blake * force the safer-but-slower fallocate.
291bda4cdcbSEric Blake */
292bda4cdcbSEric Blake if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) {
29366d201ddSDenis V. Lunev ret = bdrv_co_truncate(bs->file, host_off + bytes,
29450688be0SAlberto Faria false, PREALLOC_MODE_OFF,
29550688be0SAlberto Faria BDRV_REQ_ZERO_WRITE, NULL);
296bda4cdcbSEric Blake if (ret == -ENOTSUP) {
297bda4cdcbSEric Blake s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
298bda4cdcbSEric Blake }
299bda4cdcbSEric Blake }
30019f5dc15SDenis V. Lunev if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
30166d201ddSDenis V. Lunev ret = bdrv_co_pwrite_zeroes(bs->file, host_off, bytes, 0);
3025a41e1faSDenis V. Lunev }
3035a41e1faSDenis V. Lunev if (ret < 0) {
3045a41e1faSDenis V. Lunev return ret;
3055a41e1faSDenis V. Lunev }
306eeb1e6dcSDenis V. Lunev
30766d201ddSDenis V. Lunev new_usedsize = s->used_bmap_size + bytes / s->cluster_size;
308eeb1e6dcSDenis V. Lunev s->used_bmap = bitmap_zero_extend(s->used_bmap, s->used_bmap_size,
309eeb1e6dcSDenis V. Lunev new_usedsize);
310eeb1e6dcSDenis V. Lunev s->used_bmap_size = new_usedsize;
3113ac10d19SDenis V. Lunev } else {
3123ac10d19SDenis V. Lunev int64_t next_used;
3133ac10d19SDenis V. Lunev next_used = find_next_bit(s->used_bmap, s->used_bmap_size, first_free);
3143ac10d19SDenis V. Lunev
3153ac10d19SDenis V. Lunev /* Not enough continuous clusters in the middle, adjust the size */
3163ac10d19SDenis V. Lunev if (next_used - first_free < to_allocate) {
3173ac10d19SDenis V. Lunev to_allocate = next_used - first_free;
3183ac10d19SDenis V. Lunev *pnum = (idx + to_allocate) * s->tracks - sector_num;
3193ac10d19SDenis V. Lunev }
3203ac10d19SDenis V. Lunev
3213ac10d19SDenis V. Lunev host_off = s->data_start * BDRV_SECTOR_SIZE;
3223ac10d19SDenis V. Lunev host_off += first_free * s->cluster_size;
3233ac10d19SDenis V. Lunev
3243ac10d19SDenis V. Lunev /*
3253ac10d19SDenis V. Lunev * No need to preallocate if we are using tail area from the above
3263ac10d19SDenis V. Lunev * branch. In the other case we are likely re-using hole. Preallocate
3273ac10d19SDenis V. Lunev * the space if required by the prealloc_mode.
3283ac10d19SDenis V. Lunev */
3293ac10d19SDenis V. Lunev if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE &&
3303ac10d19SDenis V. Lunev host_off < s->data_end * BDRV_SECTOR_SIZE) {
3313ac10d19SDenis V. Lunev ret = bdrv_co_pwrite_zeroes(bs->file, host_off,
3323ac10d19SDenis V. Lunev s->cluster_size * to_allocate, 0);
3333ac10d19SDenis V. Lunev if (ret < 0) {
3343ac10d19SDenis V. Lunev return ret;
3353ac10d19SDenis V. Lunev }
3363ac10d19SDenis V. Lunev }
33719f5dc15SDenis V. Lunev }
338ddd2ef2cSDenis V. Lunev
339a338dcbbSAlexander Ivanov /*
340a338dcbbSAlexander Ivanov * Try to read from backing to fill empty clusters
341bcbb3866SEdgar Kaziakhmedov * FIXME: 1. previous write_zeroes may be redundant
342bcbb3866SEdgar Kaziakhmedov * 2. most of data we read from backing will be rewritten by
343bcbb3866SEdgar Kaziakhmedov * parallels_co_writev. On aligned-to-cluster write we do not need
344bcbb3866SEdgar Kaziakhmedov * this read at all.
345bcbb3866SEdgar Kaziakhmedov * 3. it would be good to combine write of data from backing and new
346a338dcbbSAlexander Ivanov * data into one write call.
347a338dcbbSAlexander Ivanov */
348bcbb3866SEdgar Kaziakhmedov if (bs->backing) {
349bcbb3866SEdgar Kaziakhmedov int64_t nb_cow_sectors = to_allocate * s->tracks;
350bcbb3866SEdgar Kaziakhmedov int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
351a4072543SVladimir Sementsov-Ogievskiy void *buf = qemu_blockalign(bs, nb_cow_bytes);
352bcbb3866SEdgar Kaziakhmedov
353a4072543SVladimir Sementsov-Ogievskiy ret = bdrv_co_pread(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
354a4072543SVladimir Sementsov-Ogievskiy nb_cow_bytes, buf, 0);
355bcbb3866SEdgar Kaziakhmedov if (ret < 0) {
356a4072543SVladimir Sementsov-Ogievskiy qemu_vfree(buf);
357bcbb3866SEdgar Kaziakhmedov return ret;
358bcbb3866SEdgar Kaziakhmedov }
359bcbb3866SEdgar Kaziakhmedov
360eba088f9SHanna Reitz ret = bdrv_co_pwrite(bs->file, s->data_end * BDRV_SECTOR_SIZE,
361a4072543SVladimir Sementsov-Ogievskiy nb_cow_bytes, buf, 0);
362a4072543SVladimir Sementsov-Ogievskiy qemu_vfree(buf);
363bcbb3866SEdgar Kaziakhmedov if (ret < 0) {
364bcbb3866SEdgar Kaziakhmedov return ret;
365bcbb3866SEdgar Kaziakhmedov }
366bcbb3866SEdgar Kaziakhmedov }
367bcbb3866SEdgar Kaziakhmedov
3683ac10d19SDenis V. Lunev ret = mark_used(bs, s->used_bmap, s->used_bmap_size, host_off, to_allocate);
369eeb1e6dcSDenis V. Lunev if (ret < 0) {
370eeb1e6dcSDenis V. Lunev /* Image consistency is broken. Alarm! */
371eeb1e6dcSDenis V. Lunev return ret;
372eeb1e6dcSDenis V. Lunev }
373ddd2ef2cSDenis V. Lunev for (i = 0; i < to_allocate; i++) {
3743ac10d19SDenis V. Lunev parallels_set_bat_entry(s, idx + i,
3753ac10d19SDenis V. Lunev host_off / BDRV_SECTOR_SIZE / s->off_multiplier);
3763ac10d19SDenis V. Lunev host_off += s->cluster_size;
3773ac10d19SDenis V. Lunev }
3783ac10d19SDenis V. Lunev if (host_off > s->data_end * BDRV_SECTOR_SIZE) {
3793ac10d19SDenis V. Lunev s->data_end = host_off / BDRV_SECTOR_SIZE;
380ddd2ef2cSDenis V. Lunev }
3815a41e1faSDenis V. Lunev
382ddd2ef2cSDenis V. Lunev return bat2sect(s, idx) + sector_num % s->tracks;
3835a41e1faSDenis V. Lunev }
3845a41e1faSDenis V. Lunev
3850d31c7c2SDenis V. Lunev
386b9b10c35SKevin Wolf static int coroutine_fn GRAPH_RDLOCK
parallels_co_flush_to_os(BlockDriverState * bs)387b9b10c35SKevin Wolf parallels_co_flush_to_os(BlockDriverState *bs)
3880d31c7c2SDenis V. Lunev {
3890d31c7c2SDenis V. Lunev BDRVParallelsState *s = bs->opaque;
3900d31c7c2SDenis V. Lunev unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
3910d31c7c2SDenis V. Lunev unsigned long bit;
3920d31c7c2SDenis V. Lunev
3930d31c7c2SDenis V. Lunev qemu_co_mutex_lock(&s->lock);
3940d31c7c2SDenis V. Lunev
3950d31c7c2SDenis V. Lunev bit = find_first_bit(s->bat_dirty_bmap, size);
3960d31c7c2SDenis V. Lunev while (bit < size) {
3970d31c7c2SDenis V. Lunev uint32_t off = bit * s->bat_dirty_block;
3980d31c7c2SDenis V. Lunev uint32_t to_write = s->bat_dirty_block;
3990d31c7c2SDenis V. Lunev int ret;
4000d31c7c2SDenis V. Lunev
4010d31c7c2SDenis V. Lunev if (off + to_write > s->header_size) {
4020d31c7c2SDenis V. Lunev to_write = s->header_size - off;
4030d31c7c2SDenis V. Lunev }
40450688be0SAlberto Faria ret = bdrv_co_pwrite(bs->file, off, to_write,
40550688be0SAlberto Faria (uint8_t *)s->header + off, 0);
4060d31c7c2SDenis V. Lunev if (ret < 0) {
4070d31c7c2SDenis V. Lunev qemu_co_mutex_unlock(&s->lock);
4080d31c7c2SDenis V. Lunev return ret;
4090d31c7c2SDenis V. Lunev }
4100d31c7c2SDenis V. Lunev bit = find_next_bit(s->bat_dirty_bmap, size, bit + 1);
4110d31c7c2SDenis V. Lunev }
4120d31c7c2SDenis V. Lunev bitmap_zero(s->bat_dirty_bmap, size);
4130d31c7c2SDenis V. Lunev
4140d31c7c2SDenis V. Lunev qemu_co_mutex_unlock(&s->lock);
4150d31c7c2SDenis V. Lunev return 0;
4160d31c7c2SDenis V. Lunev }
4170d31c7c2SDenis V. Lunev
41879a55866SKevin Wolf static int coroutine_fn GRAPH_RDLOCK
parallels_co_block_status(BlockDriverState * bs,bool want_zero,int64_t offset,int64_t bytes,int64_t * pnum,int64_t * map,BlockDriverState ** file)41979a55866SKevin Wolf parallels_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
42079a55866SKevin Wolf int64_t bytes, int64_t *pnum, int64_t *map,
4218e0cf59dSEric Blake BlockDriverState **file)
422dd3bed16SRoman Kagan {
423dd3bed16SRoman Kagan BDRVParallelsState *s = bs->opaque;
4248e0cf59dSEric Blake int count;
425dd3bed16SRoman Kagan
4268e0cf59dSEric Blake assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
427dd3bed16SRoman Kagan qemu_co_mutex_lock(&s->lock);
4288e0cf59dSEric Blake offset = block_status(s, offset >> BDRV_SECTOR_BITS,
4298e0cf59dSEric Blake bytes >> BDRV_SECTOR_BITS, &count);
430dd3bed16SRoman Kagan qemu_co_mutex_unlock(&s->lock);
431dd3bed16SRoman Kagan
4328e0cf59dSEric Blake *pnum = count * BDRV_SECTOR_SIZE;
433dd3bed16SRoman Kagan if (offset < 0) {
434dd3bed16SRoman Kagan return 0;
435dd3bed16SRoman Kagan }
436dd3bed16SRoman Kagan
4378e0cf59dSEric Blake *map = offset * BDRV_SECTOR_SIZE;
438ddf4987dSFam Zheng *file = bs->file->bs;
4398e0cf59dSEric Blake return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
440dd3bed16SRoman Kagan }
441dd3bed16SRoman Kagan
4427b1fb72eSKevin Wolf static int coroutine_fn GRAPH_RDLOCK
parallels_co_writev(BlockDriverState * bs,int64_t sector_num,int nb_sectors,QEMUIOVector * qiov,int flags)4437b1fb72eSKevin Wolf parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
444e18a58b4SEric Blake QEMUIOVector *qiov, int flags)
4455a41e1faSDenis V. Lunev {
4465a41e1faSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
4475a41e1faSDenis V. Lunev uint64_t bytes_done = 0;
4485a41e1faSDenis V. Lunev QEMUIOVector hd_qiov;
4495a41e1faSDenis V. Lunev int ret = 0;
4505a41e1faSDenis V. Lunev
4515a41e1faSDenis V. Lunev qemu_iovec_init(&hd_qiov, qiov->niov);
4525a41e1faSDenis V. Lunev
4535a41e1faSDenis V. Lunev while (nb_sectors > 0) {
4545a41e1faSDenis V. Lunev int64_t position;
4555a41e1faSDenis V. Lunev int n, nbytes;
4565a41e1faSDenis V. Lunev
4575a41e1faSDenis V. Lunev qemu_co_mutex_lock(&s->lock);
458ddd2ef2cSDenis V. Lunev position = allocate_clusters(bs, sector_num, nb_sectors, &n);
4595a41e1faSDenis V. Lunev qemu_co_mutex_unlock(&s->lock);
4605a41e1faSDenis V. Lunev if (position < 0) {
4615a41e1faSDenis V. Lunev ret = (int)position;
4625a41e1faSDenis V. Lunev break;
4635a41e1faSDenis V. Lunev }
4645a41e1faSDenis V. Lunev
4655a41e1faSDenis V. Lunev nbytes = n << BDRV_SECTOR_BITS;
4665a41e1faSDenis V. Lunev
4675a41e1faSDenis V. Lunev qemu_iovec_reset(&hd_qiov);
4685a41e1faSDenis V. Lunev qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
4695a41e1faSDenis V. Lunev
470d08c2a24SEric Blake ret = bdrv_co_pwritev(bs->file, position * BDRV_SECTOR_SIZE, nbytes,
471d08c2a24SEric Blake &hd_qiov, 0);
4725a41e1faSDenis V. Lunev if (ret < 0) {
4735a41e1faSDenis V. Lunev break;
4745a41e1faSDenis V. Lunev }
4755a41e1faSDenis V. Lunev
4765a41e1faSDenis V. Lunev nb_sectors -= n;
4775a41e1faSDenis V. Lunev sector_num += n;
4785a41e1faSDenis V. Lunev bytes_done += nbytes;
4795a41e1faSDenis V. Lunev }
4805a41e1faSDenis V. Lunev
4815a41e1faSDenis V. Lunev qemu_iovec_destroy(&hd_qiov);
4825a41e1faSDenis V. Lunev return ret;
4835a41e1faSDenis V. Lunev }
4845a41e1faSDenis V. Lunev
485b9b10c35SKevin Wolf static int coroutine_fn GRAPH_RDLOCK
parallels_co_readv(BlockDriverState * bs,int64_t sector_num,int nb_sectors,QEMUIOVector * qiov)486b9b10c35SKevin Wolf parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
487b9b10c35SKevin Wolf QEMUIOVector *qiov)
488019d6b8fSAnthony Liguori {
48929442569SRoman Kagan BDRVParallelsState *s = bs->opaque;
490481fb9cfSDenis V. Lunev uint64_t bytes_done = 0;
491481fb9cfSDenis V. Lunev QEMUIOVector hd_qiov;
492481fb9cfSDenis V. Lunev int ret = 0;
493481fb9cfSDenis V. Lunev
494481fb9cfSDenis V. Lunev qemu_iovec_init(&hd_qiov, qiov->niov);
49529442569SRoman Kagan
496019d6b8fSAnthony Liguori while (nb_sectors > 0) {
497481fb9cfSDenis V. Lunev int64_t position;
498481fb9cfSDenis V. Lunev int n, nbytes;
499481fb9cfSDenis V. Lunev
500481fb9cfSDenis V. Lunev qemu_co_mutex_lock(&s->lock);
5016953d920SDenis V. Lunev position = block_status(s, sector_num, nb_sectors, &n);
502481fb9cfSDenis V. Lunev qemu_co_mutex_unlock(&s->lock);
503481fb9cfSDenis V. Lunev
504481fb9cfSDenis V. Lunev nbytes = n << BDRV_SECTOR_BITS;
505481fb9cfSDenis V. Lunev
506481fb9cfSDenis V. Lunev qemu_iovec_reset(&hd_qiov);
507481fb9cfSDenis V. Lunev qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
508481fb9cfSDenis V. Lunev
509bcbb3866SEdgar Kaziakhmedov if (position < 0) {
510bcbb3866SEdgar Kaziakhmedov if (bs->backing) {
511d08c2a24SEric Blake ret = bdrv_co_preadv(bs->backing, sector_num * BDRV_SECTOR_SIZE,
512d08c2a24SEric Blake nbytes, &hd_qiov, 0);
513bcbb3866SEdgar Kaziakhmedov if (ret < 0) {
514bcbb3866SEdgar Kaziakhmedov break;
515bcbb3866SEdgar Kaziakhmedov }
516bcbb3866SEdgar Kaziakhmedov } else {
517bcbb3866SEdgar Kaziakhmedov qemu_iovec_memset(&hd_qiov, 0, 0, nbytes);
518bcbb3866SEdgar Kaziakhmedov }
519bcbb3866SEdgar Kaziakhmedov } else {
520d08c2a24SEric Blake ret = bdrv_co_preadv(bs->file, position * BDRV_SECTOR_SIZE, nbytes,
521d08c2a24SEric Blake &hd_qiov, 0);
522481fb9cfSDenis V. Lunev if (ret < 0) {
523481fb9cfSDenis V. Lunev break;
5249d8b88f6SChristoph Hellwig }
525019d6b8fSAnthony Liguori }
526019d6b8fSAnthony Liguori
527481fb9cfSDenis V. Lunev nb_sectors -= n;
528481fb9cfSDenis V. Lunev sector_num += n;
529481fb9cfSDenis V. Lunev bytes_done += nbytes;
530481fb9cfSDenis V. Lunev }
531481fb9cfSDenis V. Lunev
532481fb9cfSDenis V. Lunev qemu_iovec_destroy(&hd_qiov);
5332914caa0SPaolo Bonzini return ret;
5342914caa0SPaolo Bonzini }
5352914caa0SPaolo Bonzini
536c54fb435SDenis V. Lunev
537c54fb435SDenis V. Lunev static int coroutine_fn GRAPH_RDLOCK
parallels_co_pdiscard(BlockDriverState * bs,int64_t offset,int64_t bytes)538c54fb435SDenis V. Lunev parallels_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
539c54fb435SDenis V. Lunev {
540c54fb435SDenis V. Lunev int ret = 0;
541c54fb435SDenis V. Lunev uint32_t cluster, count;
542c54fb435SDenis V. Lunev BDRVParallelsState *s = bs->opaque;
543c54fb435SDenis V. Lunev
544c54fb435SDenis V. Lunev /*
545c54fb435SDenis V. Lunev * The image does not support ZERO mark inside the BAT, which means that
546c54fb435SDenis V. Lunev * stale data could be exposed from the backing file.
547c54fb435SDenis V. Lunev */
548c54fb435SDenis V. Lunev if (bs->backing) {
549c54fb435SDenis V. Lunev return -ENOTSUP;
550c54fb435SDenis V. Lunev }
551c54fb435SDenis V. Lunev
552c54fb435SDenis V. Lunev if (!QEMU_IS_ALIGNED(offset, s->cluster_size)) {
553c54fb435SDenis V. Lunev return -ENOTSUP;
554c54fb435SDenis V. Lunev } else if (!QEMU_IS_ALIGNED(bytes, s->cluster_size)) {
555c54fb435SDenis V. Lunev return -ENOTSUP;
556c54fb435SDenis V. Lunev }
557c54fb435SDenis V. Lunev
558c54fb435SDenis V. Lunev cluster = offset / s->cluster_size;
559c54fb435SDenis V. Lunev count = bytes / s->cluster_size;
560c54fb435SDenis V. Lunev
561c54fb435SDenis V. Lunev qemu_co_mutex_lock(&s->lock);
562c54fb435SDenis V. Lunev for (; count > 0; cluster++, count--) {
563c54fb435SDenis V. Lunev int64_t host_off = bat2sect(s, cluster) << BDRV_SECTOR_BITS;
564c54fb435SDenis V. Lunev if (host_off == 0) {
565c54fb435SDenis V. Lunev continue;
566c54fb435SDenis V. Lunev }
567c54fb435SDenis V. Lunev
568c54fb435SDenis V. Lunev ret = bdrv_co_pdiscard(bs->file, host_off, s->cluster_size);
569c54fb435SDenis V. Lunev if (ret < 0) {
570c54fb435SDenis V. Lunev goto done;
571c54fb435SDenis V. Lunev }
572c54fb435SDenis V. Lunev
573c54fb435SDenis V. Lunev parallels_set_bat_entry(s, cluster, 0);
574c54fb435SDenis V. Lunev bitmap_clear(s->used_bmap, host_cluster_index(s, host_off), 1);
575c54fb435SDenis V. Lunev }
576c54fb435SDenis V. Lunev done:
577c54fb435SDenis V. Lunev qemu_co_mutex_unlock(&s->lock);
578c54fb435SDenis V. Lunev return ret;
579c54fb435SDenis V. Lunev }
580c54fb435SDenis V. Lunev
581a98b260aSDenis V. Lunev static int coroutine_fn GRAPH_RDLOCK
parallels_co_pwrite_zeroes(BlockDriverState * bs,int64_t offset,int64_t bytes,BdrvRequestFlags flags)582a98b260aSDenis V. Lunev parallels_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
583a98b260aSDenis V. Lunev BdrvRequestFlags flags)
584a98b260aSDenis V. Lunev {
585a98b260aSDenis V. Lunev /*
586a98b260aSDenis V. Lunev * The zero flag is missed in the Parallels format specification. We can
587a98b260aSDenis V. Lunev * resort to discard if we have no backing file (this condition is checked
588a98b260aSDenis V. Lunev * inside parallels_co_pdiscard().
589a98b260aSDenis V. Lunev */
590a98b260aSDenis V. Lunev return parallels_co_pdiscard(bs, offset, bytes);
591a98b260aSDenis V. Lunev }
592a98b260aSDenis V. Lunev
593a98b260aSDenis V. Lunev
parallels_check_unclean(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)59496de69c7SAlexander Ivanov static void parallels_check_unclean(BlockDriverState *bs,
59596de69c7SAlexander Ivanov BdrvCheckResult *res,
59696de69c7SAlexander Ivanov BdrvCheckMode fix)
59796de69c7SAlexander Ivanov {
59896de69c7SAlexander Ivanov BDRVParallelsState *s = bs->opaque;
59996de69c7SAlexander Ivanov
60096de69c7SAlexander Ivanov if (!s->header_unclean) {
60196de69c7SAlexander Ivanov return;
60296de69c7SAlexander Ivanov }
60396de69c7SAlexander Ivanov
60496de69c7SAlexander Ivanov fprintf(stderr, "%s image was not closed correctly\n",
60596de69c7SAlexander Ivanov fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
60696de69c7SAlexander Ivanov res->corruptions++;
60796de69c7SAlexander Ivanov if (fix & BDRV_FIX_ERRORS) {
60896de69c7SAlexander Ivanov /* parallels_close will do the job right */
60996de69c7SAlexander Ivanov res->corruptions_fixed++;
61096de69c7SAlexander Ivanov s->header_unclean = false;
61196de69c7SAlexander Ivanov }
61296de69c7SAlexander Ivanov }
61349ad6467SDenis V. Lunev
6148cd19203SAlexander Ivanov /*
6158cd19203SAlexander Ivanov * Returns true if data_off is correct, otherwise false. In both cases
6168cd19203SAlexander Ivanov * correct_offset is set to the proper value.
6178cd19203SAlexander Ivanov */
parallels_test_data_off(BDRVParallelsState * s,int64_t file_nb_sectors,uint32_t * correct_offset)6188cd19203SAlexander Ivanov static bool parallels_test_data_off(BDRVParallelsState *s,
6198cd19203SAlexander Ivanov int64_t file_nb_sectors,
6208cd19203SAlexander Ivanov uint32_t *correct_offset)
6218cd19203SAlexander Ivanov {
6228cd19203SAlexander Ivanov uint32_t data_off, min_off;
6238cd19203SAlexander Ivanov bool old_magic;
6248cd19203SAlexander Ivanov
6258cd19203SAlexander Ivanov /*
6268cd19203SAlexander Ivanov * There are two slightly different image formats: with "WithoutFreeSpace"
6278cd19203SAlexander Ivanov * or "WithouFreSpacExt" magic words. Call the first one as "old magic".
6288cd19203SAlexander Ivanov * In such images data_off field can be zero. In this case the offset is
6298cd19203SAlexander Ivanov * calculated as the end of BAT table plus some padding to ensure sector
6308cd19203SAlexander Ivanov * size alignment.
6318cd19203SAlexander Ivanov */
6328cd19203SAlexander Ivanov old_magic = !memcmp(s->header->magic, HEADER_MAGIC, 16);
6338cd19203SAlexander Ivanov
6348cd19203SAlexander Ivanov min_off = DIV_ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE);
6358cd19203SAlexander Ivanov if (!old_magic) {
6368cd19203SAlexander Ivanov min_off = ROUND_UP(min_off, s->cluster_size / BDRV_SECTOR_SIZE);
6378cd19203SAlexander Ivanov }
6388cd19203SAlexander Ivanov
6398cd19203SAlexander Ivanov if (correct_offset) {
6408cd19203SAlexander Ivanov *correct_offset = min_off;
6418cd19203SAlexander Ivanov }
6428cd19203SAlexander Ivanov
6438cd19203SAlexander Ivanov data_off = le32_to_cpu(s->header->data_off);
6448cd19203SAlexander Ivanov if (data_off == 0 && old_magic) {
6458cd19203SAlexander Ivanov return true;
6468cd19203SAlexander Ivanov }
6478cd19203SAlexander Ivanov
6488cd19203SAlexander Ivanov if (data_off < min_off || data_off > file_nb_sectors) {
6498cd19203SAlexander Ivanov return false;
6508cd19203SAlexander Ivanov }
6518cd19203SAlexander Ivanov
6528cd19203SAlexander Ivanov if (correct_offset) {
6538cd19203SAlexander Ivanov *correct_offset = data_off;
6548cd19203SAlexander Ivanov }
6558cd19203SAlexander Ivanov
6568cd19203SAlexander Ivanov return true;
6578cd19203SAlexander Ivanov }
6588cd19203SAlexander Ivanov
6598cd19203SAlexander Ivanov static int coroutine_fn GRAPH_RDLOCK
parallels_check_data_off(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)6608cd19203SAlexander Ivanov parallels_check_data_off(BlockDriverState *bs, BdrvCheckResult *res,
6618cd19203SAlexander Ivanov BdrvCheckMode fix)
6628cd19203SAlexander Ivanov {
6638cd19203SAlexander Ivanov BDRVParallelsState *s = bs->opaque;
6648cd19203SAlexander Ivanov int64_t file_size;
6658cd19203SAlexander Ivanov uint32_t data_off;
6668cd19203SAlexander Ivanov
6678cd19203SAlexander Ivanov file_size = bdrv_co_nb_sectors(bs->file->bs);
6688cd19203SAlexander Ivanov if (file_size < 0) {
6698cd19203SAlexander Ivanov res->check_errors++;
6708cd19203SAlexander Ivanov return file_size;
6718cd19203SAlexander Ivanov }
6728cd19203SAlexander Ivanov
6738cd19203SAlexander Ivanov if (parallels_test_data_off(s, file_size, &data_off)) {
6748cd19203SAlexander Ivanov return 0;
6758cd19203SAlexander Ivanov }
6768cd19203SAlexander Ivanov
6778cd19203SAlexander Ivanov res->corruptions++;
6788cd19203SAlexander Ivanov if (fix & BDRV_FIX_ERRORS) {
679e185100fSDenis V. Lunev int err;
6808cd19203SAlexander Ivanov s->header->data_off = cpu_to_le32(data_off);
6816f2206b0SDenis V. Lunev s->data_start = data_off;
682e185100fSDenis V. Lunev
683e185100fSDenis V. Lunev parallels_free_used_bitmap(bs);
684e185100fSDenis V. Lunev err = parallels_fill_used_bitmap(bs);
685e185100fSDenis V. Lunev if (err == -ENOMEM) {
686e185100fSDenis V. Lunev res->check_errors++;
687e185100fSDenis V. Lunev return err;
688e185100fSDenis V. Lunev }
689e185100fSDenis V. Lunev
6908cd19203SAlexander Ivanov res->corruptions_fixed++;
6918cd19203SAlexander Ivanov }
6928cd19203SAlexander Ivanov
6938cd19203SAlexander Ivanov fprintf(stderr, "%s data_off field has incorrect value\n",
6948cd19203SAlexander Ivanov fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
6958cd19203SAlexander Ivanov
6968cd19203SAlexander Ivanov return 0;
6978cd19203SAlexander Ivanov }
6988cd19203SAlexander Ivanov
699c2b8e315SKevin Wolf static int coroutine_fn GRAPH_RDLOCK
parallels_check_outside_image(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)7006d416e56SAlexander Ivanov parallels_check_outside_image(BlockDriverState *bs, BdrvCheckResult *res,
7016d416e56SAlexander Ivanov BdrvCheckMode fix)
7026d416e56SAlexander Ivanov {
7036d416e56SAlexander Ivanov BDRVParallelsState *s = bs->opaque;
7046d416e56SAlexander Ivanov uint32_t i;
7056d416e56SAlexander Ivanov int64_t off, high_off, size;
7066d416e56SAlexander Ivanov
7070af02bd1SPaolo Bonzini size = bdrv_co_getlength(bs->file->bs);
7086d416e56SAlexander Ivanov if (size < 0) {
7096d416e56SAlexander Ivanov res->check_errors++;
7106d416e56SAlexander Ivanov return size;
7116d416e56SAlexander Ivanov }
7126d416e56SAlexander Ivanov
7136d416e56SAlexander Ivanov high_off = 0;
7146d416e56SAlexander Ivanov for (i = 0; i < s->bat_size; i++) {
7156d416e56SAlexander Ivanov off = bat2sect(s, i) << BDRV_SECTOR_BITS;
716029136f2SAlexander Ivanov if (off + s->cluster_size > size) {
7176d416e56SAlexander Ivanov fprintf(stderr, "%s cluster %u is outside image\n",
7186d416e56SAlexander Ivanov fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
7196d416e56SAlexander Ivanov res->corruptions++;
7206d416e56SAlexander Ivanov if (fix & BDRV_FIX_ERRORS) {
7216d416e56SAlexander Ivanov parallels_set_bat_entry(s, i, 0);
7226d416e56SAlexander Ivanov res->corruptions_fixed++;
7236d416e56SAlexander Ivanov }
7246d416e56SAlexander Ivanov continue;
7256d416e56SAlexander Ivanov }
7266d416e56SAlexander Ivanov if (high_off < off) {
7276d416e56SAlexander Ivanov high_off = off;
7286d416e56SAlexander Ivanov }
7296d416e56SAlexander Ivanov }
7306d416e56SAlexander Ivanov
7316d416e56SAlexander Ivanov if (high_off == 0) {
7326d416e56SAlexander Ivanov res->image_end_offset = s->data_end << BDRV_SECTOR_BITS;
7336d416e56SAlexander Ivanov } else {
7346d416e56SAlexander Ivanov res->image_end_offset = high_off + s->cluster_size;
7356d416e56SAlexander Ivanov s->data_end = res->image_end_offset >> BDRV_SECTOR_BITS;
7366d416e56SAlexander Ivanov }
7376d416e56SAlexander Ivanov
7386d416e56SAlexander Ivanov return 0;
7396d416e56SAlexander Ivanov }
7406d416e56SAlexander Ivanov
7416d416e56SAlexander Ivanov static int coroutine_fn GRAPH_RDLOCK
parallels_check_leak(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix,bool explicit)74209a21edfSAlexander Ivanov parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res,
743728e1017SAlexander Ivanov BdrvCheckMode fix, bool explicit)
74449ad6467SDenis V. Lunev {
74549ad6467SDenis V. Lunev BDRVParallelsState *s = bs->opaque;
74609a21edfSAlexander Ivanov int64_t size;
7476d416e56SAlexander Ivanov int ret;
74849ad6467SDenis V. Lunev
7497c5f86d5SAlexander Ivanov size = bdrv_co_getlength(bs->file->bs);
75049ad6467SDenis V. Lunev if (size < 0) {
75149ad6467SDenis V. Lunev res->check_errors++;
75249ad6467SDenis V. Lunev return size;
75349ad6467SDenis V. Lunev }
75449ad6467SDenis V. Lunev
75509a21edfSAlexander Ivanov if (size > res->image_end_offset) {
75609a21edfSAlexander Ivanov int64_t count;
75709a21edfSAlexander Ivanov count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size);
758728e1017SAlexander Ivanov if (explicit) {
759728e1017SAlexander Ivanov fprintf(stderr,
760728e1017SAlexander Ivanov "%s space leaked at the end of the image %" PRId64 "\n",
76109a21edfSAlexander Ivanov fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
76209a21edfSAlexander Ivanov size - res->image_end_offset);
76309a21edfSAlexander Ivanov res->leaks += count;
764728e1017SAlexander Ivanov }
76509a21edfSAlexander Ivanov if (fix & BDRV_FIX_LEAKS) {
76609a21edfSAlexander Ivanov Error *local_err = NULL;
76709a21edfSAlexander Ivanov
76809a21edfSAlexander Ivanov /*
76909a21edfSAlexander Ivanov * In order to really repair the image, we must shrink it.
77009a21edfSAlexander Ivanov * That means we have to pass exact=true.
77109a21edfSAlexander Ivanov */
77209a21edfSAlexander Ivanov ret = bdrv_co_truncate(bs->file, res->image_end_offset, true,
77309a21edfSAlexander Ivanov PREALLOC_MODE_OFF, 0, &local_err);
77409a21edfSAlexander Ivanov if (ret < 0) {
77509a21edfSAlexander Ivanov error_report_err(local_err);
77609a21edfSAlexander Ivanov res->check_errors++;
77709a21edfSAlexander Ivanov return ret;
77809a21edfSAlexander Ivanov }
779728e1017SAlexander Ivanov if (explicit) {
78009a21edfSAlexander Ivanov res->leaks_fixed += count;
78109a21edfSAlexander Ivanov }
78209a21edfSAlexander Ivanov }
783728e1017SAlexander Ivanov }
78409a21edfSAlexander Ivanov
78509a21edfSAlexander Ivanov return 0;
78609a21edfSAlexander Ivanov }
78709a21edfSAlexander Ivanov
7886bb8bc63SAlexander Ivanov static int coroutine_fn GRAPH_RDLOCK
parallels_check_duplicate(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)7896bb8bc63SAlexander Ivanov parallels_check_duplicate(BlockDriverState *bs, BdrvCheckResult *res,
7906bb8bc63SAlexander Ivanov BdrvCheckMode fix)
7916bb8bc63SAlexander Ivanov {
7926bb8bc63SAlexander Ivanov BDRVParallelsState *s = bs->opaque;
7936bb8bc63SAlexander Ivanov int64_t host_off, host_sector, guest_sector;
7946bb8bc63SAlexander Ivanov unsigned long *bitmap;
795a398275eSDenis V. Lunev uint32_t i, bitmap_size, bat_entry;
7966bb8bc63SAlexander Ivanov int n, ret = 0;
7976bb8bc63SAlexander Ivanov uint64_t *buf = NULL;
7986bb8bc63SAlexander Ivanov bool fixed = false;
7996bb8bc63SAlexander Ivanov
8006bb8bc63SAlexander Ivanov /*
8016bb8bc63SAlexander Ivanov * Create a bitmap of used clusters.
8026bb8bc63SAlexander Ivanov * If a bit is set, there is a BAT entry pointing to this cluster.
8036bb8bc63SAlexander Ivanov * Loop through the BAT entries, check bits relevant to an entry offset.
8046bb8bc63SAlexander Ivanov * If bit is set, this entry is duplicated. Otherwise set the bit.
8056bb8bc63SAlexander Ivanov *
8066bb8bc63SAlexander Ivanov * We shouldn't worry about newly allocated clusters outside the image
8076bb8bc63SAlexander Ivanov * because they are created higher then any existing cluster pointed by
8086bb8bc63SAlexander Ivanov * a BAT entry.
8096bb8bc63SAlexander Ivanov */
8106bb8bc63SAlexander Ivanov bitmap_size = host_cluster_index(s, res->image_end_offset);
8116bb8bc63SAlexander Ivanov if (bitmap_size == 0) {
8126bb8bc63SAlexander Ivanov return 0;
8136bb8bc63SAlexander Ivanov }
8146bb8bc63SAlexander Ivanov if (res->image_end_offset % s->cluster_size) {
8156bb8bc63SAlexander Ivanov /* A not aligned image end leads to a bitmap shorter by 1 */
8166bb8bc63SAlexander Ivanov bitmap_size++;
8176bb8bc63SAlexander Ivanov }
8186bb8bc63SAlexander Ivanov
8196bb8bc63SAlexander Ivanov bitmap = bitmap_new(bitmap_size);
8206bb8bc63SAlexander Ivanov
8216bb8bc63SAlexander Ivanov buf = qemu_blockalign(bs, s->cluster_size);
8226bb8bc63SAlexander Ivanov
8236bb8bc63SAlexander Ivanov for (i = 0; i < s->bat_size; i++) {
8246bb8bc63SAlexander Ivanov host_off = bat2sect(s, i) << BDRV_SECTOR_BITS;
8256bb8bc63SAlexander Ivanov if (host_off == 0) {
8266bb8bc63SAlexander Ivanov continue;
8276bb8bc63SAlexander Ivanov }
8286bb8bc63SAlexander Ivanov
82973194d3fSDenis V. Lunev ret = mark_used(bs, bitmap, bitmap_size, host_off, 1);
830a398275eSDenis V. Lunev assert(ret != -E2BIG);
831a398275eSDenis V. Lunev if (ret == 0) {
8326bb8bc63SAlexander Ivanov continue;
8336bb8bc63SAlexander Ivanov }
8346bb8bc63SAlexander Ivanov
8356bb8bc63SAlexander Ivanov /* this cluster duplicates another one */
8366bb8bc63SAlexander Ivanov fprintf(stderr, "%s duplicate offset in BAT entry %u\n",
8376bb8bc63SAlexander Ivanov fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
8386bb8bc63SAlexander Ivanov
8396bb8bc63SAlexander Ivanov res->corruptions++;
8406bb8bc63SAlexander Ivanov
8416bb8bc63SAlexander Ivanov if (!(fix & BDRV_FIX_ERRORS)) {
8426bb8bc63SAlexander Ivanov continue;
8436bb8bc63SAlexander Ivanov }
8446bb8bc63SAlexander Ivanov
8456bb8bc63SAlexander Ivanov /*
8466bb8bc63SAlexander Ivanov * Reset the entry and allocate a new cluster
8476bb8bc63SAlexander Ivanov * for the relevant guest offset. In this way we let
8486bb8bc63SAlexander Ivanov * the lower layer to place the new cluster properly.
8496bb8bc63SAlexander Ivanov * Copy the original cluster to the allocated one.
8506bb8bc63SAlexander Ivanov * But before save the old offset value for repairing
8516bb8bc63SAlexander Ivanov * if we have an error.
8526bb8bc63SAlexander Ivanov */
8536bb8bc63SAlexander Ivanov bat_entry = s->bat_bitmap[i];
8546bb8bc63SAlexander Ivanov parallels_set_bat_entry(s, i, 0);
8556bb8bc63SAlexander Ivanov
8566bb8bc63SAlexander Ivanov ret = bdrv_co_pread(bs->file, host_off, s->cluster_size, buf, 0);
8576bb8bc63SAlexander Ivanov if (ret < 0) {
8586bb8bc63SAlexander Ivanov res->check_errors++;
8596bb8bc63SAlexander Ivanov goto out_repair_bat;
8606bb8bc63SAlexander Ivanov }
8616bb8bc63SAlexander Ivanov
8626bb8bc63SAlexander Ivanov guest_sector = (i * (int64_t)s->cluster_size) >> BDRV_SECTOR_BITS;
8636bb8bc63SAlexander Ivanov host_sector = allocate_clusters(bs, guest_sector, s->tracks, &n);
8646bb8bc63SAlexander Ivanov if (host_sector < 0) {
8656bb8bc63SAlexander Ivanov res->check_errors++;
8666bb8bc63SAlexander Ivanov goto out_repair_bat;
8676bb8bc63SAlexander Ivanov }
8686bb8bc63SAlexander Ivanov host_off = host_sector << BDRV_SECTOR_BITS;
8696bb8bc63SAlexander Ivanov
8706bb8bc63SAlexander Ivanov ret = bdrv_co_pwrite(bs->file, host_off, s->cluster_size, buf, 0);
8716bb8bc63SAlexander Ivanov if (ret < 0) {
8726bb8bc63SAlexander Ivanov res->check_errors++;
8736bb8bc63SAlexander Ivanov goto out_repair_bat;
8746bb8bc63SAlexander Ivanov }
8756bb8bc63SAlexander Ivanov
8766bb8bc63SAlexander Ivanov if (host_off + s->cluster_size > res->image_end_offset) {
8776bb8bc63SAlexander Ivanov res->image_end_offset = host_off + s->cluster_size;
8786bb8bc63SAlexander Ivanov }
8796bb8bc63SAlexander Ivanov
8806bb8bc63SAlexander Ivanov /*
8816bb8bc63SAlexander Ivanov * In the future allocate_cluster() will reuse holed offsets
8826bb8bc63SAlexander Ivanov * inside the image. Keep the used clusters bitmap content
8836bb8bc63SAlexander Ivanov * consistent for the new allocated clusters too.
8846bb8bc63SAlexander Ivanov *
8856bb8bc63SAlexander Ivanov * Note, clusters allocated outside the current image are not
886a398275eSDenis V. Lunev * considered, and the bitmap size doesn't change. This specifically
887a398275eSDenis V. Lunev * means that -E2BIG is OK.
8886bb8bc63SAlexander Ivanov */
88973194d3fSDenis V. Lunev ret = mark_used(bs, bitmap, bitmap_size, host_off, 1);
890a398275eSDenis V. Lunev if (ret == -EBUSY) {
891a398275eSDenis V. Lunev res->check_errors++;
892a398275eSDenis V. Lunev goto out_repair_bat;
8936bb8bc63SAlexander Ivanov }
8946bb8bc63SAlexander Ivanov
8956bb8bc63SAlexander Ivanov fixed = true;
8966bb8bc63SAlexander Ivanov res->corruptions_fixed++;
8976bb8bc63SAlexander Ivanov
8986bb8bc63SAlexander Ivanov }
8996bb8bc63SAlexander Ivanov
9006bb8bc63SAlexander Ivanov if (fixed) {
9016bb8bc63SAlexander Ivanov /*
9026bb8bc63SAlexander Ivanov * When new clusters are allocated, the file size increases by
9036bb8bc63SAlexander Ivanov * 128 Mb. We need to truncate the file to the right size. Let
9046bb8bc63SAlexander Ivanov * the leak fix code make its job without res changing.
9056bb8bc63SAlexander Ivanov */
9066bb8bc63SAlexander Ivanov ret = parallels_check_leak(bs, res, fix, false);
9076bb8bc63SAlexander Ivanov }
9086bb8bc63SAlexander Ivanov
9096bb8bc63SAlexander Ivanov out_free:
9106bb8bc63SAlexander Ivanov g_free(buf);
9116bb8bc63SAlexander Ivanov g_free(bitmap);
9126bb8bc63SAlexander Ivanov return ret;
9136bb8bc63SAlexander Ivanov /*
9146bb8bc63SAlexander Ivanov * We can get here only from places where index and old_offset have
9156bb8bc63SAlexander Ivanov * meaningful values.
9166bb8bc63SAlexander Ivanov */
9176bb8bc63SAlexander Ivanov out_repair_bat:
9186bb8bc63SAlexander Ivanov s->bat_bitmap[i] = bat_entry;
9196bb8bc63SAlexander Ivanov goto out_free;
9206bb8bc63SAlexander Ivanov }
9216bb8bc63SAlexander Ivanov
parallels_collect_statistics(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)9227e259e25SAlexander Ivanov static void parallels_collect_statistics(BlockDriverState *bs,
9237e259e25SAlexander Ivanov BdrvCheckResult *res,
9247e259e25SAlexander Ivanov BdrvCheckMode fix)
9257e259e25SAlexander Ivanov {
9267e259e25SAlexander Ivanov BDRVParallelsState *s = bs->opaque;
9277e259e25SAlexander Ivanov int64_t off, prev_off;
9287e259e25SAlexander Ivanov uint32_t i;
9297e259e25SAlexander Ivanov
9307e259e25SAlexander Ivanov res->bfi.total_clusters = s->bat_size;
9317e259e25SAlexander Ivanov res->bfi.compressed_clusters = 0; /* compression is not supported */
9327e259e25SAlexander Ivanov
9337e259e25SAlexander Ivanov prev_off = 0;
9347e259e25SAlexander Ivanov for (i = 0; i < s->bat_size; i++) {
9357e259e25SAlexander Ivanov off = bat2sect(s, i) << BDRV_SECTOR_BITS;
9367e259e25SAlexander Ivanov /*
9377e259e25SAlexander Ivanov * If BDRV_FIX_ERRORS is not set, out-of-image BAT entries were not
9387e259e25SAlexander Ivanov * fixed. Skip not allocated and out-of-image BAT entries.
9397e259e25SAlexander Ivanov */
9407e259e25SAlexander Ivanov if (off == 0 || off + s->cluster_size > res->image_end_offset) {
9417e259e25SAlexander Ivanov prev_off = 0;
9427e259e25SAlexander Ivanov continue;
9437e259e25SAlexander Ivanov }
9447e259e25SAlexander Ivanov
9457e259e25SAlexander Ivanov if (prev_off != 0 && (prev_off + s->cluster_size) != off) {
9467e259e25SAlexander Ivanov res->bfi.fragmented_clusters++;
9477e259e25SAlexander Ivanov }
9487e259e25SAlexander Ivanov prev_off = off;
9497e259e25SAlexander Ivanov res->bfi.allocated_clusters++;
9507e259e25SAlexander Ivanov }
9517e259e25SAlexander Ivanov }
9527e259e25SAlexander Ivanov
95309a21edfSAlexander Ivanov static int coroutine_fn GRAPH_RDLOCK
parallels_co_check(BlockDriverState * bs,BdrvCheckResult * res,BdrvCheckMode fix)95409a21edfSAlexander Ivanov parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
95509a21edfSAlexander Ivanov BdrvCheckMode fix)
95609a21edfSAlexander Ivanov {
95709a21edfSAlexander Ivanov BDRVParallelsState *s = bs->opaque;
95809a21edfSAlexander Ivanov int ret;
95909a21edfSAlexander Ivanov
960c0fc051dSAlexander Ivanov WITH_QEMU_LOCK_GUARD(&s->lock) {
96196de69c7SAlexander Ivanov parallels_check_unclean(bs, res, fix);
9626dd6b9f1SDenis V. Lunev
9638cd19203SAlexander Ivanov ret = parallels_check_data_off(bs, res, fix);
9648cd19203SAlexander Ivanov if (ret < 0) {
9658cd19203SAlexander Ivanov return ret;
9668cd19203SAlexander Ivanov }
9678cd19203SAlexander Ivanov
9686d416e56SAlexander Ivanov ret = parallels_check_outside_image(bs, res, fix);
9696d416e56SAlexander Ivanov if (ret < 0) {
970c0fc051dSAlexander Ivanov return ret;
9716d416e56SAlexander Ivanov }
9726d416e56SAlexander Ivanov
973728e1017SAlexander Ivanov ret = parallels_check_leak(bs, res, fix, true);
97409a21edfSAlexander Ivanov if (ret < 0) {
975c0fc051dSAlexander Ivanov return ret;
97609a21edfSAlexander Ivanov }
97709a21edfSAlexander Ivanov
9786bb8bc63SAlexander Ivanov ret = parallels_check_duplicate(bs, res, fix);
9796bb8bc63SAlexander Ivanov if (ret < 0) {
9806bb8bc63SAlexander Ivanov return ret;
9816bb8bc63SAlexander Ivanov }
9826bb8bc63SAlexander Ivanov
9837e259e25SAlexander Ivanov parallels_collect_statistics(bs, res, fix);
984c0fc051dSAlexander Ivanov }
98549ad6467SDenis V. Lunev
9863569cb7bSAlexander Ivanov ret = bdrv_co_flush(bs);
9873569cb7bSAlexander Ivanov if (ret < 0) {
9883569cb7bSAlexander Ivanov res->check_errors++;
9893569cb7bSAlexander Ivanov }
9903569cb7bSAlexander Ivanov
9912fd61638SPaolo Bonzini return ret;
99249ad6467SDenis V. Lunev }
99349ad6467SDenis V. Lunev
99449ad6467SDenis V. Lunev
9954db7ba3bSKevin Wolf static int coroutine_fn GRAPH_UNLOCKED
parallels_co_create(BlockdevCreateOptions * opts,Error ** errp)9964db7ba3bSKevin Wolf parallels_co_create(BlockdevCreateOptions* opts, Error **errp)
99774cf6c50SDenis V. Lunev {
9981511b490SKevin Wolf BlockdevCreateOptionsParallels *parallels_opts;
9991511b490SKevin Wolf BlockDriverState *bs;
10001511b490SKevin Wolf BlockBackend *blk;
100174cf6c50SDenis V. Lunev int64_t total_size, cl_size;
1002369f7de9SDenis V. Lunev uint32_t bat_entries, bat_sectors;
100374cf6c50SDenis V. Lunev ParallelsHeader header;
10041511b490SKevin Wolf uint8_t tmp[BDRV_SECTOR_SIZE];
100574cf6c50SDenis V. Lunev int ret;
100674cf6c50SDenis V. Lunev
10071511b490SKevin Wolf assert(opts->driver == BLOCKDEV_DRIVER_PARALLELS);
10081511b490SKevin Wolf parallels_opts = &opts->u.parallels;
10091511b490SKevin Wolf
10101511b490SKevin Wolf /* Sanity checks */
10111511b490SKevin Wolf total_size = parallels_opts->size;
10121511b490SKevin Wolf
10131511b490SKevin Wolf if (parallels_opts->has_cluster_size) {
10141511b490SKevin Wolf cl_size = parallels_opts->cluster_size;
10151511b490SKevin Wolf } else {
10161511b490SKevin Wolf cl_size = DEFAULT_CLUSTER_SIZE;
10171511b490SKevin Wolf }
10181511b490SKevin Wolf
10192332d825SKevin Wolf /* XXX What is the real limit here? This is an insanely large maximum. */
10202332d825SKevin Wolf if (cl_size >= INT64_MAX / MAX_PARALLELS_IMAGE_FACTOR) {
10212332d825SKevin Wolf error_setg(errp, "Cluster size is too large");
10222332d825SKevin Wolf return -EINVAL;
10232332d825SKevin Wolf }
1024555a608cSKlim Kireev if (total_size >= MAX_PARALLELS_IMAGE_FACTOR * cl_size) {
10251511b490SKevin Wolf error_setg(errp, "Image size is too large for this cluster size");
1026555a608cSKlim Kireev return -E2BIG;
1027555a608cSKlim Kireev }
102874cf6c50SDenis V. Lunev
10291511b490SKevin Wolf if (!QEMU_IS_ALIGNED(total_size, BDRV_SECTOR_SIZE)) {
10301511b490SKevin Wolf error_setg(errp, "Image size must be a multiple of 512 bytes");
10311511b490SKevin Wolf return -EINVAL;
103274cf6c50SDenis V. Lunev }
103374cf6c50SDenis V. Lunev
10341511b490SKevin Wolf if (!QEMU_IS_ALIGNED(cl_size, BDRV_SECTOR_SIZE)) {
10351511b490SKevin Wolf error_setg(errp, "Cluster size must be a multiple of 512 bytes");
10361511b490SKevin Wolf return -EINVAL;
10371511b490SKevin Wolf }
10381511b490SKevin Wolf
10391511b490SKevin Wolf /* Create BlockBackend to write to the image */
104048a4e92dSKevin Wolf bs = bdrv_co_open_blockdev_ref(parallels_opts->file, errp);
10411511b490SKevin Wolf if (bs == NULL) {
10428942764fSKevin Wolf return -EIO;
104374cf6c50SDenis V. Lunev }
10448942764fSKevin Wolf
104548a4e92dSKevin Wolf blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
1046a3aeeab5SEric Blake errp);
1047a3aeeab5SEric Blake if (!blk) {
1048a3aeeab5SEric Blake ret = -EPERM;
10491511b490SKevin Wolf goto out;
10501511b490SKevin Wolf }
10511511b490SKevin Wolf blk_set_allow_write_beyond_eof(blk, true);
10521511b490SKevin Wolf
10531511b490SKevin Wolf /* Create image format */
1054369f7de9SDenis V. Lunev bat_entries = DIV_ROUND_UP(total_size, cl_size);
10552d68e22eSDenis V. Lunev bat_sectors = DIV_ROUND_UP(bat_entry_off(bat_entries), cl_size);
1056369f7de9SDenis V. Lunev bat_sectors = (bat_sectors * cl_size) >> BDRV_SECTOR_BITS;
105774cf6c50SDenis V. Lunev
105874cf6c50SDenis V. Lunev memset(&header, 0, sizeof(header));
105974cf6c50SDenis V. Lunev memcpy(header.magic, HEADER_MAGIC2, sizeof(header.magic));
106074cf6c50SDenis V. Lunev header.version = cpu_to_le32(HEADER_VERSION);
106174cf6c50SDenis V. Lunev /* don't care much about geometry, it is not used on image level */
1062908b1c84SKlim Kireev header.heads = cpu_to_le32(HEADS_NUMBER);
1063908b1c84SKlim Kireev header.cylinders = cpu_to_le32(total_size / BDRV_SECTOR_SIZE
1064908b1c84SKlim Kireev / HEADS_NUMBER / SEC_IN_CYL);
106574cf6c50SDenis V. Lunev header.tracks = cpu_to_le32(cl_size >> BDRV_SECTOR_BITS);
1066369f7de9SDenis V. Lunev header.bat_entries = cpu_to_le32(bat_entries);
106774cf6c50SDenis V. Lunev header.nb_sectors = cpu_to_le64(DIV_ROUND_UP(total_size, BDRV_SECTOR_SIZE));
1068369f7de9SDenis V. Lunev header.data_off = cpu_to_le32(bat_sectors);
106974cf6c50SDenis V. Lunev
107074cf6c50SDenis V. Lunev /* write all the data */
107174cf6c50SDenis V. Lunev memset(tmp, 0, sizeof(tmp));
107274cf6c50SDenis V. Lunev memcpy(tmp, &header, sizeof(header));
107374cf6c50SDenis V. Lunev
107450688be0SAlberto Faria ret = blk_co_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0);
107574cf6c50SDenis V. Lunev if (ret < 0) {
107674cf6c50SDenis V. Lunev goto exit;
107774cf6c50SDenis V. Lunev }
107850688be0SAlberto Faria ret = blk_co_pwrite_zeroes(blk, BDRV_SECTOR_SIZE,
1079983a1600SEric Blake (bat_sectors - 1) << BDRV_SECTOR_BITS, 0);
108074cf6c50SDenis V. Lunev if (ret < 0) {
108174cf6c50SDenis V. Lunev goto exit;
108274cf6c50SDenis V. Lunev }
108374cf6c50SDenis V. Lunev
10841511b490SKevin Wolf ret = 0;
10851511b490SKevin Wolf out:
1086b2ab5f54SKevin Wolf blk_co_unref(blk);
1087b2ab5f54SKevin Wolf bdrv_co_unref(bs);
108874cf6c50SDenis V. Lunev return ret;
108974cf6c50SDenis V. Lunev
109074cf6c50SDenis V. Lunev exit:
109174cf6c50SDenis V. Lunev error_setg_errno(errp, -ret, "Failed to create Parallels image");
10921511b490SKevin Wolf goto out;
10931511b490SKevin Wolf }
10941511b490SKevin Wolf
10954db7ba3bSKevin Wolf static int coroutine_fn GRAPH_UNLOCKED
parallels_co_create_opts(BlockDriver * drv,const char * filename,QemuOpts * opts,Error ** errp)10964ec8df01SKevin Wolf parallels_co_create_opts(BlockDriver *drv, const char *filename,
10974ec8df01SKevin Wolf QemuOpts *opts, Error **errp)
10981511b490SKevin Wolf {
10991511b490SKevin Wolf BlockdevCreateOptions *create_options = NULL;
11001511b490SKevin Wolf BlockDriverState *bs = NULL;
110192adf9dbSMarkus Armbruster QDict *qdict;
11021511b490SKevin Wolf Visitor *v;
11031511b490SKevin Wolf int ret;
11041511b490SKevin Wolf
11051511b490SKevin Wolf static const QDictRenames opt_renames[] = {
11061511b490SKevin Wolf { BLOCK_OPT_CLUSTER_SIZE, "cluster-size" },
11071511b490SKevin Wolf { NULL, NULL },
11081511b490SKevin Wolf };
11091511b490SKevin Wolf
11101511b490SKevin Wolf /* Parse options and convert legacy syntax */
11111511b490SKevin Wolf qdict = qemu_opts_to_qdict_filtered(opts, NULL, ¶llels_create_opts,
11121511b490SKevin Wolf true);
11131511b490SKevin Wolf
11141511b490SKevin Wolf if (!qdict_rename_keys(qdict, opt_renames, errp)) {
11151511b490SKevin Wolf ret = -EINVAL;
111674cf6c50SDenis V. Lunev goto done;
111774cf6c50SDenis V. Lunev }
111874cf6c50SDenis V. Lunev
11191511b490SKevin Wolf /* Create and open the file (protocol layer) */
11202475a0d0SEmanuele Giuseppe Esposito ret = bdrv_co_create_file(filename, opts, errp);
11211511b490SKevin Wolf if (ret < 0) {
11221511b490SKevin Wolf goto done;
11231511b490SKevin Wolf }
11241511b490SKevin Wolf
112548a4e92dSKevin Wolf bs = bdrv_co_open(filename, NULL, NULL,
11261511b490SKevin Wolf BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
11271511b490SKevin Wolf if (bs == NULL) {
11281511b490SKevin Wolf ret = -EIO;
11291511b490SKevin Wolf goto done;
11301511b490SKevin Wolf }
11311511b490SKevin Wolf
11321511b490SKevin Wolf /* Now get the QAPI type BlockdevCreateOptions */
11331511b490SKevin Wolf qdict_put_str(qdict, "driver", "parallels");
11341511b490SKevin Wolf qdict_put_str(qdict, "file", bs->node_name);
11351511b490SKevin Wolf
1136af91062eSMarkus Armbruster v = qobject_input_visitor_new_flat_confused(qdict, errp);
1137af91062eSMarkus Armbruster if (!v) {
11381511b490SKevin Wolf ret = -EINVAL;
11391511b490SKevin Wolf goto done;
11401511b490SKevin Wolf }
11411511b490SKevin Wolf
1142b11a093cSMarkus Armbruster visit_type_BlockdevCreateOptions(v, NULL, &create_options, errp);
11431511b490SKevin Wolf visit_free(v);
1144b11a093cSMarkus Armbruster if (!create_options) {
11451511b490SKevin Wolf ret = -EINVAL;
11461511b490SKevin Wolf goto done;
11471511b490SKevin Wolf }
11481511b490SKevin Wolf
11491511b490SKevin Wolf /* Silently round up sizes */
11501511b490SKevin Wolf create_options->u.parallels.size =
11511511b490SKevin Wolf ROUND_UP(create_options->u.parallels.size, BDRV_SECTOR_SIZE);
11521511b490SKevin Wolf create_options->u.parallels.cluster_size =
11531511b490SKevin Wolf ROUND_UP(create_options->u.parallels.cluster_size, BDRV_SECTOR_SIZE);
11541511b490SKevin Wolf
11551511b490SKevin Wolf /* Create the Parallels image (format layer) */
11561511b490SKevin Wolf ret = parallels_co_create(create_options, errp);
11571511b490SKevin Wolf if (ret < 0) {
11581511b490SKevin Wolf goto done;
11591511b490SKevin Wolf }
11601511b490SKevin Wolf ret = 0;
11611511b490SKevin Wolf
11621511b490SKevin Wolf done:
1163cb3e7f08SMarc-André Lureau qobject_unref(qdict);
1164b2ab5f54SKevin Wolf bdrv_co_unref(bs);
11651511b490SKevin Wolf qapi_free_BlockdevCreateOptions(create_options);
11661511b490SKevin Wolf return ret;
11671511b490SKevin Wolf }
11681511b490SKevin Wolf
116923d6bd3bSDenis V. Lunev
parallels_probe(const uint8_t * buf,int buf_size,const char * filename)117023d6bd3bSDenis V. Lunev static int parallels_probe(const uint8_t *buf, int buf_size,
117123d6bd3bSDenis V. Lunev const char *filename)
117223d6bd3bSDenis V. Lunev {
117323d6bd3bSDenis V. Lunev const ParallelsHeader *ph = (const void *)buf;
117423d6bd3bSDenis V. Lunev
117523d6bd3bSDenis V. Lunev if (buf_size < sizeof(ParallelsHeader)) {
117623d6bd3bSDenis V. Lunev return 0;
117723d6bd3bSDenis V. Lunev }
117823d6bd3bSDenis V. Lunev
117923d6bd3bSDenis V. Lunev if ((!memcmp(ph->magic, HEADER_MAGIC, 16) ||
118023d6bd3bSDenis V. Lunev !memcmp(ph->magic, HEADER_MAGIC2, 16)) &&
118123d6bd3bSDenis V. Lunev (le32_to_cpu(ph->version) == HEADER_VERSION)) {
118223d6bd3bSDenis V. Lunev return 100;
118323d6bd3bSDenis V. Lunev }
118423d6bd3bSDenis V. Lunev
118523d6bd3bSDenis V. Lunev return 0;
118623d6bd3bSDenis V. Lunev }
118723d6bd3bSDenis V. Lunev
parallels_update_header(BlockDriverState * bs)11881f051dcbSKevin Wolf static int GRAPH_RDLOCK parallels_update_header(BlockDriverState *bs)
11896dd6b9f1SDenis V. Lunev {
11906dd6b9f1SDenis V. Lunev BDRVParallelsState *s = bs->opaque;
11919a4f4c31SKevin Wolf unsigned size = MAX(bdrv_opt_mem_align(bs->file->bs),
11929a4f4c31SKevin Wolf sizeof(ParallelsHeader));
11936dd6b9f1SDenis V. Lunev
11946dd6b9f1SDenis V. Lunev if (size > s->header_size) {
11956dd6b9f1SDenis V. Lunev size = s->header_size;
11966dd6b9f1SDenis V. Lunev }
119732cc71deSAlberto Faria return bdrv_pwrite_sync(bs->file, 0, size, s->header, 0);
11986dd6b9f1SDenis V. Lunev }
11996dd6b9f1SDenis V. Lunev
120093361b7eSDenis V. Lunev
parallels_opts_prealloc(BlockDriverState * bs,QDict * options,Error ** errp)120193361b7eSDenis V. Lunev static int parallels_opts_prealloc(BlockDriverState *bs, QDict *options,
120293361b7eSDenis V. Lunev Error **errp)
120393361b7eSDenis V. Lunev {
120493361b7eSDenis V. Lunev int err;
120593361b7eSDenis V. Lunev char *buf;
120693361b7eSDenis V. Lunev int64_t bytes;
120793361b7eSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
120893361b7eSDenis V. Lunev Error *local_err = NULL;
120993361b7eSDenis V. Lunev QemuOpts *opts = qemu_opts_create(¶llels_runtime_opts, NULL, 0, errp);
121093361b7eSDenis V. Lunev if (!opts) {
121193361b7eSDenis V. Lunev return -ENOMEM;
121293361b7eSDenis V. Lunev }
121393361b7eSDenis V. Lunev
121493361b7eSDenis V. Lunev err = -EINVAL;
121593361b7eSDenis V. Lunev if (!qemu_opts_absorb_qdict(opts, options, errp)) {
121693361b7eSDenis V. Lunev goto done;
121793361b7eSDenis V. Lunev }
121893361b7eSDenis V. Lunev
121993361b7eSDenis V. Lunev bytes = qemu_opt_get_size_del(opts, PARALLELS_OPT_PREALLOC_SIZE, 0);
122093361b7eSDenis V. Lunev s->prealloc_size = bytes >> BDRV_SECTOR_BITS;
122193361b7eSDenis V. Lunev buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
122293361b7eSDenis V. Lunev /* prealloc_mode can be downgraded later during allocate_clusters */
122393361b7eSDenis V. Lunev s->prealloc_mode = qapi_enum_parse(&prealloc_mode_lookup, buf,
122493361b7eSDenis V. Lunev PRL_PREALLOC_MODE_FALLOCATE,
122593361b7eSDenis V. Lunev &local_err);
122693361b7eSDenis V. Lunev g_free(buf);
122793361b7eSDenis V. Lunev if (local_err != NULL) {
122893361b7eSDenis V. Lunev error_propagate(errp, local_err);
122993361b7eSDenis V. Lunev goto done;
123093361b7eSDenis V. Lunev }
123193361b7eSDenis V. Lunev err = 0;
123293361b7eSDenis V. Lunev
123393361b7eSDenis V. Lunev done:
123493361b7eSDenis V. Lunev qemu_opts_del(opts);
123593361b7eSDenis V. Lunev return err;
123693361b7eSDenis V. Lunev }
123793361b7eSDenis V. Lunev
parallels_open(BlockDriverState * bs,QDict * options,int flags,Error ** errp)123823d6bd3bSDenis V. Lunev static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
123923d6bd3bSDenis V. Lunev Error **errp)
124023d6bd3bSDenis V. Lunev {
124123d6bd3bSDenis V. Lunev BDRVParallelsState *s = bs->opaque;
124223d6bd3bSDenis V. Lunev ParallelsHeader ph;
124319f5dc15SDenis V. Lunev int ret, size, i;
1244cfce1091SAlexander Ivanov int64_t file_nb_sectors, sector;
1245c89d4362SAlexander Ivanov uint32_t data_start;
12468f5f5326SDenis V. Lunev bool need_check = false;
124723d6bd3bSDenis V. Lunev
124893361b7eSDenis V. Lunev ret = parallels_opts_prealloc(bs, options, errp);
124993361b7eSDenis V. Lunev if (ret < 0) {
125093361b7eSDenis V. Lunev return ret;
125193361b7eSDenis V. Lunev }
125293361b7eSDenis V. Lunev
125383930780SVladimir Sementsov-Ogievskiy ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
125483930780SVladimir Sementsov-Ogievskiy if (ret < 0) {
125583930780SVladimir Sementsov-Ogievskiy return ret;
12564e4bf5c4SKevin Wolf }
12574e4bf5c4SKevin Wolf
1258a4b740dbSKevin Wolf GRAPH_RDLOCK_GUARD_MAINLOOP();
1259a4b740dbSKevin Wolf
1260f5e715dbSAlexander Ivanov file_nb_sectors = bdrv_nb_sectors(bs->file->bs);
1261f5e715dbSAlexander Ivanov if (file_nb_sectors < 0) {
1262f5e715dbSAlexander Ivanov return -EINVAL;
1263f5e715dbSAlexander Ivanov }
1264f5e715dbSAlexander Ivanov
126532cc71deSAlberto Faria ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0);
126623d6bd3bSDenis V. Lunev if (ret < 0) {
1267e17b9d08SDenis V. Lunev return ret;
126823d6bd3bSDenis V. Lunev }
126923d6bd3bSDenis V. Lunev
127023d6bd3bSDenis V. Lunev bs->total_sectors = le64_to_cpu(ph.nb_sectors);
127123d6bd3bSDenis V. Lunev
127223d6bd3bSDenis V. Lunev if (le32_to_cpu(ph.version) != HEADER_VERSION) {
127323d6bd3bSDenis V. Lunev goto fail_format;
127423d6bd3bSDenis V. Lunev }
127523d6bd3bSDenis V. Lunev if (!memcmp(ph.magic, HEADER_MAGIC, 16)) {
127623d6bd3bSDenis V. Lunev s->off_multiplier = 1;
127723d6bd3bSDenis V. Lunev bs->total_sectors = 0xffffffff & bs->total_sectors;
127823d6bd3bSDenis V. Lunev } else if (!memcmp(ph.magic, HEADER_MAGIC2, 16)) {
127923d6bd3bSDenis V. Lunev s->off_multiplier = le32_to_cpu(ph.tracks);
128023d6bd3bSDenis V. Lunev } else {
128123d6bd3bSDenis V. Lunev goto fail_format;
128223d6bd3bSDenis V. Lunev }
128323d6bd3bSDenis V. Lunev
128423d6bd3bSDenis V. Lunev s->tracks = le32_to_cpu(ph.tracks);
128523d6bd3bSDenis V. Lunev if (s->tracks == 0) {
128623d6bd3bSDenis V. Lunev error_setg(errp, "Invalid image: Zero sectors per track");
1287e17b9d08SDenis V. Lunev return -EINVAL;
128823d6bd3bSDenis V. Lunev }
128923d6bd3bSDenis V. Lunev if (s->tracks > INT32_MAX/513) {
129023d6bd3bSDenis V. Lunev error_setg(errp, "Invalid image: Too big cluster");
1291e17b9d08SDenis V. Lunev return -EFBIG;
129223d6bd3bSDenis V. Lunev }
129393361b7eSDenis V. Lunev s->prealloc_size = MAX(s->tracks, s->prealloc_size);
1294e0b5207fSVladimir Sementsov-Ogievskiy s->cluster_size = s->tracks << BDRV_SECTOR_BITS;
129523d6bd3bSDenis V. Lunev
129623d6bd3bSDenis V. Lunev s->bat_size = le32_to_cpu(ph.bat_entries);
129723d6bd3bSDenis V. Lunev if (s->bat_size > INT_MAX / sizeof(uint32_t)) {
129823d6bd3bSDenis V. Lunev error_setg(errp, "Catalog too large");
1299e17b9d08SDenis V. Lunev return -EFBIG;
130023d6bd3bSDenis V. Lunev }
130123d6bd3bSDenis V. Lunev
13022d68e22eSDenis V. Lunev size = bat_entry_off(s->bat_size);
13039a4f4c31SKevin Wolf s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file->bs));
13049a4f4c31SKevin Wolf s->header = qemu_try_blockalign(bs->file->bs, s->header_size);
130523d6bd3bSDenis V. Lunev if (s->header == NULL) {
1306e17b9d08SDenis V. Lunev return -ENOMEM;
130723d6bd3bSDenis V. Lunev }
130823d6bd3bSDenis V. Lunev
130932cc71deSAlberto Faria ret = bdrv_pread(bs->file, 0, s->header_size, s->header, 0);
131023d6bd3bSDenis V. Lunev if (ret < 0) {
131123d6bd3bSDenis V. Lunev goto fail;
131223d6bd3bSDenis V. Lunev }
131323d6bd3bSDenis V. Lunev s->bat_bitmap = (uint32_t *)(s->header + 1);
131423d6bd3bSDenis V. Lunev
13156dd6b9f1SDenis V. Lunev if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
13168f5f5326SDenis V. Lunev need_check = s->header_unclean = true;
13176dd6b9f1SDenis V. Lunev }
13186dd6b9f1SDenis V. Lunev
13198f5f5326SDenis V. Lunev {
13208f5f5326SDenis V. Lunev bool ok = parallels_test_data_off(s, file_nb_sectors, &data_start);
13218f5f5326SDenis V. Lunev need_check = need_check || !ok;
13228f5f5326SDenis V. Lunev }
13238f5f5326SDenis V. Lunev
1324c89d4362SAlexander Ivanov s->data_start = data_start;
1325c89d4362SAlexander Ivanov s->data_end = s->data_start;
1326c89d4362SAlexander Ivanov if (s->data_end < (s->header_size >> BDRV_SECTOR_BITS)) {
1327c89d4362SAlexander Ivanov /*
1328c89d4362SAlexander Ivanov * There is not enough unused space to fit to block align between BAT
1329c89d4362SAlexander Ivanov * and actual data. We can't avoid read-modify-write...
1330c89d4362SAlexander Ivanov */
1331c89d4362SAlexander Ivanov s->header_size = size;
1332c89d4362SAlexander Ivanov }
1333c89d4362SAlexander Ivanov
1334baefd977SVladimir Sementsov-Ogievskiy if (ph.ext_off) {
1335baefd977SVladimir Sementsov-Ogievskiy if (flags & BDRV_O_RDWR) {
1336baefd977SVladimir Sementsov-Ogievskiy /*
1337baefd977SVladimir Sementsov-Ogievskiy * It's unsafe to open image RW if there is an extension (as we
1338baefd977SVladimir Sementsov-Ogievskiy * don't support it). But parallels driver in QEMU historically
1339baefd977SVladimir Sementsov-Ogievskiy * ignores the extension, so print warning and don't care.
1340baefd977SVladimir Sementsov-Ogievskiy */
1341baefd977SVladimir Sementsov-Ogievskiy warn_report("Format Extension ignored in RW mode");
1342baefd977SVladimir Sementsov-Ogievskiy } else {
1343baefd977SVladimir Sementsov-Ogievskiy ret = parallels_read_format_extension(
1344baefd977SVladimir Sementsov-Ogievskiy bs, le64_to_cpu(ph.ext_off) << BDRV_SECTOR_BITS, errp);
1345baefd977SVladimir Sementsov-Ogievskiy if (ret < 0) {
1346baefd977SVladimir Sementsov-Ogievskiy goto fail;
1347baefd977SVladimir Sementsov-Ogievskiy }
1348baefd977SVladimir Sementsov-Ogievskiy }
1349baefd977SVladimir Sementsov-Ogievskiy }
1350baefd977SVladimir Sementsov-Ogievskiy
13516c7d390bSJeff Cody if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_INACTIVE)) {
13526dd6b9f1SDenis V. Lunev s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC);
13536dd6b9f1SDenis V. Lunev ret = parallels_update_header(bs);
13546dd6b9f1SDenis V. Lunev if (ret < 0) {
13556dd6b9f1SDenis V. Lunev goto fail;
13566dd6b9f1SDenis V. Lunev }
13576dd6b9f1SDenis V. Lunev }
13586dd6b9f1SDenis V. Lunev
13598e3b0cbbSMarc-André Lureau s->bat_dirty_block = 4 * qemu_real_host_page_size();
13600d31c7c2SDenis V. Lunev s->bat_dirty_bmap =
13610d31c7c2SDenis V. Lunev bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block));
13620d31c7c2SDenis V. Lunev
1363a94750d9SEmanuele Giuseppe Esposito /* Disable migration until bdrv_activate method is added */
13641d0f37cfSJeff Cody error_setg(&s->migration_blocker, "The Parallels format used by node '%s' "
13651d0f37cfSJeff Cody "does not support live migration",
13661d0f37cfSJeff Cody bdrv_get_device_or_node_name(bs));
13674026f1c4SKevin Wolf
1368e0ee3a8fSSteve Sistare ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
1369386f6c07SMarkus Armbruster if (ret < 0) {
13701d0f37cfSJeff Cody goto fail;
13711d0f37cfSJeff Cody }
137223d6bd3bSDenis V. Lunev qemu_co_mutex_init(&s->lock);
1373cfce1091SAlexander Ivanov
1374cfce1091SAlexander Ivanov for (i = 0; i < s->bat_size; i++) {
1375cfce1091SAlexander Ivanov sector = bat2sect(s, i);
1376cfce1091SAlexander Ivanov if (sector + s->tracks > s->data_end) {
1377cfce1091SAlexander Ivanov s->data_end = sector + s->tracks;
1378cfce1091SAlexander Ivanov }
1379cfce1091SAlexander Ivanov }
13808f5f5326SDenis V. Lunev need_check = need_check || s->data_end > file_nb_sectors;
1381cfce1091SAlexander Ivanov
1382e185100fSDenis V. Lunev if (!need_check) {
1383e185100fSDenis V. Lunev ret = parallels_fill_used_bitmap(bs);
1384e185100fSDenis V. Lunev if (ret == -ENOMEM) {
1385e185100fSDenis V. Lunev goto fail;
1386e185100fSDenis V. Lunev }
1387e185100fSDenis V. Lunev need_check = need_check || ret < 0; /* These are correctable errors */
1388e185100fSDenis V. Lunev }
1389e185100fSDenis V. Lunev
1390cfce1091SAlexander Ivanov /*
1391cfce1091SAlexander Ivanov * We don't repair the image here if it's opened for checks. Also we don't
1392cfce1091SAlexander Ivanov * want to change inactive images and can't change readonly images.
1393cfce1091SAlexander Ivanov */
1394cfce1091SAlexander Ivanov if ((flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) || !(flags & BDRV_O_RDWR)) {
1395cfce1091SAlexander Ivanov return 0;
1396cfce1091SAlexander Ivanov }
1397cfce1091SAlexander Ivanov
13988f5f5326SDenis V. Lunev /* Repair the image if corruption was detected. */
13998f5f5326SDenis V. Lunev if (need_check) {
1400cfce1091SAlexander Ivanov BdrvCheckResult res;
1401cfce1091SAlexander Ivanov ret = bdrv_check(bs, &res, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);
1402cfce1091SAlexander Ivanov if (ret < 0) {
1403cfce1091SAlexander Ivanov error_setg_errno(errp, -ret, "Could not repair corrupted image");
1404c8a7fc51SSteve Sistare migrate_del_blocker(&s->migration_blocker);
1405cfce1091SAlexander Ivanov goto fail;
1406cfce1091SAlexander Ivanov }
1407cfce1091SAlexander Ivanov }
140823d6bd3bSDenis V. Lunev return 0;
140923d6bd3bSDenis V. Lunev
141023d6bd3bSDenis V. Lunev fail_format:
141123d6bd3bSDenis V. Lunev error_setg(errp, "Image not in Parallels format");
14129c398781SDenis V. Lunev return -EINVAL;
14139c398781SDenis V. Lunev
141423d6bd3bSDenis V. Lunev fail:
1415cfce1091SAlexander Ivanov /*
1416cfce1091SAlexander Ivanov * "s" object was allocated by g_malloc0 so we can safely
1417cfce1091SAlexander Ivanov * try to free its fields even they were not allocated.
1418cfce1091SAlexander Ivanov */
1419e185100fSDenis V. Lunev parallels_free_used_bitmap(bs);
1420e185100fSDenis V. Lunev
1421cfce1091SAlexander Ivanov g_free(s->bat_dirty_bmap);
142223d6bd3bSDenis V. Lunev qemu_vfree(s->header);
142323d6bd3bSDenis V. Lunev return ret;
142423d6bd3bSDenis V. Lunev }
142523d6bd3bSDenis V. Lunev
142623d6bd3bSDenis V. Lunev
parallels_close(BlockDriverState * bs)1427019d6b8fSAnthony Liguori static void parallels_close(BlockDriverState *bs)
1428019d6b8fSAnthony Liguori {
1429019d6b8fSAnthony Liguori BDRVParallelsState *s = bs->opaque;
14306dd6b9f1SDenis V. Lunev
14311f051dcbSKevin Wolf GRAPH_RDLOCK_GUARD_MAINLOOP();
14321f051dcbSKevin Wolf
14336c7d390bSJeff Cody if ((bs->open_flags & BDRV_O_RDWR) && !(bs->open_flags & BDRV_O_INACTIVE)) {
14346dd6b9f1SDenis V. Lunev s->header->inuse = 0;
14356dd6b9f1SDenis V. Lunev parallels_update_header(bs);
1436e8d04f92SMax Reitz
1437e8d04f92SMax Reitz /* errors are ignored, so we might as well pass exact=true */
1438e8d04f92SMax Reitz bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
14397b8e4857SKevin Wolf PREALLOC_MODE_OFF, 0, NULL);
144019f5dc15SDenis V. Lunev }
144119f5dc15SDenis V. Lunev
1442e185100fSDenis V. Lunev parallels_free_used_bitmap(bs);
1443e185100fSDenis V. Lunev
14440d31c7c2SDenis V. Lunev g_free(s->bat_dirty_bmap);
14459eae9ccaSDenis V. Lunev qemu_vfree(s->header);
14461d0f37cfSJeff Cody
1447c8a7fc51SSteve Sistare migrate_del_blocker(&s->migration_blocker);
1448019d6b8fSAnthony Liguori }
1449019d6b8fSAnthony Liguori
parallels_is_support_dirty_bitmaps(BlockDriverState * bs)145073f3e136SDenis V. Lunev static bool parallels_is_support_dirty_bitmaps(BlockDriverState *bs)
145173f3e136SDenis V. Lunev {
145273f3e136SDenis V. Lunev return 1;
145373f3e136SDenis V. Lunev }
145473f3e136SDenis V. Lunev
1455019d6b8fSAnthony Liguori static BlockDriver bdrv_parallels = {
1456019d6b8fSAnthony Liguori .format_name = "parallels",
1457019d6b8fSAnthony Liguori .instance_size = sizeof(BDRVParallelsState),
1458bb16991fSDenis V. Lunev .create_opts = ¶llels_create_opts,
1459bb16991fSDenis V. Lunev .is_format = true,
1460bb16991fSDenis V. Lunev .supports_backing = true,
1461bb16991fSDenis V. Lunev
1462bb16991fSDenis V. Lunev .bdrv_has_zero_init = bdrv_has_zero_init_1,
146373f3e136SDenis V. Lunev .bdrv_supports_persistent_dirty_bitmap = parallels_is_support_dirty_bitmaps,
1464bb16991fSDenis V. Lunev
1465019d6b8fSAnthony Liguori .bdrv_probe = parallels_probe,
14661dec5a70SChristoph Hellwig .bdrv_open = parallels_open,
1467019d6b8fSAnthony Liguori .bdrv_close = parallels_close,
146869dca43dSMax Reitz .bdrv_child_perm = bdrv_default_perms,
14698e0cf59dSEric Blake .bdrv_co_block_status = parallels_co_block_status,
14700d31c7c2SDenis V. Lunev .bdrv_co_flush_to_os = parallels_co_flush_to_os,
1471481fb9cfSDenis V. Lunev .bdrv_co_readv = parallels_co_readv,
14725a41e1faSDenis V. Lunev .bdrv_co_writev = parallels_co_writev,
14731511b490SKevin Wolf .bdrv_co_create = parallels_co_create,
1474efc75e2aSStefan Hajnoczi .bdrv_co_create_opts = parallels_co_create_opts,
14752fd61638SPaolo Bonzini .bdrv_co_check = parallels_co_check,
1476c54fb435SDenis V. Lunev .bdrv_co_pdiscard = parallels_co_pdiscard,
1477a98b260aSDenis V. Lunev .bdrv_co_pwrite_zeroes = parallels_co_pwrite_zeroes,
1478019d6b8fSAnthony Liguori };
1479019d6b8fSAnthony Liguori
bdrv_parallels_init(void)1480019d6b8fSAnthony Liguori static void bdrv_parallels_init(void)
1481019d6b8fSAnthony Liguori {
1482019d6b8fSAnthony Liguori bdrv_register(&bdrv_parallels);
1483019d6b8fSAnthony Liguori }
1484019d6b8fSAnthony Liguori
1485019d6b8fSAnthony Liguori block_init(bdrv_parallels_init);
1486