Statistics
| Branch: | Revision:

root / block.c @ ca821806

History | View | Annotate | Download (61.7 kB)

1 fc01f7e7 bellard
/*
2 fc01f7e7 bellard
 * QEMU System Emulator block driver
3 5fafdf24 ths
 *
4 fc01f7e7 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5fafdf24 ths
 *
6 fc01f7e7 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 fc01f7e7 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 fc01f7e7 bellard
 * in the Software without restriction, including without limitation the rights
9 fc01f7e7 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 fc01f7e7 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 fc01f7e7 bellard
 * furnished to do so, subject to the following conditions:
12 fc01f7e7 bellard
 *
13 fc01f7e7 bellard
 * The above copyright notice and this permission notice shall be included in
14 fc01f7e7 bellard
 * all copies or substantial portions of the Software.
15 fc01f7e7 bellard
 *
16 fc01f7e7 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 fc01f7e7 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 fc01f7e7 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 fc01f7e7 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 fc01f7e7 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 fc01f7e7 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 fc01f7e7 bellard
 * THE SOFTWARE.
23 fc01f7e7 bellard
 */
24 3990d09a blueswir1
#include "config-host.h"
25 faf07963 pbrook
#include "qemu-common.h"
26 376253ec aliguori
#include "monitor.h"
27 ea2384d3 bellard
#include "block_int.h"
28 5efa9d5a Anthony Liguori
#include "module.h"
29 d15e5465 Luiz Capitulino
#include "qemu-objects.h"
30 fc01f7e7 bellard
31 71e72a19 Juan Quintela
#ifdef CONFIG_BSD
32 7674e7bf bellard
#include <sys/types.h>
33 7674e7bf bellard
#include <sys/stat.h>
34 7674e7bf bellard
#include <sys/ioctl.h>
35 72cf2d4f Blue Swirl
#include <sys/queue.h>
36 c5e97233 blueswir1
#ifndef __DragonFly__
37 7674e7bf bellard
#include <sys/disk.h>
38 7674e7bf bellard
#endif
39 c5e97233 blueswir1
#endif
40 7674e7bf bellard
41 49dc768d aliguori
#ifdef _WIN32
42 49dc768d aliguori
#include <windows.h>
43 49dc768d aliguori
#endif
44 49dc768d aliguori
45 f141eafe aliguori
static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
46 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
47 c87c0672 aliguori
        BlockDriverCompletionFunc *cb, void *opaque);
48 f141eafe aliguori
static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
49 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
50 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque);
51 b2e12bc6 Christoph Hellwig
static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
52 b2e12bc6 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque);
53 5fafdf24 ths
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
54 83f64091 bellard
                        uint8_t *buf, int nb_sectors);
55 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
56 83f64091 bellard
                         const uint8_t *buf, int nb_sectors);
57 ec530c81 bellard
58 7ee930d0 blueswir1
BlockDriverState *bdrv_first;
59 7ee930d0 blueswir1
60 ea2384d3 bellard
static BlockDriver *first_drv;
61 ea2384d3 bellard
62 eb852011 Markus Armbruster
/* If non-zero, use only whitelisted block drivers */
63 eb852011 Markus Armbruster
static int use_bdrv_whitelist;
64 eb852011 Markus Armbruster
65 83f64091 bellard
int path_is_absolute(const char *path)
66 3b0d4f61 bellard
{
67 83f64091 bellard
    const char *p;
68 21664424 bellard
#ifdef _WIN32
69 21664424 bellard
    /* specific case for names like: "\\.\d:" */
70 21664424 bellard
    if (*path == '/' || *path == '\\')
71 21664424 bellard
        return 1;
72 21664424 bellard
#endif
73 83f64091 bellard
    p = strchr(path, ':');
74 83f64091 bellard
    if (p)
75 83f64091 bellard
        p++;
76 83f64091 bellard
    else
77 83f64091 bellard
        p = path;
78 3b9f94e1 bellard
#ifdef _WIN32
79 3b9f94e1 bellard
    return (*p == '/' || *p == '\\');
80 3b9f94e1 bellard
#else
81 3b9f94e1 bellard
    return (*p == '/');
82 3b9f94e1 bellard
#endif
83 3b0d4f61 bellard
}
84 3b0d4f61 bellard
85 83f64091 bellard
/* if filename is absolute, just copy it to dest. Otherwise, build a
86 83f64091 bellard
   path to it by considering it is relative to base_path. URL are
87 83f64091 bellard
   supported. */
88 83f64091 bellard
void path_combine(char *dest, int dest_size,
89 83f64091 bellard
                  const char *base_path,
90 83f64091 bellard
                  const char *filename)
91 3b0d4f61 bellard
{
92 83f64091 bellard
    const char *p, *p1;
93 83f64091 bellard
    int len;
94 83f64091 bellard
95 83f64091 bellard
    if (dest_size <= 0)
96 83f64091 bellard
        return;
97 83f64091 bellard
    if (path_is_absolute(filename)) {
98 83f64091 bellard
        pstrcpy(dest, dest_size, filename);
99 83f64091 bellard
    } else {
100 83f64091 bellard
        p = strchr(base_path, ':');
101 83f64091 bellard
        if (p)
102 83f64091 bellard
            p++;
103 83f64091 bellard
        else
104 83f64091 bellard
            p = base_path;
105 3b9f94e1 bellard
        p1 = strrchr(base_path, '/');
106 3b9f94e1 bellard
#ifdef _WIN32
107 3b9f94e1 bellard
        {
108 3b9f94e1 bellard
            const char *p2;
109 3b9f94e1 bellard
            p2 = strrchr(base_path, '\\');
110 3b9f94e1 bellard
            if (!p1 || p2 > p1)
111 3b9f94e1 bellard
                p1 = p2;
112 3b9f94e1 bellard
        }
113 3b9f94e1 bellard
#endif
114 83f64091 bellard
        if (p1)
115 83f64091 bellard
            p1++;
116 83f64091 bellard
        else
117 83f64091 bellard
            p1 = base_path;
118 83f64091 bellard
        if (p1 > p)
119 83f64091 bellard
            p = p1;
120 83f64091 bellard
        len = p - base_path;
121 83f64091 bellard
        if (len > dest_size - 1)
122 83f64091 bellard
            len = dest_size - 1;
123 83f64091 bellard
        memcpy(dest, base_path, len);
124 83f64091 bellard
        dest[len] = '\0';
125 83f64091 bellard
        pstrcat(dest, dest_size, filename);
126 3b0d4f61 bellard
    }
127 3b0d4f61 bellard
}
128 3b0d4f61 bellard
129 5efa9d5a Anthony Liguori
void bdrv_register(BlockDriver *bdrv)
130 ea2384d3 bellard
{
131 f141eafe aliguori
    if (!bdrv->bdrv_aio_readv) {
132 83f64091 bellard
        /* add AIO emulation layer */
133 f141eafe aliguori
        bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
134 f141eafe aliguori
        bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
135 eda578e5 aliguori
    } else if (!bdrv->bdrv_read) {
136 83f64091 bellard
        /* add synchronous IO emulation layer */
137 83f64091 bellard
        bdrv->bdrv_read = bdrv_read_em;
138 83f64091 bellard
        bdrv->bdrv_write = bdrv_write_em;
139 83f64091 bellard
    }
140 b2e12bc6 Christoph Hellwig
141 b2e12bc6 Christoph Hellwig
    if (!bdrv->bdrv_aio_flush)
142 b2e12bc6 Christoph Hellwig
        bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
143 b2e12bc6 Christoph Hellwig
144 ea2384d3 bellard
    bdrv->next = first_drv;
145 ea2384d3 bellard
    first_drv = bdrv;
146 ea2384d3 bellard
}
147 b338082b bellard
148 b338082b bellard
/* create a new block device (by default it is empty) */
149 b338082b bellard
BlockDriverState *bdrv_new(const char *device_name)
150 b338082b bellard
{
151 b338082b bellard
    BlockDriverState **pbs, *bs;
152 b338082b bellard
153 b338082b bellard
    bs = qemu_mallocz(sizeof(BlockDriverState));
154 b338082b bellard
    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
155 ea2384d3 bellard
    if (device_name[0] != '\0') {
156 ea2384d3 bellard
        /* insert at the end */
157 ea2384d3 bellard
        pbs = &bdrv_first;
158 ea2384d3 bellard
        while (*pbs != NULL)
159 ea2384d3 bellard
            pbs = &(*pbs)->next;
160 ea2384d3 bellard
        *pbs = bs;
161 ea2384d3 bellard
    }
162 b338082b bellard
    return bs;
163 b338082b bellard
}
164 b338082b bellard
165 ea2384d3 bellard
BlockDriver *bdrv_find_format(const char *format_name)
166 ea2384d3 bellard
{
167 ea2384d3 bellard
    BlockDriver *drv1;
168 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
169 ea2384d3 bellard
        if (!strcmp(drv1->format_name, format_name))
170 ea2384d3 bellard
            return drv1;
171 ea2384d3 bellard
    }
172 ea2384d3 bellard
    return NULL;
173 ea2384d3 bellard
}
174 ea2384d3 bellard
175 eb852011 Markus Armbruster
static int bdrv_is_whitelisted(BlockDriver *drv)
176 eb852011 Markus Armbruster
{
177 eb852011 Markus Armbruster
    static const char *whitelist[] = {
178 eb852011 Markus Armbruster
        CONFIG_BDRV_WHITELIST
179 eb852011 Markus Armbruster
    };
180 eb852011 Markus Armbruster
    const char **p;
181 eb852011 Markus Armbruster
182 eb852011 Markus Armbruster
    if (!whitelist[0])
183 eb852011 Markus Armbruster
        return 1;               /* no whitelist, anything goes */
184 eb852011 Markus Armbruster
185 eb852011 Markus Armbruster
    for (p = whitelist; *p; p++) {
186 eb852011 Markus Armbruster
        if (!strcmp(drv->format_name, *p)) {
187 eb852011 Markus Armbruster
            return 1;
188 eb852011 Markus Armbruster
        }
189 eb852011 Markus Armbruster
    }
190 eb852011 Markus Armbruster
    return 0;
191 eb852011 Markus Armbruster
}
192 eb852011 Markus Armbruster
193 eb852011 Markus Armbruster
BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
194 eb852011 Markus Armbruster
{
195 eb852011 Markus Armbruster
    BlockDriver *drv = bdrv_find_format(format_name);
196 eb852011 Markus Armbruster
    return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
197 eb852011 Markus Armbruster
}
198 eb852011 Markus Armbruster
199 0e7e1989 Kevin Wolf
int bdrv_create(BlockDriver *drv, const char* filename,
200 0e7e1989 Kevin Wolf
    QEMUOptionParameter *options)
201 ea2384d3 bellard
{
202 ea2384d3 bellard
    if (!drv->bdrv_create)
203 ea2384d3 bellard
        return -ENOTSUP;
204 0e7e1989 Kevin Wolf
205 0e7e1989 Kevin Wolf
    return drv->bdrv_create(filename, options);
206 ea2384d3 bellard
}
207 ea2384d3 bellard
208 d5249393 bellard
#ifdef _WIN32
209 95389c86 bellard
void get_tmp_filename(char *filename, int size)
210 d5249393 bellard
{
211 3b9f94e1 bellard
    char temp_dir[MAX_PATH];
212 3b46e624 ths
213 3b9f94e1 bellard
    GetTempPath(MAX_PATH, temp_dir);
214 3b9f94e1 bellard
    GetTempFileName(temp_dir, "qem", 0, filename);
215 d5249393 bellard
}
216 d5249393 bellard
#else
217 95389c86 bellard
void get_tmp_filename(char *filename, int size)
218 fc01f7e7 bellard
{
219 67b915a5 bellard
    int fd;
220 7ccfb2eb blueswir1
    const char *tmpdir;
221 d5249393 bellard
    /* XXX: race condition possible */
222 0badc1ee aurel32
    tmpdir = getenv("TMPDIR");
223 0badc1ee aurel32
    if (!tmpdir)
224 0badc1ee aurel32
        tmpdir = "/tmp";
225 0badc1ee aurel32
    snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
226 ea2384d3 bellard
    fd = mkstemp(filename);
227 ea2384d3 bellard
    close(fd);
228 ea2384d3 bellard
}
229 d5249393 bellard
#endif
230 fc01f7e7 bellard
231 19cb3738 bellard
#ifdef _WIN32
232 f45512fe bellard
static int is_windows_drive_prefix(const char *filename)
233 f45512fe bellard
{
234 f45512fe bellard
    return (((filename[0] >= 'a' && filename[0] <= 'z') ||
235 f45512fe bellard
             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
236 f45512fe bellard
            filename[1] == ':');
237 f45512fe bellard
}
238 3b46e624 ths
239 508c7cb3 Christoph Hellwig
int is_windows_drive(const char *filename)
240 19cb3738 bellard
{
241 5fafdf24 ths
    if (is_windows_drive_prefix(filename) &&
242 f45512fe bellard
        filename[2] == '\0')
243 19cb3738 bellard
        return 1;
244 19cb3738 bellard
    if (strstart(filename, "\\\\.\\", NULL) ||
245 19cb3738 bellard
        strstart(filename, "//./", NULL))
246 19cb3738 bellard
        return 1;
247 19cb3738 bellard
    return 0;
248 19cb3738 bellard
}
249 19cb3738 bellard
#endif
250 19cb3738 bellard
251 83f64091 bellard
static BlockDriver *find_protocol(const char *filename)
252 83f64091 bellard
{
253 83f64091 bellard
    BlockDriver *drv1;
254 83f64091 bellard
    char protocol[128];
255 1cec71e3 Anthony Liguori
    int len;
256 83f64091 bellard
    const char *p;
257 19cb3738 bellard
258 19cb3738 bellard
#ifdef _WIN32
259 f45512fe bellard
    if (is_windows_drive(filename) ||
260 f45512fe bellard
        is_windows_drive_prefix(filename))
261 5efa9d5a Anthony Liguori
        return bdrv_find_format("raw");
262 19cb3738 bellard
#endif
263 1cec71e3 Anthony Liguori
    p = strchr(filename, ':');
264 1cec71e3 Anthony Liguori
    if (!p)
265 5efa9d5a Anthony Liguori
        return bdrv_find_format("raw");
266 1cec71e3 Anthony Liguori
    len = p - filename;
267 1cec71e3 Anthony Liguori
    if (len > sizeof(protocol) - 1)
268 1cec71e3 Anthony Liguori
        len = sizeof(protocol) - 1;
269 1cec71e3 Anthony Liguori
    memcpy(protocol, filename, len);
270 1cec71e3 Anthony Liguori
    protocol[len] = '\0';
271 83f64091 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
272 5fafdf24 ths
        if (drv1->protocol_name &&
273 83f64091 bellard
            !strcmp(drv1->protocol_name, protocol))
274 83f64091 bellard
            return drv1;
275 83f64091 bellard
    }
276 83f64091 bellard
    return NULL;
277 83f64091 bellard
}
278 83f64091 bellard
279 f3a5d3f8 Christoph Hellwig
/*
280 f3a5d3f8 Christoph Hellwig
 * Detect host devices. By convention, /dev/cdrom[N] is always
281 f3a5d3f8 Christoph Hellwig
 * recognized as a host CDROM.
282 f3a5d3f8 Christoph Hellwig
 */
283 f3a5d3f8 Christoph Hellwig
static BlockDriver *find_hdev_driver(const char *filename)
284 f3a5d3f8 Christoph Hellwig
{
285 508c7cb3 Christoph Hellwig
    int score_max = 0, score;
286 508c7cb3 Christoph Hellwig
    BlockDriver *drv = NULL, *d;
287 f3a5d3f8 Christoph Hellwig
288 508c7cb3 Christoph Hellwig
    for (d = first_drv; d; d = d->next) {
289 508c7cb3 Christoph Hellwig
        if (d->bdrv_probe_device) {
290 508c7cb3 Christoph Hellwig
            score = d->bdrv_probe_device(filename);
291 508c7cb3 Christoph Hellwig
            if (score > score_max) {
292 508c7cb3 Christoph Hellwig
                score_max = score;
293 508c7cb3 Christoph Hellwig
                drv = d;
294 508c7cb3 Christoph Hellwig
            }
295 508c7cb3 Christoph Hellwig
        }
296 19cb3738 bellard
    }
297 f3a5d3f8 Christoph Hellwig
298 508c7cb3 Christoph Hellwig
    return drv;
299 f3a5d3f8 Christoph Hellwig
}
300 3b46e624 ths
301 f3a5d3f8 Christoph Hellwig
static BlockDriver *find_image_format(const char *filename)
302 f3a5d3f8 Christoph Hellwig
{
303 f3a5d3f8 Christoph Hellwig
    int ret, score, score_max;
304 f3a5d3f8 Christoph Hellwig
    BlockDriver *drv1, *drv;
305 f3a5d3f8 Christoph Hellwig
    uint8_t buf[2048];
306 f3a5d3f8 Christoph Hellwig
    BlockDriverState *bs;
307 f3a5d3f8 Christoph Hellwig
308 83f64091 bellard
    drv = find_protocol(filename);
309 19cb3738 bellard
    /* no need to test disk image formats for vvfat */
310 c833ab73 Anthony Liguori
    if (drv && strcmp(drv->format_name, "vvfat") == 0)
311 83f64091 bellard
        return drv;
312 19cb3738 bellard
313 f5edb014 Naphtali Sprei
    ret = bdrv_file_open(&bs, filename, 0);
314 83f64091 bellard
    if (ret < 0)
315 83f64091 bellard
        return NULL;
316 83f64091 bellard
    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
317 83f64091 bellard
    bdrv_delete(bs);
318 83f64091 bellard
    if (ret < 0) {
319 83f64091 bellard
        return NULL;
320 83f64091 bellard
    }
321 83f64091 bellard
322 ea2384d3 bellard
    score_max = 0;
323 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
324 83f64091 bellard
        if (drv1->bdrv_probe) {
325 83f64091 bellard
            score = drv1->bdrv_probe(buf, ret, filename);
326 83f64091 bellard
            if (score > score_max) {
327 83f64091 bellard
                score_max = score;
328 83f64091 bellard
                drv = drv1;
329 83f64091 bellard
            }
330 0849bf08 bellard
        }
331 fc01f7e7 bellard
    }
