Statistics
| Branch: | Revision:

root / block / vmdk.c @ f53f81e0

History | View | Annotate | Download (63.6 kB)

1 ea2384d3 bellard
/*
2 ea2384d3 bellard
 * Block driver for the VMDK format
3 5fafdf24 ths
 *
4 ea2384d3 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 ff1afc72 bellard
 * Copyright (c) 2005 Filip Navara
6 5fafdf24 ths
 *
7 ea2384d3 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 ea2384d3 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 ea2384d3 bellard
 * in the Software without restriction, including without limitation the rights
10 ea2384d3 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 ea2384d3 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 ea2384d3 bellard
 * furnished to do so, subject to the following conditions:
13 ea2384d3 bellard
 *
14 ea2384d3 bellard
 * The above copyright notice and this permission notice shall be included in
15 ea2384d3 bellard
 * all copies or substantial portions of the Software.
16 ea2384d3 bellard
 *
17 ea2384d3 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 ea2384d3 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 ea2384d3 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 ea2384d3 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 ea2384d3 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 ea2384d3 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 ea2384d3 bellard
 * THE SOFTWARE.
24 ea2384d3 bellard
 */
25 5f4da8c0 ths
26 faf07963 pbrook
#include "qemu-common.h"
27 737e150e Paolo Bonzini
#include "block/block_int.h"
28 1de7afc9 Paolo Bonzini
#include "qemu/module.h"
29 caf71f86 Paolo Bonzini
#include "migration/migration.h"
30 2923d34f Stefan Weil
#include <zlib.h>
31 ea2384d3 bellard
32 ea2384d3 bellard
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
33 ea2384d3 bellard
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
34 432bb170 Fam Zheng
#define VMDK4_COMPRESSION_DEFLATE 1
35 95b0aa42 Fam Zheng
#define VMDK4_FLAG_NL_DETECT (1 << 0)
36 bb45ded9 Fam Zheng
#define VMDK4_FLAG_RGD (1 << 1)
37 14ead646 Fam Zheng
/* Zeroed-grain enable bit */
38 14ead646 Fam Zheng
#define VMDK4_FLAG_ZERO_GRAIN   (1 << 2)
39 432bb170 Fam Zheng
#define VMDK4_FLAG_COMPRESS (1 << 16)
40 432bb170 Fam Zheng
#define VMDK4_FLAG_MARKER (1 << 17)
41 65bd155c Kevin Wolf
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
42 ea2384d3 bellard
43 14ead646 Fam Zheng
#define VMDK_GTE_ZEROED 0x1
44 65f74725 Fam Zheng
45 65f74725 Fam Zheng
/* VMDK internal error codes */
46 65f74725 Fam Zheng
#define VMDK_OK      0
47 65f74725 Fam Zheng
#define VMDK_ERROR   (-1)
48 65f74725 Fam Zheng
/* Cluster not allocated */
49 65f74725 Fam Zheng
#define VMDK_UNALLOC (-2)
50 65f74725 Fam Zheng
#define VMDK_ZEROED  (-3)
51 65f74725 Fam Zheng
52 69e0b6df Fam Zheng
#define BLOCK_OPT_ZEROED_GRAIN "zeroed_grain"
53 69e0b6df Fam Zheng
54 ea2384d3 bellard
typedef struct {
55 ea2384d3 bellard
    uint32_t version;
56 ea2384d3 bellard
    uint32_t flags;
57 ea2384d3 bellard
    uint32_t disk_sectors;
58 ea2384d3 bellard
    uint32_t granularity;
59 ea2384d3 bellard
    uint32_t l1dir_offset;
60 ea2384d3 bellard
    uint32_t l1dir_size;
61 ea2384d3 bellard
    uint32_t file_sectors;
62 ea2384d3 bellard
    uint32_t cylinders;
63 ea2384d3 bellard
    uint32_t heads;
64 ea2384d3 bellard
    uint32_t sectors_per_track;
65 5d8caa54 Fam Zheng
} QEMU_PACKED VMDK3Header;
66 ea2384d3 bellard
67 ea2384d3 bellard
typedef struct {
68 ea2384d3 bellard
    uint32_t version;
69 ea2384d3 bellard
    uint32_t flags;
70 e98768d4 Fam Zheng
    uint64_t capacity;
71 e98768d4 Fam Zheng
    uint64_t granularity;
72 e98768d4 Fam Zheng
    uint64_t desc_offset;
73 e98768d4 Fam Zheng
    uint64_t desc_size;
74 ca8804ce Fam Zheng
    /* Number of GrainTableEntries per GrainTable */
75 ca8804ce Fam Zheng
    uint32_t num_gtes_per_gt;
76 e98768d4 Fam Zheng
    uint64_t rgd_offset;
77 e98768d4 Fam Zheng
    uint64_t gd_offset;
78 e98768d4 Fam Zheng
    uint64_t grain_offset;
79 ea2384d3 bellard
    char filler[1];
80 ea2384d3 bellard
    char check_bytes[4];
81 432bb170 Fam Zheng
    uint16_t compressAlgorithm;
82 541dc0d4 Stefan Weil
} QEMU_PACKED VMDK4Header;
83 ea2384d3 bellard
84 ea2384d3 bellard
#define L2_CACHE_SIZE 16
85 ea2384d3 bellard
86 b3976d3c Fam Zheng
typedef struct VmdkExtent {
87 b3976d3c Fam Zheng
    BlockDriverState *file;
88 b3976d3c Fam Zheng
    bool flat;
89 432bb170 Fam Zheng
    bool compressed;
90 432bb170 Fam Zheng
    bool has_marker;
91 14ead646 Fam Zheng
    bool has_zero_grain;
92 14ead646 Fam Zheng
    int version;
93 b3976d3c Fam Zheng
    int64_t sectors;
94 b3976d3c Fam Zheng
    int64_t end_sector;
95 7fa60fa3 Fam Zheng
    int64_t flat_start_offset;
96 ea2384d3 bellard
    int64_t l1_table_offset;
97 ff1afc72 bellard
    int64_t l1_backup_table_offset;
98 ea2384d3 bellard
    uint32_t *l1_table;
99 ff1afc72 bellard
    uint32_t *l1_backup_table;
100 ea2384d3 bellard
    unsigned int l1_size;
101 ea2384d3 bellard
    uint32_t l1_entry_sectors;
102 ea2384d3 bellard
103 ea2384d3 bellard
    unsigned int l2_size;
104 ea2384d3 bellard
    uint32_t *l2_cache;
105 ea2384d3 bellard
    uint32_t l2_cache_offsets[L2_CACHE_SIZE];
106 ea2384d3 bellard
    uint32_t l2_cache_counts[L2_CACHE_SIZE];
107 ea2384d3 bellard
108 301c7d38 Fam Zheng
    int64_t cluster_sectors;
109 f4c129a3 Fam Zheng
    char *type;
110 b3976d3c Fam Zheng
} VmdkExtent;
111 b3976d3c Fam Zheng
112 b3976d3c Fam Zheng
typedef struct BDRVVmdkState {
113 848c66e8 Paolo Bonzini
    CoMutex lock;
114 e98768d4 Fam Zheng
    uint64_t desc_offset;
115 69b4d86d Fam Zheng
    bool cid_updated;
116 c338b6ad Fam Zheng
    bool cid_checked;
117 f4c129a3 Fam Zheng
    uint32_t cid;
118 5f4da8c0 ths
    uint32_t parent_cid;
119 b3976d3c Fam Zheng
    int num_extents;
120 b3976d3c Fam Zheng
    /* Extent array with num_extents entries, ascend ordered by address */
121 b3976d3c Fam Zheng
    VmdkExtent *extents;
122 2bc3166c Kevin Wolf
    Error *migration_blocker;
123 f4c129a3 Fam Zheng
    char *create_type;
124 ea2384d3 bellard
} BDRVVmdkState;
125 ea2384d3 bellard
126 630530a6 ths
typedef struct VmdkMetaData {
127 630530a6 ths
    uint32_t offset;
128 630530a6 ths
    unsigned int l1_index;
129 630530a6 ths
    unsigned int l2_index;
130 630530a6 ths
    unsigned int l2_offset;
131 630530a6 ths
    int valid;
132 cdeaf1f1 Fam Zheng
    uint32_t *l2_cache_entry;
133 630530a6 ths
} VmdkMetaData;
134 630530a6 ths
135 432bb170 Fam Zheng
typedef struct VmdkGrainMarker {
136 432bb170 Fam Zheng
    uint64_t lba;
137 432bb170 Fam Zheng
    uint32_t size;
138 432bb170 Fam Zheng
    uint8_t  data[0];
139 5d8caa54 Fam Zheng
} QEMU_PACKED VmdkGrainMarker;
140 432bb170 Fam Zheng
141 65bd155c Kevin Wolf
enum {
142 65bd155c Kevin Wolf
    MARKER_END_OF_STREAM    = 0,
143 65bd155c Kevin Wolf
    MARKER_GRAIN_TABLE      = 1,
144 65bd155c Kevin Wolf
    MARKER_GRAIN_DIRECTORY  = 2,
145 65bd155c Kevin Wolf
    MARKER_FOOTER           = 3,
146 65bd155c Kevin Wolf
};
147 65bd155c Kevin Wolf
148 ea2384d3 bellard
static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
149 ea2384d3 bellard
{
150 ea2384d3 bellard
    uint32_t magic;
151 ea2384d3 bellard
152 ae261c86 Fam Zheng
    if (buf_size < 4) {
153 ea2384d3 bellard
        return 0;
154 ae261c86 Fam Zheng
    }
155 ea2384d3 bellard
    magic = be32_to_cpu(*(uint32_t *)buf);
156 ea2384d3 bellard
    if (magic == VMDK3_MAGIC ||
157 01fc99d6 Fam Zheng
        magic == VMDK4_MAGIC) {
158 ea2384d3 bellard
        return 100;
159 01fc99d6 Fam Zheng
    } else {
160 01fc99d6 Fam Zheng
        const char *p = (const char *)buf;
161 01fc99d6 Fam Zheng
        const char *end = p + buf_size;
162 01fc99d6 Fam Zheng
        while (p < end) {
163 01fc99d6 Fam Zheng
            if (*p == '#') {
164 01fc99d6 Fam Zheng
                /* skip comment line */
165 01fc99d6 Fam Zheng
                while (p < end && *p != '\n') {
166 01fc99d6 Fam Zheng
                    p++;
167 01fc99d6 Fam Zheng
                }
168 01fc99d6 Fam Zheng
                p++;
169 01fc99d6 Fam Zheng
                continue;
170 01fc99d6 Fam Zheng
            }
171 01fc99d6 Fam Zheng
            if (*p == ' ') {
172 01fc99d6 Fam Zheng
                while (p < end && *p == ' ') {
173 01fc99d6 Fam Zheng
                    p++;
174 01fc99d6 Fam Zheng
                }
175 01fc99d6 Fam Zheng
                /* skip '\r' if windows line endings used. */
176 01fc99d6 Fam Zheng
                if (p < end && *p == '\r') {
177 01fc99d6 Fam Zheng
                    p++;
178 01fc99d6 Fam Zheng
                }
179 01fc99d6 Fam Zheng
                /* only accept blank lines before 'version=' line */
180 01fc99d6 Fam Zheng
                if (p == end || *p != '\n') {
181 01fc99d6 Fam Zheng
                    return 0;
182 01fc99d6 Fam Zheng
                }
183 01fc99d6 Fam Zheng
                p++;
184 01fc99d6 Fam Zheng
                continue;
185 01fc99d6 Fam Zheng
            }
186 01fc99d6 Fam Zheng
            if (end - p >= strlen("version=X\n")) {
187 01fc99d6 Fam Zheng
                if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
188 01fc99d6 Fam Zheng
                    strncmp("version=2\n", p, strlen("version=2\n")) == 0) {
189 01fc99d6 Fam Zheng
                    return 100;
190 01fc99d6 Fam Zheng
                }
191 01fc99d6 Fam Zheng
            }
192 01fc99d6 Fam Zheng
            if (end - p >= strlen("version=X\r\n")) {
193 01fc99d6 Fam Zheng
                if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
194 01fc99d6 Fam Zheng
                    strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) {
195 01fc99d6 Fam Zheng
                    return 100;
196 01fc99d6 Fam Zheng
                }
197 01fc99d6 Fam Zheng
            }
198 01fc99d6 Fam Zheng
            return 0;
199 01fc99d6 Fam Zheng
        }
200 ea2384d3 bellard
        return 0;
201 01fc99d6 Fam Zheng
    }
202 ea2384d3 bellard
}
203 ea2384d3 bellard
204 3b46e624 ths
#define SECTOR_SIZE 512
205 f66fd6c3 Fam Zheng
#define DESC_SIZE (20 * SECTOR_SIZE)    /* 20 sectors of 512 bytes each */
206 f66fd6c3 Fam Zheng
#define BUF_SIZE 4096
207 f66fd6c3 Fam Zheng
#define HEADER_SIZE 512                 /* first sector of 512 bytes */
208 5f4da8c0 ths
209 b3976d3c Fam Zheng
static void vmdk_free_extents(BlockDriverState *bs)
210 b3976d3c Fam Zheng
{
211 b3976d3c Fam Zheng
    int i;
212 b3976d3c Fam Zheng
    BDRVVmdkState *s = bs->opaque;
213 b3c0bfb6 Fam Zheng
    VmdkExtent *e;
214 b3976d3c Fam Zheng
215 b3976d3c Fam Zheng
    for (i = 0; i < s->num_extents; i++) {
216 b3c0bfb6 Fam Zheng
        e = &s->extents[i];
217 b3c0bfb6 Fam Zheng
        g_free(e->l1_table);
218 b3c0bfb6 Fam Zheng
        g_free(e->l2_cache);
219 b3c0bfb6 Fam Zheng
        g_free(e->l1_backup_table);
220 f4c129a3 Fam Zheng
        g_free(e->type);
221 b3c0bfb6 Fam Zheng
        if (e->file != bs->file) {
222 4f6fd349 Fam Zheng
            bdrv_unref(e->file);
223 b3c0bfb6 Fam Zheng
        }
224 b3976d3c Fam Zheng
    }
225 7267c094 Anthony Liguori
    g_free(s->extents);
226 b3976d3c Fam Zheng
}
227 b3976d3c Fam Zheng
228 86c6b429 Fam Zheng
static void vmdk_free_last_extent(BlockDriverState *bs)
229 86c6b429 Fam Zheng
{
230 86c6b429 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
231 86c6b429 Fam Zheng
232 86c6b429 Fam Zheng
    if (s->num_extents == 0) {
233 86c6b429 Fam Zheng
        return;
234 86c6b429 Fam Zheng
    }
235 86c6b429 Fam Zheng
    s->num_extents--;
236 86c6b429 Fam Zheng
    s->extents = g_realloc(s->extents, s->num_extents * sizeof(VmdkExtent));
237 86c6b429 Fam Zheng
}
238 86c6b429 Fam Zheng
239 5f4da8c0 ths
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
240 ea2384d3 bellard
{
241 5f4da8c0 ths
    char desc[DESC_SIZE];
242 8379e46d Pavel Borzenkov
    uint32_t cid = 0xffffffff;
243 7ccfb2eb blueswir1
    const char *p_name, *cid_str;
244 5f4da8c0 ths
    size_t cid_str_size;
245 e1da9b24 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
246 99f1835d Kevin Wolf
    int ret;
247 5f4da8c0 ths
248 99f1835d Kevin Wolf
    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
249 99f1835d Kevin Wolf
    if (ret < 0) {
250 5f4da8c0 ths
        return 0;
251 e1da9b24 Fam Zheng
    }
252 5f4da8c0 ths
253 5f4da8c0 ths
    if (parent) {
254 5f4da8c0 ths
        cid_str = "parentCID";
255 5f4da8c0 ths
        cid_str_size = sizeof("parentCID");
256 5f4da8c0 ths
    } else {
257 5f4da8c0 ths
        cid_str = "CID";
258 5f4da8c0 ths
        cid_str_size = sizeof("CID");
259 5f4da8c0 ths
    }
260 5f4da8c0 ths
261 93897b9f Kevin Wolf
    desc[DESC_SIZE - 1] = '\0';
262 ae261c86 Fam Zheng
    p_name = strstr(desc, cid_str);
263 ae261c86 Fam Zheng
    if (p_name != NULL) {
264 5f4da8c0 ths
        p_name += cid_str_size;
265 ae261c86 Fam Zheng
        sscanf(p_name, "%x", &cid);
266 5f4da8c0 ths
    }
267 5f4da8c0 ths
268 5f4da8c0 ths
    return cid;
269 5f4da8c0 ths
}
270 5f4da8c0 ths
271 5f4da8c0 ths
static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
272 5f4da8c0 ths
{
273 5f4da8c0 ths
    char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
274 5f4da8c0 ths
    char *p_name, *tmp_str;
275 e1da9b24 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
276 99f1835d Kevin Wolf
    int ret;
277 5f4da8c0 ths
278 99f1835d Kevin Wolf
    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
279 99f1835d Kevin Wolf
    if (ret < 0) {
280 99f1835d Kevin Wolf
        return ret;
281 e1da9b24 Fam Zheng
    }
282 5f4da8c0 ths
283 93897b9f Kevin Wolf
    desc[DESC_SIZE - 1] = '\0';
284 ae261c86 Fam Zheng
    tmp_str = strstr(desc, "parentCID");
285 93897b9f Kevin Wolf
    if (tmp_str == NULL) {
286 93897b9f Kevin Wolf
        return -EINVAL;
287 93897b9f Kevin Wolf
    }
288 93897b9f Kevin Wolf
289 363a37d5 blueswir1
    pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
290 ae261c86 Fam Zheng
    p_name = strstr(desc, "CID");
291 ae261c86 Fam Zheng
    if (p_name != NULL) {
292 5f4da8c0 ths
        p_name += sizeof("CID");
293 363a37d5 blueswir1
        snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
294 363a37d5 blueswir1
        pstrcat(desc, sizeof(desc), tmp_desc);
295 5f4da8c0 ths
    }
296 5f4da8c0 ths
297 99f1835d Kevin Wolf
    ret = bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE);
298 99f1835d Kevin Wolf
    if (ret < 0) {
299 99f1835d Kevin Wolf
        return ret;
300 e1da9b24 Fam Zheng
    }
301 99f1835d Kevin Wolf
302 5f4da8c0 ths
    return 0;
303 5f4da8c0 ths
}
304 5f4da8c0 ths
305 5f4da8c0 ths
static int vmdk_is_cid_valid(BlockDriverState *bs)
306 5f4da8c0 ths
{
307 5f4da8c0 ths
    BDRVVmdkState *s = bs->opaque;
308 b171271a Kevin Wolf
    BlockDriverState *p_bs = bs->backing_hd;
309 5f4da8c0 ths
    uint32_t cur_pcid;
310 5f4da8c0 ths
311 c338b6ad Fam Zheng
    if (!s->cid_checked && p_bs) {
312 ae261c86 Fam Zheng
        cur_pcid = vmdk_read_cid(p_bs, 0);
313 ae261c86 Fam Zheng
        if (s->parent_cid != cur_pcid) {
314 ae261c86 Fam Zheng
            /* CID not valid */
315 5f4da8c0 ths
            return 0;
316 ae261c86 Fam Zheng
        }
317 5f4da8c0 ths
    }
318 c338b6ad Fam Zheng
    s->cid_checked = true;
319 ae261c86 Fam Zheng
    /* CID valid */
320 5f4da8c0 ths
    return 1;
321 5f4da8c0 ths
}
322 5f4da8c0 ths
323 3897575f Jeff Cody
/* Queue extents, if any, for reopen() */
324 3897575f Jeff Cody
static int vmdk_reopen_prepare(BDRVReopenState *state,
325 3897575f Jeff Cody
                               BlockReopenQueue *queue, Error **errp)
326 3897575f Jeff Cody
{
327 3897575f Jeff Cody
    BDRVVmdkState *s;
328 3897575f Jeff Cody
    int ret = -1;
329 3897575f Jeff Cody
    int i;
330 3897575f Jeff Cody
    VmdkExtent *e;
331 3897575f Jeff Cody
332 3897575f Jeff Cody
    assert(state != NULL);
333 3897575f Jeff Cody
    assert(state->bs != NULL);
334 3897575f Jeff Cody
335 3897575f Jeff Cody
    if (queue == NULL) {
336 4823970b Fam Zheng
        error_setg(errp, "No reopen queue for VMDK extents");
337 3897575f Jeff Cody
        goto exit;
338 3897575f Jeff Cody
    }
339 3897575f Jeff Cody
340 3897575f Jeff Cody
    s = state->bs->opaque;
341 3897575f Jeff Cody
342 3897575f Jeff Cody
    assert(s != NULL);
343 3897575f Jeff Cody
344 3897575f Jeff Cody
    for (i = 0; i < s->num_extents; i++) {
345 3897575f Jeff Cody
        e = &s->extents[i];
346 3897575f Jeff Cody
        if (e->file != state->bs->file) {
347 3897575f Jeff Cody
            bdrv_reopen_queue(queue, e->file, state->flags);
348 3897575f Jeff Cody
        }
349 3897575f Jeff Cody
    }
350 3897575f Jeff Cody
    ret = 0;
351 3897575f Jeff Cody
352 3897575f Jeff Cody
exit:
353 3897575f Jeff Cody
    return ret;
354 3897575f Jeff Cody
}
355 3897575f Jeff Cody
356 9949f97e Kevin Wolf
static int vmdk_parent_open(BlockDriverState *bs)
357 5f4da8c0 ths
{
358 5fafdf24 ths
    char *p_name;
359 7fa60fa3 Fam Zheng
    char desc[DESC_SIZE + 1];
360 e1da9b24 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
361 588b65a3 Paolo Bonzini
    int ret;
362 5f4da8c0 ths
363 7fa60fa3 Fam Zheng
    desc[DESC_SIZE] = '\0';
364 588b65a3 Paolo Bonzini
    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
365 588b65a3 Paolo Bonzini
    if (ret < 0) {
366 588b65a3 Paolo Bonzini
        return ret;
367 e1da9b24 Fam Zheng
    }
368 5f4da8c0 ths
369 ae261c86 Fam Zheng
    p_name = strstr(desc, "parentFileNameHint");
370 ae261c86 Fam Zheng
    if (p_name != NULL) {
371 5f4da8c0 ths
        char *end_name;
372 5f4da8c0 ths
373 5f4da8c0 ths
        p_name += sizeof("parentFileNameHint") + 1;
374 ae261c86 Fam Zheng
        end_name = strchr(p_name, '\"');
375 ae261c86 Fam Zheng
        if (end_name == NULL) {
376 588b65a3 Paolo Bonzini
            return -EINVAL;
377 ae261c86 Fam Zheng
        }
378 ae261c86 Fam Zheng
        if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
379 588b65a3 Paolo Bonzini
            return -EINVAL;
380 ae261c86 Fam Zheng
        }
381 3b46e624 ths
382 b171271a Kevin Wolf
        pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
383 ff1afc72 bellard
    }
384 5f4da8c0 ths
385 5f4da8c0 ths
    return 0;
386 5f4da8c0 ths
}
387 5f4da8c0 ths
388 b3976d3c Fam Zheng
/* Create and append extent to the extent array. Return the added VmdkExtent
389 b3976d3c Fam Zheng
 * address. return NULL if allocation failed. */
390 8aa1331c Fam Zheng
static int vmdk_add_extent(BlockDriverState *bs,
391 b3976d3c Fam Zheng
                           BlockDriverState *file, bool flat, int64_t sectors,
392 b3976d3c Fam Zheng
                           int64_t l1_offset, int64_t l1_backup_offset,
393 b3976d3c Fam Zheng
                           uint32_t l1_size,
394 8aa1331c Fam Zheng
                           int l2_size, uint64_t cluster_sectors,
395 4823970b Fam Zheng
                           VmdkExtent **new_extent,
396 4823970b Fam Zheng
                           Error **errp)
397 b3976d3c Fam Zheng
{
398 b3976d3c Fam Zheng
    VmdkExtent *extent;
399 b3976d3c Fam Zheng
    BDRVVmdkState *s = bs->opaque;
400 b3976d3c Fam Zheng
401 8aa1331c Fam Zheng
    if (cluster_sectors > 0x200000) {
402 8aa1331c Fam Zheng
        /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
403 4823970b Fam Zheng
        error_setg(errp, "Invalid granularity, image may be corrupt");
404 4823970b Fam Zheng
        return -EFBIG;
405 8aa1331c Fam Zheng
    }
406 b0651b8c Fam Zheng
    if (l1_size > 512 * 1024 * 1024) {
407 b0651b8c Fam Zheng
        /* Although with big capacity and small l1_entry_sectors, we can get a
408 b0651b8c Fam Zheng
         * big l1_size, we don't want unbounded value to allocate the table.
409 b0651b8c Fam Zheng
         * Limit it to 512M, which is 16PB for default cluster and L2 table
410 b0651b8c Fam Zheng
         * size */
411 4823970b Fam Zheng
        error_setg(errp, "L1 size too big");
412 b0651b8c Fam Zheng
        return -EFBIG;
413 b0651b8c Fam Zheng
    }
414 8aa1331c Fam Zheng
415 7267c094 Anthony Liguori
    s->extents = g_realloc(s->extents,
416 b3976d3c Fam Zheng
                              (s->num_extents + 1) * sizeof(VmdkExtent));
417 b3976d3c Fam Zheng
    extent = &s->extents[s->num_extents];
418 b3976d3c Fam Zheng
    s->num_extents++;
419 b3976d3c Fam Zheng
420 b3976d3c Fam Zheng
    memset(extent, 0, sizeof(VmdkExtent));
421 b3976d3c Fam Zheng
    extent->file = file;
422 b3976d3c Fam Zheng
    extent->flat = flat;
423 b3976d3c Fam Zheng
    extent->sectors = sectors;
424 b3976d3c Fam Zheng
    extent->l1_table_offset = l1_offset;
425 b3976d3c Fam Zheng
    extent->l1_backup_table_offset = l1_backup_offset;
426 b3976d3c Fam Zheng
    extent->l1_size = l1_size;
427 b3976d3c Fam Zheng
    extent->l1_entry_sectors = l2_size * cluster_sectors;
428 b3976d3c Fam Zheng
    extent->l2_size = l2_size;
429 301c7d38 Fam Zheng
    extent->cluster_sectors = flat ? sectors : cluster_sectors;
430 b3976d3c Fam Zheng
431 b3976d3c Fam Zheng
    if (s->num_extents > 1) {
432 b3976d3c Fam Zheng
        extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
433 b3976d3c Fam Zheng
    } else {
434 b3976d3c Fam Zheng
        extent->end_sector = extent->sectors;
435 b3976d3c Fam Zheng
    }
436 b3976d3c Fam Zheng
    bs->total_sectors = extent->end_sector;
437 8aa1331c Fam Zheng
    if (new_extent) {
438 8aa1331c Fam Zheng
        *new_extent = extent;
439 8aa1331c Fam Zheng
    }
440 8aa1331c Fam Zheng
    return 0;
441 b3976d3c Fam Zheng
}
442 b3976d3c Fam Zheng
443 4823970b Fam Zheng
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent,
444 4823970b Fam Zheng
                            Error **errp)
445 5f4da8c0 ths
{
446 b4b3ab14 Fam Zheng
    int ret;
447 b4b3ab14 Fam Zheng
    int l1_size, i;
448 5f4da8c0 ths
449 ea2384d3 bellard
    /* read the L1 table */
450 b3976d3c Fam Zheng
    l1_size = extent->l1_size * sizeof(uint32_t);
451 7267c094 Anthony Liguori
    extent->l1_table = g_malloc(l1_size);
452 b4b3ab14 Fam Zheng
    ret = bdrv_pread(extent->file,
453 4823970b Fam Zheng
                     extent->l1_table_offset,
454 4823970b Fam Zheng
                     extent->l1_table,
455 4823970b Fam Zheng
                     l1_size);
456 b4b3ab14 Fam Zheng
    if (ret < 0) {
457 4823970b Fam Zheng
        error_setg_errno(errp, -ret,
458 4823970b Fam Zheng
                         "Could not read l1 table from extent '%s'",
459 4823970b Fam Zheng
                         extent->file->filename);
460 b4b3ab14 Fam Zheng
        goto fail_l1;
461 b3976d3c Fam Zheng
    }
462 b3976d3c Fam Zheng
    for (i = 0; i < extent->l1_size; i++) {
463 b3976d3c Fam Zheng
        le32_to_cpus(&extent->l1_table[i]);
464 ea2384d3 bellard
    }
465 ea2384d3 bellard
466 b3976d3c Fam Zheng
    if (extent->l1_backup_table_offset) {
467 7267c094 Anthony Liguori
        extent->l1_backup_table = g_malloc(l1_size);
468 b4b3ab14 Fam Zheng
        ret = bdrv_pread(extent->file,
469 4823970b Fam Zheng
                         extent->l1_backup_table_offset,
470 4823970b Fam Zheng
                         extent->l1_backup_table,
471 4823970b Fam Zheng
                         l1_size);
472 b4b3ab14 Fam Zheng
        if (ret < 0) {
473 4823970b Fam Zheng
            error_setg_errno(errp, -ret,
474 4823970b Fam Zheng
                             "Could not read l1 backup table from extent '%s'",
475 4823970b Fam Zheng
                             extent->file->filename);
476 b4b3ab14 Fam Zheng
            goto fail_l1b;
477 b3976d3c Fam Zheng
        }
478 b3976d3c Fam Zheng
        for (i = 0; i < extent->l1_size; i++) {
479 b3976d3c Fam Zheng
            le32_to_cpus(&extent->l1_backup_table[i]);
480 ff1afc72 bellard
        }
481 ff1afc72 bellard
    }
482 ff1afc72 bellard
483 b3976d3c Fam Zheng
    extent->l2_cache =
484 7267c094 Anthony Liguori
        g_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
485 ea2384d3 bellard
    return 0;
486 b4b3ab14 Fam Zheng
 fail_l1b:
487 7267c094 Anthony Liguori
    g_free(extent->l1_backup_table);
488 b4b3ab14 Fam Zheng
 fail_l1:
489 7267c094 Anthony Liguori
    g_free(extent->l1_table);
490 b4b3ab14 Fam Zheng
    return ret;
491 b4b3ab14 Fam Zheng
}
492 b4b3ab14 Fam Zheng
493 daac8fdc Fam Zheng
static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
494 daac8fdc Fam Zheng
                                 BlockDriverState *file,
495 4823970b Fam Zheng
                                 int flags, Error **errp)
496 b4b3ab14 Fam Zheng
{
497 b4b3ab14 Fam Zheng
    int ret;
498 b4b3ab14 Fam Zheng
    uint32_t magic;
499 b4b3ab14 Fam Zheng
    VMDK3Header header;
500 b4b3ab14 Fam Zheng
    VmdkExtent *extent;
501 b4b3ab14 Fam Zheng
502 86c6b429 Fam Zheng
    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
503 b4b3ab14 Fam Zheng
    if (ret < 0) {
504 4823970b Fam Zheng
        error_setg_errno(errp, -ret,
505 4823970b Fam Zheng
                         "Could not read header from file '%s'",
506 4823970b Fam Zheng
                         file->filename);
507 86c6b429 Fam Zheng
        return ret;
508 b4b3ab14 Fam Zheng
    }
509 f6b61e54 Fam Zheng
    ret = vmdk_add_extent(bs, file, false,
510 f6b61e54 Fam Zheng
                          le32_to_cpu(header.disk_sectors),
511 f6b61e54 Fam Zheng
                          le32_to_cpu(header.l1dir_offset) << 9,
512 f6b61e54 Fam Zheng
                          0,
513 f6b61e54 Fam Zheng
                          le32_to_cpu(header.l1dir_size),
514 f6b61e54 Fam Zheng
                          4096,
515 f6b61e54 Fam Zheng
                          le32_to_cpu(header.granularity),
516 4823970b Fam Zheng
                          &extent,
517 4823970b Fam Zheng
                          errp);
518 8aa1331c Fam Zheng
    if (ret < 0) {
519 8aa1331c Fam Zheng
        return ret;
520 8aa1331c Fam Zheng
    }
521 4823970b Fam Zheng
    ret = vmdk_init_tables(bs, extent, errp);
522 b4b3ab14 Fam Zheng
    if (ret) {
523 86c6b429 Fam Zheng
        /* free extent allocated by vmdk_add_extent */
524 86c6b429 Fam Zheng
        vmdk_free_last_extent(bs);
525 b4b3ab14 Fam Zheng
    }
526 b4b3ab14 Fam Zheng
    return ret;
527 b4b3ab14 Fam Zheng
}
528 b4b3ab14 Fam Zheng
529 d1833ef5 Paolo Bonzini
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
530 d1833ef5 Paolo Bonzini
                               Error **errp);
531 f16f509d Fam Zheng
532 a8842e6d Paolo Bonzini
static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
533 a8842e6d Paolo Bonzini
                            Error **errp)
534 a8842e6d Paolo Bonzini
{
535 a8842e6d Paolo Bonzini
    int64_t size;
536 a8842e6d Paolo Bonzini
    char *buf;
537 a8842e6d Paolo Bonzini
    int ret;
538 a8842e6d Paolo Bonzini
539 a8842e6d Paolo Bonzini
    size = bdrv_getlength(file);
540 a8842e6d Paolo Bonzini
    if (size < 0) {
541 a8842e6d Paolo Bonzini
        error_setg_errno(errp, -size, "Could not access file");
542 a8842e6d Paolo Bonzini
        return NULL;
543 a8842e6d Paolo Bonzini
    }
544 a8842e6d Paolo Bonzini
545 a8842e6d Paolo Bonzini
    size = MIN(size, 1 << 20);  /* avoid unbounded allocation */
546 a8842e6d Paolo Bonzini
    buf = g_malloc0(size + 1);
547 a8842e6d Paolo Bonzini
548 a8842e6d Paolo Bonzini
    ret = bdrv_pread(file, desc_offset, buf, size);
549 a8842e6d Paolo Bonzini
    if (ret < 0) {
550 a8842e6d Paolo Bonzini
        error_setg_errno(errp, -ret, "Could not read from file");
551 a8842e6d Paolo Bonzini
        g_free(buf);
552 a8842e6d Paolo Bonzini
        return NULL;
553 a8842e6d Paolo Bonzini
    }
554 a8842e6d Paolo Bonzini
555 a8842e6d Paolo Bonzini
    return buf;
556 a8842e6d Paolo Bonzini
}
557 a8842e6d Paolo Bonzini
558 86c6b429 Fam Zheng
static int vmdk_open_vmdk4(BlockDriverState *bs,
559 86c6b429 Fam Zheng
                           BlockDriverState *file,
560 4823970b Fam Zheng
                           int flags, Error **errp)