332 ea2384d3 bellard
    return drv;
333 ea2384d3 bellard
}
334 ea2384d3 bellard
335 83f64091 bellard
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
336 ea2384d3 bellard
{
337 83f64091 bellard
    BlockDriverState *bs;
338 83f64091 bellard
    int ret;
339 83f64091 bellard
340 83f64091 bellard
    bs = bdrv_new("");
341 83f64091 bellard
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
342 83f64091 bellard
    if (ret < 0) {
343 83f64091 bellard
        bdrv_delete(bs);
344 83f64091 bellard
        return ret;
345 3b0d4f61 bellard
    }
346 71d0770c aliguori
    bs->growable = 1;
347 83f64091 bellard
    *pbs = bs;
348 83f64091 bellard
    return 0;
349 83f64091 bellard
}
350 83f64091 bellard
351 83f64091 bellard
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
352 83f64091 bellard
{
353 83f64091 bellard
    return bdrv_open2(bs, filename, flags, NULL);
354 ea2384d3 bellard
}
355 ea2384d3 bellard
356 83f64091 bellard
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
357 ea2384d3 bellard
               BlockDriver *drv)
358 ea2384d3 bellard
{
359 f5edb014 Naphtali Sprei
    int ret, open_flags;
360 eb5c851f ths
    char tmp_filename[PATH_MAX];
361 eb5c851f ths
    char backing_filename[PATH_MAX];
362 3b46e624 ths
363 ea2384d3 bellard
    bs->is_temporary = 0;
364 ea2384d3 bellard
    bs->encrypted = 0;
365 c0f4ce77 aliguori
    bs->valid_key = 0;
366 4dca4b63 Naphtali Sprei
    bs->open_flags = flags;
367 e268ca52 aliguori
    /* buffer_alignment defaulted to 512, drivers can change this value */
368 e268ca52 aliguori
    bs->buffer_alignment = 512;
369 712e7874 bellard
370 83f64091 bellard
    if (flags & BDRV_O_SNAPSHOT) {
371 ea2384d3 bellard
        BlockDriverState *bs1;
372 ea2384d3 bellard
        int64_t total_size;
373 7c96d46e aliguori
        int is_protocol = 0;
374 91a073a9 Kevin Wolf
        BlockDriver *bdrv_qcow2;
375 91a073a9 Kevin Wolf
        QEMUOptionParameter *options;
376 3b46e624 ths
377 ea2384d3 bellard
        /* if snapshot, we create a temporary backing file and open it
378 ea2384d3 bellard
           instead of opening 'filename' directly */
379 33e3963e bellard
380 ea2384d3 bellard
        /* if there is a backing file, use it */
381 ea2384d3 bellard
        bs1 = bdrv_new("");
382 5eb45639 aliguori
        ret = bdrv_open2(bs1, filename, 0, drv);
383 51d7c00c aliguori
        if (ret < 0) {
384 ea2384d3 bellard
            bdrv_delete(bs1);
385 51d7c00c aliguori
            return ret;
386 ea2384d3 bellard
        }
387 6ea44308 Jan Kiszka
        total_size = bdrv_getlength(bs1) >> BDRV_SECTOR_BITS;
388 7c96d46e aliguori
389 7c96d46e aliguori
        if (bs1->drv && bs1->drv->protocol_name)
390 7c96d46e aliguori
            is_protocol = 1;
391 7c96d46e aliguori
392 ea2384d3 bellard
        bdrv_delete(bs1);
393 3b46e624 ths
394 ea2384d3 bellard
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
395 7c96d46e aliguori
396 7c96d46e aliguori
        /* Real path is meaningless for protocols */
397 7c96d46e aliguori
        if (is_protocol)
398 7c96d46e aliguori
            snprintf(backing_filename, sizeof(backing_filename),
399 7c96d46e aliguori
                     "%s", filename);
400 114cdfa9 Kirill A. Shutemov
        else if (!realpath(filename, backing_filename))
401 114cdfa9 Kirill A. Shutemov
            return -errno;
402 7c96d46e aliguori
403 91a073a9 Kevin Wolf
        bdrv_qcow2 = bdrv_find_format("qcow2");
404 91a073a9 Kevin Wolf
        options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
405 91a073a9 Kevin Wolf
406 91a073a9 Kevin Wolf
        set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size * 512);
407 91a073a9 Kevin Wolf
        set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
408 91a073a9 Kevin Wolf
        if (drv) {
409 91a073a9 Kevin Wolf
            set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
410 91a073a9 Kevin Wolf
                drv->format_name);
411 91a073a9 Kevin Wolf
        }
412 91a073a9 Kevin Wolf
413 91a073a9 Kevin Wolf
        ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
414 51d7c00c aliguori
        if (ret < 0) {
415 51d7c00c aliguori
            return ret;
416 ea2384d3 bellard
        }
417 91a073a9 Kevin Wolf
418 ea2384d3 bellard
        filename = tmp_filename;
419 91a073a9 Kevin Wolf
        drv = bdrv_qcow2;
420 ea2384d3 bellard
        bs->is_temporary = 1;
421 ea2384d3 bellard
    }
422 712e7874 bellard
423 ea2384d3 bellard
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
424 83f64091 bellard
    if (flags & BDRV_O_FILE) {
425 83f64091 bellard
        drv = find_protocol(filename);
426 51d7c00c aliguori
    } else if (!drv) {
427 f3a5d3f8 Christoph Hellwig
        drv = find_hdev_driver(filename);
428 f3a5d3f8 Christoph Hellwig
        if (!drv) {
429 f3a5d3f8 Christoph Hellwig
            drv = find_image_format(filename);
430 f3a5d3f8 Christoph Hellwig
        }
431 51d7c00c aliguori
    }
432 6987307c Christoph Hellwig
433 51d7c00c aliguori
    if (!drv) {
434 51d7c00c aliguori
        ret = -ENOENT;
435 51d7c00c aliguori
        goto unlink_and_fail;
436 ea2384d3 bellard
    }
437 6987307c Christoph Hellwig
    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
438 6987307c Christoph Hellwig
        ret = -ENOTSUP;
439 6987307c Christoph Hellwig
        goto unlink_and_fail;
440 6987307c Christoph Hellwig
    }
441 6987307c Christoph Hellwig
442 ea2384d3 bellard
    bs->drv = drv;
443 ea2384d3 bellard
    bs->opaque = qemu_mallocz(drv->instance_size);
444 e900a7b7 Christoph Hellwig
445 e900a7b7 Christoph Hellwig
    /*
446 e900a7b7 Christoph Hellwig
     * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
447 e900a7b7 Christoph Hellwig
     * write cache to the guest.  We do need the fdatasync to flush
448 e900a7b7 Christoph Hellwig
     * out transactions for block allocations, and we maybe have a
449 e900a7b7 Christoph Hellwig
     * volatile write cache in our backing device to deal with.
450 e900a7b7 Christoph Hellwig
     */
451 e900a7b7 Christoph Hellwig
    if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
452 e900a7b7 Christoph Hellwig
        bs->enable_write_cache = 1;
453 e900a7b7 Christoph Hellwig
454 15dc2697 Christoph Hellwig
    /*
455 15dc2697 Christoph Hellwig
     * Clear flags that are internal to the block layer before opening the
456 15dc2697 Christoph Hellwig
     * image.
457 15dc2697 Christoph Hellwig
     */
458 15dc2697 Christoph Hellwig
    open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
459 15dc2697 Christoph Hellwig
460 15dc2697 Christoph Hellwig
    /*
461 15dc2697 Christoph Hellwig
     * Snapshots should be writeable.
462 15dc2697 Christoph Hellwig
     *
463 15dc2697 Christoph Hellwig
     * XXX(hch): and what is the point of a snapshot during a read-only open?
464 15dc2697 Christoph Hellwig
     */
465 15dc2697 Christoph Hellwig
    if (!(flags & BDRV_O_FILE) && bs->is_temporary) {
466 15dc2697 Christoph Hellwig
        open_flags |= BDRV_O_RDWR;
467 f5edb014 Naphtali Sprei
    }
468 6987307c Christoph Hellwig
469 6987307c Christoph Hellwig
    ret = drv->bdrv_open(bs, filename, open_flags);
470 ea2384d3 bellard
    if (ret < 0) {
471 6987307c Christoph Hellwig
        goto free_and_fail;
472 33e3963e bellard
    }
473 6987307c Christoph Hellwig
474 4dca4b63 Naphtali Sprei
    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
475 d15a771d bellard
    if (drv->bdrv_getlength) {
476 6ea44308 Jan Kiszka
        bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
477 d15a771d bellard
    }
478 67b915a5 bellard
#ifndef _WIN32
479 ea2384d3 bellard
    if (bs->is_temporary) {
480 ea2384d3 bellard
        unlink(filename);
481 ea2384d3 bellard
    }
482 ea2384d3 bellard
#endif
483 b783e409 Kevin Wolf
    if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
484 ea2384d3 bellard
        /* if there is a backing file, use it */
485 5eb45639 aliguori
        BlockDriver *back_drv = NULL;
486 ea2384d3 bellard
        bs->backing_hd = bdrv_new("");
487 83f64091 bellard
        path_combine(backing_filename, sizeof(backing_filename),
488 83f64091 bellard
                     filename, bs->backing_file);
489 5eb45639 aliguori
        if (bs->backing_format[0] != '\0')
490 5eb45639 aliguori
            back_drv = bdrv_find_format(bs->backing_format);
491 4dca4b63 Naphtali Sprei
492 4dca4b63 Naphtali Sprei
        /* backing files always opened read-only */
493 4dca4b63 Naphtali Sprei
        open_flags &= ~BDRV_O_RDWR;
494 4dca4b63 Naphtali Sprei
        
495 5eb45639 aliguori
        ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
496 5eb45639 aliguori
                         back_drv);
497 51d7c00c aliguori
        if (ret < 0) {
498 51d7c00c aliguori
            bdrv_close(bs);
499 51d7c00c aliguori
            return ret;
500 51d7c00c aliguori
        }
501 4dca4b63 Naphtali Sprei
        if (bs->is_temporary) {
502 4dca4b63 Naphtali Sprei
            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
503 4dca4b63 Naphtali Sprei
        } else {
504 4dca4b63 Naphtali Sprei
            /* base image inherits from "parent" */
505 4dca4b63 Naphtali Sprei
            bs->backing_hd->keep_read_only = bs->keep_read_only;
506 4dca4b63 Naphtali Sprei
        }
507 33e3963e bellard
    }
508 33e3963e bellard
509 bb5fc20f aliguori
    if (!bdrv_key_required(bs)) {
510 bb5fc20f aliguori
        /* call the change callback */
511 bb5fc20f aliguori
        bs->media_changed = 1;
512 bb5fc20f aliguori
        if (bs->change_cb)
513 bb5fc20f aliguori
            bs->change_cb(bs->change_opaque);
514 bb5fc20f aliguori
    }
515 b338082b bellard
    return 0;
516 6987307c Christoph Hellwig
517 6987307c Christoph Hellwig
free_and_fail:
518 6987307c Christoph Hellwig
    qemu_free(bs->opaque);
519 6987307c Christoph Hellwig
    bs->opaque = NULL;
520 6987307c Christoph Hellwig
    bs->drv = NULL;
521 6987307c Christoph Hellwig
unlink_and_fail:
522 6987307c Christoph Hellwig
    if (bs->is_temporary)
523 6987307c Christoph Hellwig
        unlink(filename);
524 6987307c Christoph Hellwig
    return ret;
525 fc01f7e7 bellard
}
526 fc01f7e7 bellard
527 fc01f7e7 bellard
void bdrv_close(BlockDriverState *bs)
528 fc01f7e7 bellard
{
529 19cb3738 bellard
    if (bs->drv) {
530 ea2384d3 bellard
        if (bs->backing_hd)
531 ea2384d3 bellard
            bdrv_delete(bs->backing_hd);
532 ea2384d3 bellard
        bs->drv->bdrv_close(bs);
533 ea2384d3 bellard
        qemu_free(bs->opaque);
534 ea2384d3 bellard
#ifdef _WIN32
535 ea2384d3 bellard
        if (bs->is_temporary) {
536 ea2384d3 bellard
            unlink(bs->filename);
537 ea2384d3 bellard
        }
538 67b915a5 bellard
#endif
539 ea2384d3 bellard
        bs->opaque = NULL;
540 ea2384d3 bellard
        bs->drv = NULL;
541 b338082b bellard
542 b338082b bellard
        /* call the change callback */
543 19cb3738 bellard
        bs->media_changed = 1;
544 b338082b bellard
        if (bs->change_cb)
545 b338082b bellard
            bs->change_cb(bs->change_opaque);
546 b338082b bellard
    }
547 b338082b bellard
}
548 b338082b bellard
549 b338082b bellard
void bdrv_delete(BlockDriverState *bs)
550 b338082b bellard
{
551 34c6f050 aurel32
    BlockDriverState **pbs;
552 34c6f050 aurel32
553 34c6f050 aurel32
    pbs = &bdrv_first;
554 34c6f050 aurel32
    while (*pbs != bs && *pbs != NULL)
555 34c6f050 aurel32
        pbs = &(*pbs)->next;
556 34c6f050 aurel32
    if (*pbs == bs)
557 34c6f050 aurel32
        *pbs = bs->next;
558 34c6f050 aurel32
559 b338082b bellard
    bdrv_close(bs);
560 b338082b bellard
    qemu_free(bs);
561 fc01f7e7 bellard
}
562 fc01f7e7 bellard
563 e97fc193 aliguori
/*
564 e97fc193 aliguori
 * Run consistency checks on an image
565 e97fc193 aliguori
 *
566 e97fc193 aliguori
 * Returns the number of errors or -errno when an internal error occurs
567 e97fc193 aliguori
 */
568 e97fc193 aliguori
int bdrv_check(BlockDriverState *bs)
569 e97fc193 aliguori
{
570 e97fc193 aliguori
    if (bs->drv->bdrv_check == NULL) {
571 e97fc193 aliguori
        return -ENOTSUP;
572 e97fc193 aliguori
    }
573 e97fc193 aliguori
574 e97fc193 aliguori
    return bs->drv->bdrv_check(bs);
575 e97fc193 aliguori
}
576 e97fc193 aliguori
577 33e3963e bellard
/* commit COW file into the raw image */
578 33e3963e bellard
int bdrv_commit(BlockDriverState *bs)
579 33e3963e bellard
{
580 19cb3738 bellard
    BlockDriver *drv = bs->drv;
581 83f64091 bellard
    int64_t i, total_sectors;
582 4dca4b63 Naphtali Sprei
    int n, j, ro, open_flags;
583 4dca4b63 Naphtali Sprei
    int ret = 0, rw_ret = 0;
584 ea2384d3 bellard
    unsigned char sector[512];
585 4dca4b63 Naphtali Sprei
    char filename[1024];
586 4dca4b63 Naphtali Sprei
    BlockDriverState *bs_rw, *bs_ro;
587 33e3963e bellard
588 19cb3738 bellard
    if (!drv)
589 19cb3738 bellard
        return -ENOMEDIUM;
590 4dca4b63 Naphtali Sprei
    
591 4dca4b63 Naphtali Sprei
    if (!bs->backing_hd) {
592 4dca4b63 Naphtali Sprei
        return -ENOTSUP;
593 33e3963e bellard
    }
594 33e3963e bellard
595 4dca4b63 Naphtali Sprei
    if (bs->backing_hd->keep_read_only) {
596 4dca4b63 Naphtali Sprei
        return -EACCES;
597 4dca4b63 Naphtali Sprei
    }
598 4dca4b63 Naphtali Sprei
    
599 4dca4b63 Naphtali Sprei
    ro = bs->backing_hd->read_only;
600 4dca4b63 Naphtali Sprei
    strncpy(filename, bs->backing_hd->filename, sizeof(filename));
601 4dca4b63 Naphtali Sprei
    open_flags =  bs->backing_hd->open_flags;
602 4dca4b63 Naphtali Sprei
603 4dca4b63 Naphtali Sprei
    if (ro) {
604 4dca4b63 Naphtali Sprei
        /* re-open as RW */
605 4dca4b63 Naphtali Sprei
        bdrv_delete(bs->backing_hd);
606 4dca4b63 Naphtali Sprei
        bs->backing_hd = NULL;
607 4dca4b63 Naphtali Sprei
        bs_rw = bdrv_new("");
608 4dca4b63 Naphtali Sprei
        rw_ret = bdrv_open2(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL);
609 4dca4b63 Naphtali Sprei
        if (rw_ret < 0) {
610 4dca4b63 Naphtali Sprei
            bdrv_delete(bs_rw);
611 4dca4b63 Naphtali Sprei
            /* try to re-open read-only */
612 4dca4b63 Naphtali Sprei
            bs_ro = bdrv_new("");
613 4dca4b63 Naphtali Sprei
            ret = bdrv_open2(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
614 4dca4b63 Naphtali Sprei
            if (ret < 0) {
615 4dca4b63 Naphtali Sprei
                bdrv_delete(bs_ro);
616 4dca4b63 Naphtali Sprei
                /* drive not functional anymore */
617 4dca4b63 Naphtali Sprei
                bs->drv = NULL;
618 4dca4b63 Naphtali Sprei
                return ret;
619 4dca4b63 Naphtali Sprei
            }
620 4dca4b63 Naphtali Sprei
            bs->backing_hd = bs_ro;
621 4dca4b63 Naphtali Sprei
            return rw_ret;
622 4dca4b63 Naphtali Sprei
        }
623 4dca4b63 Naphtali Sprei
        bs->backing_hd = bs_rw;
624 ea2384d3 bellard
    }
625 33e3963e bellard
626 6ea44308 Jan Kiszka
    total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
627 83f64091 bellard
    for (i = 0; i < total_sectors;) {
628 19cb3738 bellard
        if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
629 ea2384d3 bellard
            for(j = 0; j < n; j++) {
630 ea2384d3 bellard
                if (bdrv_read(bs, i, sector, 1) != 0) {
631 4dca4b63 Naphtali Sprei
                    ret = -EIO;
632 4dca4b63 Naphtali Sprei
                    goto ro_cleanup;
633 ea2384d3 bellard
                }
634 ea2384d3 bellard
635 ea2384d3 bellard
                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
636 4dca4b63 Naphtali Sprei
                    ret = -EIO;
637 4dca4b63 Naphtali Sprei
                    goto ro_cleanup;
638 ea2384d3 bellard
                }
639 ea2384d3 bellard
                i++;
640 33e3963e bellard
            }
641 ea2384d3 bellard
        } else {
642 ea2384d3 bellard
            i += n;
643 ea2384d3 bellard
        }
644 33e3963e bellard
    }
645 95389c86 bellard
646 1d44952f Christoph Hellwig
    if (drv->bdrv_make_empty) {
647 1d44952f Christoph Hellwig
        ret = drv->bdrv_make_empty(bs);
648 1d44952f Christoph Hellwig
        bdrv_flush(bs);
649 1d44952f Christoph Hellwig
    }
650 95389c86 bellard
651 3f5075ae Christoph Hellwig
    /*
652 3f5075ae Christoph Hellwig
     * Make sure all data we wrote to the backing device is actually
653 3f5075ae Christoph Hellwig
     * stable on disk.
654 3f5075ae Christoph Hellwig
     */
655 3f5075ae Christoph Hellwig
    if (bs->backing_hd)
656 3f5075ae Christoph Hellwig
        bdrv_flush(bs->backing_hd);
657 4dca4b63 Naphtali Sprei
658 4dca4b63 Naphtali Sprei
ro_cleanup:
659 4dca4b63 Naphtali Sprei
660 4dca4b63 Naphtali Sprei
    if (ro) {
661 4dca4b63 Naphtali Sprei
        /* re-open as RO */
662 4dca4b63 Naphtali Sprei
        bdrv_delete(bs->backing_hd);
663 4dca4b63 Naphtali Sprei
        bs->backing_hd = NULL;
664 4dca4b63 Naphtali Sprei
        bs_ro = bdrv_new("");
665 4dca4b63 Naphtali Sprei
        ret = bdrv_open2(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
666 4dca4b63 Naphtali Sprei
        if (ret < 0) {
667 4dca4b63 Naphtali Sprei
            bdrv_delete(bs_ro);
668 4dca4b63 Naphtali Sprei
            /* drive not functional anymore */
669 4dca4b63 Naphtali Sprei
            bs->drv = NULL;
670 4dca4b63 Naphtali Sprei
            return ret;
671 4dca4b63 Naphtali Sprei
        }
672 4dca4b63 Naphtali Sprei
        bs->backing_hd = bs_ro;
673 4dca4b63 Naphtali Sprei
        bs->backing_hd->keep_read_only = 0;
674 4dca4b63 Naphtali Sprei
    }
675 4dca4b63 Naphtali Sprei
676 1d44952f Christoph Hellwig
    return ret;
677 33e3963e bellard
}
678 33e3963e bellard
679 756e6736 Kevin Wolf
/*
680 756e6736 Kevin Wolf
 * Return values:
681 756e6736 Kevin Wolf
 * 0        - success
682 756e6736 Kevin Wolf
 * -EINVAL  - backing format specified, but no file
683 756e6736 Kevin Wolf
 * -ENOSPC  - can't update the backing file because no space is left in the
684 756e6736 Kevin Wolf
 *            image file header
685 756e6736 Kevin Wolf
 * -ENOTSUP - format driver doesn't support changing the backing file
686 756e6736 Kevin Wolf
 */
687 756e6736 Kevin Wolf
int bdrv_change_backing_file(BlockDriverState *bs,
688 756e6736 Kevin Wolf
    const char *backing_file, const char *backing_fmt)
689 756e6736 Kevin Wolf
{
690 756e6736 Kevin Wolf
    BlockDriver *drv = bs->drv;
691 756e6736 Kevin Wolf
692 756e6736 Kevin Wolf
    if (drv->bdrv_change_backing_file != NULL) {
693 756e6736 Kevin Wolf
        return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
694 756e6736 Kevin Wolf
    } else {
695 756e6736 Kevin Wolf
        return -ENOTSUP;
696 756e6736 Kevin Wolf
    }
697 756e6736 Kevin Wolf
}
698 756e6736 Kevin Wolf
699 71d0770c aliguori
static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
700 71d0770c aliguori
                                   size_t size)
701 71d0770c aliguori
{
702 71d0770c aliguori
    int64_t len;
703 71d0770c aliguori
704 71d0770c aliguori
    if (!bdrv_is_inserted(bs))
705 71d0770c aliguori
        return -ENOMEDIUM;
706 71d0770c aliguori
707 71d0770c aliguori
    if (bs->growable)
708 71d0770c aliguori
        return 0;
709 71d0770c aliguori
710 71d0770c aliguori
    len = bdrv_getlength(bs);
711 71d0770c aliguori
712 fbb7b4e0 Kevin Wolf
    if (offset < 0)
713 fbb7b4e0 Kevin Wolf
        return -EIO;
714 fbb7b4e0 Kevin Wolf
715 fbb7b4e0 Kevin Wolf
    if ((offset > len) || (len - offset < size))
716 71d0770c aliguori
        return -EIO;
717 71d0770c aliguori
718 71d0770c aliguori
    return 0;
719 71d0770c aliguori
}
720 71d0770c aliguori
721 71d0770c aliguori
static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
722 71d0770c aliguori
                              int nb_sectors)
723 71d0770c aliguori
{
724 999dec57 aliguori
    return bdrv_check_byte_request(bs, sector_num * 512, nb_sectors * 512);
725 71d0770c aliguori
}
726 71d0770c aliguori
727 19cb3738 bellard
/* return < 0 if error. See bdrv_write() for the return codes */
728 5fafdf24 ths
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
729 fc01f7e7 bellard
              uint8_t *buf, int nb_sectors)
730 fc01f7e7 bellard
{
731 ea2384d3 bellard
    BlockDriver *drv = bs->drv;
732 ea2384d3 bellard
733 19cb3738 bellard
    if (!drv)
734 19cb3738 bellard
        return -ENOMEDIUM;
735 71d0770c aliguori
    if (bdrv_check_request(bs, sector_num, nb_sectors))
736 71d0770c aliguori
        return -EIO;
737 b338082b bellard
738 eda578e5 aliguori
    return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
739 fc01f7e7 bellard
}
740 fc01f7e7 bellard
741 7cd1e32a lirans@il.ibm.com
static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
742 a55eb92c Jan Kiszka
                             int nb_sectors, int dirty)
743 7cd1e32a lirans@il.ibm.com
{
744 7cd1e32a lirans@il.ibm.com
    int64_t start, end;
745 c6d22830 Jan Kiszka
    unsigned long val, idx, bit;
746 a55eb92c Jan Kiszka
747 6ea44308 Jan Kiszka
    start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
748 c6d22830 Jan Kiszka
    end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
749 a55eb92c Jan Kiszka
750 a55eb92c Jan Kiszka
    for (; start <= end; start++) {
751 c6d22830 Jan Kiszka
        idx = start / (sizeof(unsigned long) * 8);
752 c6d22830 Jan Kiszka
        bit = start % (sizeof(unsigned long) * 8);
753 c6d22830 Jan Kiszka
        val = bs->dirty_bitmap[idx];
754 c6d22830 Jan Kiszka
        if (dirty) {
755 aaa0eb75 Liran Schour
            if (!(val & (1 << bit))) {
756 aaa0eb75 Liran Schour
                bs->dirty_count++;
757 aaa0eb75 Liran Schour
                val |= 1 << bit;
758 aaa0eb75 Liran Schour
            }
759 c6d22830 Jan Kiszka
        } else {
760 aaa0eb75 Liran Schour
            if (val & (1 << bit)) {
761 aaa0eb75 Liran Schour
                bs->dirty_count--;
762 aaa0eb75 Liran Schour
                val &= ~(1 << bit);
763 aaa0eb75 Liran Schour
            }
764 c6d22830 Jan Kiszka
        }
765 c6d22830 Jan Kiszka
        bs->dirty_bitmap[idx] = val;
766 7cd1e32a lirans@il.ibm.com
    }
767 7cd1e32a lirans@il.ibm.com
}
768 7cd1e32a lirans@il.ibm.com
769 5fafdf24 ths
/* Return < 0 if error. Important errors are:
770 19cb3738 bellard
  -EIO         generic I/O error (may happen for all errors)
771 19cb3738 bellard
  -ENOMEDIUM   No media inserted.
772 19cb3738 bellard
  -EINVAL      Invalid sector number or nb_sectors
773 19cb3738 bellard
  -EACCES      Trying to write a read-only device
774 19cb3738 bellard
*/
775 5fafdf24 ths
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
776 fc01f7e7 bellard
               const uint8_t *buf, int nb_sectors)
777 fc01f7e7 bellard
{
778 83f64091 bellard
    BlockDriver *drv = bs->drv;
779 19cb3738 bellard
    if (!bs->drv)
780 19cb3738 bellard
        return -ENOMEDIUM;
781 0849bf08 bellard
    if (bs->read_only)
782 19cb3738 bellard
        return -EACCES;
783 71d0770c aliguori
    if (bdrv_check_request(bs, sector_num, nb_sectors))
784 71d0770c aliguori
        return -EIO;
785 a55eb92c Jan Kiszka
786 c6d22830 Jan Kiszka
    if (bs->dirty_bitmap) {
787 7cd1e32a lirans@il.ibm.com
        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
788 7cd1e32a lirans@il.ibm.com
    }
789 a55eb92c Jan Kiszka
790 42fb2807 aliguori
    return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
791 83f64091 bellard
}
792 83f64091 bellard
793 eda578e5 aliguori
int bdrv_pread(BlockDriverState *bs, int64_t offset,
794 eda578e5 aliguori
               void *buf, int count1)
795 83f64091 bellard
{
796 6ea44308 Jan Kiszka
    uint8_t tmp_buf[BDRV_SECTOR_SIZE];
797 83f64091 bellard
    int len, nb_sectors, count;
798 83f64091 bellard
    int64_t sector_num;
799 9a8c4cce Kevin Wolf
    int ret;
800 83f64091 bellard
801 83f64091 bellard
    count = count1;
802 83f64091 bellard
    /* first read to align to sector start */
803 6ea44308 Jan Kiszka
    len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
804 83f64091 bellard
    if (len > count)
805 83f64091 bellard
        len = count;
806 6ea44308 Jan Kiszka
    sector_num = offset >> BDRV_SECTOR_BITS;
807 83f64091 bellard
    if (len > 0) {
808 9a8c4cce Kevin Wolf
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
809 9a8c4cce Kevin Wolf
            return ret;
810 6ea44308 Jan Kiszka
        memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
811 83f64091 bellard
        count -= len;
812 83f64091 bellard
        if (count == 0)
813 83f64091 bellard
            return count1;
814 83f64091 bellard
        sector_num++;
815 83f64091 bellard
        buf += len;
816 83f64091 bellard
    }
817 83f64091 bellard
818 83f64091 bellard
    /* read the sectors "in place" */
819 6ea44308 Jan Kiszka
    nb_sectors = count >> BDRV_SECTOR_BITS;
820 83f64091 bellard
    if (nb_sectors > 0) {
821 9a8c4cce Kevin Wolf
        if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
822 9a8c4cce Kevin Wolf
            return ret;
823 83f64091 bellard
        sector_num += nb_sectors;
824 6ea44308 Jan Kiszka
        len = nb_sectors << BDRV_SECTOR_BITS;
825 83f64091 bellard
        buf += len;
826 83f64091 bellard
        count -= len;
827 83f64091 bellard
    }
828 83f64091 bellard
829 83f64091 bellard
    /* add data from the last sector */
830 83f64091 bellard
    if (count > 0) {
831 9a8c4cce Kevin Wolf
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
832 9a8c4cce Kevin Wolf
            return ret;
833 83f64091 bellard
        memcpy(buf, tmp_buf, count);
834 83f64091 bellard
    }
835 83f64091 bellard
    return count1;
836 83f64091 bellard
}
837 83f64091 bellard
838 eda578e5 aliguori
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
839 eda578e5 aliguori
                const void *buf, int count1)
840 83f64091 bellard
{
841 6ea44308 Jan Kiszka
    uint8_t tmp_buf[BDRV_SECTOR_SIZE];
842 83f64091 bellard
    int len, nb_sectors, count;
843 83f64091 bellard
    int64_t sector_num;
844 9a8c4cce Kevin Wolf
    int ret;
845 83f64091 bellard
846 83f64091 bellard
    count = count1;
847 83f64091 bellard
    /* first write to align to sector start */
848 6ea44308 Jan Kiszka
    len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
849 83f64091 bellard
    if (len > count)
850 83f64091 bellard
        len = count;
851 6ea44308 Jan Kiszka
    sector_num = offset >> BDRV_SECTOR_BITS;
852 83f64091 bellard
    if (len > 0) {
853 9a8c4cce Kevin Wolf
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
854 9a8c4cce Kevin Wolf
            return ret;
855 6ea44308 Jan Kiszka
        memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
856 9a8c4cce Kevin Wolf
        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
857 9a8c4cce Kevin Wolf
            return ret;
858 83f64091 bellard
        count -= len;
859 83f64091 bellard
        if (count == 0)
860 83f64091 bellard
            return count1;
861 83f64091 bellard
        sector_num++;
862 83f64091 bellard
        buf += len;
863 83f64091 bellard
    }
864 83f64091 bellard
865 83f64091 bellard
    /* write the sectors "in place" */
866 6ea44308 Jan Kiszka
    nb_sectors = count >> BDRV_SECTOR_BITS;
867 83f64091 bellard
    if (nb_sectors > 0) {
868 9a8c4cce Kevin Wolf
        if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
869 9a8c4cce Kevin Wolf
            return ret;
870 83f64091 bellard
        sector_num += nb_sectors;
871 6ea44308 Jan Kiszka
        len = nb_sectors << BDRV_SECTOR_BITS;
872 83f64091 bellard
        buf += len;
873 83f64091 bellard
        count -= len;
874 83f64091 bellard
    }
875 83f64091 bellard
876 83f64091 bellard
    /* add data from the last sector */
877 83f64091 bellard
    if (count > 0) {
878 9a8c4cce Kevin Wolf
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
879 9a8c4cce Kevin Wolf
            return ret;
880 83f64091 bellard
        memcpy(tmp_buf, buf, count);
881 9a8c4cce Kevin Wolf
        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
882 9a8c4cce Kevin Wolf
            return ret;
883 83f64091 bellard
    }
884 83f64091 bellard
    return count1;
885 83f64091 bellard
}
886 83f64091 bellard
887 83f64091 bellard
/**
888 83f64091 bellard
 * Truncate file to 'offset' bytes (needed only for file protocols)
889 83f64091 bellard
 */