561 b4b3ab14 Fam Zheng
{
562 b4b3ab14 Fam Zheng
    int ret;
563 b4b3ab14 Fam Zheng
    uint32_t magic;
564 b4b3ab14 Fam Zheng
    uint32_t l1_size, l1_entry_sectors;
565 b4b3ab14 Fam Zheng
    VMDK4Header header;
566 b4b3ab14 Fam Zheng
    VmdkExtent *extent;
567 f4c129a3 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
568 bb45ded9 Fam Zheng
    int64_t l1_backup_offset = 0;
569 b4b3ab14 Fam Zheng
570 86c6b429 Fam Zheng
    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
571 b4b3ab14 Fam Zheng
    if (ret < 0) {
572 4823970b Fam Zheng
        error_setg_errno(errp, -ret,
573 4823970b Fam Zheng
                         "Could not read header from file '%s'",
574 4823970b Fam Zheng
                         file->filename);
575 89ac8480 Paolo Bonzini
        return -EINVAL;
576 b4b3ab14 Fam Zheng
    }
577 5a394b9e Stefan Hajnoczi
    if (header.capacity == 0) {
578 e98768d4 Fam Zheng
        uint64_t desc_offset = le64_to_cpu(header.desc_offset);
579 5a394b9e Stefan Hajnoczi
        if (desc_offset) {
580 d1833ef5 Paolo Bonzini
            char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
581 d1833ef5 Paolo Bonzini
            if (!buf) {
582 d1833ef5 Paolo Bonzini
                return -EINVAL;
583 d1833ef5 Paolo Bonzini
            }
584 d1833ef5 Paolo Bonzini
            ret = vmdk_open_desc_file(bs, flags, buf, errp);
585 d1833ef5 Paolo Bonzini
            g_free(buf);
586 d1833ef5 Paolo Bonzini
            return ret;
587 5a394b9e Stefan Hajnoczi
        }
588 f16f509d Fam Zheng
    }
589 65bd155c Kevin Wolf
590 f4c129a3 Fam Zheng
    if (!s->create_type) {
591 f4c129a3 Fam Zheng
        s->create_type = g_strdup("monolithicSparse");
592 f4c129a3 Fam Zheng
    }
593 f4c129a3 Fam Zheng
594 65bd155c Kevin Wolf
    if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
595 65bd155c Kevin Wolf
        /*
596 65bd155c Kevin Wolf
         * The footer takes precedence over the header, so read it in. The
597 65bd155c Kevin Wolf
         * footer starts at offset -1024 from the end: One sector for the
598 65bd155c Kevin Wolf
         * footer, and another one for the end-of-stream marker.
599 65bd155c Kevin Wolf
         */
600 65bd155c Kevin Wolf
        struct {
601 65bd155c Kevin Wolf
            struct {
602 65bd155c Kevin Wolf
                uint64_t val;
603 65bd155c Kevin Wolf
                uint32_t size;
604 65bd155c Kevin Wolf
                uint32_t type;
605 65bd155c Kevin Wolf
                uint8_t pad[512 - 16];
606 65bd155c Kevin Wolf
            } QEMU_PACKED footer_marker;
607 65bd155c Kevin Wolf
608 65bd155c Kevin Wolf
            uint32_t magic;
609 65bd155c Kevin Wolf
            VMDK4Header header;
610 65bd155c Kevin Wolf
            uint8_t pad[512 - 4 - sizeof(VMDK4Header)];
611 65bd155c Kevin Wolf
612 65bd155c Kevin Wolf
            struct {
613 65bd155c Kevin Wolf
                uint64_t val;
614 65bd155c Kevin Wolf
                uint32_t size;
615 65bd155c Kevin Wolf
                uint32_t type;
616 65bd155c Kevin Wolf
                uint8_t pad[512 - 16];
617 65bd155c Kevin Wolf
            } QEMU_PACKED eos_marker;
618 65bd155c Kevin Wolf
        } QEMU_PACKED footer;
619 65bd155c Kevin Wolf
620 65bd155c Kevin Wolf
        ret = bdrv_pread(file,
621 65bd155c Kevin Wolf
            bs->file->total_sectors * 512 - 1536,
622 65bd155c Kevin Wolf
            &footer, sizeof(footer));
623 65bd155c Kevin Wolf
        if (ret < 0) {
624 65bd155c Kevin Wolf
            return ret;
625 65bd155c Kevin Wolf
        }
626 65bd155c Kevin Wolf
627 65bd155c Kevin Wolf
        /* Some sanity checks for the footer */
628 65bd155c Kevin Wolf
        if (be32_to_cpu(footer.magic) != VMDK4_MAGIC ||
629 65bd155c Kevin Wolf
            le32_to_cpu(footer.footer_marker.size) != 0  ||
630 65bd155c Kevin Wolf
            le32_to_cpu(footer.footer_marker.type) != MARKER_FOOTER ||
631 65bd155c Kevin Wolf
            le64_to_cpu(footer.eos_marker.val) != 0  ||
632 65bd155c Kevin Wolf
            le32_to_cpu(footer.eos_marker.size) != 0  ||
633 65bd155c Kevin Wolf
            le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
634 65bd155c Kevin Wolf
        {
635 65bd155c Kevin Wolf
            return -EINVAL;
636 65bd155c Kevin Wolf
        }
637 65bd155c Kevin Wolf
638 65bd155c Kevin Wolf
        header = footer.header;
639 65bd155c Kevin Wolf
    }
640 65bd155c Kevin Wolf
641 509d39aa Fam Zheng
    if (le32_to_cpu(header.version) > 3) {
642 96c51eb5 Fam Zheng
        char buf[64];
643 96c51eb5 Fam Zheng
        snprintf(buf, sizeof(buf), "VMDK version %d",
644 96c51eb5 Fam Zheng
                 le32_to_cpu(header.version));
645 89ac8480 Paolo Bonzini
        error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
646 89ac8480 Paolo Bonzini
                  bs->device_name, "vmdk", buf);
647 96c51eb5 Fam Zheng
        return -ENOTSUP;
648 509d39aa Fam Zheng
    } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
649 509d39aa Fam Zheng
        /* VMware KB 2064959 explains that version 3 added support for
650 509d39aa Fam Zheng
         * persistent changed block tracking (CBT), and backup software can
651 509d39aa Fam Zheng
         * read it as version=1 if it doesn't care about the changed area
652 509d39aa Fam Zheng
         * information. So we are safe to enable read only. */
653 509d39aa Fam Zheng
        error_setg(errp, "VMDK version 3 must be read only");
654 509d39aa Fam Zheng
        return -EINVAL;
655 96c51eb5 Fam Zheng
    }
656 96c51eb5 Fam Zheng
657 ca8804ce Fam Zheng
    if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
658 89ac8480 Paolo Bonzini
        error_setg(errp, "L2 table size too big");
659 f8ce0403 Fam Zheng
        return -EINVAL;
660 f8ce0403 Fam Zheng
    }
661 f8ce0403 Fam Zheng
662 ca8804ce Fam Zheng
    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
663 b4b3ab14 Fam Zheng
                        * le64_to_cpu(header.granularity);
664 75d12341 Stefan Weil
    if (l1_entry_sectors == 0) {
665 86c6b429 Fam Zheng
        return -EINVAL;
666 86c6b429 Fam Zheng
    }
667 b4b3ab14 Fam Zheng
    l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
668 b4b3ab14 Fam Zheng
                / l1_entry_sectors;
669 bb45ded9 Fam Zheng
    if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
670 bb45ded9 Fam Zheng
        l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
671 bb45ded9 Fam Zheng
    }
672 34ceed81 Fam Zheng
    if (bdrv_getlength(file) <
673 34ceed81 Fam Zheng
            le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE) {
674 89ac8480 Paolo Bonzini
        error_setg(errp, "File truncated, expecting at least %lld bytes",
675 89ac8480 Paolo Bonzini
                   le64_to_cpu(header.grain_offset) * BDRV_SECTOR_SIZE);
676 34ceed81 Fam Zheng
        return -EINVAL;
677 34ceed81 Fam Zheng
    }
678 34ceed81 Fam Zheng
679 8aa1331c Fam Zheng
    ret = vmdk_add_extent(bs, file, false,
680 b4b3ab14 Fam Zheng
                          le64_to_cpu(header.capacity),
681 b4b3ab14 Fam Zheng
                          le64_to_cpu(header.gd_offset) << 9,
682 bb45ded9 Fam Zheng
                          l1_backup_offset,
683 b4b3ab14 Fam Zheng
                          l1_size,
684 ca8804ce Fam Zheng
                          le32_to_cpu(header.num_gtes_per_gt),
685 8aa1331c Fam Zheng
                          le64_to_cpu(header.granularity),
686 4823970b Fam Zheng
                          &extent,
687 4823970b Fam Zheng
                          errp);
688 8aa1331c Fam Zheng
    if (ret < 0) {
689 8aa1331c Fam Zheng
        return ret;
690 8aa1331c Fam Zheng
    }
691 432bb170 Fam Zheng
    extent->compressed =
692 432bb170 Fam Zheng
        le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
693 d8a7b061 Fam Zheng
    if (extent->compressed) {
694 d8a7b061 Fam Zheng
        g_free(s->create_type);
695 d8a7b061 Fam Zheng
        s->create_type = g_strdup("streamOptimized");
696 d8a7b061 Fam Zheng
    }
697 432bb170 Fam Zheng
    extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
698 14ead646 Fam Zheng
    extent->version = le32_to_cpu(header.version);
699 14ead646 Fam Zheng
    extent->has_zero_grain = le32_to_cpu(header.flags) & VMDK4_FLAG_ZERO_GRAIN;
700 4823970b Fam Zheng
    ret = vmdk_init_tables(bs, extent, errp);
701 b4b3ab14 Fam Zheng
    if (ret) {
702 86c6b429 Fam Zheng
        /* free extent allocated by vmdk_add_extent */
703 86c6b429 Fam Zheng
        vmdk_free_last_extent(bs);
704 b4b3ab14 Fam Zheng
    }
705 b4b3ab14 Fam Zheng
    return ret;
706 b4b3ab14 Fam Zheng
}
707 b4b3ab14 Fam Zheng
708 7fa60fa3 Fam Zheng
/* find an option value out of descriptor file */
709 7fa60fa3 Fam Zheng
static int vmdk_parse_description(const char *desc, const char *opt_name,
710 7fa60fa3 Fam Zheng
        char *buf, int buf_size)
711 7fa60fa3 Fam Zheng
{
712 7fa60fa3 Fam Zheng
    char *opt_pos, *opt_end;
713 7fa60fa3 Fam Zheng
    const char *end = desc + strlen(desc);
714 7fa60fa3 Fam Zheng
715 7fa60fa3 Fam Zheng
    opt_pos = strstr(desc, opt_name);
716 7fa60fa3 Fam Zheng
    if (!opt_pos) {
717 65f74725 Fam Zheng
        return VMDK_ERROR;
718 7fa60fa3 Fam Zheng
    }
719 7fa60fa3 Fam Zheng
    /* Skip "=\"" following opt_name */
720 7fa60fa3 Fam Zheng
    opt_pos += strlen(opt_name) + 2;
721 7fa60fa3 Fam Zheng
    if (opt_pos >= end) {
722 65f74725 Fam Zheng
        return VMDK_ERROR;
723 7fa60fa3 Fam Zheng
    }
724 7fa60fa3 Fam Zheng
    opt_end = opt_pos;
725 7fa60fa3 Fam Zheng
    while (opt_end < end && *opt_end != '"') {
726 7fa60fa3 Fam Zheng
        opt_end++;
727 7fa60fa3 Fam Zheng
    }
728 7fa60fa3 Fam Zheng
    if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
729 65f74725 Fam Zheng
        return VMDK_ERROR;
730 7fa60fa3 Fam Zheng
    }
731 7fa60fa3 Fam Zheng
    pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
732 65f74725 Fam Zheng
    return VMDK_OK;
733 7fa60fa3 Fam Zheng
}
734 7fa60fa3 Fam Zheng
735 86c6b429 Fam Zheng
/* Open an extent file and append to bs array */
736 86c6b429 Fam Zheng
static int vmdk_open_sparse(BlockDriverState *bs,
737 d1833ef5 Paolo Bonzini
                            BlockDriverState *file, int flags,
738 d1833ef5 Paolo Bonzini
                            char *buf, Error **errp)
739 86c6b429 Fam Zheng
{
740 86c6b429 Fam Zheng
    uint32_t magic;
741 86c6b429 Fam Zheng
742 d1833ef5 Paolo Bonzini
    magic = ldl_be_p(buf);
743 86c6b429 Fam Zheng
    switch (magic) {
744 86c6b429 Fam Zheng
        case VMDK3_MAGIC:
745 4823970b Fam Zheng
            return vmdk_open_vmfs_sparse(bs, file, flags, errp);
746 86c6b429 Fam Zheng
            break;
747 86c6b429 Fam Zheng
        case VMDK4_MAGIC:
748 4823970b Fam Zheng
            return vmdk_open_vmdk4(bs, file, flags, errp);
749 86c6b429 Fam Zheng
            break;
750 86c6b429 Fam Zheng
        default:
751 76abe407 Paolo Bonzini
            error_setg(errp, "Image not in VMDK format");
752 76abe407 Paolo Bonzini
            return -EINVAL;
753 86c6b429 Fam Zheng
            break;
754 86c6b429 Fam Zheng
    }
755 86c6b429 Fam Zheng
}
756 86c6b429 Fam Zheng
757 7fa60fa3 Fam Zheng
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
758 4823970b Fam Zheng
                              const char *desc_file_path, Error **errp)
759 7fa60fa3 Fam Zheng
{
760 7fa60fa3 Fam Zheng
    int ret;
761 7fa60fa3 Fam Zheng
    char access[11];
762 7fa60fa3 Fam Zheng
    char type[11];
763 7fa60fa3 Fam Zheng
    char fname[512];
764 7fa60fa3 Fam Zheng
    const char *p = desc;
765 7fa60fa3 Fam Zheng
    int64_t sectors = 0;
766 7fa60fa3 Fam Zheng
    int64_t flat_offset;
767 86c6b429 Fam Zheng
    char extent_path[PATH_MAX];
768 86c6b429 Fam Zheng
    BlockDriverState *extent_file;
769 f4c129a3 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
770 f4c129a3 Fam Zheng
    VmdkExtent *extent;
771 7fa60fa3 Fam Zheng
772 7fa60fa3 Fam Zheng
    while (*p) {
773 7fa60fa3 Fam Zheng
        /* parse extent line:
774 7fa60fa3 Fam Zheng
         * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
775 7fa60fa3 Fam Zheng
         * or
776 7fa60fa3 Fam Zheng
         * RW [size in sectors] SPARSE "file-name.vmdk"
777 7fa60fa3 Fam Zheng
         */
778 7fa60fa3 Fam Zheng
        flat_offset = -1;
779 cd923475 Philipp Hahn
        ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
780 7fa60fa3 Fam Zheng
                access, &sectors, type, fname, &flat_offset);
781 7fa60fa3 Fam Zheng
        if (ret < 4 || strcmp(access, "RW")) {
782 7fa60fa3 Fam Zheng
            goto next_line;
783 7fa60fa3 Fam Zheng
        } else if (!strcmp(type, "FLAT")) {
784 7fa60fa3 Fam Zheng
            if (ret != 5 || flat_offset < 0) {
785 4823970b Fam Zheng
                error_setg(errp, "Invalid extent lines: \n%s", p);
786 7fa60fa3 Fam Zheng
                return -EINVAL;
787 7fa60fa3 Fam Zheng
            }
788 dbbcaa8d Fam Zheng
        } else if (!strcmp(type, "VMFS")) {
789 b47053bd Fam Zheng
            if (ret == 4) {
790 b47053bd Fam Zheng
                flat_offset = 0;
791 b47053bd Fam Zheng
            } else {
792 b47053bd Fam Zheng
                error_setg(errp, "Invalid extent lines:\n%s", p);
793 b47053bd Fam Zheng
                return -EINVAL;
794 b47053bd Fam Zheng
            }
795 7fa60fa3 Fam Zheng
        } else if (ret != 4) {
796 b47053bd Fam Zheng
            error_setg(errp, "Invalid extent lines:\n%s", p);
797 7fa60fa3 Fam Zheng
            return -EINVAL;
798 7fa60fa3 Fam Zheng
        }
799 7fa60fa3 Fam Zheng
800 7fa60fa3 Fam Zheng
        if (sectors <= 0 ||
801 daac8fdc Fam Zheng
            (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
802 04d542c8 Paolo Bonzini
             strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
803 7fa60fa3 Fam Zheng
            (strcmp(access, "RW"))) {
804 7fa60fa3 Fam Zheng
            goto next_line;
805 7fa60fa3 Fam Zheng
        }
806 7fa60fa3 Fam Zheng
807 86c6b429 Fam Zheng
        path_combine(extent_path, sizeof(extent_path),
808 86c6b429 Fam Zheng
                desc_file_path, fname);
809 2e40134b Max Reitz
        extent_file = NULL;
810 2e40134b Max Reitz
        ret = bdrv_open(&extent_file, extent_path, NULL, NULL,
811 2e40134b Max Reitz
                        bs->open_flags | BDRV_O_PROTOCOL, NULL, errp);
812 86c6b429 Fam Zheng
        if (ret) {
813 86c6b429 Fam Zheng
            return ret;
814 86c6b429 Fam Zheng
        }
815 86c6b429 Fam Zheng
816 7fa60fa3 Fam Zheng
        /* save to extents array */
817 04d542c8 Paolo Bonzini
        if (!strcmp(type, "FLAT") || !strcmp(type, "VMFS")) {
818 7fa60fa3 Fam Zheng
            /* FLAT extent */
819 7fa60fa3 Fam Zheng
820 8aa1331c Fam Zheng
            ret = vmdk_add_extent(bs, extent_file, true, sectors,
821 4823970b Fam Zheng
                            0, 0, 0, 0, 0, &extent, errp);
822 8aa1331c Fam Zheng
            if (ret < 0) {
823 8aa1331c Fam Zheng
                return ret;
824 8aa1331c Fam Zheng
            }
825 f16f509d Fam Zheng
            extent->flat_start_offset = flat_offset << 9;
826 daac8fdc Fam Zheng
        } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
827 daac8fdc Fam Zheng
            /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
828 d1833ef5 Paolo Bonzini
            char *buf = vmdk_read_desc(extent_file, 0, errp);
829 d1833ef5 Paolo Bonzini
            if (!buf) {
830 d1833ef5 Paolo Bonzini
                ret = -EINVAL;
831 d1833ef5 Paolo Bonzini
            } else {
832 d1833ef5 Paolo Bonzini
                ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp);
833 d1833ef5 Paolo Bonzini
            }
834 86c6b429 Fam Zheng
            if (ret) {
835 d1833ef5 Paolo Bonzini
                g_free(buf);
836 4f6fd349 Fam Zheng
                bdrv_unref(extent_file);
837 86c6b429 Fam Zheng
                return ret;
838 86c6b429 Fam Zheng
            }
839 f4c129a3 Fam Zheng
            extent = &s->extents[s->num_extents - 1];
840 7fa60fa3 Fam Zheng
        } else {
841 4823970b Fam Zheng
            error_setg(errp, "Unsupported extent type '%s'", type);
842 7fa60fa3 Fam Zheng
            return -ENOTSUP;
843 7fa60fa3 Fam Zheng
        }
844 f4c129a3 Fam Zheng
        extent->type = g_strdup(type);
845 7fa60fa3 Fam Zheng
next_line:
846 7fa60fa3 Fam Zheng
        /* move to next line */
847 899f1ae2 Fam Zheng
        while (*p) {
848 899f1ae2 Fam Zheng
            if (*p == '\n') {
849 899f1ae2 Fam Zheng
                p++;
850 899f1ae2 Fam Zheng
                break;
851 899f1ae2 Fam Zheng
            }
852 7fa60fa3 Fam Zheng
            p++;
853 7fa60fa3 Fam Zheng
        }