890 83f64091 bellard
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
891 83f64091 bellard
{
892 83f64091 bellard
    BlockDriver *drv = bs->drv;
893 83f64091 bellard
    if (!drv)
894 19cb3738 bellard
        return -ENOMEDIUM;
895 83f64091 bellard
    if (!drv->bdrv_truncate)
896 83f64091 bellard
        return -ENOTSUP;
897 59f2689d Naphtali Sprei
    if (bs->read_only)
898 59f2689d Naphtali Sprei
        return -EACCES;
899 83f64091 bellard
    return drv->bdrv_truncate(bs, offset);
900 83f64091 bellard
}
901 83f64091 bellard
902 83f64091 bellard
/**
903 83f64091 bellard
 * Length of a file in bytes. Return < 0 if error or unknown.
904 83f64091 bellard
 */
905 83f64091 bellard
int64_t bdrv_getlength(BlockDriverState *bs)
906 83f64091 bellard
{
907 83f64091 bellard
    BlockDriver *drv = bs->drv;
908 83f64091 bellard
    if (!drv)
909 19cb3738 bellard
        return -ENOMEDIUM;
910 83f64091 bellard
    if (!drv->bdrv_getlength) {
911 83f64091 bellard
        /* legacy mode */
912 6ea44308 Jan Kiszka
        return bs->total_sectors * BDRV_SECTOR_SIZE;
913 83f64091 bellard
    }
914 83f64091 bellard
    return drv->bdrv_getlength(bs);
915 fc01f7e7 bellard
}
916 fc01f7e7 bellard
917 19cb3738 bellard
/* return 0 as number of sectors if no device present or error */
918 96b8f136 ths
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
919 fc01f7e7 bellard
{
920 19cb3738 bellard
    int64_t length;
921 19cb3738 bellard
    length = bdrv_getlength(bs);
922 19cb3738 bellard
    if (length < 0)
923 19cb3738 bellard
        length = 0;
924 19cb3738 bellard
    else
925 6ea44308 Jan Kiszka
        length = length >> BDRV_SECTOR_BITS;
926 19cb3738 bellard
    *nb_sectors_ptr = length;
927 fc01f7e7 bellard
}
928 cf98951b bellard
929 f3d54fc4 aliguori
struct partition {
930 f3d54fc4 aliguori
        uint8_t boot_ind;           /* 0x80 - active */
931 f3d54fc4 aliguori
        uint8_t head;               /* starting head */
932 f3d54fc4 aliguori
        uint8_t sector;             /* starting sector */
933 f3d54fc4 aliguori
        uint8_t cyl;                /* starting cylinder */
934 f3d54fc4 aliguori
        uint8_t sys_ind;            /* What partition type */
935 f3d54fc4 aliguori
        uint8_t end_head;           /* end head */
936 f3d54fc4 aliguori
        uint8_t end_sector;         /* end sector */
937 f3d54fc4 aliguori
        uint8_t end_cyl;            /* end cylinder */
938 f3d54fc4 aliguori
        uint32_t start_sect;        /* starting sector counting from 0 */
939 f3d54fc4 aliguori
        uint32_t nr_sects;          /* nr of sectors in partition */
940 f3d54fc4 aliguori
} __attribute__((packed));
941 f3d54fc4 aliguori
942 f3d54fc4 aliguori
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
943 f3d54fc4 aliguori
static int guess_disk_lchs(BlockDriverState *bs,
944 f3d54fc4 aliguori
                           int *pcylinders, int *pheads, int *psectors)
945 f3d54fc4 aliguori
{
946 f3d54fc4 aliguori
    uint8_t buf[512];
947 f3d54fc4 aliguori
    int ret, i, heads, sectors, cylinders;
948 f3d54fc4 aliguori
    struct partition *p;
949 f3d54fc4 aliguori
    uint32_t nr_sects;
950 a38131b6 blueswir1
    uint64_t nb_sectors;
951 f3d54fc4 aliguori
952 f3d54fc4 aliguori
    bdrv_get_geometry(bs, &nb_sectors);
953 f3d54fc4 aliguori
954 f3d54fc4 aliguori
    ret = bdrv_read(bs, 0, buf, 1);
955 f3d54fc4 aliguori
    if (ret < 0)
956 f3d54fc4 aliguori
        return -1;
957 f3d54fc4 aliguori
    /* test msdos magic */
958 f3d54fc4 aliguori
    if (buf[510] != 0x55 || buf[511] != 0xaa)
959 f3d54fc4 aliguori
        return -1;
960 f3d54fc4 aliguori
    for(i = 0; i < 4; i++) {
961 f3d54fc4 aliguori
        p = ((struct partition *)(buf + 0x1be)) + i;
962 f3d54fc4 aliguori
        nr_sects = le32_to_cpu(p->nr_sects);
963 f3d54fc4 aliguori
        if (nr_sects && p->end_head) {
964 f3d54fc4 aliguori
            /* We make the assumption that the partition terminates on
965 f3d54fc4 aliguori
               a cylinder boundary */
966 f3d54fc4 aliguori
            heads = p->end_head + 1;
967 f3d54fc4 aliguori
            sectors = p->end_sector & 63;
968 f3d54fc4 aliguori
            if (sectors == 0)
969 f3d54fc4 aliguori
                continue;
970 f3d54fc4 aliguori
            cylinders = nb_sectors / (heads * sectors);
971 f3d54fc4 aliguori
            if (cylinders < 1 || cylinders > 16383)
972 f3d54fc4 aliguori
                continue;
973 f3d54fc4 aliguori
            *pheads = heads;
974 f3d54fc4 aliguori
            *psectors = sectors;
975 f3d54fc4 aliguori
            *pcylinders = cylinders;
976 f3d54fc4 aliguori
#if 0
977 f3d54fc4 aliguori
            printf("guessed geometry: LCHS=%d %d %d\n",
978 f3d54fc4 aliguori
                   cylinders, heads, sectors);
979 f3d54fc4 aliguori
#endif
980 f3d54fc4 aliguori
            return 0;
981 f3d54fc4 aliguori
        }
982 f3d54fc4 aliguori
    }
983 f3d54fc4 aliguori
    return -1;
984 f3d54fc4 aliguori
}
985 f3d54fc4 aliguori
986 f3d54fc4 aliguori
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
987 f3d54fc4 aliguori
{
988 f3d54fc4 aliguori
    int translation, lba_detected = 0;
989 f3d54fc4 aliguori
    int cylinders, heads, secs;
990 a38131b6 blueswir1
    uint64_t nb_sectors;
991 f3d54fc4 aliguori
992 f3d54fc4 aliguori
    /* if a geometry hint is available, use it */
993 f3d54fc4 aliguori
    bdrv_get_geometry(bs, &nb_sectors);
994 f3d54fc4 aliguori
    bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
995 f3d54fc4 aliguori
    translation = bdrv_get_translation_hint(bs);
996 f3d54fc4 aliguori
    if (cylinders != 0) {
997 f3d54fc4 aliguori
        *pcyls = cylinders;
998 f3d54fc4 aliguori
        *pheads = heads;
999 f3d54fc4 aliguori
        *psecs = secs;
1000 f3d54fc4 aliguori
    } else {
1001 f3d54fc4 aliguori
        if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1002 f3d54fc4 aliguori
            if (heads > 16) {
1003 f3d54fc4 aliguori
                /* if heads > 16, it means that a BIOS LBA
1004 f3d54fc4 aliguori
                   translation was active, so the default
1005 f3d54fc4 aliguori
                   hardware geometry is OK */
1006 f3d54fc4 aliguori
                lba_detected = 1;
1007 f3d54fc4 aliguori
                goto default_geometry;
1008 f3d54fc4 aliguori
            } else {
1009 f3d54fc4 aliguori
                *pcyls = cylinders;
1010 f3d54fc4 aliguori
                *pheads = heads;
1011 f3d54fc4 aliguori
                *psecs = secs;
1012 f3d54fc4 aliguori
                /* disable any translation to be in sync with
1013 f3d54fc4 aliguori
                   the logical geometry */
1014 f3d54fc4 aliguori
                if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1015 f3d54fc4 aliguori
                    bdrv_set_translation_hint(bs,
1016 f3d54fc4 aliguori
                                              BIOS_ATA_TRANSLATION_NONE);
1017 f3d54fc4 aliguori
                }
1018 f3d54fc4 aliguori
            }
1019 f3d54fc4 aliguori
        } else {
1020 f3d54fc4 aliguori
        default_geometry:
1021 f3d54fc4 aliguori
            /* if no geometry, use a standard physical disk geometry */
1022 f3d54fc4 aliguori
            cylinders = nb_sectors / (16 * 63);
1023 f3d54fc4 aliguori
1024 f3d54fc4 aliguori
            if (cylinders > 16383)
1025 f3d54fc4 aliguori
                cylinders = 16383;
1026 f3d54fc4 aliguori
            else if (cylinders < 2)
1027 f3d54fc4 aliguori
                cylinders = 2;
1028 f3d54fc4 aliguori
            *pcyls = cylinders;
1029 f3d54fc4 aliguori
            *pheads = 16;
1030 f3d54fc4 aliguori
            *psecs = 63;
1031 f3d54fc4 aliguori
            if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1032 f3d54fc4 aliguori
                if ((*pcyls * *pheads) <= 131072) {
1033 f3d54fc4 aliguori
                    bdrv_set_translation_hint(bs,
1034 f3d54fc4 aliguori
                                              BIOS_ATA_TRANSLATION_LARGE);
1035 f3d54fc4 aliguori
                } else {
1036 f3d54fc4 aliguori
                    bdrv_set_translation_hint(bs,
1037 f3d54fc4 aliguori
                                              BIOS_ATA_TRANSLATION_LBA);
1038 f3d54fc4 aliguori
                }
1039 f3d54fc4 aliguori
            }
1040 f3d54fc4 aliguori
        }
1041 f3d54fc4 aliguori
        bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1042 f3d54fc4 aliguori
    }
1043 f3d54fc4 aliguori
}
1044 f3d54fc4 aliguori
1045 5fafdf24 ths
void bdrv_set_geometry_hint(BlockDriverState *bs,
1046 b338082b bellard
                            int cyls, int heads, int secs)
1047 b338082b bellard
{
1048 b338082b bellard
    bs->cyls = cyls;
1049 b338082b bellard
    bs->heads = heads;
1050 b338082b bellard
    bs->secs = secs;
1051 b338082b bellard
}
1052 b338082b bellard
1053 b338082b bellard
void bdrv_set_type_hint(BlockDriverState *bs, int type)
1054 b338082b bellard
{
1055 b338082b bellard
    bs->type = type;
1056 b338082b bellard
    bs->removable = ((type == BDRV_TYPE_CDROM ||
1057 b338082b bellard
                      type == BDRV_TYPE_FLOPPY));
1058 b338082b bellard
}
1059 b338082b bellard
1060 46d4767d bellard
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
1061 46d4767d bellard
{
1062 46d4767d bellard
    bs->translation = translation;
1063 46d4767d bellard
}
1064 46d4767d bellard
1065 5fafdf24 ths
void bdrv_get_geometry_hint(BlockDriverState *bs,
1066 b338082b bellard
                            int *pcyls, int *pheads, int *psecs)
1067 b338082b bellard
{
1068 b338082b bellard
    *pcyls = bs->cyls;
1069 b338082b bellard
    *pheads = bs->heads;
1070 b338082b bellard
    *psecs = bs->secs;
1071 b338082b bellard
}
1072 b338082b bellard
1073 b338082b bellard
int bdrv_get_type_hint(BlockDriverState *bs)
1074 b338082b bellard
{
1075 b338082b bellard
    return bs->type;
1076 b338082b bellard
}
1077 b338082b bellard
1078 46d4767d bellard
int bdrv_get_translation_hint(BlockDriverState *bs)
1079 46d4767d bellard
{
1080 46d4767d bellard
    return bs->translation;
1081 46d4767d bellard
}
1082 46d4767d bellard
1083 b338082b bellard
int bdrv_is_removable(BlockDriverState *bs)
1084 b338082b bellard
{
1085 b338082b bellard
    return bs->removable;
1086 b338082b bellard
}
1087 b338082b bellard
1088 b338082b bellard
int bdrv_is_read_only(BlockDriverState *bs)
1089 b338082b bellard
{
1090 b338082b bellard
    return bs->read_only;
1091 b338082b bellard
}
1092 b338082b bellard
1093 985a03b0 ths
int bdrv_is_sg(BlockDriverState *bs)
1094 985a03b0 ths
{
1095 985a03b0 ths
    return bs->sg;
1096 985a03b0 ths
}
1097 985a03b0 ths
1098 e900a7b7 Christoph Hellwig
int bdrv_enable_write_cache(BlockDriverState *bs)
1099 e900a7b7 Christoph Hellwig
{
1100 e900a7b7 Christoph Hellwig
    return bs->enable_write_cache;
1101 e900a7b7 Christoph Hellwig
}
1102 e900a7b7 Christoph Hellwig
1103 19cb3738 bellard
/* XXX: no longer used */
1104 5fafdf24 ths
void bdrv_set_change_cb(BlockDriverState *bs,
1105 b338082b bellard
                        void (*change_cb)(void *opaque), void *opaque)
1106 b338082b bellard
{
1107 b338082b bellard
    bs->change_cb = change_cb;
1108 b338082b bellard
    bs->change_opaque = opaque;
1109 b338082b bellard
}
1110 b338082b bellard
1111 ea2384d3 bellard
int bdrv_is_encrypted(BlockDriverState *bs)
1112 ea2384d3 bellard
{
1113 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted)
1114 ea2384d3 bellard
        return 1;
1115 ea2384d3 bellard
    return bs->encrypted;
1116 ea2384d3 bellard
}
1117 ea2384d3 bellard
1118 c0f4ce77 aliguori
int bdrv_key_required(BlockDriverState *bs)
1119 c0f4ce77 aliguori
{
1120 c0f4ce77 aliguori
    BlockDriverState *backing_hd = bs->backing_hd;
1121 c0f4ce77 aliguori
1122 c0f4ce77 aliguori
    if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1123 c0f4ce77 aliguori
        return 1;
1124 c0f4ce77 aliguori
    return (bs->encrypted && !bs->valid_key);
1125 c0f4ce77 aliguori
}
1126 c0f4ce77 aliguori
1127 ea2384d3 bellard
int bdrv_set_key(BlockDriverState *bs, const char *key)
1128 ea2384d3 bellard
{
1129 ea2384d3 bellard
    int ret;
1130 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted) {
1131 ea2384d3 bellard
        ret = bdrv_set_key(bs->backing_hd, key);
1132 ea2384d3 bellard
        if (ret < 0)
1133 ea2384d3 bellard
            return ret;
1134 ea2384d3 bellard
        if (!bs->encrypted)
1135 ea2384d3 bellard
            return 0;
1136 ea2384d3 bellard
    }
1137 fd04a2ae Shahar Havivi
    if (!bs->encrypted) {
1138 fd04a2ae Shahar Havivi
        return -EINVAL;
1139 fd04a2ae Shahar Havivi
    } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1140 fd04a2ae Shahar Havivi
        return -ENOMEDIUM;
1141 fd04a2ae Shahar Havivi
    }
1142 c0f4ce77 aliguori
    ret = bs->drv->bdrv_set_key(bs, key);
1143 bb5fc20f aliguori
    if (ret < 0) {
1144 bb5fc20f aliguori
        bs->valid_key = 0;
1145 bb5fc20f aliguori
    } else if (!bs->valid_key) {
1146 bb5fc20f aliguori
        bs->valid_key = 1;
1147 bb5fc20f aliguori
        /* call the change callback now, we skipped it on open */
1148 bb5fc20f aliguori
        bs->media_changed = 1;
1149 bb5fc20f aliguori
        if (bs->change_cb)
1150 bb5fc20f aliguori
            bs->change_cb(bs->change_opaque);
1151 bb5fc20f aliguori
    }
1152 c0f4ce77 aliguori
    return ret;
1153 ea2384d3 bellard
}
1154 ea2384d3 bellard
1155 ea2384d3 bellard
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1156 ea2384d3 bellard
{
1157 19cb3738 bellard
    if (!bs->drv) {
1158 ea2384d3 bellard
        buf[0] = '\0';
1159 ea2384d3 bellard
    } else {
1160 ea2384d3 bellard
        pstrcpy(buf, buf_size, bs->drv->format_name);
1161 ea2384d3 bellard
    }
1162 ea2384d3 bellard
}
1163 ea2384d3 bellard
1164 5fafdf24 ths
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1165 ea2384d3 bellard
                         void *opaque)
1166 ea2384d3 bellard
{
1167 ea2384d3 bellard
    BlockDriver *drv;
1168 ea2384d3 bellard
1169 ea2384d3 bellard
    for (drv = first_drv; drv != NULL; drv = drv->next) {
1170 ea2384d3 bellard
        it(opaque, drv->format_name);
1171 ea2384d3 bellard
    }
1172 ea2384d3 bellard
}
1173 ea2384d3 bellard
1174 b338082b bellard
BlockDriverState *bdrv_find(const char *name)
1175 b338082b bellard
{
1176 b338082b bellard
    BlockDriverState *bs;
1177 b338082b bellard
1178 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1179 b338082b bellard
        if (!strcmp(name, bs->device_name))
1180 b338082b bellard
            return bs;
1181 b338082b bellard
    }
1182 b338082b bellard
    return NULL;
1183 b338082b bellard
}
1184 b338082b bellard
1185 51de9760 aliguori
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1186 81d0912d bellard
{
1187 81d0912d bellard
    BlockDriverState *bs;
1188 81d0912d bellard
1189 81d0912d bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1190 51de9760 aliguori
        it(opaque, bs);
1191 81d0912d bellard
    }
1192 81d0912d bellard
}
1193 81d0912d bellard
1194 ea2384d3 bellard
const char *bdrv_get_device_name(BlockDriverState *bs)
1195 ea2384d3 bellard
{
1196 ea2384d3 bellard
    return bs->device_name;
1197 ea2384d3 bellard
}
1198 ea2384d3 bellard
1199 7a6cba61 pbrook
void bdrv_flush(BlockDriverState *bs)
1200 7a6cba61 pbrook
{
1201 3f5075ae Christoph Hellwig
    if (bs->drv && bs->drv->bdrv_flush)
1202 7a6cba61 pbrook
        bs->drv->bdrv_flush(bs);
1203 7a6cba61 pbrook
}
1204 7a6cba61 pbrook
1205 c6ca28d6 aliguori
void bdrv_flush_all(void)
1206 c6ca28d6 aliguori
{
1207 c6ca28d6 aliguori
    BlockDriverState *bs;
1208 c6ca28d6 aliguori
1209 c6ca28d6 aliguori
    for (bs = bdrv_first; bs != NULL; bs = bs->next)
1210 c6ca28d6 aliguori
        if (bs->drv && !bdrv_is_read_only(bs) && 
1211 c6ca28d6 aliguori
            (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
1212 c6ca28d6 aliguori
            bdrv_flush(bs);
1213 c6ca28d6 aliguori
}
1214 c6ca28d6 aliguori
1215 f58c7b35 ths
/*
1216 f58c7b35 ths
 * Returns true iff the specified sector is present in the disk image. Drivers
1217 f58c7b35 ths
 * not implementing the functionality are assumed to not support backing files,
1218 f58c7b35 ths
 * hence all their sectors are reported as allocated.
1219 f58c7b35 ths
 *
1220 f58c7b35 ths
 * 'pnum' is set to the number of sectors (including and immediately following
1221 f58c7b35 ths
 * the specified sector) that are known to be in the same
1222 f58c7b35 ths
 * allocated/unallocated state.
1223 f58c7b35 ths
 *
1224 f58c7b35 ths
 * 'nb_sectors' is the max value 'pnum' should be set to.
1225 f58c7b35 ths
 */
1226 f58c7b35 ths
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1227 f58c7b35 ths
        int *pnum)
1228 f58c7b35 ths
{
1229 f58c7b35 ths
    int64_t n;
1230 f58c7b35 ths
    if (!bs->drv->bdrv_is_allocated) {
1231 f58c7b35 ths
        if (sector_num >= bs->total_sectors) {
1232 f58c7b35 ths
            *pnum = 0;
1233 f58c7b35 ths
            return 0;
1234 f58c7b35 ths
        }
1235 f58c7b35 ths
        n = bs->total_sectors - sector_num;
1236 f58c7b35 ths
        *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1237 f58c7b35 ths
        return 1;
1238 f58c7b35 ths
    }
1239 f58c7b35 ths
    return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1240 f58c7b35 ths
}
1241 f58c7b35 ths
1242 2582bfed Luiz Capitulino
void bdrv_mon_event(const BlockDriverState *bdrv,
1243 2582bfed Luiz Capitulino
                    BlockMonEventAction action, int is_read)
1244 2582bfed Luiz Capitulino
{
1245 2582bfed Luiz Capitulino
    QObject *data;
1246 2582bfed Luiz Capitulino
    const char *action_str;
1247 2582bfed Luiz Capitulino
1248 2582bfed Luiz Capitulino
    switch (action) {
1249 2582bfed Luiz Capitulino
    case BDRV_ACTION_REPORT:
1250 2582bfed Luiz Capitulino
        action_str = "report";
1251 2582bfed Luiz Capitulino
        break;
1252 2582bfed Luiz Capitulino
    case BDRV_ACTION_IGNORE:
1253 2582bfed Luiz Capitulino
        action_str = "ignore";
1254 2582bfed Luiz Capitulino
        break;
1255 2582bfed Luiz Capitulino
    case BDRV_ACTION_STOP:
1256 2582bfed Luiz Capitulino
        action_str = "stop";
1257 2582bfed Luiz Capitulino
        break;
1258 2582bfed Luiz Capitulino
    default:
1259 2582bfed Luiz Capitulino
        abort();
1260 2582bfed Luiz Capitulino
    }
1261 2582bfed Luiz Capitulino
1262 2582bfed Luiz Capitulino
    data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
1263 2582bfed Luiz Capitulino
                              bdrv->device_name,
1264 2582bfed Luiz Capitulino
                              action_str,
1265 2582bfed Luiz Capitulino
                              is_read ? "read" : "write");
1266 2582bfed Luiz Capitulino
    monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
1267 2582bfed Luiz Capitulino
1268 2582bfed Luiz Capitulino
    qobject_decref(data);
1269 2582bfed Luiz Capitulino
}
1270 2582bfed Luiz Capitulino
1271 d15e5465 Luiz Capitulino
static void bdrv_print_dict(QObject *obj, void *opaque)
1272 b338082b bellard
{
1273 d15e5465 Luiz Capitulino
    QDict *bs_dict;
1274 d15e5465 Luiz Capitulino
    Monitor *mon = opaque;
1275 d15e5465 Luiz Capitulino
1276 d15e5465 Luiz Capitulino
    bs_dict = qobject_to_qdict(obj);
1277 d15e5465 Luiz Capitulino
1278 d15e5465 Luiz Capitulino
    monitor_printf(mon, "%s: type=%s removable=%d",
1279 d15e5465 Luiz Capitulino
                        qdict_get_str(bs_dict, "device"),
1280 d15e5465 Luiz Capitulino
                        qdict_get_str(bs_dict, "type"),
1281 d15e5465 Luiz Capitulino
                        qdict_get_bool(bs_dict, "removable"));
1282 d15e5465 Luiz Capitulino
1283 d15e5465 Luiz Capitulino
    if (qdict_get_bool(bs_dict, "removable")) {
1284 d15e5465 Luiz Capitulino
        monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
1285 d15e5465 Luiz Capitulino
    }
1286 d15e5465 Luiz Capitulino
1287 d15e5465 Luiz Capitulino
    if (qdict_haskey(bs_dict, "inserted")) {
1288 d15e5465 Luiz Capitulino
        QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
1289 d15e5465 Luiz Capitulino
1290 d15e5465 Luiz Capitulino
        monitor_printf(mon, " file=");
1291 d15e5465 Luiz Capitulino
        monitor_print_filename(mon, qdict_get_str(qdict, "file"));
1292 d15e5465 Luiz Capitulino
        if (qdict_haskey(qdict, "backing_file")) {
1293 d15e5465 Luiz Capitulino
            monitor_printf(mon, " backing_file=");
1294 d15e5465 Luiz Capitulino
            monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
1295 d15e5465 Luiz Capitulino
        }
1296 d15e5465 Luiz Capitulino
        monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
1297 d15e5465 Luiz Capitulino
                            qdict_get_bool(qdict, "ro"),
1298 d15e5465 Luiz Capitulino
                            qdict_get_str(qdict, "drv"),
1299 d15e5465 Luiz Capitulino
                            qdict_get_bool(qdict, "encrypted"));
1300 d15e5465 Luiz Capitulino
    } else {
1301 d15e5465 Luiz Capitulino
        monitor_printf(mon, " [not inserted]");
1302 d15e5465 Luiz Capitulino
    }
1303 d15e5465 Luiz Capitulino
1304 d15e5465 Luiz Capitulino
    monitor_printf(mon, "\n");
1305 d15e5465 Luiz Capitulino
}
1306 d15e5465 Luiz Capitulino
1307 d15e5465 Luiz Capitulino
void bdrv_info_print(Monitor *mon, const QObject *data)
1308 d15e5465 Luiz Capitulino
{
1309 d15e5465 Luiz Capitulino
    qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
1310 d15e5465 Luiz Capitulino
}
1311 d15e5465 Luiz Capitulino
1312 d15e5465 Luiz Capitulino
/**
1313 d15e5465 Luiz Capitulino
 * bdrv_info(): Block devices information
1314 d15e5465 Luiz Capitulino
 *
1315 d15e5465 Luiz Capitulino
 * Each block device information is stored in a QDict and the
1316 d15e5465 Luiz Capitulino
 * returned QObject is a QList of all devices.
1317 d15e5465 Luiz Capitulino
 *
1318 d15e5465 Luiz Capitulino
 * The QDict contains the following:
1319 d15e5465 Luiz Capitulino
 *
1320 d15e5465 Luiz Capitulino
 * - "device": device name
1321 d15e5465 Luiz Capitulino
 * - "type": device type
1322 d15e5465 Luiz Capitulino
 * - "removable": true if the device is removable, false otherwise
1323 d15e5465 Luiz Capitulino
 * - "locked": true if the device is locked, false otherwise
1324 d15e5465 Luiz Capitulino
 * - "inserted": only present if the device is inserted, it is a QDict
1325 d15e5465 Luiz Capitulino
 *    containing the following:
1326 d15e5465 Luiz Capitulino
 *          - "file": device file name
1327 d15e5465 Luiz Capitulino
 *          - "ro": true if read-only, false otherwise
1328 d15e5465 Luiz Capitulino
 *          - "drv": driver format name
1329 d15e5465 Luiz Capitulino
 *          - "backing_file": backing file name if one is used
1330 d15e5465 Luiz Capitulino
 *          - "encrypted": true if encrypted, false otherwise
1331 d15e5465 Luiz Capitulino
 *
1332 d15e5465 Luiz Capitulino
 * Example:
1333 d15e5465 Luiz Capitulino
 *
1334 d15e5465 Luiz Capitulino
 * [ { "device": "ide0-hd0", "type": "hd", "removable": false, "locked": false,
1335 d15e5465 Luiz Capitulino
 *     "inserted": { "file": "/tmp/foobar", "ro": false, "drv": "qcow2" } },
1336 d15e5465 Luiz Capitulino
 *   { "device": "floppy0", "type": "floppy", "removable": true,
1337 d15e5465 Luiz Capitulino
 *     "locked": false } ]
1338 d15e5465 Luiz Capitulino
 */
1339 d15e5465 Luiz Capitulino
void bdrv_info(Monitor *mon, QObject **ret_data)
1340 d15e5465 Luiz Capitulino
{
1341 d15e5465 Luiz Capitulino
    QList *bs_list;
1342 b338082b bellard
    BlockDriverState *bs;
1343 b338082b bellard
1344 d15e5465 Luiz Capitulino
    bs_list = qlist_new();
1345 d15e5465 Luiz Capitulino
1346 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1347 d15e5465 Luiz Capitulino
        QObject *bs_obj;
1348 d15e5465 Luiz Capitulino
        const char *type = "unknown";
1349 d15e5465 Luiz Capitulino
1350 b338082b bellard
        switch(bs->type) {
1351 b338082b bellard
        case BDRV_TYPE_HD:
1352 d15e5465 Luiz Capitulino
            type = "hd";
1353 b338082b bellard
            break;
1354 b338082b bellard
        case BDRV_TYPE_CDROM:
1355 d15e5465 Luiz Capitulino
            type = "cdrom";
1356 b338082b bellard
            break;
1357 b338082b bellard
        case BDRV_TYPE_FLOPPY:
1358 d15e5465 Luiz Capitulino
            type = "floppy";
1359 b338082b bellard
            break;
1360 b338082b bellard
        }
1361 d15e5465 Luiz Capitulino
1362 d15e5465 Luiz Capitulino
        bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
1363 d15e5465 Luiz Capitulino
                                    "'removable': %i, 'locked': %i }",
1364 d15e5465 Luiz Capitulino
                                    bs->device_name, type, bs->removable,
1365 d15e5465 Luiz Capitulino
                                    bs->locked);
1366 d15e5465 Luiz Capitulino
1367 19cb3738 bellard
        if (bs->drv) {
1368 d15e5465 Luiz Capitulino
            QObject *obj;
1369 d15e5465 Luiz Capitulino
            QDict *bs_dict = qobject_to_qdict(bs_obj);
1370 d15e5465 Luiz Capitulino
1371 d15e5465 Luiz Capitulino
            obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
1372 d15e5465 Luiz Capitulino
                                     "'encrypted': %i }",
1373 d15e5465 Luiz Capitulino
                                     bs->filename, bs->read_only,
1374 d15e5465 Luiz Capitulino
                                     bs->drv->format_name,
1375 d15e5465 Luiz Capitulino
                                     bdrv_is_encrypted(bs));
1376 fef30743 ths
            if (bs->backing_file[0] != '\0') {
1377 d15e5465 Luiz Capitulino
                QDict *qdict = qobject_to_qdict(obj);
1378 d15e5465 Luiz Capitulino
                qdict_put(qdict, "backing_file",
1379 d15e5465 Luiz Capitulino
                          qstring_from_str(bs->backing_file));
1380 376253ec aliguori
            }
1381 d15e5465 Luiz Capitulino
1382 d15e5465 Luiz Capitulino
            qdict_put_obj(bs_dict, "inserted", obj);
1383 b338082b bellard
        }
1384 d15e5465 Luiz Capitulino
        qlist_append_obj(bs_list, bs_obj);
1385 b338082b bellard
    }
1386 d15e5465 Luiz Capitulino
1387 d15e5465 Luiz Capitulino
    *ret_data = QOBJECT(bs_list);
1388 b338082b bellard
}
1389 a36e69dd ths
1390 218a536a Luiz Capitulino
static void bdrv_stats_iter(QObject *data, void *opaque)
1391 a36e69dd ths
{
1392 218a536a Luiz Capitulino
    QDict *qdict;
1393 218a536a Luiz Capitulino
    Monitor *mon = opaque;
1394 218a536a Luiz Capitulino
1395 218a536a Luiz Capitulino
    qdict = qobject_to_qdict(data);
1396 218a536a Luiz Capitulino
    monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
1397 218a536a Luiz Capitulino
1398 218a536a Luiz Capitulino
    qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
1399 218a536a Luiz Capitulino
    monitor_printf(mon, " rd_bytes=%" PRId64
1400 218a536a Luiz Capitulino
                        " wr_bytes=%" PRId64
1401 218a536a Luiz Capitulino
                        " rd_operations=%" PRId64
1402 218a536a Luiz Capitulino
                        " wr_operations=%" PRId64
1403 218a536a Luiz Capitulino
                        "\n",
1404 218a536a Luiz Capitulino
                        qdict_get_int(qdict, "rd_bytes"),
1405 218a536a Luiz Capitulino
                        qdict_get_int(qdict, "wr_bytes"),
1406 218a536a Luiz Capitulino
                        qdict_get_int(qdict, "rd_operations"),
1407 218a536a Luiz Capitulino
                        qdict_get_int(qdict, "wr_operations"));
1408 218a536a Luiz Capitulino
}
1409 218a536a Luiz Capitulino
1410 218a536a Luiz Capitulino
void bdrv_stats_print(Monitor *mon, const QObject *data)
1411 218a536a Luiz Capitulino
{
1412 218a536a Luiz Capitulino
    qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
1413 218a536a Luiz Capitulino
}
1414 218a536a Luiz Capitulino
1415 218a536a Luiz Capitulino
/**
1416 218a536a Luiz Capitulino
 * bdrv_info_stats(): show block device statistics
1417 218a536a Luiz Capitulino
 *
1418 218a536a Luiz Capitulino
 * Each device statistic information is stored in a QDict and
1419 218a536a Luiz Capitulino
 * the returned QObject is a QList of all devices.
1420 218a536a Luiz Capitulino
 *
1421 218a536a Luiz Capitulino
 * The QDict contains the following:
1422 218a536a Luiz Capitulino
 *
1423 218a536a Luiz Capitulino
 * - "device": device name
1424 218a536a Luiz Capitulino
 * - "stats": A QDict with the statistics information, it contains:
1425 218a536a Luiz Capitulino
 *     - "rd_bytes": bytes read
1426 218a536a Luiz Capitulino
 *     - "wr_bytes": bytes written
1427 218a536a Luiz Capitulino
 *     - "rd_operations": read operations
1428 218a536a Luiz Capitulino
 *     - "wr_operations": write operations
1429 218a536a Luiz Capitulino
 * 
1430 218a536a Luiz Capitulino
 * Example:
1431 218a536a Luiz Capitulino
 *
1432 218a536a Luiz Capitulino
 * [ { "device": "ide0-hd0",
1433 218a536a Luiz Capitulino
 *               "stats": { "rd_bytes": 512,
1434 218a536a Luiz Capitulino
 *                          "wr_bytes": 0,
1435 218a536a Luiz Capitulino
 *                          "rd_operations": 1,
1436 218a536a Luiz Capitulino
 *                          "wr_operations": 0 } },
1437 218a536a Luiz Capitulino
 *   { "device": "ide1-cd0",
1438 218a536a Luiz Capitulino
 *               "stats": { "rd_bytes": 0,
1439 218a536a Luiz Capitulino
 *                          "wr_bytes": 0,
1440 218a536a Luiz Capitulino
 *                          "rd_operations": 0,
1441 218a536a Luiz Capitulino
 *                          "wr_operations": 0 } } ]
1442 218a536a Luiz Capitulino
 */