854 7fa60fa3 Fam Zheng
    }
855 7fa60fa3 Fam Zheng
    return 0;
856 7fa60fa3 Fam Zheng
}
857 7fa60fa3 Fam Zheng
858 d1833ef5 Paolo Bonzini
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
859 d1833ef5 Paolo Bonzini
                               Error **errp)
860 7fa60fa3 Fam Zheng
{
861 7fa60fa3 Fam Zheng
    int ret;
862 7fa60fa3 Fam Zheng
    char ct[128];
863 7fa60fa3 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
864 7fa60fa3 Fam Zheng
865 7fa60fa3 Fam Zheng
    if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
866 76abe407 Paolo Bonzini
        error_setg(errp, "invalid VMDK image descriptor");
867 76abe407 Paolo Bonzini
        ret = -EINVAL;
868 0bed087d Evgeny Budilovsky
        goto exit;
869 7fa60fa3 Fam Zheng
    }
870 6398de51 Fam Zheng
    if (strcmp(ct, "monolithicFlat") &&
871 04d542c8 Paolo Bonzini
        strcmp(ct, "vmfs") &&
872 daac8fdc Fam Zheng
        strcmp(ct, "vmfsSparse") &&
873 86c6b429 Fam Zheng
        strcmp(ct, "twoGbMaxExtentSparse") &&
874 6398de51 Fam Zheng
        strcmp(ct, "twoGbMaxExtentFlat")) {
875 4823970b Fam Zheng
        error_setg(errp, "Unsupported image type '%s'", ct);
876 0bed087d Evgeny Budilovsky
        ret = -ENOTSUP;
877 0bed087d Evgeny Budilovsky
        goto exit;
878 7fa60fa3 Fam Zheng
    }
879 f4c129a3 Fam Zheng
    s->create_type = g_strdup(ct);
880 7fa60fa3 Fam Zheng
    s->desc_offset = 0;
881 4823970b Fam Zheng
    ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
882 0bed087d Evgeny Budilovsky
exit:
883 0bed087d Evgeny Budilovsky
    return ret;
884 7fa60fa3 Fam Zheng
}
885 7fa60fa3 Fam Zheng
886 015a1036 Max Reitz
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
887 015a1036 Max Reitz
                     Error **errp)
888 b4b3ab14 Fam Zheng
{
889 d1833ef5 Paolo Bonzini
    char *buf = NULL;
890 86c6b429 Fam Zheng
    int ret;
891 86c6b429 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
892 37f09e5e Paolo Bonzini
    uint32_t magic;
893 b4b3ab14 Fam Zheng
894 d1833ef5 Paolo Bonzini
    buf = vmdk_read_desc(bs->file, 0, errp);
895 d1833ef5 Paolo Bonzini
    if (!buf) {
896 d1833ef5 Paolo Bonzini
        return -EINVAL;
897 d1833ef5 Paolo Bonzini
    }
898 d1833ef5 Paolo Bonzini
899 37f09e5e Paolo Bonzini
    magic = ldl_be_p(buf);
900 37f09e5e Paolo Bonzini
    switch (magic) {
901 37f09e5e Paolo Bonzini
        case VMDK3_MAGIC:
902 37f09e5e Paolo Bonzini
        case VMDK4_MAGIC:
903 37f09e5e Paolo Bonzini
            ret = vmdk_open_sparse(bs, bs->file, flags, buf, errp);
904 37f09e5e Paolo Bonzini
            s->desc_offset = 0x200;
905 37f09e5e Paolo Bonzini
            break;
906 37f09e5e Paolo Bonzini
        default:
907 37f09e5e Paolo Bonzini
            ret = vmdk_open_desc_file(bs, flags, buf, errp);
908 37f09e5e Paolo Bonzini
            break;
909 b4b3ab14 Fam Zheng
    }
910 37f09e5e Paolo Bonzini
    if (ret) {
911 37f09e5e Paolo Bonzini
        goto fail;
912 37f09e5e Paolo Bonzini
    }
913 37f09e5e Paolo Bonzini
914 bae0a0cc Paolo Bonzini
    /* try to open parent images, if exist */
915 bae0a0cc Paolo Bonzini
    ret = vmdk_parent_open(bs);
916 bae0a0cc Paolo Bonzini
    if (ret) {
917 bae0a0cc Paolo Bonzini
        goto fail;
918 bae0a0cc Paolo Bonzini
    }
919 f4c129a3 Fam Zheng
    s->cid = vmdk_read_cid(bs, 0);
920 bae0a0cc Paolo Bonzini
    s->parent_cid = vmdk_read_cid(bs, 1);
921 848c66e8 Paolo Bonzini
    qemu_co_mutex_init(&s->lock);
922 2bc3166c Kevin Wolf
923 2bc3166c Kevin Wolf
    /* Disable migration when VMDK images are used */
924 2bc3166c Kevin Wolf
    error_set(&s->migration_blocker,
925 2bc3166c Kevin Wolf
              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
926 2bc3166c Kevin Wolf
              "vmdk", bs->device_name, "live migration");
927 2bc3166c Kevin Wolf
    migrate_add_blocker(s->migration_blocker);
928 d1833ef5 Paolo Bonzini
    g_free(buf);
929 2bc3166c Kevin Wolf
    return 0;
930 bae0a0cc Paolo Bonzini
931 bae0a0cc Paolo Bonzini
fail:
932 d1833ef5 Paolo Bonzini
    g_free(buf);
933 f4c129a3 Fam Zheng
    g_free(s->create_type);
934 f4c129a3 Fam Zheng
    s->create_type = NULL;
935 bae0a0cc Paolo Bonzini
    vmdk_free_extents(bs);
936 bae0a0cc Paolo Bonzini
    return ret;
937 ea2384d3 bellard
}
938 ea2384d3 bellard
939 d34682cd Kevin Wolf
940 d34682cd Kevin Wolf
static int vmdk_refresh_limits(BlockDriverState *bs)
941 d34682cd Kevin Wolf
{
942 d34682cd Kevin Wolf
    BDRVVmdkState *s = bs->opaque;
943 d34682cd Kevin Wolf
    int i;
944 d34682cd Kevin Wolf
945 d34682cd Kevin Wolf
    for (i = 0; i < s->num_extents; i++) {
946 d34682cd Kevin Wolf
        if (!s->extents[i].flat) {
947 d34682cd Kevin Wolf
            bs->bl.write_zeroes_alignment =
948 d34682cd Kevin Wolf
                MAX(bs->bl.write_zeroes_alignment,
949 d34682cd Kevin Wolf
                    s->extents[i].cluster_sectors);
950 d34682cd Kevin Wolf
        }
951 d34682cd Kevin Wolf
    }
952 d34682cd Kevin Wolf
953 d34682cd Kevin Wolf
    return 0;
954 d34682cd Kevin Wolf
}
955 d34682cd Kevin Wolf
956 b3976d3c Fam Zheng
static int get_whole_cluster(BlockDriverState *bs,
957 b3976d3c Fam Zheng
                VmdkExtent *extent,
958 b3976d3c Fam Zheng
                uint64_t cluster_offset,
959 b3976d3c Fam Zheng
                uint64_t offset,
960 b3976d3c Fam Zheng
                bool allocate)
961 5f4da8c0 ths
{
962 bf81507d Fam Zheng
    int ret = VMDK_OK;
963 bf81507d Fam Zheng
    uint8_t *whole_grain = NULL;
964 5f4da8c0 ths
965 0e69c543 Fam Zheng
    /* we will be here if it's first write on non-exist grain(cluster).
966 0e69c543 Fam Zheng
     * try to read from parent image, if exist */
967 b171271a Kevin Wolf
    if (bs->backing_hd) {
968 bf81507d Fam Zheng
        whole_grain =
969 bf81507d Fam Zheng
            qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
970 ae261c86 Fam Zheng
        if (!vmdk_is_cid_valid(bs)) {
971 bf81507d Fam Zheng
            ret = VMDK_ERROR;
972 bf81507d Fam Zheng
            goto exit;
973 ae261c86 Fam Zheng
        }
974 5f4da8c0 ths
975 0e69c543 Fam Zheng
        /* floor offset to cluster */
976 0e69c543 Fam Zheng
        offset -= offset % (extent->cluster_sectors * 512);
977 c336500d Kevin Wolf
        ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
978 b3976d3c Fam Zheng
                extent->cluster_sectors);
979 c336500d Kevin Wolf
        if (ret < 0) {
980 bf81507d Fam Zheng
            ret = VMDK_ERROR;
981 bf81507d Fam Zheng
            goto exit;
982 c336500d Kevin Wolf
        }
983 630530a6 ths
984 0e69c543 Fam Zheng
        /* Write grain only into the active image */
985 b3976d3c Fam Zheng
        ret = bdrv_write(extent->file, cluster_offset, whole_grain,
986 b3976d3c Fam Zheng
                extent->cluster_sectors);
987 c336500d Kevin Wolf
        if (ret < 0) {
988 bf81507d Fam Zheng
            ret = VMDK_ERROR;
989 bf81507d Fam Zheng
            goto exit;
990 630530a6 ths
        }
991 630530a6 ths
    }
992 bf81507d Fam Zheng
exit:
993 bf81507d Fam Zheng
    qemu_vfree(whole_grain);
994 bf81507d Fam Zheng
    return ret;
995 630530a6 ths
}
996 630530a6 ths
997 b3976d3c Fam Zheng
static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
998 630530a6 ths
{
999 e304e8e5 Fam Zheng
    uint32_t offset;
1000 e304e8e5 Fam Zheng
    QEMU_BUILD_BUG_ON(sizeof(offset) != sizeof(m_data->offset));
1001 e304e8e5 Fam Zheng
    offset = cpu_to_le32(m_data->offset);
1002 630530a6 ths
    /* update L2 table */
1003 b3976d3c Fam Zheng
    if (bdrv_pwrite_sync(
1004 b3976d3c Fam Zheng
                extent->file,
1005 b3976d3c Fam Zheng
                ((int64_t)m_data->l2_offset * 512)
1006 b3976d3c Fam Zheng
                    + (m_data->l2_index * sizeof(m_data->offset)),
1007 e304e8e5 Fam Zheng
                &offset, sizeof(offset)) < 0) {
1008 65f74725 Fam Zheng
        return VMDK_ERROR;
1009 b3976d3c Fam Zheng
    }
1010 630530a6 ths
    /* update backup L2 table */
1011 b3976d3c Fam Zheng
    if (extent->l1_backup_table_offset != 0) {
1012 b3976d3c Fam Zheng
        m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
1013 b3976d3c Fam Zheng
        if (bdrv_pwrite_sync(
1014 b3976d3c Fam Zheng
                    extent->file,
1015 b3976d3c Fam Zheng
                    ((int64_t)m_data->l2_offset * 512)
1016 b3976d3c Fam Zheng
                        + (m_data->l2_index * sizeof(m_data->offset)),
1017 e304e8e5 Fam Zheng
                    &offset, sizeof(offset)) < 0) {
1018 65f74725 Fam Zheng
            return VMDK_ERROR;
1019 b3976d3c Fam Zheng
        }
1020 5f4da8c0 ths
    }
1021 cdeaf1f1 Fam Zheng
    if (m_data->l2_cache_entry) {
1022 cdeaf1f1 Fam Zheng
        *m_data->l2_cache_entry = offset;
1023 cdeaf1f1 Fam Zheng
    }
1024 630530a6 ths
1025 65f74725 Fam Zheng
    return VMDK_OK;
1026 5f4da8c0 ths
}
1027 5f4da8c0 ths
1028 91b85bd3 Fam Zheng
static int get_cluster_offset(BlockDriverState *bs,
1029 b3976d3c Fam Zheng
                                    VmdkExtent *extent,
1030 b3976d3c Fam Zheng
                                    VmdkMetaData *m_data,
1031 91b85bd3 Fam Zheng
                                    uint64_t offset,
1032 91b85bd3 Fam Zheng
                                    int allocate,
1033 91b85bd3 Fam Zheng
                                    uint64_t *cluster_offset)
1034 ea2384d3 bellard
{
1035 ea2384d3 bellard
    unsigned int l1_index, l2_offset, l2_index;
1036 ea2384d3 bellard
    int min_index, i, j;
1037 e304e8e5 Fam Zheng
    uint32_t min_count, *l2_table;
1038 14ead646 Fam Zheng
    bool zeroed = false;
1039 630530a6 ths
1040 ae261c86 Fam Zheng
    if (m_data) {
1041 630530a6 ths
        m_data->valid = 0;
1042 ae261c86 Fam Zheng
    }
1043 91b85bd3 Fam Zheng
    if (extent->flat) {
1044 7fa60fa3 Fam Zheng
        *cluster_offset = extent->flat_start_offset;
1045 65f74725 Fam Zheng
        return VMDK_OK;
1046 91b85bd3 Fam Zheng
    }
1047 630530a6 ths
1048 6398de51 Fam Zheng
    offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE;
1049 b3976d3c Fam Zheng
    l1_index = (offset >> 9) / extent->l1_entry_sectors;
1050 b3976d3c Fam Zheng
    if (l1_index >= extent->l1_size) {
1051 65f74725 Fam Zheng
        return VMDK_ERROR;
1052 b3976d3c Fam Zheng
    }
1053 b3976d3c Fam Zheng
    l2_offset = extent->l1_table[l1_index];
1054 b3976d3c Fam Zheng
    if (!l2_offset) {
1055 65f74725 Fam Zheng
        return VMDK_UNALLOC;
1056 b3976d3c Fam Zheng
    }
1057 b4b3ab14 Fam Zheng
    for (i = 0; i < L2_CACHE_SIZE; i++) {
1058 b3976d3c Fam Zheng
        if (l2_offset == extent->l2_cache_offsets[i]) {
1059 ea2384d3 bellard
            /* increment the hit count */
1060 b3976d3c Fam Zheng
            if (++extent->l2_cache_counts[i] == 0xffffffff) {
1061 b4b3ab14 Fam Zheng
                for (j = 0; j < L2_CACHE_SIZE; j++) {
1062 b3976d3c Fam Zheng
                    extent->l2_cache_counts[j] >>= 1;
1063 ea2384d3 bellard
                }
1064 ea2384d3 bellard
            }
1065 b3976d3c Fam Zheng
            l2_table = extent->l2_cache + (i * extent->l2_size);
1066 ea2384d3 bellard
            goto found;
1067 ea2384d3 bellard
        }
1068 ea2384d3 bellard
    }
1069 ea2384d3 bellard
    /* not found: load a new entry in the least used one */
1070 ea2384d3 bellard
    min_index = 0;
1071 ea2384d3 bellard
    min_count = 0xffffffff;
1072 b4b3ab14 Fam Zheng
    for (i = 0; i < L2_CACHE_SIZE; i++) {
1073 b3976d3c Fam Zheng
        if (extent->l2_cache_counts[i] < min_count) {
1074 b3976d3c Fam Zheng
            min_count = extent->l2_cache_counts[i];
1075 ea2384d3 bellard
            min_index = i;
1076 ea2384d3 bellard
        }
1077 ea2384d3 bellard
    }
1078 b3976d3c Fam Zheng
    l2_table = extent->l2_cache + (min_index * extent->l2_size);
1079 b3976d3c Fam Zheng
    if (bdrv_pread(
1080 b3976d3c Fam Zheng
                extent->file,
1081 b3976d3c Fam Zheng
                (int64_t)l2_offset * 512,
1082 b3976d3c Fam Zheng
                l2_table,
1083 b3976d3c Fam Zheng
                extent->l2_size * sizeof(uint32_t)
1084 b3976d3c Fam Zheng
            ) != extent->l2_size * sizeof(uint32_t)) {
1085 65f74725 Fam Zheng
        return VMDK_ERROR;
1086 b3976d3c Fam Zheng
    }
1087 5f4da8c0 ths
1088 b3976d3c Fam Zheng
    extent->l2_cache_offsets[min_index] = l2_offset;
1089 b3976d3c Fam Zheng
    extent->l2_cache_counts[min_index] = 1;
1090 ea2384d3 bellard
 found:
1091 b3976d3c Fam Zheng
    l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
1092 91b85bd3 Fam Zheng
    *cluster_offset = le32_to_cpu(l2_table[l2_index]);
1093 630530a6 ths
1094 cdeaf1f1 Fam Zheng
    if (m_data) {
1095 cdeaf1f1 Fam Zheng
        m_data->valid = 1;
1096 cdeaf1f1 Fam Zheng
        m_data->l1_index = l1_index;
1097 cdeaf1f1 Fam Zheng
        m_data->l2_index = l2_index;
1098 cdeaf1f1 Fam Zheng
        m_data->offset = *cluster_offset;
1099 cdeaf1f1 Fam Zheng
        m_data->l2_offset = l2_offset;
1100 cdeaf1f1 Fam Zheng
        m_data->l2_cache_entry = &l2_table[l2_index];
1101 cdeaf1f1 Fam Zheng
    }
1102 14ead646 Fam Zheng
    if (extent->has_zero_grain && *cluster_offset == VMDK_GTE_ZEROED) {
1103 14ead646 Fam Zheng
        zeroed = true;
1104 14ead646 Fam Zheng
    }
1105 14ead646 Fam Zheng
1106 14ead646 Fam Zheng
    if (!*cluster_offset || zeroed) {
1107 91b85bd3 Fam Zheng
        if (!allocate) {
1108 14ead646 Fam Zheng
            return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
1109 91b85bd3 Fam Zheng
        }
1110 9949f97e Kevin Wolf
1111 ae261c86 Fam Zheng
        /* Avoid the L2 tables update for the images that have snapshots. */
1112 91b85bd3 Fam Zheng
        *cluster_offset = bdrv_getlength(extent->file);
1113 2b2c8c5d Fam Zheng
        if (!extent->compressed) {
1114 2b2c8c5d Fam Zheng
            bdrv_truncate(
1115 2b2c8c5d Fam Zheng
                extent->file,
1116 2b2c8c5d Fam Zheng
                *cluster_offset + (extent->cluster_sectors << 9)
1117 2b2c8c5d Fam Zheng
            );
1118 2b2c8c5d Fam Zheng
        }
1119 9949f97e Kevin Wolf
1120 91b85bd3 Fam Zheng
        *cluster_offset >>= 9;
1121 e304e8e5 Fam Zheng
        l2_table[l2_index] = cpu_to_le32(*cluster_offset);
1122 630530a6 ths
1123 630530a6 ths
        /* First of all we write grain itself, to avoid race condition
1124 630530a6 ths
         * that may to corrupt the image.
1125 630530a6 ths
         * This problem may occur because of insufficient space on host disk
1126 630530a6 ths
         * or inappropriate VM shutdown.
1127 630530a6 ths
         */
1128 b3976d3c Fam Zheng
        if (get_whole_cluster(
1129 ae261c86 Fam Zheng
                bs, extent, *cluster_offset, offset, allocate) == -1) {
1130 65f74725 Fam Zheng
            return VMDK_ERROR;
1131 ae261c86 Fam Zheng
        }
1132 630530a6 ths
1133 630530a6 ths
        if (m_data) {
1134 e304e8e5 Fam Zheng
            m_data->offset = *cluster_offset;
1135 630530a6 ths
        }
1136 ff1afc72 bellard
    }
1137 91b85bd3 Fam Zheng
    *cluster_offset <<= 9;
1138 65f74725 Fam Zheng
    return VMDK_OK;
1139 ea2384d3 bellard
}
1140 ea2384d3 bellard
1141 b3976d3c Fam Zheng
static VmdkExtent *find_extent(BDRVVmdkState *s,
1142 b3976d3c Fam Zheng
                                int64_t sector_num, VmdkExtent *start_hint)