1443 218a536a Luiz Capitulino
void bdrv_info_stats(Monitor *mon, QObject **ret_data)
1444 218a536a Luiz Capitulino
{
1445 218a536a Luiz Capitulino
    QObject *obj;
1446 218a536a Luiz Capitulino
    QList *devices;
1447 a36e69dd ths
    BlockDriverState *bs;
1448 a36e69dd ths
1449 218a536a Luiz Capitulino
    devices = qlist_new();
1450 218a536a Luiz Capitulino
1451 a36e69dd ths
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1452 218a536a Luiz Capitulino
        obj = qobject_from_jsonf("{ 'device': %s, 'stats': {"
1453 218a536a Luiz Capitulino
                                 "'rd_bytes': %" PRId64 ","
1454 218a536a Luiz Capitulino
                                 "'wr_bytes': %" PRId64 ","
1455 218a536a Luiz Capitulino
                                 "'rd_operations': %" PRId64 ","
1456 218a536a Luiz Capitulino
                                 "'wr_operations': %" PRId64
1457 218a536a Luiz Capitulino
                                 "} }",
1458 218a536a Luiz Capitulino
                                 bs->device_name,
1459 218a536a Luiz Capitulino
                                 bs->rd_bytes, bs->wr_bytes,
1460 218a536a Luiz Capitulino
                                 bs->rd_ops, bs->wr_ops);
1461 218a536a Luiz Capitulino
        qlist_append_obj(devices, obj);
1462 a36e69dd ths
    }
1463 218a536a Luiz Capitulino
1464 218a536a Luiz Capitulino
    *ret_data = QOBJECT(devices);
1465 a36e69dd ths
}
1466 ea2384d3 bellard
1467 045df330 aliguori
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1468 045df330 aliguori
{
1469 045df330 aliguori
    if (bs->backing_hd && bs->backing_hd->encrypted)
1470 045df330 aliguori
        return bs->backing_file;
1471 045df330 aliguori
    else if (bs->encrypted)
1472 045df330 aliguori
        return bs->filename;
1473 045df330 aliguori
    else
1474 045df330 aliguori
        return NULL;
1475 045df330 aliguori
}
1476 045df330 aliguori
1477 5fafdf24 ths
void bdrv_get_backing_filename(BlockDriverState *bs,
1478 83f64091 bellard
                               char *filename, int filename_size)
1479 83f64091 bellard
{
1480 b783e409 Kevin Wolf
    if (!bs->backing_file) {
1481 83f64091 bellard
        pstrcpy(filename, filename_size, "");
1482 83f64091 bellard
    } else {
1483 83f64091 bellard
        pstrcpy(filename, filename_size, bs->backing_file);
1484 83f64091 bellard
    }
1485 83f64091 bellard
}
1486 83f64091 bellard
1487 5fafdf24 ths
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1488 faea38e7 bellard
                          const uint8_t *buf, int nb_sectors)
1489 faea38e7 bellard
{
1490 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1491 faea38e7 bellard
    if (!drv)
1492 19cb3738 bellard
        return -ENOMEDIUM;
1493 faea38e7 bellard
    if (!drv->bdrv_write_compressed)
1494 faea38e7 bellard
        return -ENOTSUP;
1495 fbb7b4e0 Kevin Wolf
    if (bdrv_check_request(bs, sector_num, nb_sectors))
1496 fbb7b4e0 Kevin Wolf
        return -EIO;
1497 a55eb92c Jan Kiszka
1498 c6d22830 Jan Kiszka
    if (bs->dirty_bitmap) {
1499 7cd1e32a lirans@il.ibm.com
        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1500 7cd1e32a lirans@il.ibm.com
    }
1501 a55eb92c Jan Kiszka
1502 faea38e7 bellard
    return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
1503 faea38e7 bellard
}
1504 3b46e624 ths
1505 faea38e7 bellard
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1506 faea38e7 bellard
{
1507 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1508 faea38e7 bellard
    if (!drv)
1509 19cb3738 bellard
        return -ENOMEDIUM;
1510 faea38e7 bellard
    if (!drv->bdrv_get_info)
1511 faea38e7 bellard
        return -ENOTSUP;
1512 faea38e7 bellard
    memset(bdi, 0, sizeof(*bdi));
1513 faea38e7 bellard
    return drv->bdrv_get_info(bs, bdi);
1514 faea38e7 bellard
}
1515 faea38e7 bellard
1516 45566e9c Christoph Hellwig
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
1517 45566e9c Christoph Hellwig
                      int64_t pos, int size)
1518 178e08a5 aliguori
{
1519 178e08a5 aliguori
    BlockDriver *drv = bs->drv;
1520 178e08a5 aliguori
    if (!drv)
1521 178e08a5 aliguori
        return -ENOMEDIUM;
1522 45566e9c Christoph Hellwig
    if (!drv->bdrv_save_vmstate)
1523 178e08a5 aliguori
        return -ENOTSUP;
1524 45566e9c Christoph Hellwig
    return drv->bdrv_save_vmstate(bs, buf, pos, size);
1525 178e08a5 aliguori
}
1526 178e08a5 aliguori
1527 45566e9c Christoph Hellwig
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
1528 45566e9c Christoph Hellwig
                      int64_t pos, int size)
1529 178e08a5 aliguori
{
1530 178e08a5 aliguori
    BlockDriver *drv = bs->drv;
1531 178e08a5 aliguori
    if (!drv)
1532 178e08a5 aliguori
        return -ENOMEDIUM;
1533 45566e9c Christoph Hellwig
    if (!drv->bdrv_load_vmstate)
1534 178e08a5 aliguori
        return -ENOTSUP;
1535 45566e9c Christoph Hellwig
    return drv->bdrv_load_vmstate(bs, buf, pos, size);
1536 178e08a5 aliguori
}
1537 178e08a5 aliguori
1538 faea38e7 bellard
/**************************************************************/
1539 faea38e7 bellard
/* handling of snapshots */
1540 faea38e7 bellard
1541 5fafdf24 ths
int bdrv_snapshot_create(BlockDriverState *bs,
1542 faea38e7 bellard
                         QEMUSnapshotInfo *sn_info)
1543 faea38e7 bellard
{
1544 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1545 faea38e7 bellard
    if (!drv)
1546 19cb3738 bellard
        return -ENOMEDIUM;
1547 faea38e7 bellard
    if (!drv->bdrv_snapshot_create)
1548 faea38e7 bellard
        return -ENOTSUP;
1549 faea38e7 bellard
    return drv->bdrv_snapshot_create(bs, sn_info);
1550 faea38e7 bellard
}
1551 faea38e7 bellard
1552 5fafdf24 ths
int bdrv_snapshot_goto(BlockDriverState *bs,
1553 faea38e7 bellard
                       const char *snapshot_id)
1554 faea38e7 bellard
{
1555 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1556 faea38e7 bellard
    if (!drv)
1557 19cb3738 bellard
        return -ENOMEDIUM;
1558 faea38e7 bellard
    if (!drv->bdrv_snapshot_goto)
1559 faea38e7 bellard
        return -ENOTSUP;
1560 faea38e7 bellard
    return drv->bdrv_snapshot_goto(bs, snapshot_id);
1561 faea38e7 bellard
}
1562 faea38e7 bellard
1563 faea38e7 bellard
int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1564 faea38e7 bellard
{
1565 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1566 faea38e7 bellard
    if (!drv)
1567 19cb3738 bellard
        return -ENOMEDIUM;
1568 faea38e7 bellard
    if (!drv->bdrv_snapshot_delete)
1569 faea38e7 bellard
        return -ENOTSUP;
1570 faea38e7 bellard
    return drv->bdrv_snapshot_delete(bs, snapshot_id);
1571 faea38e7 bellard
}
1572 faea38e7 bellard
1573 5fafdf24 ths
int bdrv_snapshot_list(BlockDriverState *bs,
1574 faea38e7 bellard
                       QEMUSnapshotInfo **psn_info)
1575 faea38e7 bellard
{
1576 faea38e7 bellard
    BlockDriver *drv = bs->drv;
1577 faea38e7 bellard
    if (!drv)
1578 19cb3738 bellard
        return -ENOMEDIUM;
1579 faea38e7 bellard
    if (!drv->bdrv_snapshot_list)
1580 faea38e7 bellard
        return -ENOTSUP;
1581 faea38e7 bellard
    return drv->bdrv_snapshot_list(bs, psn_info);
1582 faea38e7 bellard
}
1583 faea38e7 bellard
1584 faea38e7 bellard
#define NB_SUFFIXES 4
1585 faea38e7 bellard
1586 faea38e7 bellard
char *get_human_readable_size(char *buf, int buf_size, int64_t size)
1587 faea38e7 bellard
{
1588 faea38e7 bellard
    static const char suffixes[NB_SUFFIXES] = "KMGT";
1589 faea38e7 bellard
    int64_t base;
1590 faea38e7 bellard
    int i;
1591 faea38e7 bellard
1592 faea38e7 bellard
    if (size <= 999) {
1593 faea38e7 bellard
        snprintf(buf, buf_size, "%" PRId64, size);
1594 faea38e7 bellard
    } else {
1595 faea38e7 bellard
        base = 1024;
1596 faea38e7 bellard
        for(i = 0; i < NB_SUFFIXES; i++) {
1597 faea38e7 bellard
            if (size < (10 * base)) {
1598 5fafdf24 ths
                snprintf(buf, buf_size, "%0.1f%c",
1599 faea38e7 bellard
                         (double)size / base,
1600 faea38e7 bellard
                         suffixes[i]);
1601 faea38e7 bellard
                break;
1602 faea38e7 bellard
            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1603 5fafdf24 ths
                snprintf(buf, buf_size, "%" PRId64 "%c",
1604 faea38e7 bellard
                         ((size + (base >> 1)) / base),
1605 faea38e7 bellard
                         suffixes[i]);
1606 faea38e7 bellard
                break;
1607 faea38e7 bellard
            }
1608 faea38e7 bellard
            base = base * 1024;
1609 faea38e7 bellard
        }
1610 faea38e7 bellard
    }
1611 faea38e7 bellard
    return buf;
1612 faea38e7 bellard
}
1613 faea38e7 bellard
1614 faea38e7 bellard
char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1615 faea38e7 bellard
{
1616 faea38e7 bellard
    char buf1[128], date_buf[128], clock_buf[128];
1617 3b9f94e1 bellard
#ifdef _WIN32
1618 3b9f94e1 bellard
    struct tm *ptm;
1619 3b9f94e1 bellard
#else
1620 faea38e7 bellard
    struct tm tm;
1621 3b9f94e1 bellard
#endif
1622 faea38e7 bellard
    time_t ti;
1623 faea38e7 bellard
    int64_t secs;
1624 faea38e7 bellard
1625 faea38e7 bellard
    if (!sn) {
1626 5fafdf24 ths
        snprintf(buf, buf_size,
1627 5fafdf24 ths
                 "%-10s%-20s%7s%20s%15s",
1628 faea38e7 bellard
                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1629 faea38e7 bellard
    } else {
1630 faea38e7 bellard
        ti = sn->date_sec;
1631 3b9f94e1 bellard
#ifdef _WIN32
1632 3b9f94e1 bellard
        ptm = localtime(&ti);
1633 3b9f94e1 bellard
        strftime(date_buf, sizeof(date_buf),
1634 3b9f94e1 bellard
                 "%Y-%m-%d %H:%M:%S", ptm);
1635 3b9f94e1 bellard
#else
1636 faea38e7 bellard
        localtime_r(&ti, &tm);
1637 faea38e7 bellard
        strftime(date_buf, sizeof(date_buf),
1638 faea38e7 bellard
                 "%Y-%m-%d %H:%M:%S", &tm);
1639 3b9f94e1 bellard
#endif
1640 faea38e7 bellard
        secs = sn->vm_clock_nsec / 1000000000;
1641 faea38e7 bellard
        snprintf(clock_buf, sizeof(clock_buf),
1642 faea38e7 bellard
                 "%02d:%02d:%02d.%03d",
1643 faea38e7 bellard
                 (int)(secs / 3600),
1644 faea38e7 bellard
                 (int)((secs / 60) % 60),
1645 5fafdf24 ths
                 (int)(secs % 60),
1646 faea38e7 bellard
                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
1647 faea38e7 bellard
        snprintf(buf, buf_size,
1648 5fafdf24 ths
                 "%-10s%-20s%7s%20s%15s",
1649 faea38e7 bellard
                 sn->id_str, sn->name,
1650 faea38e7 bellard
                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1651 faea38e7 bellard
                 date_buf,
1652 faea38e7 bellard
                 clock_buf);
1653 faea38e7 bellard
    }
1654 faea38e7 bellard
    return buf;
1655 faea38e7 bellard
}
1656 faea38e7 bellard
1657 83f64091 bellard
1658 ea2384d3 bellard
/**************************************************************/
1659 83f64091 bellard
/* async I/Os */
1660 ea2384d3 bellard
1661 3b69e4b9 aliguori
BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
1662 f141eafe aliguori
                                 QEMUIOVector *qiov, int nb_sectors,
1663 3b69e4b9 aliguori
                                 BlockDriverCompletionFunc *cb, void *opaque)
1664 3b69e4b9 aliguori
{
1665 83f64091 bellard
    BlockDriver *drv = bs->drv;
1666 a36e69dd ths
    BlockDriverAIOCB *ret;
1667 83f64091 bellard
1668 19cb3738 bellard
    if (!drv)
1669 ce1a14dc pbrook
        return NULL;
1670 71d0770c aliguori
    if (bdrv_check_request(bs, sector_num, nb_sectors))
1671 71d0770c aliguori
        return NULL;
1672 3b46e624 ths
1673 f141eafe aliguori
    ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
1674 f141eafe aliguori
                              cb, opaque);
1675 a36e69dd ths
1676 a36e69dd ths
    if (ret) {
1677 a36e69dd ths
        /* Update stats even though technically transfer has not happened. */
1678 6ea44308 Jan Kiszka
        bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
1679 a36e69dd ths
        bs->rd_ops ++;
1680 a36e69dd ths
    }
1681 a36e69dd ths
1682 a36e69dd ths
    return ret;
1683 ea2384d3 bellard
}
1684 ea2384d3 bellard
1685 f141eafe aliguori
BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
1686 f141eafe aliguori
                                  QEMUIOVector *qiov, int nb_sectors,
1687 f141eafe aliguori
                                  BlockDriverCompletionFunc *cb, void *opaque)
1688 ea2384d3 bellard
{
1689 83f64091 bellard
    BlockDriver *drv = bs->drv;
1690 a36e69dd ths
    BlockDriverAIOCB *ret;
1691 ea2384d3 bellard
1692 19cb3738 bellard
    if (!drv)
1693 ce1a14dc pbrook
        return NULL;
1694 83f64091 bellard
    if (bs->read_only)
1695 ce1a14dc pbrook
        return NULL;
1696 71d0770c aliguori
    if (bdrv_check_request(bs, sector_num, nb_sectors))
1697 71d0770c aliguori
        return NULL;
1698 83f64091 bellard
1699 c6d22830 Jan Kiszka
    if (bs->dirty_bitmap) {
1700 7cd1e32a lirans@il.ibm.com
        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1701 7cd1e32a lirans@il.ibm.com
    }
1702 a55eb92c Jan Kiszka
1703 f141eafe aliguori
    ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
1704 f141eafe aliguori
                               cb, opaque);
1705 a36e69dd ths
1706 a36e69dd ths
    if (ret) {
1707 a36e69dd ths
        /* Update stats even though technically transfer has not happened. */
1708 6ea44308 Jan Kiszka
        bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
1709 a36e69dd ths
        bs->wr_ops ++;
1710 a36e69dd ths
    }
1711 a36e69dd ths
1712 a36e69dd ths
    return ret;
1713 83f64091 bellard
}
1714 83f64091 bellard
1715 40b4f539 Kevin Wolf
1716 40b4f539 Kevin Wolf
typedef struct MultiwriteCB {
1717 40b4f539 Kevin Wolf
    int error;
1718 40b4f539 Kevin Wolf
    int num_requests;
1719 40b4f539 Kevin Wolf
    int num_callbacks;
1720 40b4f539 Kevin Wolf
    struct {
1721 40b4f539 Kevin Wolf
        BlockDriverCompletionFunc *cb;
1722 40b4f539 Kevin Wolf
        void *opaque;
1723 40b4f539 Kevin Wolf
        QEMUIOVector *free_qiov;
1724 40b4f539 Kevin Wolf
        void *free_buf;
1725 40b4f539 Kevin Wolf
    } callbacks[];
1726 40b4f539 Kevin Wolf
} MultiwriteCB;
1727 40b4f539 Kevin Wolf
1728 40b4f539 Kevin Wolf
static void multiwrite_user_cb(MultiwriteCB *mcb)
1729 40b4f539 Kevin Wolf
{
1730 40b4f539 Kevin Wolf
    int i;
1731 40b4f539 Kevin Wolf
1732 40b4f539 Kevin Wolf
    for (i = 0; i < mcb->num_callbacks; i++) {
1733 40b4f539 Kevin Wolf
        mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
1734 40b4f539 Kevin Wolf
        qemu_free(mcb->callbacks[i].free_qiov);
1735 f8a83245 Herve Poussineau
        qemu_vfree(mcb->callbacks[i].free_buf);
1736 40b4f539 Kevin Wolf
    }
1737 40b4f539 Kevin Wolf
}
1738 40b4f539 Kevin Wolf
1739 40b4f539 Kevin Wolf
static void multiwrite_cb(void *opaque, int ret)
1740 40b4f539 Kevin Wolf
{
1741 40b4f539 Kevin Wolf
    MultiwriteCB *mcb = opaque;
1742 40b4f539 Kevin Wolf
1743 40b4f539 Kevin Wolf
    if (ret < 0) {
1744 40b4f539 Kevin Wolf
        mcb->error = ret;
1745 40b4f539 Kevin Wolf
        multiwrite_user_cb(mcb);
1746 40b4f539 Kevin Wolf
    }
1747 40b4f539 Kevin Wolf
1748 40b4f539 Kevin Wolf
    mcb->num_requests--;
1749 40b4f539 Kevin Wolf
    if (mcb->num_requests == 0) {
1750 40b4f539 Kevin Wolf
        if (mcb->error == 0) {
1751 40b4f539 Kevin Wolf
            multiwrite_user_cb(mcb);
1752 40b4f539 Kevin Wolf
        }
1753 40b4f539 Kevin Wolf
        qemu_free(mcb);
1754 40b4f539 Kevin Wolf
    }
1755 40b4f539 Kevin Wolf
}
1756 40b4f539 Kevin Wolf
1757 40b4f539 Kevin Wolf
static int multiwrite_req_compare(const void *a, const void *b)
1758 40b4f539 Kevin Wolf
{
1759 40b4f539 Kevin Wolf
    return (((BlockRequest*) a)->sector - ((BlockRequest*) b)->sector);
1760 40b4f539 Kevin Wolf
}
1761 40b4f539 Kevin Wolf
1762 40b4f539 Kevin Wolf
/*
1763 40b4f539 Kevin Wolf
 * Takes a bunch of requests and tries to merge them. Returns the number of
1764 40b4f539 Kevin Wolf
 * requests that remain after merging.
1765 40b4f539 Kevin Wolf
 */
1766 40b4f539 Kevin Wolf
static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
1767 40b4f539 Kevin Wolf
    int num_reqs, MultiwriteCB *mcb)
1768 40b4f539 Kevin Wolf
{
1769 40b4f539 Kevin Wolf
    int i, outidx;
1770 40b4f539 Kevin Wolf
1771 40b4f539 Kevin Wolf
    // Sort requests by start sector
1772 40b4f539 Kevin Wolf
    qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
1773 40b4f539 Kevin Wolf
1774 40b4f539 Kevin Wolf
    // Check if adjacent requests touch the same clusters. If so, combine them,
1775 40b4f539 Kevin Wolf
    // filling up gaps with zero sectors.
1776 40b4f539 Kevin Wolf
    outidx = 0;
1777 40b4f539 Kevin Wolf
    for (i = 1; i < num_reqs; i++) {
1778 40b4f539 Kevin Wolf
        int merge = 0;
1779 40b4f539 Kevin Wolf
        int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
1780 40b4f539 Kevin Wolf
1781 40b4f539 Kevin Wolf
        // This handles the cases that are valid for all block drivers, namely
1782 40b4f539 Kevin Wolf
        // exactly sequential writes and overlapping writes.
1783 40b4f539 Kevin Wolf
        if (reqs[i].sector <= oldreq_last) {
1784 40b4f539 Kevin Wolf
            merge = 1;
1785 40b4f539 Kevin Wolf
        }
1786 40b4f539 Kevin Wolf
1787 40b4f539 Kevin Wolf
        // The block driver may decide that it makes sense to combine requests
1788 40b4f539 Kevin Wolf
        // even if there is a gap of some sectors between them. In this case,
1789 40b4f539 Kevin Wolf
        // the gap is filled with zeros (therefore only applicable for yet
1790 40b4f539 Kevin Wolf
        // unused space in format like qcow2).
1791 40b4f539 Kevin Wolf
        if (!merge && bs->drv->bdrv_merge_requests) {
1792 40b4f539 Kevin Wolf
            merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
1793 40b4f539 Kevin Wolf
        }
1794 40b4f539 Kevin Wolf
1795 e2a305fb Christoph Hellwig
        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
1796 e2a305fb Christoph Hellwig
            merge = 0;
1797 e2a305fb Christoph Hellwig
        }
1798 e2a305fb Christoph Hellwig
1799 40b4f539 Kevin Wolf
        if (merge) {
1800 40b4f539 Kevin Wolf
            size_t size;
1801 40b4f539 Kevin Wolf
            QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
1802 40b4f539 Kevin Wolf
            qemu_iovec_init(qiov,
1803 40b4f539 Kevin Wolf
                reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
1804 40b4f539 Kevin Wolf
1805 40b4f539 Kevin Wolf
            // Add the first request to the merged one. If the requests are
1806 40b4f539 Kevin Wolf
            // overlapping, drop the last sectors of the first request.
1807 40b4f539 Kevin Wolf
            size = (reqs[i].sector - reqs[outidx].sector) << 9;
1808 40b4f539 Kevin Wolf
            qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
1809 40b4f539 Kevin Wolf
1810 40b4f539 Kevin Wolf
            // We might need to add some zeros between the two requests
1811 40b4f539 Kevin Wolf
            if (reqs[i].sector > oldreq_last) {
1812 40b4f539 Kevin Wolf
                size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
1813 40b4f539 Kevin Wolf
                uint8_t *buf = qemu_blockalign(bs, zero_bytes);
1814 40b4f539 Kevin Wolf
                memset(buf, 0, zero_bytes);
1815 40b4f539 Kevin Wolf
                qemu_iovec_add(qiov, buf, zero_bytes);
1816 40b4f539 Kevin Wolf
                mcb->callbacks[i].free_buf = buf;
1817 40b4f539 Kevin Wolf
            }
1818 40b4f539 Kevin Wolf
1819 40b4f539 Kevin Wolf
            // Add the second request
1820 40b4f539 Kevin Wolf
            qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
1821 40b4f539 Kevin Wolf
1822 40b4f539 Kevin Wolf
            reqs[outidx].nb_sectors += reqs[i].nb_sectors;
1823 40b4f539 Kevin Wolf
            reqs[outidx].qiov = qiov;
1824 40b4f539 Kevin Wolf
1825 40b4f539 Kevin Wolf
            mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
1826 40b4f539 Kevin Wolf
        } else {
1827 40b4f539 Kevin Wolf
            outidx++;
1828 40b4f539 Kevin Wolf
            reqs[outidx].sector     = reqs[i].sector;
1829 40b4f539 Kevin Wolf
            reqs[outidx].nb_sectors = reqs[i].nb_sectors;
1830 40b4f539 Kevin Wolf
            reqs[outidx].qiov       = reqs[i].qiov;
1831 40b4f539 Kevin Wolf
        }
1832 40b4f539 Kevin Wolf
    }
1833 40b4f539 Kevin Wolf
1834 40b4f539 Kevin Wolf
    return outidx + 1;
1835 40b4f539 Kevin Wolf
}
1836 40b4f539 Kevin Wolf
1837 40b4f539 Kevin Wolf
/*
1838 40b4f539 Kevin Wolf
 * Submit multiple AIO write requests at once.
1839 40b4f539 Kevin Wolf
 *
1840 40b4f539 Kevin Wolf
 * On success, the function returns 0 and all requests in the reqs array have
1841 40b4f539 Kevin Wolf
 * been submitted. In error case this function returns -1, and any of the
1842 40b4f539 Kevin Wolf
 * requests may or may not be submitted yet. In particular, this means that the
1843 40b4f539 Kevin Wolf
 * callback will be called for some of the requests, for others it won't. The
1844 40b4f539 Kevin Wolf
 * caller must check the error field of the BlockRequest to wait for the right
1845 40b4f539 Kevin Wolf
 * callbacks (if error != 0, no callback will be called).
1846 40b4f539 Kevin Wolf
 *
1847 40b4f539 Kevin Wolf
 * The implementation may modify the contents of the reqs array, e.g. to merge
1848 40b4f539 Kevin Wolf
 * requests. However, the fields opaque and error are left unmodified as they
1849 40b4f539 Kevin Wolf
 * are used to signal failure for a single request to the caller.
1850 40b4f539 Kevin Wolf
 */
1851 40b4f539 Kevin Wolf
int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
1852 40b4f539 Kevin Wolf
{
1853 40b4f539 Kevin Wolf
    BlockDriverAIOCB *acb;
1854 40b4f539 Kevin Wolf
    MultiwriteCB *mcb;
1855 40b4f539 Kevin Wolf
    int i;
1856 40b4f539 Kevin Wolf
1857 40b4f539 Kevin Wolf
    if (num_reqs == 0) {
1858 40b4f539 Kevin Wolf
        return 0;
1859 40b4f539 Kevin Wolf
    }
1860 40b4f539 Kevin Wolf
1861 40b4f539 Kevin Wolf
    // Create MultiwriteCB structure
1862 40b4f539 Kevin Wolf
    mcb = qemu_mallocz(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
1863 40b4f539 Kevin Wolf
    mcb->num_requests = 0;
1864 40b4f539 Kevin Wolf
    mcb->num_callbacks = num_reqs;
1865 40b4f539 Kevin Wolf
1866 40b4f539 Kevin Wolf
    for (i = 0; i < num_reqs; i++) {
1867 40b4f539 Kevin Wolf
        mcb->callbacks[i].cb = reqs[i].cb;
1868 40b4f539 Kevin Wolf
        mcb->callbacks[i].opaque = reqs[i].opaque;
1869 40b4f539 Kevin Wolf
    }
1870 40b4f539 Kevin Wolf
1871 40b4f539 Kevin Wolf
    // Check for mergable requests
1872 40b4f539 Kevin Wolf
    num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
1873 40b4f539 Kevin Wolf
1874 40b4f539 Kevin Wolf
    // Run the aio requests
1875 40b4f539 Kevin Wolf
    for (i = 0; i < num_reqs; i++) {
1876 40b4f539 Kevin Wolf
        acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
1877 40b4f539 Kevin Wolf
            reqs[i].nb_sectors, multiwrite_cb, mcb);
1878 40b4f539 Kevin Wolf
1879 40b4f539 Kevin Wolf
        if (acb == NULL) {
1880 40b4f539 Kevin Wolf
            // We can only fail the whole thing if no request has been
1881 40b4f539 Kevin Wolf
            // submitted yet. Otherwise we'll wait for the submitted AIOs to
1882 40b4f539 Kevin Wolf
            // complete and report the error in the callback.
1883 40b4f539 Kevin Wolf
            if (mcb->num_requests == 0) {
1884 40b4f539 Kevin Wolf
                reqs[i].error = EIO;
1885 40b4f539 Kevin Wolf
                goto fail;
1886 40b4f539 Kevin Wolf
            } else {
1887 40b4f539 Kevin Wolf
                mcb->error = EIO;
1888 40b4f539 Kevin Wolf
                break;
1889 40b4f539 Kevin Wolf
            }
1890 40b4f539 Kevin Wolf
        } else {
1891 40b4f539 Kevin Wolf
            mcb->num_requests++;
1892 40b4f539 Kevin Wolf
        }
1893 40b4f539 Kevin Wolf
    }
1894 40b4f539 Kevin Wolf
1895 40b4f539 Kevin Wolf
    return 0;
1896 40b4f539 Kevin Wolf
1897 40b4f539 Kevin Wolf
fail:
1898 40b4f539 Kevin Wolf
    free(mcb);
1899 40b4f539 Kevin Wolf
    return -1;
1900 40b4f539 Kevin Wolf
}
1901 40b4f539 Kevin Wolf
1902 b2e12bc6 Christoph Hellwig
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
1903 b2e12bc6 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque)
1904 b2e12bc6 Christoph Hellwig
{
1905 b2e12bc6 Christoph Hellwig
    BlockDriver *drv = bs->drv;
1906 b2e12bc6 Christoph Hellwig
1907 b2e12bc6 Christoph Hellwig
    if (!drv)
1908 b2e12bc6 Christoph Hellwig
        return NULL;
1909 b2e12bc6 Christoph Hellwig
    return drv->bdrv_aio_flush(bs, cb, opaque);
1910 b2e12bc6 Christoph Hellwig
}
1911 b2e12bc6 Christoph Hellwig
1912 83f64091 bellard
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1913 83f64091 bellard
{
1914 6bbff9a0 aliguori
    acb->pool->cancel(acb);
1915 83f64091 bellard
}
1916 83f64091 bellard
1917 ce1a14dc pbrook
1918 83f64091 bellard
/**************************************************************/
1919 83f64091 bellard
/* async block device emulation */
1920 83f64091 bellard
1921 c16b5a2c Christoph Hellwig
typedef struct BlockDriverAIOCBSync {
1922 c16b5a2c Christoph Hellwig
    BlockDriverAIOCB common;
1923 c16b5a2c Christoph Hellwig
    QEMUBH *bh;
1924 c16b5a2c Christoph Hellwig
    int ret;
1925 c16b5a2c Christoph Hellwig
    /* vector translation state */
1926 c16b5a2c Christoph Hellwig
    QEMUIOVector *qiov;
1927 c16b5a2c Christoph Hellwig
    uint8_t *bounce;
1928 c16b5a2c Christoph Hellwig
    int is_write;
1929 c16b5a2c Christoph Hellwig
} BlockDriverAIOCBSync;
1930 c16b5a2c Christoph Hellwig
1931 c16b5a2c Christoph Hellwig
static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1932 c16b5a2c Christoph Hellwig
{
1933 c16b5a2c Christoph Hellwig
    BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1934 6a7ad299 Dor Laor
    qemu_bh_delete(acb->bh);
1935 36afc451 Avi Kivity
    acb->bh = NULL;
1936 c16b5a2c Christoph Hellwig
    qemu_aio_release(acb);
1937 c16b5a2c Christoph Hellwig
}
1938 c16b5a2c Christoph Hellwig
1939 c16b5a2c Christoph Hellwig
static AIOPool bdrv_em_aio_pool = {
1940 c16b5a2c Christoph Hellwig
    .aiocb_size         = sizeof(BlockDriverAIOCBSync),
1941 c16b5a2c Christoph Hellwig
    .cancel             = bdrv_aio_cancel_em,
1942 c16b5a2c Christoph Hellwig
};
1943 c16b5a2c Christoph Hellwig
1944 ce1a14dc pbrook
static void bdrv_aio_bh_cb(void *opaque)
1945 83f64091 bellard
{
1946 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb = opaque;
1947 f141eafe aliguori
1948 f141eafe aliguori
    if (!acb->is_write)
1949 f141eafe aliguori
        qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
1950 ceb42de8 aliguori
    qemu_vfree(acb->bounce);
1951 ce1a14dc pbrook
    acb->common.cb(acb->common.opaque, acb->ret);
1952 6a7ad299 Dor Laor
    qemu_bh_delete(acb->bh);
1953 36afc451 Avi Kivity
    acb->bh = NULL;
1954 ce1a14dc pbrook
    qemu_aio_release(acb);
1955 83f64091 bellard
}
1956 beac80cd bellard
1957 f141eafe aliguori
static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
1958 f141eafe aliguori
                                            int64_t sector_num,
1959 f141eafe aliguori
                                            QEMUIOVector *qiov,
1960 f141eafe aliguori
                                            int nb_sectors,
1961 f141eafe aliguori
                                            BlockDriverCompletionFunc *cb,
1962 f141eafe aliguori
                                            void *opaque,
1963 f141eafe aliguori
                                            int is_write)
1964 f141eafe aliguori
1965 83f64091 bellard
{
1966 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb;
1967 ce1a14dc pbrook
1968 c16b5a2c Christoph Hellwig
    acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
1969 f141eafe aliguori
    acb->is_write = is_write;
1970 f141eafe aliguori
    acb->qiov = qiov;
1971 e268ca52 aliguori
    acb->bounce = qemu_blockalign(bs, qiov->size);
1972 f141eafe aliguori
1973 ce1a14dc pbrook
    if (!acb->bh)
1974 ce1a14dc pbrook
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1975 f141eafe aliguori
1976 f141eafe aliguori
    if (is_write) {
1977 f141eafe aliguori
        qemu_iovec_to_buffer(acb->qiov, acb->bounce);
1978 f141eafe aliguori
        acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
1979 f141eafe aliguori
    } else {
1980 f141eafe aliguori
        acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
1981 f141eafe aliguori
    }
1982 f141eafe aliguori
1983 ce1a14dc pbrook
    qemu_bh_schedule(acb->bh);
1984 f141eafe aliguori
1985 ce1a14dc pbrook
    return &acb->common;
1986 beac80cd bellard
}
1987 beac80cd bellard
1988 f141eafe aliguori
static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
1989 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1990 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
1991 beac80cd bellard
{
1992 f141eafe aliguori
    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
1993 f141eafe aliguori
}
1994 83f64091 bellard
1995 f141eafe aliguori
static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
1996 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1997 f141eafe aliguori
        BlockDriverCompletionFunc *cb, void *opaque)