1143 b3976d3c Fam Zheng
{
1144 b3976d3c Fam Zheng
    VmdkExtent *extent = start_hint;
1145 b3976d3c Fam Zheng
1146 b3976d3c Fam Zheng
    if (!extent) {
1147 b3976d3c Fam Zheng
        extent = &s->extents[0];
1148 b3976d3c Fam Zheng
    }
1149 b3976d3c Fam Zheng
    while (extent < &s->extents[s->num_extents]) {
1150 b3976d3c Fam Zheng
        if (sector_num < extent->end_sector) {
1151 b3976d3c Fam Zheng
            return extent;
1152 b3976d3c Fam Zheng
        }
1153 b3976d3c Fam Zheng
        extent++;
1154 b3976d3c Fam Zheng
    }
1155 b3976d3c Fam Zheng
    return NULL;
1156 b3976d3c Fam Zheng
}
1157 b3976d3c Fam Zheng
1158 b6b8a333 Paolo Bonzini
static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
1159 f8a2e5e3 Stefan Hajnoczi
        int64_t sector_num, int nb_sectors, int *pnum)
1160 ea2384d3 bellard
{
1161 ea2384d3 bellard
    BDRVVmdkState *s = bs->opaque;
1162 b3976d3c Fam Zheng
    int64_t index_in_cluster, n, ret;
1163 b3976d3c Fam Zheng
    uint64_t offset;
1164 b3976d3c Fam Zheng
    VmdkExtent *extent;
1165 b3976d3c Fam Zheng
1166 b3976d3c Fam Zheng
    extent = find_extent(s, sector_num, NULL);
1167 b3976d3c Fam Zheng
    if (!extent) {
1168 b3976d3c Fam Zheng
        return 0;
1169 b3976d3c Fam Zheng
    }
1170 f8a2e5e3 Stefan Hajnoczi
    qemu_co_mutex_lock(&s->lock);
1171 91b85bd3 Fam Zheng
    ret = get_cluster_offset(bs, extent, NULL,
1172 91b85bd3 Fam Zheng
                            sector_num * 512, 0, &offset);
1173 f8a2e5e3 Stefan Hajnoczi
    qemu_co_mutex_unlock(&s->lock);
1174 14ead646 Fam Zheng
1175 4bc74be9 Paolo Bonzini
    switch (ret) {
1176 4bc74be9 Paolo Bonzini
    case VMDK_ERROR:
1177 4bc74be9 Paolo Bonzini
        ret = -EIO;
1178 4bc74be9 Paolo Bonzini
        break;
1179 4bc74be9 Paolo Bonzini
    case VMDK_UNALLOC:
1180 4bc74be9 Paolo Bonzini
        ret = 0;
1181 4bc74be9 Paolo Bonzini
        break;
1182 4bc74be9 Paolo Bonzini
    case VMDK_ZEROED:
1183 4bc74be9 Paolo Bonzini
        ret = BDRV_BLOCK_ZERO;
1184 4bc74be9 Paolo Bonzini
        break;
1185 4bc74be9 Paolo Bonzini
    case VMDK_OK:
1186 4bc74be9 Paolo Bonzini
        ret = BDRV_BLOCK_DATA;
1187 3eba13ec Peter Lieven
        if (extent->file == bs->file && !extent->compressed) {
1188 4bc74be9 Paolo Bonzini
            ret |= BDRV_BLOCK_OFFSET_VALID | offset;
1189 4bc74be9 Paolo Bonzini
        }
1190 4bc74be9 Paolo Bonzini
1191 4bc74be9 Paolo Bonzini
        break;
1192 4bc74be9 Paolo Bonzini
    }
1193 91b85bd3 Fam Zheng
1194 91b85bd3 Fam Zheng
    index_in_cluster = sector_num % extent->cluster_sectors;
1195 91b85bd3 Fam Zheng
    n = extent->cluster_sectors - index_in_cluster;
1196 ae261c86 Fam Zheng
    if (n > nb_sectors) {
1197 ea2384d3 bellard
        n = nb_sectors;
1198 ae261c86 Fam Zheng
    }
1199 ea2384d3 bellard
    *pnum = n;
1200 b3976d3c Fam Zheng
    return ret;
1201 ea2384d3 bellard
}
1202 ea2384d3 bellard
1203 dd3f6ee2 Fam Zheng
static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
1204 dd3f6ee2 Fam Zheng
                            int64_t offset_in_cluster, const uint8_t *buf,
1205 dd3f6ee2 Fam Zheng
                            int nb_sectors, int64_t sector_num)
1206 dd3f6ee2 Fam Zheng
{
1207 dd3f6ee2 Fam Zheng
    int ret;
1208 2b2c8c5d Fam Zheng
    VmdkGrainMarker *data = NULL;
1209 2b2c8c5d Fam Zheng
    uLongf buf_len;
1210 dd3f6ee2 Fam Zheng
    const uint8_t *write_buf = buf;
1211 dd3f6ee2 Fam Zheng
    int write_len = nb_sectors * 512;
1212 dd3f6ee2 Fam Zheng
1213 2b2c8c5d Fam Zheng
    if (extent->compressed) {
1214 2b2c8c5d Fam Zheng
        if (!extent->has_marker) {
1215 2b2c8c5d Fam Zheng
            ret = -EINVAL;
1216 2b2c8c5d Fam Zheng
            goto out;
1217 2b2c8c5d Fam Zheng
        }
1218 2b2c8c5d Fam Zheng
        buf_len = (extent->cluster_sectors << 9) * 2;
1219 2b2c8c5d Fam Zheng
        data = g_malloc(buf_len + sizeof(VmdkGrainMarker));
1220 2b2c8c5d Fam Zheng
        if (compress(data->data, &buf_len, buf, nb_sectors << 9) != Z_OK ||
1221 2b2c8c5d Fam Zheng
                buf_len == 0) {
1222 2b2c8c5d Fam Zheng
            ret = -EINVAL;
1223 2b2c8c5d Fam Zheng
            goto out;
1224 2b2c8c5d Fam Zheng
        }
1225 2b2c8c5d Fam Zheng
        data->lba = sector_num;
1226 2b2c8c5d Fam Zheng
        data->size = buf_len;
1227 2b2c8c5d Fam Zheng
        write_buf = (uint8_t *)data;
1228 2b2c8c5d Fam Zheng
        write_len = buf_len + sizeof(VmdkGrainMarker);
1229 2b2c8c5d Fam Zheng
    }
1230 dd3f6ee2 Fam Zheng
    ret = bdrv_pwrite(extent->file,
1231 dd3f6ee2 Fam Zheng
                        cluster_offset + offset_in_cluster,
1232 dd3f6ee2 Fam Zheng
                        write_buf,
1233 dd3f6ee2 Fam Zheng
                        write_len);
1234 dd3f6ee2 Fam Zheng
    if (ret != write_len) {
1235 dd3f6ee2 Fam Zheng
        ret = ret < 0 ? ret : -EIO;
1236 dd3f6ee2 Fam Zheng
        goto out;
1237 dd3f6ee2 Fam Zheng
    }
1238 dd3f6ee2 Fam Zheng
    ret = 0;
1239 dd3f6ee2 Fam Zheng
 out:
1240 2b2c8c5d Fam Zheng
    g_free(data);
1241 dd3f6ee2 Fam Zheng
    return ret;
1242 dd3f6ee2 Fam Zheng
}
1243 dd3f6ee2 Fam Zheng
1244 dd3f6ee2 Fam Zheng
static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
1245 dd3f6ee2 Fam Zheng
                            int64_t offset_in_cluster, uint8_t *buf,
1246 dd3f6ee2 Fam Zheng
                            int nb_sectors)
1247 dd3f6ee2 Fam Zheng
{
1248 dd3f6ee2 Fam Zheng
    int ret;
1249 2b2c8c5d Fam Zheng
    int cluster_bytes, buf_bytes;
1250 2b2c8c5d Fam Zheng
    uint8_t *cluster_buf, *compressed_data;
1251 2b2c8c5d Fam Zheng
    uint8_t *uncomp_buf;
1252 2b2c8c5d Fam Zheng
    uint32_t data_len;
1253 2b2c8c5d Fam Zheng
    VmdkGrainMarker *marker;
1254 2b2c8c5d Fam Zheng
    uLongf buf_len;
1255 2b2c8c5d Fam Zheng
1256 dd3f6ee2 Fam Zheng
1257 2b2c8c5d Fam Zheng
    if (!extent->compressed) {
1258 2b2c8c5d Fam Zheng
        ret = bdrv_pread(extent->file,
1259 2b2c8c5d Fam Zheng
                          cluster_offset + offset_in_cluster,
1260 2b2c8c5d Fam Zheng
                          buf, nb_sectors * 512);
1261 2b2c8c5d Fam Zheng
        if (ret == nb_sectors * 512) {
1262 2b2c8c5d Fam Zheng
            return 0;
1263 2b2c8c5d Fam Zheng
        } else {
1264 2b2c8c5d Fam Zheng
            return -EIO;
1265 2b2c8c5d Fam Zheng
        }
1266 2b2c8c5d Fam Zheng
    }
1267 2b2c8c5d Fam Zheng
    cluster_bytes = extent->cluster_sectors * 512;
1268 2b2c8c5d Fam Zheng
    /* Read two clusters in case GrainMarker + compressed data > one cluster */
1269 2b2c8c5d Fam Zheng
    buf_bytes = cluster_bytes * 2;
1270 2b2c8c5d Fam Zheng
    cluster_buf = g_malloc(buf_bytes);
1271 2b2c8c5d Fam Zheng
    uncomp_buf = g_malloc(cluster_bytes);
1272 dd3f6ee2 Fam Zheng
    ret = bdrv_pread(extent->file,
1273 2b2c8c5d Fam Zheng
                cluster_offset,
1274 2b2c8c5d Fam Zheng
                cluster_buf, buf_bytes);
1275 2b2c8c5d Fam Zheng
    if (ret < 0) {
1276 2b2c8c5d Fam Zheng
        goto out;
1277 2b2c8c5d Fam Zheng
    }
1278 2b2c8c5d Fam Zheng
    compressed_data = cluster_buf;
1279 2b2c8c5d Fam Zheng
    buf_len = cluster_bytes;
1280 2b2c8c5d Fam Zheng
    data_len = cluster_bytes;
1281 2b2c8c5d Fam Zheng
    if (extent->has_marker) {
1282 2b2c8c5d Fam Zheng
        marker = (VmdkGrainMarker *)cluster_buf;
1283 2b2c8c5d Fam Zheng
        compressed_data = marker->data;
1284 2b2c8c5d Fam Zheng
        data_len = le32_to_cpu(marker->size);
1285 2b2c8c5d Fam Zheng
    }
1286 2b2c8c5d Fam Zheng
    if (!data_len || data_len > buf_bytes) {
1287 2b2c8c5d Fam Zheng
        ret = -EINVAL;
1288 2b2c8c5d Fam Zheng
        goto out;
1289 2b2c8c5d Fam Zheng
    }
1290 2b2c8c5d Fam Zheng
    ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len);
1291 2b2c8c5d Fam Zheng
    if (ret != Z_OK) {
1292 2b2c8c5d Fam Zheng
        ret = -EINVAL;
1293 2b2c8c5d Fam Zheng
        goto out;
1294 2b2c8c5d Fam Zheng
1295 2b2c8c5d Fam Zheng
    }
1296 2b2c8c5d Fam Zheng
    if (offset_in_cluster < 0 ||
1297 2b2c8c5d Fam Zheng
            offset_in_cluster + nb_sectors * 512 > buf_len) {
1298 2b2c8c5d Fam Zheng
        ret = -EINVAL;
1299 2b2c8c5d Fam Zheng
        goto out;
1300 dd3f6ee2 Fam Zheng
    }
1301 2b2c8c5d Fam Zheng
    memcpy(buf, uncomp_buf + offset_in_cluster, nb_sectors * 512);
1302 2b2c8c5d Fam Zheng
    ret = 0;
1303 2b2c8c5d Fam Zheng
1304 2b2c8c5d Fam Zheng
 out:
1305 2b2c8c5d Fam Zheng
    g_free(uncomp_buf);
1306 2b2c8c5d Fam Zheng
    g_free(cluster_buf);
1307 2b2c8c5d Fam Zheng
    return ret;
1308 dd3f6ee2 Fam Zheng
}
1309 dd3f6ee2 Fam Zheng
1310 5fafdf24 ths
static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
1311 ea2384d3 bellard
                    uint8_t *buf, int nb_sectors)
1312 ea2384d3 bellard
{
1313 ea2384d3 bellard
    BDRVVmdkState *s = bs->opaque;
1314 b3976d3c Fam Zheng
    int ret;
1315 b3976d3c Fam Zheng
    uint64_t n, index_in_cluster;
1316 b1649fae Gerhard Wiesinger
    uint64_t extent_begin_sector, extent_relative_sector_num;
1317 b3976d3c Fam Zheng
    VmdkExtent *extent = NULL;
1318 ea2384d3 bellard
    uint64_t cluster_offset;
1319 5f4da8c0 ths
1320 ea2384d3 bellard
    while (nb_sectors > 0) {
1321 b3976d3c Fam Zheng
        extent = find_extent(s, sector_num, extent);
1322 b3976d3c Fam Zheng
        if (!extent) {
1323 b3976d3c Fam Zheng
            return -EIO;
1324 b3976d3c Fam Zheng
        }
1325 91b85bd3 Fam Zheng
        ret = get_cluster_offset(
1326 91b85bd3 Fam Zheng
                            bs, extent, NULL,
1327 91b85bd3 Fam Zheng
                            sector_num << 9, 0, &cluster_offset);
1328 b1649fae Gerhard Wiesinger
        extent_begin_sector = extent->end_sector - extent->sectors;
1329 b1649fae Gerhard Wiesinger
        extent_relative_sector_num = sector_num - extent_begin_sector;
1330 b1649fae Gerhard Wiesinger
        index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
1331 b3976d3c Fam Zheng
        n = extent->cluster_sectors - index_in_cluster;
1332 ae261c86 Fam Zheng
        if (n > nb_sectors) {
1333 ea2384d3 bellard
            n = nb_sectors;
1334 ae261c86 Fam Zheng
        }
1335 14ead646 Fam Zheng
        if (ret != VMDK_OK) {
1336 91b85bd3 Fam Zheng
            /* if not allocated, try to read from parent image, if exist */
1337 14ead646 Fam Zheng
            if (bs->backing_hd && ret != VMDK_ZEROED) {
1338 ae261c86 Fam Zheng
                if (!vmdk_is_cid_valid(bs)) {
1339 7fa60fa3 Fam Zheng
                    return -EINVAL;
1340 ae261c86 Fam Zheng
                }
1341 b171271a Kevin Wolf
                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
1342 ae261c86 Fam Zheng
                if (ret < 0) {
1343 7fa60fa3 Fam Zheng
                    return ret;
1344 ae261c86 Fam Zheng
                }
1345 5f4da8c0 ths
            } else {
1346 5f4da8c0 ths
                memset(buf, 0, 512 * n);
1347 5f4da8c0 ths
            }
1348 ea2384d3 bellard
        } else {
1349 dd3f6ee2 Fam Zheng
            ret = vmdk_read_extent(extent,
1350 dd3f6ee2 Fam Zheng
                            cluster_offset, index_in_cluster * 512,
1351 dd3f6ee2 Fam Zheng
                            buf, n);
1352 dd3f6ee2 Fam Zheng
            if (ret) {
1353 7fa60fa3 Fam Zheng
                return ret;
1354 7fa60fa3 Fam Zheng
            }
1355 ea2384d3 bellard
        }
1356 ea2384d3 bellard
        nb_sectors -= n;
1357 ea2384d3 bellard
        sector_num += n;
1358 ea2384d3 bellard
        buf += n * 512;
1359 ea2384d3 bellard
    }
1360 ea2384d3 bellard
    return 0;
1361 ea2384d3 bellard
}
1362 ea2384d3 bellard
1363 2914caa0 Paolo Bonzini
static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
1364 2914caa0 Paolo Bonzini
                                     uint8_t *buf, int nb_sectors)
1365 2914caa0 Paolo Bonzini
{
1366 2914caa0 Paolo Bonzini
    int ret;
1367 2914caa0 Paolo Bonzini
    BDRVVmdkState *s = bs->opaque;
1368 2914caa0 Paolo Bonzini
    qemu_co_mutex_lock(&s->lock);
1369 2914caa0 Paolo Bonzini
    ret = vmdk_read(bs, sector_num, buf, nb_sectors);
1370 2914caa0 Paolo Bonzini
    qemu_co_mutex_unlock(&s->lock);
1371 2914caa0 Paolo Bonzini
    return ret;
1372 2914caa0 Paolo Bonzini
}
1373 2914caa0 Paolo Bonzini
1374 cdeaf1f1 Fam Zheng
/**
1375 cdeaf1f1 Fam Zheng
 * vmdk_write:
1376 cdeaf1f1 Fam Zheng
 * @zeroed:       buf is ignored (data is zero), use zeroed_grain GTE feature
1377 8e507243 Fam Zheng
 *                if possible, otherwise return -ENOTSUP.
1378 8e507243 Fam Zheng
 * @zero_dry_run: used for zeroed == true only, don't update L2 table, just try
1379 8e507243 Fam Zheng
 *                with each cluster. By dry run we can find if the zero write
1380 8e507243 Fam Zheng
 *                is possible without modifying image data.
1381 cdeaf1f1 Fam Zheng
 *
1382 cdeaf1f1 Fam Zheng
 * Returns: error code with 0 for success.
1383 cdeaf1f1 Fam Zheng
 */