1998 f141eafe aliguori
{
1999 f141eafe aliguori
    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2000 beac80cd bellard
}
2001 beac80cd bellard
2002 b2e12bc6 Christoph Hellwig
static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
2003 b2e12bc6 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque)
2004 b2e12bc6 Christoph Hellwig
{
2005 b2e12bc6 Christoph Hellwig
    BlockDriverAIOCBSync *acb;
2006 b2e12bc6 Christoph Hellwig
2007 b2e12bc6 Christoph Hellwig
    acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2008 b2e12bc6 Christoph Hellwig
    acb->is_write = 1; /* don't bounce in the completion hadler */
2009 b2e12bc6 Christoph Hellwig
    acb->qiov = NULL;
2010 b2e12bc6 Christoph Hellwig
    acb->bounce = NULL;
2011 b2e12bc6 Christoph Hellwig
    acb->ret = 0;
2012 b2e12bc6 Christoph Hellwig
2013 b2e12bc6 Christoph Hellwig
    if (!acb->bh)
2014 b2e12bc6 Christoph Hellwig
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2015 b2e12bc6 Christoph Hellwig
2016 b2e12bc6 Christoph Hellwig
    bdrv_flush(bs);
2017 b2e12bc6 Christoph Hellwig
    qemu_bh_schedule(acb->bh);
2018 b2e12bc6 Christoph Hellwig
    return &acb->common;
2019 b2e12bc6 Christoph Hellwig
}
2020 b2e12bc6 Christoph Hellwig
2021 83f64091 bellard
/**************************************************************/
2022 83f64091 bellard
/* sync block device emulation */
2023 ea2384d3 bellard
2024 83f64091 bellard
static void bdrv_rw_em_cb(void *opaque, int ret)
2025 83f64091 bellard
{
2026 83f64091 bellard
    *(int *)opaque = ret;
2027 ea2384d3 bellard
}
2028 ea2384d3 bellard
2029 83f64091 bellard
#define NOT_DONE 0x7fffffff
2030 83f64091 bellard
2031 5fafdf24 ths
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
2032 83f64091 bellard
                        uint8_t *buf, int nb_sectors)
2033 7a6cba61 pbrook
{
2034 ce1a14dc pbrook
    int async_ret;
2035 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
2036 f141eafe aliguori
    struct iovec iov;
2037 f141eafe aliguori
    QEMUIOVector qiov;
2038 83f64091 bellard
2039 65d6b3d8 Kevin Wolf
    async_context_push();
2040 65d6b3d8 Kevin Wolf
2041 83f64091 bellard
    async_ret = NOT_DONE;
2042 3f4cb3d3 blueswir1
    iov.iov_base = (void *)buf;
2043 f141eafe aliguori
    iov.iov_len = nb_sectors * 512;
2044 f141eafe aliguori
    qemu_iovec_init_external(&qiov, &iov, 1);
2045 f141eafe aliguori
    acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
2046 f141eafe aliguori
        bdrv_rw_em_cb, &async_ret);
2047 65d6b3d8 Kevin Wolf
    if (acb == NULL) {
2048 65d6b3d8 Kevin Wolf
        async_ret = -1;
2049 65d6b3d8 Kevin Wolf
        goto fail;
2050 65d6b3d8 Kevin Wolf
    }
2051 baf35cb9 aliguori
2052 83f64091 bellard
    while (async_ret == NOT_DONE) {
2053 83f64091 bellard
        qemu_aio_wait();
2054 83f64091 bellard
    }
2055 baf35cb9 aliguori
2056 65d6b3d8 Kevin Wolf
2057 65d6b3d8 Kevin Wolf
fail:
2058 65d6b3d8 Kevin Wolf
    async_context_pop();
2059 83f64091 bellard
    return async_ret;
2060 7a6cba61 pbrook
}
2061 7a6cba61 pbrook
2062 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
2063 83f64091 bellard
                         const uint8_t *buf, int nb_sectors)
2064 83f64091 bellard
{
2065 ce1a14dc pbrook
    int async_ret;
2066 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
2067 f141eafe aliguori
    struct iovec iov;
2068 f141eafe aliguori
    QEMUIOVector qiov;
2069 83f64091 bellard
2070 65d6b3d8 Kevin Wolf
    async_context_push();
2071 65d6b3d8 Kevin Wolf
2072 83f64091 bellard
    async_ret = NOT_DONE;
2073 f141eafe aliguori
    iov.iov_base = (void *)buf;
2074 f141eafe aliguori
    iov.iov_len = nb_sectors * 512;
2075 f141eafe aliguori
    qemu_iovec_init_external(&qiov, &iov, 1);
2076 f141eafe aliguori
    acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
2077 f141eafe aliguori
        bdrv_rw_em_cb, &async_ret);
2078 65d6b3d8 Kevin Wolf
    if (acb == NULL) {
2079 65d6b3d8 Kevin Wolf
        async_ret = -1;
2080 65d6b3d8 Kevin Wolf
        goto fail;
2081 65d6b3d8 Kevin Wolf
    }
2082 83f64091 bellard
    while (async_ret == NOT_DONE) {
2083 83f64091 bellard
        qemu_aio_wait();
2084 83f64091 bellard
    }
2085 65d6b3d8 Kevin Wolf
2086 65d6b3d8 Kevin Wolf
fail:
2087 65d6b3d8 Kevin Wolf
    async_context_pop();
2088 83f64091 bellard
    return async_ret;
2089 83f64091 bellard
}
2090 ea2384d3 bellard
2091 ea2384d3 bellard
void bdrv_init(void)
2092 ea2384d3 bellard
{
2093 5efa9d5a Anthony Liguori
    module_call_init(MODULE_INIT_BLOCK);
2094 ea2384d3 bellard
}
2095 ce1a14dc pbrook
2096 eb852011 Markus Armbruster
void bdrv_init_with_whitelist(void)
2097 eb852011 Markus Armbruster
{
2098 eb852011 Markus Armbruster
    use_bdrv_whitelist = 1;
2099 eb852011 Markus Armbruster
    bdrv_init();
2100 eb852011 Markus Armbruster
}
2101 eb852011 Markus Armbruster
2102 c16b5a2c Christoph Hellwig
void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
2103 c16b5a2c Christoph Hellwig
                   BlockDriverCompletionFunc *cb, void *opaque)
2104 ce1a14dc pbrook
{
2105 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
2106 ce1a14dc pbrook
2107 6bbff9a0 aliguori
    if (pool->free_aiocb) {
2108 6bbff9a0 aliguori
        acb = pool->free_aiocb;
2109 6bbff9a0 aliguori
        pool->free_aiocb = acb->next;
2110 ce1a14dc pbrook
    } else {
2111 6bbff9a0 aliguori
        acb = qemu_mallocz(pool->aiocb_size);
2112 6bbff9a0 aliguori
        acb->pool = pool;
2113 ce1a14dc pbrook
    }
2114 ce1a14dc pbrook
    acb->bs = bs;
2115 ce1a14dc pbrook
    acb->cb = cb;
2116 ce1a14dc pbrook
    acb->opaque = opaque;
2117 ce1a14dc pbrook
    return acb;
2118 ce1a14dc pbrook
}
2119 ce1a14dc pbrook
2120 ce1a14dc pbrook
void qemu_aio_release(void *p)
2121 ce1a14dc pbrook
{
2122 6bbff9a0 aliguori
    BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
2123 6bbff9a0 aliguori
    AIOPool *pool = acb->pool;
2124 6bbff9a0 aliguori
    acb->next = pool->free_aiocb;
2125 6bbff9a0 aliguori
    pool->free_aiocb = acb;
2126 ce1a14dc pbrook
}
2127 19cb3738 bellard
2128 19cb3738 bellard
/**************************************************************/
2129 19cb3738 bellard
/* removable device support */
2130 19cb3738 bellard
2131 19cb3738 bellard
/**
2132 19cb3738 bellard
 * Return TRUE if the media is present
2133 19cb3738 bellard
 */
2134 19cb3738 bellard
int bdrv_is_inserted(BlockDriverState *bs)
2135 19cb3738 bellard
{
2136 19cb3738 bellard
    BlockDriver *drv = bs->drv;
2137 19cb3738 bellard
    int ret;
2138 19cb3738 bellard
    if (!drv)
2139 19cb3738 bellard
        return 0;
2140 19cb3738 bellard
    if (!drv->bdrv_is_inserted)
2141 19cb3738 bellard
        return 1;
2142 19cb3738 bellard
    ret = drv->bdrv_is_inserted(bs);
2143 19cb3738 bellard
    return ret;
2144 19cb3738 bellard
}
2145 19cb3738 bellard
2146 19cb3738 bellard
/**
2147 19cb3738 bellard
 * Return TRUE if the media changed since the last call to this
2148 5fafdf24 ths
 * function. It is currently only used for floppy disks
2149 19cb3738 bellard
 */
2150 19cb3738 bellard
int bdrv_media_changed(BlockDriverState *bs)
2151 19cb3738 bellard
{
2152 19cb3738 bellard
    BlockDriver *drv = bs->drv;
2153 19cb3738 bellard
    int ret;
2154 19cb3738 bellard
2155 19cb3738 bellard
    if (!drv || !drv->bdrv_media_changed)
2156 19cb3738 bellard
        ret = -ENOTSUP;
2157 19cb3738 bellard
    else
2158 19cb3738 bellard
        ret = drv->bdrv_media_changed(bs);
2159 19cb3738 bellard
    if (ret == -ENOTSUP)
2160 19cb3738 bellard
        ret = bs->media_changed;
2161 19cb3738 bellard
    bs->media_changed = 0;
2162 19cb3738 bellard
    return ret;
2163 19cb3738 bellard
}
2164 19cb3738 bellard
2165 19cb3738 bellard
/**
2166 19cb3738 bellard
 * If eject_flag is TRUE, eject the media. Otherwise, close the tray
2167 19cb3738 bellard
 */
2168 aea2a33c Mark McLoughlin
int bdrv_eject(BlockDriverState *bs, int eject_flag)
2169 19cb3738 bellard
{
2170 19cb3738 bellard
    BlockDriver *drv = bs->drv;
2171 19cb3738 bellard
    int ret;
2172 19cb3738 bellard
2173 aea2a33c Mark McLoughlin
    if (bs->locked) {
2174 aea2a33c Mark McLoughlin
        return -EBUSY;
2175 aea2a33c Mark McLoughlin
    }
2176 aea2a33c Mark McLoughlin
2177 19cb3738 bellard
    if (!drv || !drv->bdrv_eject) {
2178 19cb3738 bellard
        ret = -ENOTSUP;
2179 19cb3738 bellard
    } else {
2180 19cb3738 bellard
        ret = drv->bdrv_eject(bs, eject_flag);
2181 19cb3738 bellard
    }
2182 19cb3738 bellard
    if (ret == -ENOTSUP) {
2183 19cb3738 bellard
        if (eject_flag)
2184 19cb3738 bellard
            bdrv_close(bs);
2185 aea2a33c Mark McLoughlin
        ret = 0;
2186 19cb3738 bellard
    }
2187 aea2a33c Mark McLoughlin
2188 aea2a33c Mark McLoughlin
    return ret;
2189 19cb3738 bellard
}
2190 19cb3738 bellard
2191 19cb3738 bellard
int bdrv_is_locked(BlockDriverState *bs)
2192 19cb3738 bellard
{
2193 19cb3738 bellard
    return bs->locked;
2194 19cb3738 bellard
}
2195 19cb3738 bellard
2196 19cb3738 bellard
/**
2197 19cb3738 bellard
 * Lock or unlock the media (if it is locked, the user won't be able
2198 19cb3738 bellard
 * to eject it manually).
2199 19cb3738 bellard
 */
2200 19cb3738 bellard
void bdrv_set_locked(BlockDriverState *bs, int locked)
2201 19cb3738 bellard
{
2202 19cb3738 bellard
    BlockDriver *drv = bs->drv;
2203 19cb3738 bellard
2204 19cb3738 bellard
    bs->locked = locked;
2205 19cb3738 bellard
    if (drv && drv->bdrv_set_locked) {
2206 19cb3738 bellard
        drv->bdrv_set_locked(bs, locked);
2207 19cb3738 bellard
    }
2208 19cb3738 bellard
}
2209 985a03b0 ths
2210 985a03b0 ths
/* needed for generic scsi interface */
2211 985a03b0 ths
2212 985a03b0 ths
int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
2213 985a03b0 ths
{
2214 985a03b0 ths
    BlockDriver *drv = bs->drv;
2215 985a03b0 ths
2216 985a03b0 ths
    if (drv && drv->bdrv_ioctl)
2217 985a03b0 ths
        return drv->bdrv_ioctl(bs, req, buf);
2218 985a03b0 ths
    return -ENOTSUP;
2219 985a03b0 ths
}
2220 7d780669 aliguori
2221 221f715d aliguori
BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
2222 221f715d aliguori
        unsigned long int req, void *buf,
2223 221f715d aliguori
        BlockDriverCompletionFunc *cb, void *opaque)
2224 7d780669 aliguori
{
2225 221f715d aliguori
    BlockDriver *drv = bs->drv;
2226 7d780669 aliguori
2227 221f715d aliguori
    if (drv && drv->bdrv_aio_ioctl)
2228 221f715d aliguori
        return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
2229 221f715d aliguori
    return NULL;
2230 7d780669 aliguori
}
2231 e268ca52 aliguori
2232 7cd1e32a lirans@il.ibm.com
2233 7cd1e32a lirans@il.ibm.com
2234 e268ca52 aliguori
void *qemu_blockalign(BlockDriverState *bs, size_t size)
2235 e268ca52 aliguori
{
2236 e268ca52 aliguori
    return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
2237 e268ca52 aliguori
}
2238 7cd1e32a lirans@il.ibm.com
2239 7cd1e32a lirans@il.ibm.com
void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
2240 7cd1e32a lirans@il.ibm.com
{
2241 7cd1e32a lirans@il.ibm.com
    int64_t bitmap_size;
2242 a55eb92c Jan Kiszka
2243 aaa0eb75 Liran Schour
    bs->dirty_count = 0;
2244 a55eb92c Jan Kiszka
    if (enable) {
2245 c6d22830 Jan Kiszka
        if (!bs->dirty_bitmap) {
2246 c6d22830 Jan Kiszka
            bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
2247 c6d22830 Jan Kiszka
                    BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
2248 c6d22830 Jan Kiszka
            bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
2249 a55eb92c Jan Kiszka
2250 7cd1e32a lirans@il.ibm.com
            bs->dirty_bitmap = qemu_mallocz(bitmap_size);
2251 a55eb92c Jan Kiszka
        }
2252 7cd1e32a lirans@il.ibm.com
    } else {
2253 c6d22830 Jan Kiszka
        if (bs->dirty_bitmap) {
2254 7cd1e32a lirans@il.ibm.com
            qemu_free(bs->dirty_bitmap);
2255 c6d22830 Jan Kiszka
            bs->dirty_bitmap = NULL;
2256 a55eb92c Jan Kiszka
        }
2257 7cd1e32a lirans@il.ibm.com
    }
2258 7cd1e32a lirans@il.ibm.com
}
2259 7cd1e32a lirans@il.ibm.com
2260 7cd1e32a lirans@il.ibm.com
int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
2261 7cd1e32a lirans@il.ibm.com
{
2262 6ea44308 Jan Kiszka
    int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
2263 a55eb92c Jan Kiszka
2264 c6d22830 Jan Kiszka
    if (bs->dirty_bitmap &&
2265 c6d22830 Jan Kiszka
        (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
2266 c6d22830 Jan Kiszka
        return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
2267 c6d22830 Jan Kiszka
            (1 << (chunk % (sizeof(unsigned long) * 8)));
2268 7cd1e32a lirans@il.ibm.com
    } else {
2269 7cd1e32a lirans@il.ibm.com
        return 0;
2270 7cd1e32a lirans@il.ibm.com
    }
2271 7cd1e32a lirans@il.ibm.com
}
2272 7cd1e32a lirans@il.ibm.com
2273 a55eb92c Jan Kiszka
void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
2274 a55eb92c Jan Kiszka
                      int nr_sectors)
2275 7cd1e32a lirans@il.ibm.com
{
2276 7cd1e32a lirans@il.ibm.com
    set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
2277 7cd1e32a lirans@il.ibm.com
}
2278 aaa0eb75 Liran Schour
2279 aaa0eb75 Liran Schour
int64_t bdrv_get_dirty_count(BlockDriverState *bs)
2280 aaa0eb75 Liran Schour
{
2281 aaa0eb75 Liran Schour
    return bs->dirty_count;
2282 aaa0eb75 Liran Schour
}