1384 5fafdf24 ths
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
1385 cdeaf1f1 Fam Zheng
                      const uint8_t *buf, int nb_sectors,
1386 cdeaf1f1 Fam Zheng
                      bool zeroed, bool zero_dry_run)
1387 ea2384d3 bellard
{
1388 ff1afc72 bellard
    BDRVVmdkState *s = bs->opaque;
1389 b3976d3c Fam Zheng
    VmdkExtent *extent = NULL;
1390 585ea0c8 Fam Zheng
    int ret;
1391 585ea0c8 Fam Zheng
    int64_t index_in_cluster, n;
1392 b1649fae Gerhard Wiesinger
    uint64_t extent_begin_sector, extent_relative_sector_num;
1393 ff1afc72 bellard
    uint64_t cluster_offset;
1394 b3976d3c Fam Zheng
    VmdkMetaData m_data;
1395 ff1afc72 bellard
1396 630530a6 ths
    if (sector_num > bs->total_sectors) {
1397 4823970b Fam Zheng
        error_report("Wrong offset: sector_num=0x%" PRIx64
1398 92868412 j_mayer
                " total_sectors=0x%" PRIx64 "\n",
1399 630530a6 ths
                sector_num, bs->total_sectors);
1400 7fa60fa3 Fam Zheng
        return -EIO;
1401 630530a6 ths
    }
1402 630530a6 ths
1403 ff1afc72 bellard
    while (nb_sectors > 0) {
1404 b3976d3c Fam Zheng
        extent = find_extent(s, sector_num, extent);
1405 b3976d3c Fam Zheng
        if (!extent) {
1406 b3976d3c Fam Zheng
            return -EIO;
1407 b3976d3c Fam Zheng
        }
1408 91b85bd3 Fam Zheng
        ret = get_cluster_offset(
1409 b3976d3c Fam Zheng
                                bs,
1410 b3976d3c Fam Zheng
                                extent,
1411 b3976d3c Fam Zheng
                                &m_data,
1412 2b2c8c5d Fam Zheng
                                sector_num << 9, !extent->compressed,
1413 91b85bd3 Fam Zheng
                                &cluster_offset);
1414 2b2c8c5d Fam Zheng
        if (extent->compressed) {
1415 65f74725 Fam Zheng
            if (ret == VMDK_OK) {
1416 2b2c8c5d Fam Zheng
                /* Refuse write to allocated cluster for streamOptimized */
1417 4823970b Fam Zheng
                error_report("Could not write to allocated cluster"
1418 4823970b Fam Zheng
                              " for streamOptimized");
1419 2b2c8c5d Fam Zheng
                return -EIO;
1420 2b2c8c5d Fam Zheng
            } else {
1421 2b2c8c5d Fam Zheng
                /* allocate */
1422 2b2c8c5d Fam Zheng
                ret = get_cluster_offset(
1423 2b2c8c5d Fam Zheng
                                        bs,
1424 2b2c8c5d Fam Zheng
                                        extent,
1425 2b2c8c5d Fam Zheng
                                        &m_data,
1426 2b2c8c5d Fam Zheng
                                        sector_num << 9, 1,
1427 2b2c8c5d Fam Zheng
                                        &cluster_offset);
1428 2b2c8c5d Fam Zheng
            }
1429 2b2c8c5d Fam Zheng
        }
1430 cdeaf1f1 Fam Zheng
        if (ret == VMDK_ERROR) {
1431 91b85bd3 Fam Zheng
            return -EINVAL;
1432 b3976d3c Fam Zheng
        }
1433 b1649fae Gerhard Wiesinger
        extent_begin_sector = extent->end_sector - extent->sectors;
1434 b1649fae Gerhard Wiesinger
        extent_relative_sector_num = sector_num - extent_begin_sector;
1435 b1649fae Gerhard Wiesinger
        index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
1436 b3976d3c Fam Zheng
        n = extent->cluster_sectors - index_in_cluster;
1437 b3976d3c Fam Zheng
        if (n > nb_sectors) {
1438 b3976d3c Fam Zheng
            n = nb_sectors;
1439 b3976d3c Fam Zheng
        }
1440 cdeaf1f1 Fam Zheng
        if (zeroed) {
1441 cdeaf1f1 Fam Zheng
            /* Do zeroed write, buf is ignored */
1442 cdeaf1f1 Fam Zheng
            if (extent->has_zero_grain &&
1443 cdeaf1f1 Fam Zheng
                    index_in_cluster == 0 &&
1444 cdeaf1f1 Fam Zheng
                    n >= extent->cluster_sectors) {
1445 cdeaf1f1 Fam Zheng
                n = extent->cluster_sectors;
1446 cdeaf1f1 Fam Zheng
                if (!zero_dry_run) {
1447 cdeaf1f1 Fam Zheng
                    m_data.offset = VMDK_GTE_ZEROED;
1448 cdeaf1f1 Fam Zheng
                    /* update L2 tables */
1449 cdeaf1f1 Fam Zheng
                    if (vmdk_L2update(extent, &m_data) != VMDK_OK) {
1450 cdeaf1f1 Fam Zheng
                        return -EIO;
1451 cdeaf1f1 Fam Zheng
                    }
1452 cdeaf1f1 Fam Zheng
                }
1453 cdeaf1f1 Fam Zheng
            } else {
1454 cdeaf1f1 Fam Zheng
                return -ENOTSUP;
1455 cdeaf1f1 Fam Zheng
            }
1456 cdeaf1f1 Fam Zheng
        } else {
1457 cdeaf1f1 Fam Zheng
            ret = vmdk_write_extent(extent,
1458 cdeaf1f1 Fam Zheng
                            cluster_offset, index_in_cluster * 512,
1459 cdeaf1f1 Fam Zheng
                            buf, n, sector_num);
1460 cdeaf1f1 Fam Zheng
            if (ret) {
1461 cdeaf1f1 Fam Zheng
                return ret;
1462 cdeaf1f1 Fam Zheng
            }
1463 cdeaf1f1 Fam Zheng
            if (m_data.valid) {
1464 cdeaf1f1 Fam Zheng
                /* update L2 tables */
1465 cdeaf1f1 Fam Zheng
                if (vmdk_L2update(extent, &m_data) != VMDK_OK) {
1466 cdeaf1f1 Fam Zheng
                    return -EIO;
1467 cdeaf1f1 Fam Zheng
                }
1468 b3976d3c Fam Zheng
            }
1469 630530a6 ths
        }
1470 ff1afc72 bellard
        nb_sectors -= n;
1471 ff1afc72 bellard
        sector_num += n;
1472 ff1afc72 bellard
        buf += n * 512;
1473 5f4da8c0 ths
1474 ae261c86 Fam Zheng
        /* update CID on the first write every time the virtual disk is
1475 ae261c86 Fam Zheng
         * opened */
1476 69b4d86d Fam Zheng
        if (!s->cid_updated) {
1477 99f1835d Kevin Wolf
            ret = vmdk_write_cid(bs, time(NULL));
1478 99f1835d Kevin Wolf
            if (ret < 0) {
1479 99f1835d Kevin Wolf
                return ret;
1480 99f1835d Kevin Wolf
            }
1481 69b4d86d Fam Zheng
            s->cid_updated = true;
1482 5f4da8c0 ths
        }
1483 ff1afc72 bellard
    }
1484 ff1afc72 bellard
    return 0;
1485 ea2384d3 bellard
}
1486 ea2384d3 bellard
1487 e183ef75 Paolo Bonzini
static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
1488 e183ef75 Paolo Bonzini
                                      const uint8_t *buf, int nb_sectors)
1489 e183ef75 Paolo Bonzini
{
1490 e183ef75 Paolo Bonzini
    int ret;
1491 e183ef75 Paolo Bonzini
    BDRVVmdkState *s = bs->opaque;
1492 e183ef75 Paolo Bonzini
    qemu_co_mutex_lock(&s->lock);
1493 cdeaf1f1 Fam Zheng
    ret = vmdk_write(bs, sector_num, buf, nb_sectors, false, false);
1494 cdeaf1f1 Fam Zheng
    qemu_co_mutex_unlock(&s->lock);
1495 cdeaf1f1 Fam Zheng
    return ret;
1496 cdeaf1f1 Fam Zheng
}
1497 cdeaf1f1 Fam Zheng
1498 cdeaf1f1 Fam Zheng
static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
1499 cdeaf1f1 Fam Zheng
                                             int64_t sector_num,
1500 aa7bfbff Peter Lieven
                                             int nb_sectors,
1501 aa7bfbff Peter Lieven
                                             BdrvRequestFlags flags)
1502 cdeaf1f1 Fam Zheng
{
1503 cdeaf1f1 Fam Zheng
    int ret;
1504 cdeaf1f1 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
1505 cdeaf1f1 Fam Zheng
    qemu_co_mutex_lock(&s->lock);
1506 8e507243 Fam Zheng
    /* write zeroes could fail if sectors not aligned to cluster, test it with
1507 8e507243 Fam Zheng
     * dry_run == true before really updating image */
1508 cdeaf1f1 Fam Zheng
    ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true);
1509 cdeaf1f1 Fam Zheng
    if (!ret) {
1510 cdeaf1f1 Fam Zheng
        ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false);
1511 cdeaf1f1 Fam Zheng
    }
1512 e183ef75 Paolo Bonzini
    qemu_co_mutex_unlock(&s->lock);
1513 e183ef75 Paolo Bonzini
    return ret;
1514 e183ef75 Paolo Bonzini
}
1515 e183ef75 Paolo Bonzini
1516 6c031aac Fam Zheng
static int vmdk_create_extent(const char *filename, int64_t filesize,
1517 917703c1 Fam Zheng
                              bool flat, bool compress, bool zeroed_grain,
1518 917703c1 Fam Zheng
                              Error **errp)
1519 8979b227 bellard
{
1520 f66fd6c3 Fam Zheng
    int ret, i;
1521 917703c1 Fam Zheng
    BlockDriverState *bs = NULL;
1522 8979b227 bellard
    VMDK4Header header;
1523 917703c1 Fam Zheng
    Error *local_err;
1524 917703c1 Fam Zheng
    uint32_t tmp, magic, grains, gd_sectors, gt_size, gt_count;
1525 917703c1 Fam Zheng
    uint32_t *gd_buf = NULL;
1526 917703c1 Fam Zheng
    int gd_buf_size;
1527 0e7e1989 Kevin Wolf
1528 917703c1 Fam Zheng
    ret = bdrv_create_file(filename, NULL, &local_err);
1529 917703c1 Fam Zheng
    if (ret < 0) {
1530 917703c1 Fam Zheng
        error_propagate(errp, local_err);
1531 917703c1 Fam Zheng
        goto exit;
1532 0e7e1989 Kevin Wolf
    }
1533 917703c1 Fam Zheng
1534 2e40134b Max Reitz
    assert(bs == NULL);
1535 2e40134b Max Reitz
    ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
1536 2e40134b Max Reitz
                    NULL, &local_err);
1537 917703c1 Fam Zheng
    if (ret < 0) {
1538 917703c1 Fam Zheng
        error_propagate(errp, local_err);
1539 917703c1 Fam Zheng
        goto exit;
1540 917703c1 Fam Zheng
    }
1541 917703c1 Fam Zheng
1542 f66fd6c3 Fam Zheng
    if (flat) {
1543 917703c1 Fam Zheng
        ret = bdrv_truncate(bs, filesize);
1544 f66fd6c3 Fam Zheng
        if (ret < 0) {
1545 39a611a3 Jeff Cody
            error_setg_errno(errp, -ret, "Could not truncate file");
1546 f66fd6c3 Fam Zheng
        }
1547 f66fd6c3 Fam Zheng
        goto exit;
1548 5f4da8c0 ths
    }
1549 8979b227 bellard
    magic = cpu_to_be32(VMDK4_MAGIC);
1550 8979b227 bellard
    memset(&header, 0, sizeof(header));
1551 69e0b6df Fam Zheng
    header.version = zeroed_grain ? 2 : 1;
1552 95b0aa42 Fam Zheng
    header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
1553 69e0b6df Fam Zheng
                   | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
1554 69e0b6df Fam Zheng
                   | (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);
1555 6c031aac Fam Zheng
    header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
1556 917703c1 Fam Zheng
    header.capacity = filesize / BDRV_SECTOR_SIZE;
1557 16372ff0 Alexander Graf
    header.granularity = 128;
1558 917703c1 Fam Zheng
    header.num_gtes_per_gt = BDRV_SECTOR_SIZE;
1559 8979b227 bellard
1560 917703c1 Fam Zheng
    grains = DIV_ROUND_UP(filesize / BDRV_SECTOR_SIZE, header.granularity);
1561 917703c1 Fam Zheng
    gt_size = DIV_ROUND_UP(header.num_gtes_per_gt * sizeof(uint32_t),
1562 917703c1 Fam Zheng
                           BDRV_SECTOR_SIZE);
1563 917703c1 Fam Zheng
    gt_count = DIV_ROUND_UP(grains, header.num_gtes_per_gt);
1564 917703c1 Fam Zheng
    gd_sectors = DIV_ROUND_UP(gt_count * sizeof(uint32_t), BDRV_SECTOR_SIZE);
1565 8979b227 bellard
1566 8979b227 bellard
    header.desc_offset = 1;
1567 8979b227 bellard
    header.desc_size = 20;
1568 8979b227 bellard
    header.rgd_offset = header.desc_offset + header.desc_size;
1569 917703c1 Fam Zheng
    header.gd_offset = header.rgd_offset + gd_sectors + (gt_size * gt_count);
1570 8979b227 bellard
    header.grain_offset =
1571 917703c1 Fam Zheng
        ROUND_UP(header.gd_offset + gd_sectors + (gt_size * gt_count),
1572 917703c1 Fam Zheng
                 header.granularity);
1573 16372ff0 Alexander Graf
    /* swap endianness for all header fields */
1574 16372ff0 Alexander Graf
    header.version = cpu_to_le32(header.version);
1575 16372ff0 Alexander Graf
    header.flags = cpu_to_le32(header.flags);
1576 16372ff0 Alexander Graf
    header.capacity = cpu_to_le64(header.capacity);
1577 16372ff0 Alexander Graf
    header.granularity = cpu_to_le64(header.granularity);
1578 ca8804ce Fam Zheng
    header.num_gtes_per_gt = cpu_to_le32(header.num_gtes_per_gt);
1579 8979b227 bellard
    header.desc_offset = cpu_to_le64(header.desc_offset);
1580 8979b227 bellard
    header.desc_size = cpu_to_le64(header.desc_size);
1581 8979b227 bellard
    header.rgd_offset = cpu_to_le64(header.rgd_offset);
1582 8979b227 bellard
    header.gd_offset = cpu_to_le64(header.gd_offset);
1583 8979b227 bellard
    header.grain_offset = cpu_to_le64(header.grain_offset);
1584 6c031aac Fam Zheng
    header.compressAlgorithm = cpu_to_le16(header.compressAlgorithm);
1585 8979b227 bellard
1586 8979b227 bellard
    header.check_bytes[0] = 0xa;
1587 8979b227 bellard
    header.check_bytes[1] = 0x20;
1588 8979b227 bellard
    header.check_bytes[2] = 0xd;
1589 8979b227 bellard
    header.check_bytes[3] = 0xa;
1590 3b46e624 ths
1591 3b46e624 ths
    /* write all the data */
1592 917703c1 Fam Zheng
    ret = bdrv_pwrite(bs, 0, &magic, sizeof(magic));
1593 917703c1 Fam Zheng
    if (ret < 0) {
1594 917703c1 Fam Zheng
        error_set(errp, QERR_IO_ERROR);
1595 1640366c Kirill A. Shutemov
        goto exit;
1596 1640366c Kirill A. Shutemov
    }
1597 917703c1 Fam Zheng
    ret = bdrv_pwrite(bs, sizeof(magic), &header, sizeof(header));
1598 917703c1 Fam Zheng
    if (ret < 0) {
1599 917703c1 Fam Zheng
        error_set(errp, QERR_IO_ERROR);
1600 1640366c Kirill A. Shutemov
        goto exit;
1601 1640366c Kirill A. Shutemov
    }
1602 8979b227 bellard
1603 917703c1 Fam Zheng
    ret = bdrv_truncate(bs, le64_to_cpu(header.grain_offset) << 9);
1604 1640366c Kirill A. Shutemov
    if (ret < 0) {
1605 39a611a3 Jeff Cody
        error_setg_errno(errp, -ret, "Could not truncate file");
1606 1640366c Kirill A. Shutemov
        goto exit;
1607 1640366c Kirill A. Shutemov
    }
1608 8979b227 bellard
1609 8979b227 bellard
    /* write grain directory */
1610 917703c1 Fam Zheng
    gd_buf_size = gd_sectors * BDRV_SECTOR_SIZE;
1611 917703c1 Fam Zheng
    gd_buf = g_malloc0(gd_buf_size);
1612 917703c1 Fam Zheng
    for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_sectors;
1613 1640366c Kirill A. Shutemov
         i < gt_count; i++, tmp += gt_size) {
1614 917703c1 Fam Zheng
        gd_buf[i] = cpu_to_le32(tmp);
1615 917703c1 Fam Zheng
    }
1616 917703c1 Fam Zheng
    ret = bdrv_pwrite(bs, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE,
1617 917703c1 Fam Zheng
                      gd_buf, gd_buf_size);
1618 917703c1 Fam Zheng
    if (ret < 0) {
1619 917703c1 Fam Zheng
        error_set(errp, QERR_IO_ERROR);
1620 917703c1 Fam Zheng
        goto exit;
1621 1640366c Kirill A. Shutemov
    }
1622 3b46e624 ths
1623 8979b227 bellard
    /* write backup grain directory */
1624 917703c1 Fam Zheng
    for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_sectors;
1625 1640366c Kirill A. Shutemov
         i < gt_count; i++, tmp += gt_size) {
1626 917703c1 Fam Zheng
        gd_buf[i] = cpu_to_le32(tmp);
1627 917703c1 Fam Zheng
    }
1628 917703c1 Fam Zheng
    ret = bdrv_pwrite(bs, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE,
1629 917703c1 Fam Zheng
                      gd_buf, gd_buf_size);
1630 917703c1 Fam Zheng
    if (ret < 0) {
1631 917703c1 Fam Zheng
        error_set(errp, QERR_IO_ERROR);
1632 917703c1 Fam Zheng
        goto exit;
1633 1640366c Kirill A. Shutemov
    }
1634 8979b227 bellard
1635 f66fd6c3 Fam Zheng
    ret = 0;
1636 917703c1 Fam Zheng
exit:
1637 917703c1 Fam Zheng
    if (bs) {
1638 917703c1 Fam Zheng
        bdrv_unref(bs);
1639 917703c1 Fam Zheng
    }
1640 917703c1 Fam Zheng
    g_free(gd_buf);
1641 f66fd6c3 Fam Zheng
    return ret;
1642 f66fd6c3 Fam Zheng
}
1643 f66fd6c3 Fam Zheng
1644 f66fd6c3 Fam Zheng
static int filename_decompose(const char *filename, char *path, char *prefix,
1645 4823970b Fam Zheng
                              char *postfix, size_t buf_len, Error **errp)
1646 f66fd6c3 Fam Zheng
{
1647 f66fd6c3 Fam Zheng
    const char *p, *q;
1648 f66fd6c3 Fam Zheng
1649 f66fd6c3 Fam Zheng
    if (filename == NULL || !strlen(filename)) {
1650 4823970b Fam Zheng
        error_setg(errp, "No filename provided");
1651 65f74725 Fam Zheng
        return VMDK_ERROR;
1652 f66fd6c3 Fam Zheng
    }
1653 f66fd6c3 Fam Zheng
    p = strrchr(filename, '/');
1654 f66fd6c3 Fam Zheng
    if (p == NULL) {
1655 f66fd6c3 Fam Zheng
        p = strrchr(filename, '\\');
1656 f66fd6c3 Fam Zheng
    }
1657 f66fd6c3 Fam Zheng
    if (p == NULL) {
1658 f66fd6c3 Fam Zheng
        p = strrchr(filename, ':');
1659 f66fd6c3 Fam Zheng
    }
1660 f66fd6c3 Fam Zheng
    if (p != NULL) {
1661 f66fd6c3 Fam Zheng
        p++;
1662 f66fd6c3 Fam Zheng
        if (p - filename >= buf_len) {
1663 65f74725 Fam Zheng
            return VMDK_ERROR;
1664 f66fd6c3 Fam Zheng
        }
1665 f66fd6c3 Fam Zheng
        pstrcpy(path, p - filename + 1, filename);
1666 f66fd6c3 Fam Zheng
    } else {
1667 f66fd6c3 Fam Zheng
        p = filename;
1668 f66fd6c3 Fam Zheng
        path[0] = '\0';
1669 f66fd6c3 Fam Zheng
    }
1670 f66fd6c3 Fam Zheng
    q = strrchr(p, '.');
1671 f66fd6c3 Fam Zheng
    if (q == NULL) {
1672 f66fd6c3 Fam Zheng
        pstrcpy(prefix, buf_len, p);
1673 f66fd6c3 Fam Zheng
        postfix[0] = '\0';
1674 f66fd6c3 Fam Zheng
    } else {
1675 f66fd6c3 Fam Zheng
        if (q - p >= buf_len) {
1676 65f74725 Fam Zheng
            return VMDK_ERROR;
1677 f66fd6c3 Fam Zheng
        }
1678 f66fd6c3 Fam Zheng
        pstrcpy(prefix, q - p + 1, p);
1679 f66fd6c3 Fam Zheng
        pstrcpy(postfix, buf_len, q);
1680 f66fd6c3 Fam Zheng
    }
1681 65f74725 Fam Zheng
    return VMDK_OK;
1682 f66fd6c3 Fam Zheng
}
1683 f66fd6c3 Fam Zheng
1684 d5124c00 Max Reitz
static int vmdk_create(const char *filename, QEMUOptionParameter *options,
1685 d5124c00 Max Reitz
                       Error **errp)
1686 f66fd6c3 Fam Zheng
{
1687 917703c1 Fam Zheng
    int idx = 0;
1688 917703c1 Fam Zheng
    BlockDriverState *new_bs = NULL;
1689 917703c1 Fam Zheng
    Error *local_err;
1690 af057fe7 Fam Zheng
    char *desc = NULL;
1691 f66fd6c3 Fam Zheng
    int64_t total_size = 0, filesize;
1692 7f2039f6 Othmar Pasteka
    const char *adapter_type = NULL;
1693 f66fd6c3 Fam Zheng
    const char *backing_file = NULL;
1694 f66fd6c3 Fam Zheng
    const char *fmt = NULL;
1695 f66fd6c3 Fam Zheng
    int flags = 0;
1696 f66fd6c3 Fam Zheng
    int ret = 0;
1697 6c031aac Fam Zheng
    bool flat, split, compress;
1698 af057fe7 Fam Zheng
    GString *ext_desc_lines;
1699 f66fd6c3 Fam Zheng
    char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
1700 f66fd6c3 Fam Zheng
    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
1701 f66fd6c3 Fam Zheng
    const char *desc_extent_line;
1702 f66fd6c3 Fam Zheng
    char parent_desc_line[BUF_SIZE] = "";
1703 f66fd6c3 Fam Zheng
    uint32_t parent_cid = 0xffffffff;
1704 7f2039f6 Othmar Pasteka
    uint32_t number_heads = 16;
1705 69e0b6df Fam Zheng
    bool zeroed_grain = false;
1706 917703c1 Fam Zheng
    uint32_t desc_offset = 0, desc_len;
1707 f66fd6c3 Fam Zheng
    const char desc_template[] =
1708 f66fd6c3 Fam Zheng
        "# Disk DescriptorFile\n"
1709 f66fd6c3 Fam Zheng
        "version=1\n"
1710 f66fd6c3 Fam Zheng
        "CID=%x\n"
1711 f66fd6c3 Fam Zheng
        "parentCID=%x\n"
1712 f66fd6c3 Fam Zheng
        "createType=\"%s\"\n"
1713 f66fd6c3 Fam Zheng
        "%s"
1714 f66fd6c3 Fam Zheng
        "\n"
1715 f66fd6c3 Fam Zheng
        "# Extent description\n"
1716 f66fd6c3 Fam Zheng
        "%s"
1717 f66fd6c3 Fam Zheng
        "\n"
1718 f66fd6c3 Fam Zheng
        "# The Disk Data Base\n"
1719 f66fd6c3 Fam Zheng
        "#DDB\n"
1720 f66fd6c3 Fam Zheng
        "\n"
1721 f66fd6c3 Fam Zheng
        "ddb.virtualHWVersion = \"%d\"\n"
1722 f66fd6c3 Fam Zheng
        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
1723 7f2039f6 Othmar Pasteka
        "ddb.geometry.heads = \"%d\"\n"
1724 f66fd6c3 Fam Zheng
        "ddb.geometry.sectors = \"63\"\n"
1725 7f2039f6 Othmar Pasteka
        "ddb.adapterType = \"%s\"\n";
1726 f66fd6c3 Fam Zheng
1727 af057fe7 Fam Zheng
    ext_desc_lines = g_string_new(NULL);
1728 af057fe7 Fam Zheng
1729 4823970b Fam Zheng
    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
1730 af057fe7 Fam Zheng
        ret = -EINVAL;
1731 af057fe7 Fam Zheng
        goto exit;
1732 f66fd6c3 Fam Zheng
    }
1733 f66fd6c3 Fam Zheng
    /* Read out options */
1734 f66fd6c3 Fam Zheng
    while (options && options->name) {
1735 f66fd6c3 Fam Zheng
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
1736 f66fd6c3 Fam Zheng
            total_size = options->value.n;
1737 7f2039f6 Othmar Pasteka
        } else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
1738 7f2039f6 Othmar Pasteka
            adapter_type = options->value.s;
1739 f66fd6c3 Fam Zheng
        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
1740 f66fd6c3 Fam Zheng
            backing_file = options->value.s;
1741 f66fd6c3 Fam Zheng
        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
1742 f66fd6c3 Fam Zheng
            flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
1743 f66fd6c3 Fam Zheng
        } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
1744 f66fd6c3 Fam Zheng
            fmt = options->value.s;
1745 69e0b6df Fam Zheng
        } else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) {
1746 69e0b6df Fam Zheng
            zeroed_grain |= options->value.n;
1747 f66fd6c3 Fam Zheng
        }
1748 f66fd6c3 Fam Zheng
        options++;
1749 f66fd6c3 Fam Zheng
    }
1750 7f2039f6 Othmar Pasteka
    if (!adapter_type) {
1751 7f2039f6 Othmar Pasteka
        adapter_type = "ide";
1752 7f2039f6 Othmar Pasteka
    } else if (strcmp(adapter_type, "ide") &&
1753 7f2039f6 Othmar Pasteka
               strcmp(adapter_type, "buslogic") &&
1754 7f2039f6 Othmar Pasteka
               strcmp(adapter_type, "lsilogic") &&
1755 7f2039f6 Othmar Pasteka
               strcmp(adapter_type, "legacyESX")) {
1756 4823970b Fam Zheng
        error_setg(errp, "Unknown adapter type: '%s'", adapter_type);
1757 af057fe7 Fam Zheng
        ret = -EINVAL;
1758 af057fe7 Fam Zheng
        goto exit;
1759 7f2039f6 Othmar Pasteka
    }
1760 7f2039f6 Othmar Pasteka
    if (strcmp(adapter_type, "ide") != 0) {
1761 7f2039f6 Othmar Pasteka
        /* that's the number of heads with which vmware operates when
1762 7f2039f6 Othmar Pasteka
           creating, exporting, etc. vmdk files with a non-ide adapter type */
1763 7f2039f6 Othmar Pasteka
        number_heads = 255;
1764 7f2039f6 Othmar Pasteka
    }
1765 f66fd6c3 Fam Zheng
    if (!fmt) {
1766 f66fd6c3 Fam Zheng
        /* Default format to monolithicSparse */
1767 f66fd6c3 Fam Zheng
        fmt = "monolithicSparse";
1768 f66fd6c3 Fam Zheng
    } else if (strcmp(fmt, "monolithicFlat") &&
1769 f66fd6c3 Fam Zheng
               strcmp(fmt, "monolithicSparse") &&
1770 f66fd6c3 Fam Zheng
               strcmp(fmt, "twoGbMaxExtentSparse") &&
1771 6c031aac Fam Zheng
               strcmp(fmt, "twoGbMaxExtentFlat") &&
1772 6c031aac Fam Zheng
               strcmp(fmt, "streamOptimized")) {
1773 4823970b Fam Zheng
        error_setg(errp, "Unknown subformat: '%s'", fmt);
1774 af057fe7 Fam Zheng
        ret = -EINVAL;
1775 af057fe7 Fam Zheng
        goto exit;
1776 f66fd6c3 Fam Zheng
    }
1777 f66fd6c3 Fam Zheng
    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
1778 f66fd6c3 Fam Zheng
              strcmp(fmt, "twoGbMaxExtentSparse"));
1779 f66fd6c3 Fam Zheng
    flat = !(strcmp(fmt, "monolithicFlat") &&
1780 f66fd6c3 Fam Zheng
             strcmp(fmt, "twoGbMaxExtentFlat"));
1781 6c031aac Fam Zheng
    compress = !strcmp(fmt, "streamOptimized");
1782 f66fd6c3 Fam Zheng
    if (flat) {
1783 f66fd6c3 Fam Zheng
        desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
1784 f66fd6c3 Fam Zheng
    } else {
1785 f66fd6c3 Fam Zheng
        desc_extent_line = "RW %lld SPARSE \"%s\"\n";
1786 f66fd6c3 Fam Zheng
    }
1787 f66fd6c3 Fam Zheng
    if (flat && backing_file) {
1788 4823970b Fam Zheng
        error_setg(errp, "Flat image can't have backing file");
1789 af057fe7 Fam Zheng
        ret = -ENOTSUP;
1790 af057fe7 Fam Zheng
        goto exit;
1791 f66fd6c3 Fam Zheng
    }
1792 52c8d629 Fam Zheng
    if (flat && zeroed_grain) {
1793 52c8d629 Fam Zheng
        error_setg(errp, "Flat image can't enable zeroed grain");
1794 af057fe7 Fam Zheng
        ret = -ENOTSUP;
1795 af057fe7 Fam Zheng
        goto exit;
1796 52c8d629 Fam Zheng
    }
1797 f66fd6c3 Fam Zheng
    if (backing_file) {
1798 f67503e5 Max Reitz
        BlockDriverState *bs = NULL;
1799 ddf5636d Max Reitz
        ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_NO_BACKING, NULL,
1800 ddf5636d Max Reitz
                        errp);
1801 f66fd6c3 Fam Zheng
        if (ret != 0) {
1802 af057fe7 Fam Zheng
            goto exit;
1803 f66fd6c3 Fam Zheng
        }
1804 f66fd6c3 Fam Zheng
        if (strcmp(bs->drv->format_name, "vmdk")) {
1805 4f6fd349 Fam Zheng
            bdrv_unref(bs);
1806 af057fe7 Fam Zheng
            ret = -EINVAL;
1807 af057fe7 Fam Zheng
            goto exit;
1808 f66fd6c3 Fam Zheng
        }
1809 f66fd6c3 Fam Zheng
        parent_cid = vmdk_read_cid(bs, 0);
1810 4f6fd349 Fam Zheng
        bdrv_unref(bs);
1811 f66fd6c3 Fam Zheng
        snprintf(parent_desc_line, sizeof(parent_desc_line),
1812 8ed610a1 Fam Zheng
                "parentFileNameHint=\"%s\"", backing_file);
1813 f66fd6c3 Fam Zheng
    }
1814 f66fd6c3 Fam Zheng
1815 f66fd6c3 Fam Zheng
    /* Create extents */
1816 f66fd6c3 Fam Zheng
    filesize = total_size;
1817 f66fd6c3 Fam Zheng
    while (filesize > 0) {
1818 f66fd6c3 Fam Zheng
        char desc_line[BUF_SIZE];
1819 f66fd6c3 Fam Zheng
        char ext_filename[PATH_MAX];
1820 f66fd6c3 Fam Zheng
        char desc_filename[PATH_MAX];
1821 f66fd6c3 Fam Zheng
        int64_t size = filesize;
1822 f66fd6c3 Fam Zheng
1823 f66fd6c3 Fam Zheng
        if (split && size > split_size) {
1824 f66fd6c3 Fam Zheng
            size = split_size;
1825 f66fd6c3 Fam Zheng
        }
1826 f66fd6c3 Fam Zheng
        if (split) {
1827 f66fd6c3 Fam Zheng
            snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
1828 f66fd6c3 Fam Zheng
                    prefix, flat ? 'f' : 's', ++idx, postfix);
1829 f66fd6c3 Fam Zheng
        } else if (flat) {
1830 f66fd6c3 Fam Zheng
            snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
1831 f66fd6c3 Fam Zheng
                    prefix, postfix);
1832 f66fd6c3 Fam Zheng
        } else {
1833 f66fd6c3 Fam Zheng
            snprintf(desc_filename, sizeof(desc_filename), "%s%s",
1834 f66fd6c3 Fam Zheng
                    prefix, postfix);
1835 f66fd6c3 Fam Zheng
        }
1836 f66fd6c3 Fam Zheng
        snprintf(ext_filename, sizeof(ext_filename), "%s%s",
1837 f66fd6c3 Fam Zheng
                path, desc_filename);
1838 f66fd6c3 Fam Zheng
1839 69e0b6df Fam Zheng
        if (vmdk_create_extent(ext_filename, size,
1840 917703c1 Fam Zheng
                               flat, compress, zeroed_grain, errp)) {
1841 af057fe7 Fam Zheng
            ret = -EINVAL;
1842 af057fe7 Fam Zheng
            goto exit;
1843 f66fd6c3 Fam Zheng
        }
1844 f66fd6c3 Fam Zheng
        filesize -= size;
1845 f66fd6c3 Fam Zheng
1846 f66fd6c3 Fam Zheng
        /* Format description line */
1847 f66fd6c3 Fam Zheng
        snprintf(desc_line, sizeof(desc_line),
1848 917703c1 Fam Zheng
                    desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);
1849 af057fe7 Fam Zheng
        g_string_append(ext_desc_lines, desc_line);
1850 f66fd6c3 Fam Zheng
    }
1851 f66fd6c3 Fam Zheng
    /* generate descriptor file */
1852 af057fe7 Fam Zheng
    desc = g_strdup_printf(desc_template,
1853 af057fe7 Fam Zheng
                           (unsigned int)time(NULL),
1854 af057fe7 Fam Zheng
                           parent_cid,
1855 af057fe7 Fam Zheng
                           fmt,
1856 af057fe7 Fam Zheng
                           parent_desc_line,
1857 af057fe7 Fam Zheng
                           ext_desc_lines->str,
1858 af057fe7 Fam Zheng
                           (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
1859 917703c1 Fam Zheng
                           total_size /
1860 917703c1 Fam Zheng
                               (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),
1861 af057fe7 Fam Zheng
                           number_heads,
1862 af057fe7 Fam Zheng
                           adapter_type);
1863 917703c1 Fam Zheng
    desc_len = strlen(desc);
1864 917703c1 Fam Zheng
    /* the descriptor offset = 0x200 */
1865 917703c1 Fam Zheng
    if (!split && !flat) {
1866 917703c1 Fam Zheng
        desc_offset = 0x200;
1867 f66fd6c3 Fam Zheng
    } else {
1868 917703c1 Fam Zheng
        ret = bdrv_create_file(filename, options, &local_err);
1869 917703c1 Fam Zheng
        if (ret < 0) {
1870 917703c1 Fam Zheng
            error_setg_errno(errp, -ret, "Could not create image file");
1871 917703c1 Fam Zheng
            goto exit;
1872 917703c1 Fam Zheng
        }
1873 f66fd6c3 Fam Zheng
    }
1874 2e40134b Max Reitz
    assert(new_bs == NULL);
1875 2e40134b Max Reitz
    ret = bdrv_open(&new_bs, filename, NULL, NULL,
1876 2e40134b Max Reitz
                    BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
1877 917703c1 Fam Zheng
    if (ret < 0) {
1878 917703c1 Fam Zheng
        error_setg_errno(errp, -ret, "Could not write description");
1879 af057fe7 Fam Zheng
        goto exit;
1880 f66fd6c3 Fam Zheng
    }
1881 917703c1 Fam Zheng
    ret = bdrv_pwrite(new_bs, desc_offset, desc, desc_len);
1882 917703c1 Fam Zheng
    if (ret < 0) {
1883 917703c1 Fam Zheng
        error_setg_errno(errp, -ret, "Could not write description");
1884 917703c1 Fam Zheng
        goto exit;
1885 f66fd6c3 Fam Zheng
    }
1886 917703c1 Fam Zheng
    /* bdrv_pwrite write padding zeros to align to sector, we don't need that
1887 917703c1 Fam Zheng
     * for description file */
1888 917703c1 Fam Zheng
    if (desc_offset == 0) {
1889 917703c1 Fam Zheng
        ret = bdrv_truncate(new_bs, desc_len);
1890 917703c1 Fam Zheng
        if (ret < 0) {
1891 39a611a3 Jeff Cody
            error_setg_errno(errp, -ret, "Could not truncate file");
1892 917703c1 Fam Zheng
        }
1893 1640366c Kirill A. Shutemov
    }
1894 af057fe7 Fam Zheng
exit:
1895 917703c1 Fam Zheng
    if (new_bs) {
1896 917703c1 Fam Zheng
        bdrv_unref(new_bs);
1897 917703c1 Fam Zheng
    }
1898 af057fe7 Fam Zheng
    g_free(desc);
1899 af057fe7 Fam Zheng
    g_string_free(ext_desc_lines, true);
1900 1640366c Kirill A. Shutemov
    return ret;
1901 8979b227 bellard
}
1902 8979b227 bellard
1903 e2731add bellard
static void vmdk_close(BlockDriverState *bs)
1904 ea2384d3 bellard
{
1905 2bc3166c Kevin Wolf
    BDRVVmdkState *s = bs->opaque;
1906 2bc3166c Kevin Wolf
1907 b3976d3c Fam Zheng
    vmdk_free_extents(bs);
1908 f4c129a3 Fam Zheng
    g_free(s->create_type);
1909 2bc3166c Kevin Wolf
1910 2bc3166c Kevin Wolf
    migrate_del_blocker(s->migration_blocker);
1911 2bc3166c Kevin Wolf
    error_free(s->migration_blocker);
1912 ea2384d3 bellard
}
1913 ea2384d3 bellard
1914 8b94ff85 Paolo Bonzini
static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
1915 7a6cba61 pbrook
{
1916 333c574d Fam Zheng
    BDRVVmdkState *s = bs->opaque;
1917 29cdb251 Paolo Bonzini
    int i, err;
1918 29cdb251 Paolo Bonzini
    int ret = 0;
1919 333c574d Fam Zheng
1920 333c574d Fam Zheng
    for (i = 0; i < s->num_extents; i++) {
1921 8b94ff85 Paolo Bonzini
        err = bdrv_co_flush(s->extents[i].file);
1922 333c574d Fam Zheng
        if (err < 0) {
1923 333c574d Fam Zheng
            ret = err;
1924 333c574d Fam Zheng
        }
1925 333c574d Fam Zheng
    }
1926 333c574d Fam Zheng
    return ret;
1927 7a6cba61 pbrook
}
1928 7a6cba61 pbrook
1929 4a1d5e1f Fam Zheng
static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
1930 4a1d5e1f Fam Zheng
{
1931 4a1d5e1f Fam Zheng
    int i;
1932 4a1d5e1f Fam Zheng
    int64_t ret = 0;
1933 4a1d5e1f Fam Zheng
    int64_t r;
1934 4a1d5e1f Fam Zheng
    BDRVVmdkState *s = bs->opaque;
1935 4a1d5e1f Fam Zheng
1936 4a1d5e1f Fam Zheng
    ret = bdrv_get_allocated_file_size(bs->file);
1937 4a1d5e1f Fam Zheng
    if (ret < 0) {
1938 4a1d5e1f Fam Zheng
        return ret;
1939 4a1d5e1f Fam Zheng
    }
1940 4a1d5e1f Fam Zheng
    for (i = 0; i < s->num_extents; i++) {
1941 4a1d5e1f Fam Zheng
        if (s->extents[i].file == bs->file) {
1942 4a1d5e1f Fam Zheng
            continue;
1943 4a1d5e1f Fam Zheng
        }
1944 4a1d5e1f Fam Zheng
        r = bdrv_get_allocated_file_size(s->extents[i].file);
1945 4a1d5e1f Fam Zheng
        if (r < 0) {
1946 4a1d5e1f Fam Zheng
            return r;
1947 4a1d5e1f Fam Zheng
        }
1948 4a1d5e1f Fam Zheng
        ret += r;
1949 4a1d5e1f Fam Zheng
    }
1950 4a1d5e1f Fam Zheng
    return ret;
1951 4a1d5e1f Fam Zheng
}
1952 0e7e1989 Kevin Wolf
1953 da7a50f9 Fam Zheng
static int vmdk_has_zero_init(BlockDriverState *bs)
1954 da7a50f9 Fam Zheng
{
1955 da7a50f9 Fam Zheng
    int i;
1956 da7a50f9 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
1957 da7a50f9 Fam Zheng
1958 da7a50f9 Fam Zheng
    /* If has a flat extent and its underlying storage doesn't have zero init,
1959 da7a50f9 Fam Zheng
     * return 0. */
1960 da7a50f9 Fam Zheng
    for (i = 0; i < s->num_extents; i++) {
1961 da7a50f9 Fam Zheng
        if (s->extents[i].flat) {
1962 da7a50f9 Fam Zheng
            if (!bdrv_has_zero_init(s->extents[i].file)) {
1963 da7a50f9 Fam Zheng
                return 0;
1964 da7a50f9 Fam Zheng
            }
1965 da7a50f9 Fam Zheng
        }
1966 da7a50f9 Fam Zheng
    }
1967 da7a50f9 Fam Zheng
    return 1;
1968 da7a50f9 Fam Zheng
}
1969 da7a50f9 Fam Zheng
1970 f4c129a3 Fam Zheng
static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent)
1971 f4c129a3 Fam Zheng
{
1972 f4c129a3 Fam Zheng
    ImageInfo *info = g_new0(ImageInfo, 1);
1973 f4c129a3 Fam Zheng
1974 f4c129a3 Fam Zheng
    *info = (ImageInfo){
1975 f4c129a3 Fam Zheng
        .filename         = g_strdup(extent->file->filename),
1976 f4c129a3 Fam Zheng
        .format           = g_strdup(extent->type),
1977 f4c129a3 Fam Zheng
        .virtual_size     = extent->sectors * BDRV_SECTOR_SIZE,
1978 f4c129a3 Fam Zheng
        .compressed       = extent->compressed,
1979 f4c129a3 Fam Zheng
        .has_compressed   = extent->compressed,
1980 f4c129a3 Fam Zheng
        .cluster_size     = extent->cluster_sectors * BDRV_SECTOR_SIZE,
1981 f4c129a3 Fam Zheng
        .has_cluster_size = !extent->flat,
1982 f4c129a3 Fam Zheng
    };
1983 f4c129a3 Fam Zheng
1984 f4c129a3 Fam Zheng
    return info;
1985 f4c129a3 Fam Zheng
}
1986 f4c129a3 Fam Zheng
1987 f43aa8e1 Peter Lieven
static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
1988 f43aa8e1 Peter Lieven
                      BdrvCheckMode fix)
1989 f43aa8e1 Peter Lieven
{
1990 f43aa8e1 Peter Lieven
    BDRVVmdkState *s = bs->opaque;
1991 f43aa8e1 Peter Lieven
    VmdkExtent *extent = NULL;
1992 f43aa8e1 Peter Lieven
    int64_t sector_num = 0;
1993 f43aa8e1 Peter Lieven
    int64_t total_sectors = bdrv_getlength(bs) / BDRV_SECTOR_SIZE;
1994 f43aa8e1 Peter Lieven
    int ret;
1995 f43aa8e1 Peter Lieven
    uint64_t cluster_offset;
1996 f43aa8e1 Peter Lieven
1997 f43aa8e1 Peter Lieven
    if (fix) {
1998 f43aa8e1 Peter Lieven
        return -ENOTSUP;
1999 f43aa8e1 Peter Lieven
    }
2000 f43aa8e1 Peter Lieven
2001 f43aa8e1 Peter Lieven
    for (;;) {
2002 f43aa8e1 Peter Lieven
        if (sector_num >= total_sectors) {
2003 f43aa8e1 Peter Lieven
            return 0;
2004 f43aa8e1 Peter Lieven
        }
2005 f43aa8e1 Peter Lieven
        extent = find_extent(s, sector_num, extent);
2006 f43aa8e1 Peter Lieven
        if (!extent) {
2007 f43aa8e1 Peter Lieven
            fprintf(stderr,
2008 f43aa8e1 Peter Lieven
                    "ERROR: could not find extent for sector %" PRId64 "\n",
2009 f43aa8e1 Peter Lieven
                    sector_num);
2010 f43aa8e1 Peter Lieven
            break;
2011 f43aa8e1 Peter Lieven
        }
2012 f43aa8e1 Peter Lieven
        ret = get_cluster_offset(bs, extent, NULL,
2013 f43aa8e1 Peter Lieven
                                 sector_num << BDRV_SECTOR_BITS,
2014 f43aa8e1 Peter Lieven
                                 0, &cluster_offset);
2015 f43aa8e1 Peter Lieven
        if (ret == VMDK_ERROR) {
2016 f43aa8e1 Peter Lieven
            fprintf(stderr,
2017 f43aa8e1 Peter Lieven
                    "ERROR: could not get cluster_offset for sector %"
2018 f43aa8e1 Peter Lieven
                    PRId64 "\n", sector_num);
2019 f43aa8e1 Peter Lieven
            break;
2020 f43aa8e1 Peter Lieven
        }
2021 f43aa8e1 Peter Lieven
        if (ret == VMDK_OK && cluster_offset >= bdrv_getlength(extent->file)) {
2022 f43aa8e1 Peter Lieven
            fprintf(stderr,
2023 f43aa8e1 Peter Lieven
                    "ERROR: cluster offset for sector %"
2024 f43aa8e1 Peter Lieven
                    PRId64 " points after EOF\n", sector_num);
2025 f43aa8e1 Peter Lieven
            break;
2026 f43aa8e1 Peter Lieven
        }
2027 f43aa8e1 Peter Lieven
        sector_num += extent->cluster_sectors;
2028 f43aa8e1 Peter Lieven
    }
2029 f43aa8e1 Peter Lieven
2030 f43aa8e1 Peter Lieven
    result->corruptions++;
2031 f43aa8e1 Peter Lieven
    return 0;
2032 f43aa8e1 Peter Lieven
}
2033 f43aa8e1 Peter Lieven
2034 f4c129a3 Fam Zheng
static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
2035 f4c129a3 Fam Zheng
{
2036 f4c129a3 Fam Zheng
    int i;
2037 f4c129a3 Fam Zheng
    BDRVVmdkState *s = bs->opaque;
2038 f4c129a3 Fam Zheng
    ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1);
2039 f4c129a3 Fam Zheng
    ImageInfoList **next;
2040 f4c129a3 Fam Zheng
2041 f4c129a3 Fam Zheng
    *spec_info = (ImageInfoSpecific){
2042 f4c129a3 Fam Zheng
        .kind = IMAGE_INFO_SPECIFIC_KIND_VMDK,
2043 f4c129a3 Fam Zheng
        {
2044 f4c129a3 Fam Zheng
            .vmdk = g_new0(ImageInfoSpecificVmdk, 1),
2045 f4c129a3 Fam Zheng
        },
2046 f4c129a3 Fam Zheng
    };
2047 f4c129a3 Fam Zheng
2048 f4c129a3 Fam Zheng
    *spec_info->vmdk = (ImageInfoSpecificVmdk) {
2049 f4c129a3 Fam Zheng
        .create_type = g_strdup(s->create_type),
2050 f4c129a3 Fam Zheng
        .cid = s->cid,
2051 f4c129a3 Fam Zheng
        .parent_cid = s->parent_cid,
2052 f4c129a3 Fam Zheng
    };
2053 f4c129a3 Fam Zheng
2054 f4c129a3 Fam Zheng
    next = &spec_info->vmdk->extents;
2055 f4c129a3 Fam Zheng
    for (i = 0; i < s->num_extents; i++) {
2056 f4c129a3 Fam Zheng
        *next = g_new0(ImageInfoList, 1);
2057 f4c129a3 Fam Zheng
        (*next)->value = vmdk_get_extent_info(&s->extents[i]);
2058 f4c129a3 Fam Zheng
        (*next)->next = NULL;
2059 f4c129a3 Fam Zheng
        next = &(*next)->next;
2060 f4c129a3 Fam Zheng
    }
2061 f4c129a3 Fam Zheng
2062 f4c129a3 Fam Zheng
    return spec_info;
2063 f4c129a3 Fam Zheng
}
2064 f4c129a3 Fam Zheng
2065 0e7e1989 Kevin Wolf
static QEMUOptionParameter vmdk_create_options[] = {
2066 db08adf5 Kevin Wolf
    {
2067 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_SIZE,
2068 db08adf5 Kevin Wolf
        .type = OPT_SIZE,
2069 db08adf5 Kevin Wolf
        .help = "Virtual disk size"
2070 db08adf5 Kevin Wolf
    },
2071 db08adf5 Kevin Wolf
    {
2072 7f2039f6 Othmar Pasteka
        .name = BLOCK_OPT_ADAPTER_TYPE,
2073 7f2039f6 Othmar Pasteka
        .type = OPT_STRING,
2074 7f2039f6 Othmar Pasteka
        .help = "Virtual adapter type, can be one of "
2075 7f2039f6 Othmar Pasteka
                "ide (default), lsilogic, buslogic or legacyESX"
2076 7f2039f6 Othmar Pasteka
    },
2077 7f2039f6 Othmar Pasteka
    {
2078 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_BACKING_FILE,
2079 db08adf5 Kevin Wolf
        .type = OPT_STRING,
2080 db08adf5 Kevin Wolf
        .help = "File name of a base image"
2081 db08adf5 Kevin Wolf
    },
2082 db08adf5 Kevin Wolf
    {
2083 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_COMPAT6,
2084 db08adf5 Kevin Wolf
        .type = OPT_FLAG,
2085 db08adf5 Kevin Wolf
        .help = "VMDK version 6 image"
2086 db08adf5 Kevin Wolf
    },
2087 f66fd6c3 Fam Zheng
    {
2088 f66fd6c3 Fam Zheng
        .name = BLOCK_OPT_SUBFMT,
2089 f66fd6c3 Fam Zheng
        .type = OPT_STRING,
2090 f66fd6c3 Fam Zheng
        .help =
2091 f66fd6c3 Fam Zheng
            "VMDK flat extent format, can be one of "
2092 6c031aac Fam Zheng
            "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
2093 f66fd6c3 Fam Zheng
    },
2094 69e0b6df Fam Zheng
    {
2095 69e0b6df Fam Zheng
        .name = BLOCK_OPT_ZEROED_GRAIN,
2096 69e0b6df Fam Zheng
        .type = OPT_FLAG,
2097 69e0b6df Fam Zheng
        .help = "Enable efficient zero writes using the zeroed-grain GTE feature"
2098 69e0b6df Fam Zheng
    },
2099 0e7e1989 Kevin Wolf
    { NULL }
2100 0e7e1989 Kevin Wolf
};
2101 0e7e1989 Kevin Wolf
2102 5efa9d5a Anthony Liguori
static BlockDriver bdrv_vmdk = {
2103 da7a50f9 Fam Zheng
    .format_name                  = "vmdk",
2104 da7a50f9 Fam Zheng
    .instance_size                = sizeof(BDRVVmdkState),
2105 da7a50f9 Fam Zheng
    .bdrv_probe                   = vmdk_probe,
2106 da7a50f9 Fam Zheng
    .bdrv_open                    = vmdk_open,
2107 f43aa8e1 Peter Lieven
    .bdrv_check                   = vmdk_check,
2108 da7a50f9 Fam Zheng
    .bdrv_reopen_prepare          = vmdk_reopen_prepare,
2109 da7a50f9 Fam Zheng
    .bdrv_read                    = vmdk_co_read,
2110 da7a50f9 Fam Zheng
    .bdrv_write                   = vmdk_co_write,
2111 da7a50f9 Fam Zheng
    .bdrv_co_write_zeroes         = vmdk_co_write_zeroes,
2112 da7a50f9 Fam Zheng
    .bdrv_close                   = vmdk_close,
2113 da7a50f9 Fam Zheng
    .bdrv_create                  = vmdk_create,
2114 da7a50f9 Fam Zheng
    .bdrv_co_flush_to_disk        = vmdk_co_flush,
2115 b6b8a333 Paolo Bonzini
    .bdrv_co_get_block_status     = vmdk_co_get_block_status,
2116 da7a50f9 Fam Zheng
    .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
2117 da7a50f9 Fam Zheng
    .bdrv_has_zero_init           = vmdk_has_zero_init,
2118 f4c129a3 Fam Zheng
    .bdrv_get_specific_info       = vmdk_get_specific_info,
2119 d34682cd Kevin Wolf
    .bdrv_refresh_limits          = vmdk_refresh_limits,
2120 da7a50f9 Fam Zheng
2121 da7a50f9 Fam Zheng
    .create_options               = vmdk_create_options,
2122 ea2384d3 bellard
};
2123 5efa9d5a Anthony Liguori
2124 5efa9d5a Anthony Liguori
static void bdrv_vmdk_init(void)
2125 5efa9d5a Anthony Liguori
{
2126 5efa9d5a Anthony Liguori
    bdrv_register(&bdrv_vmdk);
2127 5efa9d5a Anthony Liguori
}
2128 5efa9d5a Anthony Liguori
2129 5efa9d5a Anthony Liguori
block_init(bdrv_vmdk_init);