xref: /openbmc/qemu/block.c (revision 0563e191516289c9d2f282a8c50f2eecef2fa773)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
243990d09aSblueswir1 #include "config-host.h"
25faf07963Spbrook #include "qemu-common.h"
266d519a5fSStefan Hajnoczi #include "trace.h"
27376253ecSaliguori #include "monitor.h"
28ea2384d3Sbellard #include "block_int.h"
295efa9d5aSAnthony Liguori #include "module.h"
30f795e743SLuiz Capitulino #include "qjson.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32b2023818SLuiz Capitulino #include "qmp-commands.h"
33*0563e191SZhi Yong Wu #include "qemu-timer.h"
34fc01f7e7Sbellard 
3571e72a19SJuan Quintela #ifdef CONFIG_BSD
367674e7bfSbellard #include <sys/types.h>
377674e7bfSbellard #include <sys/stat.h>
387674e7bfSbellard #include <sys/ioctl.h>
3972cf2d4fSBlue Swirl #include <sys/queue.h>
40c5e97233Sblueswir1 #ifndef __DragonFly__
417674e7bfSbellard #include <sys/disk.h>
427674e7bfSbellard #endif
43c5e97233Sblueswir1 #endif
447674e7bfSbellard 
4549dc768dSaliguori #ifdef _WIN32
4649dc768dSaliguori #include <windows.h>
4749dc768dSaliguori #endif
4849dc768dSaliguori 
491c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
501c9805a3SStefan Hajnoczi 
517d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
52f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
53f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
54c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
55f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
56f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
57ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
58f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
59f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
60f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
61f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
62f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
63f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
64c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
65c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
661c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
671c9805a3SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
68b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
69b2a61371SStefan Hajnoczi                                                int64_t sector_num,
70b2a61371SStefan Hajnoczi                                                QEMUIOVector *qiov,
71b2a61371SStefan Hajnoczi                                                int nb_sectors,
72b2a61371SStefan Hajnoczi                                                BlockDriverCompletionFunc *cb,
73b2a61371SStefan Hajnoczi                                                void *opaque,
748c5873d6SStefan Hajnoczi                                                bool is_write);
75b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque);
76ec530c81Sbellard 
771b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
781b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
797ee930d0Sblueswir1 
808a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
818a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
82ea2384d3Sbellard 
83f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
84f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
85f9092b10SMarkus Armbruster 
86eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
87eb852011SMarkus Armbruster static int use_bdrv_whitelist;
88eb852011SMarkus Armbruster 
899e0b22f4SStefan Hajnoczi #ifdef _WIN32
909e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
919e0b22f4SStefan Hajnoczi {
929e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
939e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
949e0b22f4SStefan Hajnoczi             filename[1] == ':');
959e0b22f4SStefan Hajnoczi }
969e0b22f4SStefan Hajnoczi 
979e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
989e0b22f4SStefan Hajnoczi {
999e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
1009e0b22f4SStefan Hajnoczi         filename[2] == '\0')
1019e0b22f4SStefan Hajnoczi         return 1;
1029e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1039e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1049e0b22f4SStefan Hajnoczi         return 1;
1059e0b22f4SStefan Hajnoczi     return 0;
1069e0b22f4SStefan Hajnoczi }
1079e0b22f4SStefan Hajnoczi #endif
1089e0b22f4SStefan Hajnoczi 
109*0563e191SZhi Yong Wu /* throttling disk I/O limits */
110*0563e191SZhi Yong Wu static void bdrv_block_timer(void *opaque)
111*0563e191SZhi Yong Wu {
112*0563e191SZhi Yong Wu     BlockDriverState *bs = opaque;
113*0563e191SZhi Yong Wu 
114*0563e191SZhi Yong Wu     qemu_co_queue_next(&bs->throttled_reqs);
115*0563e191SZhi Yong Wu }
116*0563e191SZhi Yong Wu 
117*0563e191SZhi Yong Wu void bdrv_io_limits_enable(BlockDriverState *bs)
118*0563e191SZhi Yong Wu {
119*0563e191SZhi Yong Wu     qemu_co_queue_init(&bs->throttled_reqs);
120*0563e191SZhi Yong Wu     bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
121*0563e191SZhi Yong Wu     bs->slice_time  = 5 * BLOCK_IO_SLICE_TIME;
122*0563e191SZhi Yong Wu     bs->slice_start = qemu_get_clock_ns(vm_clock);
123*0563e191SZhi Yong Wu     bs->slice_end   = bs->slice_start + bs->slice_time;
124*0563e191SZhi Yong Wu     memset(&bs->io_base, 0, sizeof(bs->io_base));
125*0563e191SZhi Yong Wu     bs->io_limits_enabled = true;
126*0563e191SZhi Yong Wu }
127*0563e191SZhi Yong Wu 
128*0563e191SZhi Yong Wu bool bdrv_io_limits_enabled(BlockDriverState *bs)
129*0563e191SZhi Yong Wu {
130*0563e191SZhi Yong Wu     BlockIOLimit *io_limits = &bs->io_limits;
131*0563e191SZhi Yong Wu     return io_limits->bps[BLOCK_IO_LIMIT_READ]
132*0563e191SZhi Yong Wu          || io_limits->bps[BLOCK_IO_LIMIT_WRITE]
133*0563e191SZhi Yong Wu          || io_limits->bps[BLOCK_IO_LIMIT_TOTAL]
134*0563e191SZhi Yong Wu          || io_limits->iops[BLOCK_IO_LIMIT_READ]
135*0563e191SZhi Yong Wu          || io_limits->iops[BLOCK_IO_LIMIT_WRITE]
136*0563e191SZhi Yong Wu          || io_limits->iops[BLOCK_IO_LIMIT_TOTAL];
137*0563e191SZhi Yong Wu }
138*0563e191SZhi Yong Wu 
1399e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1409e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1419e0b22f4SStefan Hajnoczi {
1429e0b22f4SStefan Hajnoczi #ifdef _WIN32
1439e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1449e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1459e0b22f4SStefan Hajnoczi         return 0;
1469e0b22f4SStefan Hajnoczi     }
1479e0b22f4SStefan Hajnoczi #endif
1489e0b22f4SStefan Hajnoczi 
1499e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1509e0b22f4SStefan Hajnoczi }
1519e0b22f4SStefan Hajnoczi 
15283f64091Sbellard int path_is_absolute(const char *path)
15383f64091Sbellard {
15483f64091Sbellard     const char *p;
15521664424Sbellard #ifdef _WIN32
15621664424Sbellard     /* specific case for names like: "\\.\d:" */
15721664424Sbellard     if (*path == '/' || *path == '\\')
15821664424Sbellard         return 1;
15921664424Sbellard #endif
16083f64091Sbellard     p = strchr(path, ':');
16183f64091Sbellard     if (p)
16283f64091Sbellard         p++;
16383f64091Sbellard     else
16483f64091Sbellard         p = path;
1653b9f94e1Sbellard #ifdef _WIN32
1663b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1673b9f94e1Sbellard #else
1683b9f94e1Sbellard     return (*p == '/');
1693b9f94e1Sbellard #endif
17083f64091Sbellard }
17183f64091Sbellard 
17283f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
17383f64091Sbellard    path to it by considering it is relative to base_path. URL are
17483f64091Sbellard    supported. */
17583f64091Sbellard void path_combine(char *dest, int dest_size,
17683f64091Sbellard                   const char *base_path,
17783f64091Sbellard                   const char *filename)
17883f64091Sbellard {
17983f64091Sbellard     const char *p, *p1;
18083f64091Sbellard     int len;
18183f64091Sbellard 
18283f64091Sbellard     if (dest_size <= 0)
18383f64091Sbellard         return;
18483f64091Sbellard     if (path_is_absolute(filename)) {
18583f64091Sbellard         pstrcpy(dest, dest_size, filename);
18683f64091Sbellard     } else {
18783f64091Sbellard         p = strchr(base_path, ':');
18883f64091Sbellard         if (p)
18983f64091Sbellard             p++;
19083f64091Sbellard         else
19183f64091Sbellard             p = base_path;
1923b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1933b9f94e1Sbellard #ifdef _WIN32
1943b9f94e1Sbellard         {
1953b9f94e1Sbellard             const char *p2;
1963b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1973b9f94e1Sbellard             if (!p1 || p2 > p1)
1983b9f94e1Sbellard                 p1 = p2;
1993b9f94e1Sbellard         }
2003b9f94e1Sbellard #endif
20183f64091Sbellard         if (p1)
20283f64091Sbellard             p1++;
20383f64091Sbellard         else
20483f64091Sbellard             p1 = base_path;
20583f64091Sbellard         if (p1 > p)
20683f64091Sbellard             p = p1;
20783f64091Sbellard         len = p - base_path;
20883f64091Sbellard         if (len > dest_size - 1)
20983f64091Sbellard             len = dest_size - 1;
21083f64091Sbellard         memcpy(dest, base_path, len);
21183f64091Sbellard         dest[len] = '\0';
21283f64091Sbellard         pstrcat(dest, dest_size, filename);
21383f64091Sbellard     }
21483f64091Sbellard }
21583f64091Sbellard 
2165efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
217ea2384d3Sbellard {
2188c5873d6SStefan Hajnoczi     /* Block drivers without coroutine functions need emulation */
2198c5873d6SStefan Hajnoczi     if (!bdrv->bdrv_co_readv) {
220f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
221f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
222f9f05dc5SKevin Wolf 
223f8c35c1dSStefan Hajnoczi         /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
224f8c35c1dSStefan Hajnoczi          * the block driver lacks aio we need to emulate that too.
225f8c35c1dSStefan Hajnoczi          */
226f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
22783f64091Sbellard             /* add AIO emulation layer */
228f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
229f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
23083f64091Sbellard         }
231f9f05dc5SKevin Wolf     }
232b2e12bc6SChristoph Hellwig 
2338a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
234ea2384d3Sbellard }
235b338082bSbellard 
236b338082bSbellard /* create a new block device (by default it is empty) */
237b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
238fc01f7e7Sbellard {
2391b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
240b338082bSbellard 
2417267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
242b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
243ea2384d3Sbellard     if (device_name[0] != '\0') {
2441b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
245ea2384d3Sbellard     }
24628a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
247b338082bSbellard     return bs;
248b338082bSbellard }
249b338082bSbellard 
250ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
251ea2384d3Sbellard {
252ea2384d3Sbellard     BlockDriver *drv1;
2538a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2548a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
255ea2384d3Sbellard             return drv1;
256ea2384d3Sbellard         }
2578a22f02aSStefan Hajnoczi     }
258ea2384d3Sbellard     return NULL;
259ea2384d3Sbellard }
260ea2384d3Sbellard 
261eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
262eb852011SMarkus Armbruster {
263eb852011SMarkus Armbruster     static const char *whitelist[] = {
264eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
265eb852011SMarkus Armbruster     };
266eb852011SMarkus Armbruster     const char **p;
267eb852011SMarkus Armbruster 
268eb852011SMarkus Armbruster     if (!whitelist[0])
269eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
270eb852011SMarkus Armbruster 
271eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
272eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
273eb852011SMarkus Armbruster             return 1;
274eb852011SMarkus Armbruster         }
275eb852011SMarkus Armbruster     }
276eb852011SMarkus Armbruster     return 0;
277eb852011SMarkus Armbruster }
278eb852011SMarkus Armbruster 
279eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
280eb852011SMarkus Armbruster {
281eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
282eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
283eb852011SMarkus Armbruster }
284eb852011SMarkus Armbruster 
2850e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2860e7e1989SKevin Wolf     QEMUOptionParameter *options)
287ea2384d3Sbellard {
288ea2384d3Sbellard     if (!drv->bdrv_create)
289ea2384d3Sbellard         return -ENOTSUP;
2900e7e1989SKevin Wolf 
2910e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
292ea2384d3Sbellard }
293ea2384d3Sbellard 
29484a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
29584a12e66SChristoph Hellwig {
29684a12e66SChristoph Hellwig     BlockDriver *drv;
29784a12e66SChristoph Hellwig 
298b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
29984a12e66SChristoph Hellwig     if (drv == NULL) {
30016905d71SStefan Hajnoczi         return -ENOENT;
30184a12e66SChristoph Hellwig     }
30284a12e66SChristoph Hellwig 
30384a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
30484a12e66SChristoph Hellwig }
30584a12e66SChristoph Hellwig 
306d5249393Sbellard #ifdef _WIN32
30795389c86Sbellard void get_tmp_filename(char *filename, int size)
308d5249393Sbellard {
3093b9f94e1Sbellard     char temp_dir[MAX_PATH];
3103b9f94e1Sbellard 
3113b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
3123b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
313d5249393Sbellard }
314d5249393Sbellard #else
31595389c86Sbellard void get_tmp_filename(char *filename, int size)
316ea2384d3Sbellard {
317ea2384d3Sbellard     int fd;
3187ccfb2ebSblueswir1     const char *tmpdir;
319d5249393Sbellard     /* XXX: race condition possible */
3200badc1eeSaurel32     tmpdir = getenv("TMPDIR");
3210badc1eeSaurel32     if (!tmpdir)
3220badc1eeSaurel32         tmpdir = "/tmp";
3230badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
324ea2384d3Sbellard     fd = mkstemp(filename);
325ea2384d3Sbellard     close(fd);
326ea2384d3Sbellard }
327d5249393Sbellard #endif
328ea2384d3Sbellard 
329f3a5d3f8SChristoph Hellwig /*
330f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
331f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
332f3a5d3f8SChristoph Hellwig  */
333f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
334f3a5d3f8SChristoph Hellwig {
335508c7cb3SChristoph Hellwig     int score_max = 0, score;
336508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
337f3a5d3f8SChristoph Hellwig 
3388a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
339508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
340508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
341508c7cb3SChristoph Hellwig             if (score > score_max) {
342508c7cb3SChristoph Hellwig                 score_max = score;
343508c7cb3SChristoph Hellwig                 drv = d;
344f3a5d3f8SChristoph Hellwig             }
345508c7cb3SChristoph Hellwig         }
346f3a5d3f8SChristoph Hellwig     }
347f3a5d3f8SChristoph Hellwig 
348508c7cb3SChristoph Hellwig     return drv;
349f3a5d3f8SChristoph Hellwig }
350f3a5d3f8SChristoph Hellwig 
351b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
35284a12e66SChristoph Hellwig {
35384a12e66SChristoph Hellwig     BlockDriver *drv1;
35484a12e66SChristoph Hellwig     char protocol[128];
35584a12e66SChristoph Hellwig     int len;
35684a12e66SChristoph Hellwig     const char *p;
35784a12e66SChristoph Hellwig 
35866f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
35966f82ceeSKevin Wolf 
36039508e7aSChristoph Hellwig     /*
36139508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
36239508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
36339508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
36439508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
36539508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
36639508e7aSChristoph Hellwig      */
36784a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
36839508e7aSChristoph Hellwig     if (drv1) {
36984a12e66SChristoph Hellwig         return drv1;
37084a12e66SChristoph Hellwig     }
37139508e7aSChristoph Hellwig 
3729e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
37339508e7aSChristoph Hellwig         return bdrv_find_format("file");
37439508e7aSChristoph Hellwig     }
3759e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3769e0b22f4SStefan Hajnoczi     assert(p != NULL);
37784a12e66SChristoph Hellwig     len = p - filename;
37884a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
37984a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
38084a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
38184a12e66SChristoph Hellwig     protocol[len] = '\0';
38284a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
38384a12e66SChristoph Hellwig         if (drv1->protocol_name &&
38484a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
38584a12e66SChristoph Hellwig             return drv1;
38684a12e66SChristoph Hellwig         }
38784a12e66SChristoph Hellwig     }
38884a12e66SChristoph Hellwig     return NULL;
38984a12e66SChristoph Hellwig }
39084a12e66SChristoph Hellwig 
391c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
392ea2384d3Sbellard {
39383f64091Sbellard     int ret, score, score_max;
394ea2384d3Sbellard     BlockDriver *drv1, *drv;
39583f64091Sbellard     uint8_t buf[2048];
39683f64091Sbellard     BlockDriverState *bs;
397ea2384d3Sbellard 
398f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
399c98ac35dSStefan Weil     if (ret < 0) {
400c98ac35dSStefan Weil         *pdrv = NULL;
401c98ac35dSStefan Weil         return ret;
402c98ac35dSStefan Weil     }
403f8ea0b00SNicholas Bellinger 
40408a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
40508a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
4061a396859SNicholas A. Bellinger         bdrv_delete(bs);
407c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
408c98ac35dSStefan Weil         if (!drv) {
409c98ac35dSStefan Weil             ret = -ENOENT;
410c98ac35dSStefan Weil         }
411c98ac35dSStefan Weil         *pdrv = drv;
412c98ac35dSStefan Weil         return ret;
4131a396859SNicholas A. Bellinger     }
414f8ea0b00SNicholas Bellinger 
41583f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
41683f64091Sbellard     bdrv_delete(bs);
417ea2384d3Sbellard     if (ret < 0) {
418c98ac35dSStefan Weil         *pdrv = NULL;
419c98ac35dSStefan Weil         return ret;
420ea2384d3Sbellard     }
421ea2384d3Sbellard 
422ea2384d3Sbellard     score_max = 0;
42384a12e66SChristoph Hellwig     drv = NULL;
4248a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
42583f64091Sbellard         if (drv1->bdrv_probe) {
426ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
427ea2384d3Sbellard             if (score > score_max) {
428ea2384d3Sbellard                 score_max = score;
429ea2384d3Sbellard                 drv = drv1;
430ea2384d3Sbellard             }
431ea2384d3Sbellard         }
43283f64091Sbellard     }
433c98ac35dSStefan Weil     if (!drv) {
434c98ac35dSStefan Weil         ret = -ENOENT;
435c98ac35dSStefan Weil     }
436c98ac35dSStefan Weil     *pdrv = drv;
437c98ac35dSStefan Weil     return ret;
438ea2384d3Sbellard }
439ea2384d3Sbellard 
44051762288SStefan Hajnoczi /**
44151762288SStefan Hajnoczi  * Set the current 'total_sectors' value
44251762288SStefan Hajnoczi  */
44351762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
44451762288SStefan Hajnoczi {
44551762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
44651762288SStefan Hajnoczi 
447396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
448396759adSNicholas Bellinger     if (bs->sg)
449396759adSNicholas Bellinger         return 0;
450396759adSNicholas Bellinger 
45151762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
45251762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
45351762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
45451762288SStefan Hajnoczi         if (length < 0) {
45551762288SStefan Hajnoczi             return length;
45651762288SStefan Hajnoczi         }
45751762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
45851762288SStefan Hajnoczi     }
45951762288SStefan Hajnoczi 
46051762288SStefan Hajnoczi     bs->total_sectors = hint;
46151762288SStefan Hajnoczi     return 0;
46251762288SStefan Hajnoczi }
46351762288SStefan Hajnoczi 
464c3993cdcSStefan Hajnoczi /**
465c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
466c3993cdcSStefan Hajnoczi  *
467c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
468c3993cdcSStefan Hajnoczi  */
469c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
470c3993cdcSStefan Hajnoczi {
471c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
472c3993cdcSStefan Hajnoczi 
473c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
474c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
47592196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
47692196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
477c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
478c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
479c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
480c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
481c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
482c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
483c3993cdcSStefan Hajnoczi         /* this is the default */
484c3993cdcSStefan Hajnoczi     } else {
485c3993cdcSStefan Hajnoczi         return -1;
486c3993cdcSStefan Hajnoczi     }
487c3993cdcSStefan Hajnoczi 
488c3993cdcSStefan Hajnoczi     return 0;
489c3993cdcSStefan Hajnoczi }
490c3993cdcSStefan Hajnoczi 
491b6ce07aaSKevin Wolf /*
49257915332SKevin Wolf  * Common part for opening disk images and files
49357915332SKevin Wolf  */
49457915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
49557915332SKevin Wolf     int flags, BlockDriver *drv)
49657915332SKevin Wolf {
49757915332SKevin Wolf     int ret, open_flags;
49857915332SKevin Wolf 
49957915332SKevin Wolf     assert(drv != NULL);
50057915332SKevin Wolf 
50128dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
50228dcee10SStefan Hajnoczi 
50366f82ceeSKevin Wolf     bs->file = NULL;
50451762288SStefan Hajnoczi     bs->total_sectors = 0;
50557915332SKevin Wolf     bs->encrypted = 0;
50657915332SKevin Wolf     bs->valid_key = 0;
50703f541bdSStefan Hajnoczi     bs->sg = 0;
50857915332SKevin Wolf     bs->open_flags = flags;
50903f541bdSStefan Hajnoczi     bs->growable = 0;
51057915332SKevin Wolf     bs->buffer_alignment = 512;
51157915332SKevin Wolf 
51257915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
51303f541bdSStefan Hajnoczi     bs->backing_file[0] = '\0';
51457915332SKevin Wolf 
51557915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
51657915332SKevin Wolf         return -ENOTSUP;
51757915332SKevin Wolf     }
51857915332SKevin Wolf 
51957915332SKevin Wolf     bs->drv = drv;
5207267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
52157915332SKevin Wolf 
52203f541bdSStefan Hajnoczi     bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
52357915332SKevin Wolf 
52457915332SKevin Wolf     /*
52557915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
52657915332SKevin Wolf      * image.
52757915332SKevin Wolf      */
52857915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
52957915332SKevin Wolf 
53057915332SKevin Wolf     /*
531ebabb67aSStefan Weil      * Snapshots should be writable.
53257915332SKevin Wolf      */
53357915332SKevin Wolf     if (bs->is_temporary) {
53457915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
53557915332SKevin Wolf     }
53657915332SKevin Wolf 
537e7c63796SStefan Hajnoczi     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
538e7c63796SStefan Hajnoczi 
53966f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
54066f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
54166f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
54266f82ceeSKevin Wolf     } else {
54366f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
54466f82ceeSKevin Wolf         if (ret >= 0) {
54566f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
54666f82ceeSKevin Wolf         }
54766f82ceeSKevin Wolf     }
54866f82ceeSKevin Wolf 
54957915332SKevin Wolf     if (ret < 0) {
55057915332SKevin Wolf         goto free_and_fail;
55157915332SKevin Wolf     }
55257915332SKevin Wolf 
55351762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
55451762288SStefan Hajnoczi     if (ret < 0) {
55551762288SStefan Hajnoczi         goto free_and_fail;
55657915332SKevin Wolf     }
55751762288SStefan Hajnoczi 
55857915332SKevin Wolf #ifndef _WIN32
55957915332SKevin Wolf     if (bs->is_temporary) {
56057915332SKevin Wolf         unlink(filename);
56157915332SKevin Wolf     }
56257915332SKevin Wolf #endif
56357915332SKevin Wolf     return 0;
56457915332SKevin Wolf 
56557915332SKevin Wolf free_and_fail:
56666f82ceeSKevin Wolf     if (bs->file) {
56766f82ceeSKevin Wolf         bdrv_delete(bs->file);
56866f82ceeSKevin Wolf         bs->file = NULL;
56966f82ceeSKevin Wolf     }
5707267c094SAnthony Liguori     g_free(bs->opaque);
57157915332SKevin Wolf     bs->opaque = NULL;
57257915332SKevin Wolf     bs->drv = NULL;
57357915332SKevin Wolf     return ret;
57457915332SKevin Wolf }
57557915332SKevin Wolf 
57657915332SKevin Wolf /*
577b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
578b6ce07aaSKevin Wolf  */
57983f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
580b338082bSbellard {
58183f64091Sbellard     BlockDriverState *bs;
5826db95603SChristoph Hellwig     BlockDriver *drv;
58383f64091Sbellard     int ret;
5843b0d4f61Sbellard 
585b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5866db95603SChristoph Hellwig     if (!drv) {
5876db95603SChristoph Hellwig         return -ENOENT;
5886db95603SChristoph Hellwig     }
5896db95603SChristoph Hellwig 
59083f64091Sbellard     bs = bdrv_new("");
591b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
59283f64091Sbellard     if (ret < 0) {
59383f64091Sbellard         bdrv_delete(bs);
59483f64091Sbellard         return ret;
5953b0d4f61Sbellard     }
59671d0770cSaliguori     bs->growable = 1;
59783f64091Sbellard     *pbs = bs;
59883f64091Sbellard     return 0;
5993b0d4f61Sbellard }
6003b0d4f61Sbellard 
601b6ce07aaSKevin Wolf /*
602b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
603b6ce07aaSKevin Wolf  */
604d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
605ea2384d3Sbellard               BlockDriver *drv)
606ea2384d3Sbellard {
607b6ce07aaSKevin Wolf     int ret;
6082b572816SKevin Wolf     char tmp_filename[PATH_MAX];
60933e3963eSbellard 
61083f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
611ea2384d3Sbellard         BlockDriverState *bs1;
612ea2384d3Sbellard         int64_t total_size;
6137c96d46eSaliguori         int is_protocol = 0;
61491a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
61591a073a9SKevin Wolf         QEMUOptionParameter *options;
616b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
61733e3963eSbellard 
618ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
619ea2384d3Sbellard            instead of opening 'filename' directly */
620ea2384d3Sbellard 
621ea2384d3Sbellard         /* if there is a backing file, use it */
622ea2384d3Sbellard         bs1 = bdrv_new("");
623d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
62451d7c00cSaliguori         if (ret < 0) {
625ea2384d3Sbellard             bdrv_delete(bs1);
62651d7c00cSaliguori             return ret;
627ea2384d3Sbellard         }
6283e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
6297c96d46eSaliguori 
6307c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
6317c96d46eSaliguori             is_protocol = 1;
6327c96d46eSaliguori 
633ea2384d3Sbellard         bdrv_delete(bs1);
634ea2384d3Sbellard 
635ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6367c96d46eSaliguori 
6377c96d46eSaliguori         /* Real path is meaningless for protocols */
6387c96d46eSaliguori         if (is_protocol)
6397c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6407c96d46eSaliguori                      "%s", filename);
641114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
642114cdfa9SKirill A. Shutemov             return -errno;
6437c96d46eSaliguori 
64491a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
64591a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
64691a073a9SKevin Wolf 
6473e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
64891a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
64991a073a9SKevin Wolf         if (drv) {
65091a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
65191a073a9SKevin Wolf                 drv->format_name);
65291a073a9SKevin Wolf         }
65391a073a9SKevin Wolf 
65491a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
655d748768cSJan Kiszka         free_option_parameters(options);
65651d7c00cSaliguori         if (ret < 0) {
65751d7c00cSaliguori             return ret;
658ea2384d3Sbellard         }
65991a073a9SKevin Wolf 
660ea2384d3Sbellard         filename = tmp_filename;
66191a073a9SKevin Wolf         drv = bdrv_qcow2;
662ea2384d3Sbellard         bs->is_temporary = 1;
663ea2384d3Sbellard     }
664ea2384d3Sbellard 
665b6ce07aaSKevin Wolf     /* Find the right image format driver */
6666db95603SChristoph Hellwig     if (!drv) {
667c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
668ea2384d3Sbellard     }
6696987307cSChristoph Hellwig 
67051d7c00cSaliguori     if (!drv) {
67151d7c00cSaliguori         goto unlink_and_fail;
67283f64091Sbellard     }
673b6ce07aaSKevin Wolf 
674b6ce07aaSKevin Wolf     /* Open the image */
675b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
676b6ce07aaSKevin Wolf     if (ret < 0) {
6776987307cSChristoph Hellwig         goto unlink_and_fail;
6786987307cSChristoph Hellwig     }
6796987307cSChristoph Hellwig 
680b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
681b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
682b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
683b6ce07aaSKevin Wolf         int back_flags;
684b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
685b6ce07aaSKevin Wolf 
686b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
687df2dbb4aSStefan Hajnoczi 
688df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
689df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
690df2dbb4aSStefan Hajnoczi                     bs->backing_file);
691df2dbb4aSStefan Hajnoczi         } else {
692b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
693b6ce07aaSKevin Wolf                          filename, bs->backing_file);
694df2dbb4aSStefan Hajnoczi         }
695df2dbb4aSStefan Hajnoczi 
696df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
697b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
698df2dbb4aSStefan Hajnoczi         }
699b6ce07aaSKevin Wolf 
700b6ce07aaSKevin Wolf         /* backing files always opened read-only */
701b6ce07aaSKevin Wolf         back_flags =
702b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
703b6ce07aaSKevin Wolf 
704b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
705b6ce07aaSKevin Wolf         if (ret < 0) {
706b6ce07aaSKevin Wolf             bdrv_close(bs);
707b6ce07aaSKevin Wolf             return ret;
708b6ce07aaSKevin Wolf         }
709b6ce07aaSKevin Wolf         if (bs->is_temporary) {
710b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
711b6ce07aaSKevin Wolf         } else {
712b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
713b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
714b6ce07aaSKevin Wolf         }
715b6ce07aaSKevin Wolf     }
716b6ce07aaSKevin Wolf 
717b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
7187d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
719b6ce07aaSKevin Wolf     }
720b6ce07aaSKevin Wolf 
721b6ce07aaSKevin Wolf     return 0;
722b6ce07aaSKevin Wolf 
723b6ce07aaSKevin Wolf unlink_and_fail:
724b6ce07aaSKevin Wolf     if (bs->is_temporary) {
725b6ce07aaSKevin Wolf         unlink(filename);
726b6ce07aaSKevin Wolf     }
727b6ce07aaSKevin Wolf     return ret;
728b6ce07aaSKevin Wolf }
729b6ce07aaSKevin Wolf 
730fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
731fc01f7e7Sbellard {
73219cb3738Sbellard     if (bs->drv) {
733f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
734f9092b10SMarkus Armbruster             bs_snapshots = NULL;
735f9092b10SMarkus Armbruster         }
736557df6acSStefan Hajnoczi         if (bs->backing_hd) {
737ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
738557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
739557df6acSStefan Hajnoczi         }
740ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7417267c094SAnthony Liguori         g_free(bs->opaque);
742ea2384d3Sbellard #ifdef _WIN32
743ea2384d3Sbellard         if (bs->is_temporary) {
744ea2384d3Sbellard             unlink(bs->filename);
745ea2384d3Sbellard         }
74667b915a5Sbellard #endif
747ea2384d3Sbellard         bs->opaque = NULL;
748ea2384d3Sbellard         bs->drv = NULL;
749b338082bSbellard 
75066f82ceeSKevin Wolf         if (bs->file != NULL) {
75166f82ceeSKevin Wolf             bdrv_close(bs->file);
75266f82ceeSKevin Wolf         }
75366f82ceeSKevin Wolf 
7547d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
755b338082bSbellard     }
756b338082bSbellard }
757b338082bSbellard 
7582bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7592bc93fedSMORITA Kazutaka {
7602bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7612bc93fedSMORITA Kazutaka 
7622bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7632bc93fedSMORITA Kazutaka         bdrv_close(bs);
7642bc93fedSMORITA Kazutaka     }
7652bc93fedSMORITA Kazutaka }
7662bc93fedSMORITA Kazutaka 
767d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
768d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
769d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
770d22b2f41SRyan Harper {
771d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
772d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
773d22b2f41SRyan Harper     }
774d22b2f41SRyan Harper     bs->device_name[0] = '\0';
775d22b2f41SRyan Harper }
776d22b2f41SRyan Harper 
777b338082bSbellard void bdrv_delete(BlockDriverState *bs)
778b338082bSbellard {
779fa879d62SMarkus Armbruster     assert(!bs->dev);
78018846deeSMarkus Armbruster 
7811b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
782d22b2f41SRyan Harper     bdrv_make_anon(bs);
78334c6f050Saurel32 
784b338082bSbellard     bdrv_close(bs);
78566f82ceeSKevin Wolf     if (bs->file != NULL) {
78666f82ceeSKevin Wolf         bdrv_delete(bs->file);
78766f82ceeSKevin Wolf     }
78866f82ceeSKevin Wolf 
789f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7907267c094SAnthony Liguori     g_free(bs);
791fc01f7e7Sbellard }
792fc01f7e7Sbellard 
793fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
794fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
79518846deeSMarkus Armbruster {
796fa879d62SMarkus Armbruster     if (bs->dev) {
79718846deeSMarkus Armbruster         return -EBUSY;
79818846deeSMarkus Armbruster     }
799fa879d62SMarkus Armbruster     bs->dev = dev;
80028a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
80118846deeSMarkus Armbruster     return 0;
80218846deeSMarkus Armbruster }
80318846deeSMarkus Armbruster 
804fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
805fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
80618846deeSMarkus Armbruster {
807fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
808fa879d62SMarkus Armbruster         abort();
809fa879d62SMarkus Armbruster     }
810fa879d62SMarkus Armbruster }
811fa879d62SMarkus Armbruster 
812fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
813fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
814fa879d62SMarkus Armbruster {
815fa879d62SMarkus Armbruster     assert(bs->dev == dev);
816fa879d62SMarkus Armbruster     bs->dev = NULL;
8170e49de52SMarkus Armbruster     bs->dev_ops = NULL;
8180e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
81929e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
82018846deeSMarkus Armbruster }
82118846deeSMarkus Armbruster 
822fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
823fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
82418846deeSMarkus Armbruster {
825fa879d62SMarkus Armbruster     return bs->dev;
82618846deeSMarkus Armbruster }
82718846deeSMarkus Armbruster 
8280e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
8290e49de52SMarkus Armbruster                       void *opaque)
8300e49de52SMarkus Armbruster {
8310e49de52SMarkus Armbruster     bs->dev_ops = ops;
8320e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8332c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8342c6942faSMarkus Armbruster         bs_snapshots = NULL;
8352c6942faSMarkus Armbruster     }
8360e49de52SMarkus Armbruster }
8370e49de52SMarkus Armbruster 
8387d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8390e49de52SMarkus Armbruster {
840145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8417d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
842145feb17SMarkus Armbruster     }
843145feb17SMarkus Armbruster }
844145feb17SMarkus Armbruster 
8452c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8462c6942faSMarkus Armbruster {
8472c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8482c6942faSMarkus Armbruster }
8492c6942faSMarkus Armbruster 
850025ccaa7SPaolo Bonzini void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
851025ccaa7SPaolo Bonzini {
852025ccaa7SPaolo Bonzini     if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
853025ccaa7SPaolo Bonzini         bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
854025ccaa7SPaolo Bonzini     }
855025ccaa7SPaolo Bonzini }
856025ccaa7SPaolo Bonzini 
857e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
858e4def80bSMarkus Armbruster {
859e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
860e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
861e4def80bSMarkus Armbruster     }
862e4def80bSMarkus Armbruster     return false;
863e4def80bSMarkus Armbruster }
864e4def80bSMarkus Armbruster 
865145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
866145feb17SMarkus Armbruster {
867145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
868145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8690e49de52SMarkus Armbruster     }
8700e49de52SMarkus Armbruster }
8710e49de52SMarkus Armbruster 
872f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
873f107639aSMarkus Armbruster {
874f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
875f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
876f107639aSMarkus Armbruster     }
877f107639aSMarkus Armbruster     return false;
878f107639aSMarkus Armbruster }
879f107639aSMarkus Armbruster 
880e97fc193Saliguori /*
881e97fc193Saliguori  * Run consistency checks on an image
882e97fc193Saliguori  *
883e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
884a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
885e076f338SKevin Wolf  * check are stored in res.
886e97fc193Saliguori  */
887e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
888e97fc193Saliguori {
889e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
890e97fc193Saliguori         return -ENOTSUP;
891e97fc193Saliguori     }
892e97fc193Saliguori 
893e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8949ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
895e97fc193Saliguori }
896e97fc193Saliguori 
8978a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8988a426614SKevin Wolf 
89933e3963eSbellard /* commit COW file into the raw image */
90033e3963eSbellard int bdrv_commit(BlockDriverState *bs)
90133e3963eSbellard {
90219cb3738Sbellard     BlockDriver *drv = bs->drv;
903ee181196SKevin Wolf     BlockDriver *backing_drv;
9048a426614SKevin Wolf     int64_t sector, total_sectors;
9058a426614SKevin Wolf     int n, ro, open_flags;
9064dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
9078a426614SKevin Wolf     uint8_t *buf;
9084dca4b63SNaphtali Sprei     char filename[1024];
9094dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
91033e3963eSbellard 
91119cb3738Sbellard     if (!drv)
91219cb3738Sbellard         return -ENOMEDIUM;
91333e3963eSbellard 
9144dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
9154dca4b63SNaphtali Sprei         return -ENOTSUP;
9164dca4b63SNaphtali Sprei     }
9174dca4b63SNaphtali Sprei 
9184dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
919ea2384d3Sbellard         return -EACCES;
92033e3963eSbellard     }
92133e3963eSbellard 
922ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
9234dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
9244dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
9254dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
9264dca4b63SNaphtali Sprei 
9274dca4b63SNaphtali Sprei     if (ro) {
9284dca4b63SNaphtali Sprei         /* re-open as RW */
9294dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9304dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9314dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
932ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
933ee181196SKevin Wolf             backing_drv);
9344dca4b63SNaphtali Sprei         if (rw_ret < 0) {
9354dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
9364dca4b63SNaphtali Sprei             /* try to re-open read-only */
9374dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
938ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
939ee181196SKevin Wolf                 backing_drv);
9404dca4b63SNaphtali Sprei             if (ret < 0) {
9414dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9424dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9434dca4b63SNaphtali Sprei                 bs->drv = NULL;
9444dca4b63SNaphtali Sprei                 return ret;
9454dca4b63SNaphtali Sprei             }
9464dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9474dca4b63SNaphtali Sprei             return rw_ret;
9484dca4b63SNaphtali Sprei         }
9494dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
950ea2384d3Sbellard     }
951ea2384d3Sbellard 
9526ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9537267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9548a426614SKevin Wolf 
9558a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9568a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9578a426614SKevin Wolf 
9588a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9594dca4b63SNaphtali Sprei                 ret = -EIO;
9604dca4b63SNaphtali Sprei                 goto ro_cleanup;
96133e3963eSbellard             }
96233e3963eSbellard 
9638a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9644dca4b63SNaphtali Sprei                 ret = -EIO;
9654dca4b63SNaphtali Sprei                 goto ro_cleanup;
96633e3963eSbellard             }
96733e3963eSbellard         }
96833e3963eSbellard     }
96995389c86Sbellard 
9701d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9711d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9721d44952fSChristoph Hellwig         bdrv_flush(bs);
9731d44952fSChristoph Hellwig     }
97495389c86Sbellard 
9753f5075aeSChristoph Hellwig     /*
9763f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9773f5075aeSChristoph Hellwig      * stable on disk.
9783f5075aeSChristoph Hellwig      */
9793f5075aeSChristoph Hellwig     if (bs->backing_hd)
9803f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9814dca4b63SNaphtali Sprei 
9824dca4b63SNaphtali Sprei ro_cleanup:
9837267c094SAnthony Liguori     g_free(buf);
9844dca4b63SNaphtali Sprei 
9854dca4b63SNaphtali Sprei     if (ro) {
9864dca4b63SNaphtali Sprei         /* re-open as RO */
9874dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9884dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9894dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
990ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
991ee181196SKevin Wolf             backing_drv);
9924dca4b63SNaphtali Sprei         if (ret < 0) {
9934dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9944dca4b63SNaphtali Sprei             /* drive not functional anymore */
9954dca4b63SNaphtali Sprei             bs->drv = NULL;
9964dca4b63SNaphtali Sprei             return ret;
9974dca4b63SNaphtali Sprei         }
9984dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9994dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
10004dca4b63SNaphtali Sprei     }
10014dca4b63SNaphtali Sprei 
10021d44952fSChristoph Hellwig     return ret;
100333e3963eSbellard }
100433e3963eSbellard 
10056ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
10066ab4b5abSMarkus Armbruster {
10076ab4b5abSMarkus Armbruster     BlockDriverState *bs;
10086ab4b5abSMarkus Armbruster 
10096ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
10106ab4b5abSMarkus Armbruster         bdrv_commit(bs);
10116ab4b5abSMarkus Armbruster     }
10126ab4b5abSMarkus Armbruster }
10136ab4b5abSMarkus Armbruster 
1014756e6736SKevin Wolf /*
1015756e6736SKevin Wolf  * Return values:
1016756e6736SKevin Wolf  * 0        - success
1017756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
1018756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
1019756e6736SKevin Wolf  *            image file header
1020756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
1021756e6736SKevin Wolf  */
1022756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
1023756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
1024756e6736SKevin Wolf {
1025756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
1026756e6736SKevin Wolf 
1027756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
1028756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
1029756e6736SKevin Wolf     } else {
1030756e6736SKevin Wolf         return -ENOTSUP;
1031756e6736SKevin Wolf     }
1032756e6736SKevin Wolf }
1033756e6736SKevin Wolf 
103471d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
103571d0770cSaliguori                                    size_t size)
103671d0770cSaliguori {
103771d0770cSaliguori     int64_t len;
103871d0770cSaliguori 
103971d0770cSaliguori     if (!bdrv_is_inserted(bs))
104071d0770cSaliguori         return -ENOMEDIUM;
104171d0770cSaliguori 
104271d0770cSaliguori     if (bs->growable)
104371d0770cSaliguori         return 0;
104471d0770cSaliguori 
104571d0770cSaliguori     len = bdrv_getlength(bs);
104671d0770cSaliguori 
1047fbb7b4e0SKevin Wolf     if (offset < 0)
1048fbb7b4e0SKevin Wolf         return -EIO;
1049fbb7b4e0SKevin Wolf 
1050fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
105171d0770cSaliguori         return -EIO;
105271d0770cSaliguori 
105371d0770cSaliguori     return 0;
105471d0770cSaliguori }
105571d0770cSaliguori 
105671d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
105771d0770cSaliguori                               int nb_sectors)
105871d0770cSaliguori {
1059eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1060eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
106171d0770cSaliguori }
106271d0770cSaliguori 
10631c9805a3SStefan Hajnoczi typedef struct RwCo {
10641c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10651c9805a3SStefan Hajnoczi     int64_t sector_num;
10661c9805a3SStefan Hajnoczi     int nb_sectors;
10671c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10681c9805a3SStefan Hajnoczi     bool is_write;
10691c9805a3SStefan Hajnoczi     int ret;
10701c9805a3SStefan Hajnoczi } RwCo;
10711c9805a3SStefan Hajnoczi 
10721c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1073fc01f7e7Sbellard {
10741c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1075fc01f7e7Sbellard 
10761c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10771c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10781c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10791c9805a3SStefan Hajnoczi     } else {
10801c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10811c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10821c9805a3SStefan Hajnoczi     }
10831c9805a3SStefan Hajnoczi }
1084e7a8a783SKevin Wolf 
10851c9805a3SStefan Hajnoczi /*
10861c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10871c9805a3SStefan Hajnoczi  */
10881c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10891c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10901c9805a3SStefan Hajnoczi {
1091e7a8a783SKevin Wolf     QEMUIOVector qiov;
1092e7a8a783SKevin Wolf     struct iovec iov = {
1093e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1094e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1095e7a8a783SKevin Wolf     };
10961c9805a3SStefan Hajnoczi     Coroutine *co;
10971c9805a3SStefan Hajnoczi     RwCo rwco = {
10981c9805a3SStefan Hajnoczi         .bs = bs,
10991c9805a3SStefan Hajnoczi         .sector_num = sector_num,
11001c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
11011c9805a3SStefan Hajnoczi         .qiov = &qiov,
11021c9805a3SStefan Hajnoczi         .is_write = is_write,
11031c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
11041c9805a3SStefan Hajnoczi     };
1105e7a8a783SKevin Wolf 
1106e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
11071c9805a3SStefan Hajnoczi 
11081c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
11091c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
11101c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
11111c9805a3SStefan Hajnoczi     } else {
11121c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
11131c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
11141c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
11151c9805a3SStefan Hajnoczi             qemu_aio_wait();
11161c9805a3SStefan Hajnoczi         }
11171c9805a3SStefan Hajnoczi     }
11181c9805a3SStefan Hajnoczi     return rwco.ret;
1119e7a8a783SKevin Wolf }
1120e7a8a783SKevin Wolf 
11211c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
11221c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
11231c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
11241c9805a3SStefan Hajnoczi {
11251c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
112683f64091Sbellard }
1127fc01f7e7Sbellard 
11287cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
11297cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
11307cd1e32aSlirans@il.ibm.com {
11317cd1e32aSlirans@il.ibm.com     int64_t start, end;
1132c6d22830SJan Kiszka     unsigned long val, idx, bit;
1133a55eb92cSJan Kiszka 
11346ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1135c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
11367cd1e32aSlirans@il.ibm.com 
11377cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1138c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1139c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1140c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1141c6d22830SJan Kiszka         if (dirty) {
11426d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1143aaa0eb75SLiran Schour                 bs->dirty_count++;
11446d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1145aaa0eb75SLiran Schour             }
1146c6d22830SJan Kiszka         } else {
11476d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1148aaa0eb75SLiran Schour                 bs->dirty_count--;
11496d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1150c6d22830SJan Kiszka             }
1151aaa0eb75SLiran Schour         }
1152c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11537cd1e32aSlirans@il.ibm.com     }
11547cd1e32aSlirans@il.ibm.com }
11557cd1e32aSlirans@il.ibm.com 
115619cb3738Sbellard /* Return < 0 if error. Important errors are:
115719cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
115819cb3738Sbellard   -ENOMEDIUM   No media inserted.
115919cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
116019cb3738Sbellard   -EACCES      Trying to write a read-only device
116119cb3738Sbellard */
1162fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1163fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1164fc01f7e7Sbellard {
11651c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
116683f64091Sbellard }
116783f64091Sbellard 
1168eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1169eda578e5Saliguori                void *buf, int count1)
117083f64091Sbellard {
11716ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
117283f64091Sbellard     int len, nb_sectors, count;
117383f64091Sbellard     int64_t sector_num;
11749a8c4cceSKevin Wolf     int ret;
117583f64091Sbellard 
117683f64091Sbellard     count = count1;
117783f64091Sbellard     /* first read to align to sector start */
11786ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
117983f64091Sbellard     if (len > count)
118083f64091Sbellard         len = count;
11816ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
118283f64091Sbellard     if (len > 0) {
11839a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11849a8c4cceSKevin Wolf             return ret;
11856ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
118683f64091Sbellard         count -= len;
118783f64091Sbellard         if (count == 0)
118883f64091Sbellard             return count1;
118983f64091Sbellard         sector_num++;
119083f64091Sbellard         buf += len;
119183f64091Sbellard     }
119283f64091Sbellard 
119383f64091Sbellard     /* read the sectors "in place" */
11946ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
119583f64091Sbellard     if (nb_sectors > 0) {
11969a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11979a8c4cceSKevin Wolf             return ret;
119883f64091Sbellard         sector_num += nb_sectors;
11996ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
120083f64091Sbellard         buf += len;
120183f64091Sbellard         count -= len;
120283f64091Sbellard     }
120383f64091Sbellard 
120483f64091Sbellard     /* add data from the last sector */
120583f64091Sbellard     if (count > 0) {
12069a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12079a8c4cceSKevin Wolf             return ret;
120883f64091Sbellard         memcpy(buf, tmp_buf, count);
120983f64091Sbellard     }
121083f64091Sbellard     return count1;
121183f64091Sbellard }
121283f64091Sbellard 
1213eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1214eda578e5Saliguori                 const void *buf, int count1)
121583f64091Sbellard {
12166ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
121783f64091Sbellard     int len, nb_sectors, count;
121883f64091Sbellard     int64_t sector_num;
12199a8c4cceSKevin Wolf     int ret;
122083f64091Sbellard 
122183f64091Sbellard     count = count1;
122283f64091Sbellard     /* first write to align to sector start */
12236ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
122483f64091Sbellard     if (len > count)
122583f64091Sbellard         len = count;
12266ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
122783f64091Sbellard     if (len > 0) {
12289a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12299a8c4cceSKevin Wolf             return ret;
12306ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
12319a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12329a8c4cceSKevin Wolf             return ret;
123383f64091Sbellard         count -= len;
123483f64091Sbellard         if (count == 0)
123583f64091Sbellard             return count1;
123683f64091Sbellard         sector_num++;
123783f64091Sbellard         buf += len;
123883f64091Sbellard     }
123983f64091Sbellard 
124083f64091Sbellard     /* write the sectors "in place" */
12416ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
124283f64091Sbellard     if (nb_sectors > 0) {
12439a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12449a8c4cceSKevin Wolf             return ret;
124583f64091Sbellard         sector_num += nb_sectors;
12466ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
124783f64091Sbellard         buf += len;
124883f64091Sbellard         count -= len;
124983f64091Sbellard     }
125083f64091Sbellard 
125183f64091Sbellard     /* add data from the last sector */
125283f64091Sbellard     if (count > 0) {
12539a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12549a8c4cceSKevin Wolf             return ret;
125583f64091Sbellard         memcpy(tmp_buf, buf, count);
12569a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12579a8c4cceSKevin Wolf             return ret;
125883f64091Sbellard     }
125983f64091Sbellard     return count1;
126083f64091Sbellard }
126183f64091Sbellard 
1262f08145feSKevin Wolf /*
1263f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1264f08145feSKevin Wolf  * request (acts as a barrier)
1265f08145feSKevin Wolf  *
1266f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1267f08145feSKevin Wolf  */
1268f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1269f08145feSKevin Wolf     const void *buf, int count)
1270f08145feSKevin Wolf {
1271f08145feSKevin Wolf     int ret;
1272f08145feSKevin Wolf 
1273f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1274f08145feSKevin Wolf     if (ret < 0) {
1275f08145feSKevin Wolf         return ret;
1276f08145feSKevin Wolf     }
1277f08145feSKevin Wolf 
127892196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
127992196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1280f08145feSKevin Wolf         bdrv_flush(bs);
1281f08145feSKevin Wolf     }
1282f08145feSKevin Wolf 
1283f08145feSKevin Wolf     return 0;
1284f08145feSKevin Wolf }
1285f08145feSKevin Wolf 
1286c5fbe571SStefan Hajnoczi /*
1287c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1288c5fbe571SStefan Hajnoczi  */
1289c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1290c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1291da1fa91dSKevin Wolf {
1292da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1293da1fa91dSKevin Wolf 
1294da1fa91dSKevin Wolf     if (!drv) {
1295da1fa91dSKevin Wolf         return -ENOMEDIUM;
1296da1fa91dSKevin Wolf     }
1297da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1298da1fa91dSKevin Wolf         return -EIO;
1299da1fa91dSKevin Wolf     }
1300da1fa91dSKevin Wolf 
1301da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1302da1fa91dSKevin Wolf }
1303da1fa91dSKevin Wolf 
1304c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1305da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1306da1fa91dSKevin Wolf {
1307c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1308da1fa91dSKevin Wolf 
1309c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1310c5fbe571SStefan Hajnoczi }
1311c5fbe571SStefan Hajnoczi 
1312c5fbe571SStefan Hajnoczi /*
1313c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1314c5fbe571SStefan Hajnoczi  */
1315c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1316c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1317c5fbe571SStefan Hajnoczi {
1318c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
13196b7cb247SStefan Hajnoczi     int ret;
1320da1fa91dSKevin Wolf 
1321da1fa91dSKevin Wolf     if (!bs->drv) {
1322da1fa91dSKevin Wolf         return -ENOMEDIUM;
1323da1fa91dSKevin Wolf     }
1324da1fa91dSKevin Wolf     if (bs->read_only) {
1325da1fa91dSKevin Wolf         return -EACCES;
1326da1fa91dSKevin Wolf     }
1327da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1328da1fa91dSKevin Wolf         return -EIO;
1329da1fa91dSKevin Wolf     }
1330da1fa91dSKevin Wolf 
13316b7cb247SStefan Hajnoczi     ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
13326b7cb247SStefan Hajnoczi 
1333da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1334da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1335da1fa91dSKevin Wolf     }
1336da1fa91dSKevin Wolf 
1337da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1338da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1339da1fa91dSKevin Wolf     }
1340da1fa91dSKevin Wolf 
13416b7cb247SStefan Hajnoczi     return ret;
1342da1fa91dSKevin Wolf }
1343da1fa91dSKevin Wolf 
1344c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1345c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1346c5fbe571SStefan Hajnoczi {
1347c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1348c5fbe571SStefan Hajnoczi 
1349c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1350c5fbe571SStefan Hajnoczi }
1351c5fbe571SStefan Hajnoczi 
135283f64091Sbellard /**
135383f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
135483f64091Sbellard  */
135583f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
135683f64091Sbellard {
135783f64091Sbellard     BlockDriver *drv = bs->drv;
135851762288SStefan Hajnoczi     int ret;
135983f64091Sbellard     if (!drv)
136019cb3738Sbellard         return -ENOMEDIUM;
136183f64091Sbellard     if (!drv->bdrv_truncate)
136283f64091Sbellard         return -ENOTSUP;
136359f2689dSNaphtali Sprei     if (bs->read_only)
136459f2689dSNaphtali Sprei         return -EACCES;
13658591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13668591675fSMarcelo Tosatti         return -EBUSY;
136751762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
136851762288SStefan Hajnoczi     if (ret == 0) {
136951762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1370145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
137151762288SStefan Hajnoczi     }
137251762288SStefan Hajnoczi     return ret;
137383f64091Sbellard }
137483f64091Sbellard 
137583f64091Sbellard /**
13764a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13774a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13784a1d5e1fSFam Zheng  */
13794a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13804a1d5e1fSFam Zheng {
13814a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13824a1d5e1fSFam Zheng     if (!drv) {
13834a1d5e1fSFam Zheng         return -ENOMEDIUM;
13844a1d5e1fSFam Zheng     }
13854a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13864a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13874a1d5e1fSFam Zheng     }
13884a1d5e1fSFam Zheng     if (bs->file) {
13894a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13904a1d5e1fSFam Zheng     }
13914a1d5e1fSFam Zheng     return -ENOTSUP;
13924a1d5e1fSFam Zheng }
13934a1d5e1fSFam Zheng 
13944a1d5e1fSFam Zheng /**
139583f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
139683f64091Sbellard  */
139783f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
139883f64091Sbellard {
139983f64091Sbellard     BlockDriver *drv = bs->drv;
140083f64091Sbellard     if (!drv)
140119cb3738Sbellard         return -ENOMEDIUM;
140251762288SStefan Hajnoczi 
14032c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
140446a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
140583f64091Sbellard             return drv->bdrv_getlength(bs);
1406fc01f7e7Sbellard         }
140746a4e4e6SStefan Hajnoczi     }
140846a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
140946a4e4e6SStefan Hajnoczi }
1410fc01f7e7Sbellard 
141119cb3738Sbellard /* return 0 as number of sectors if no device present or error */
141296b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1413fc01f7e7Sbellard {
141419cb3738Sbellard     int64_t length;
141519cb3738Sbellard     length = bdrv_getlength(bs);
141619cb3738Sbellard     if (length < 0)
141719cb3738Sbellard         length = 0;
141819cb3738Sbellard     else
14196ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
142019cb3738Sbellard     *nb_sectors_ptr = length;
1421fc01f7e7Sbellard }
1422cf98951bSbellard 
1423f3d54fc4Saliguori struct partition {
1424f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1425f3d54fc4Saliguori         uint8_t head;               /* starting head */
1426f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1427f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1428f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1429f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1430f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1431f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1432f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1433f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1434541dc0d4SStefan Weil } QEMU_PACKED;
1435f3d54fc4Saliguori 
1436f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1437f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1438f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1439f3d54fc4Saliguori {
1440eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1441f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1442f3d54fc4Saliguori     struct partition *p;
1443f3d54fc4Saliguori     uint32_t nr_sects;
1444a38131b6Sblueswir1     uint64_t nb_sectors;
1445f3d54fc4Saliguori 
1446f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1447f3d54fc4Saliguori 
1448f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1449f3d54fc4Saliguori     if (ret < 0)
1450f3d54fc4Saliguori         return -1;
1451f3d54fc4Saliguori     /* test msdos magic */
1452f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1453f3d54fc4Saliguori         return -1;
1454f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1455f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1456f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1457f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1458f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1459f3d54fc4Saliguori                a cylinder boundary */
1460f3d54fc4Saliguori             heads = p->end_head + 1;
1461f3d54fc4Saliguori             sectors = p->end_sector & 63;
1462f3d54fc4Saliguori             if (sectors == 0)
1463f3d54fc4Saliguori                 continue;
1464f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1465f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1466f3d54fc4Saliguori                 continue;
1467f3d54fc4Saliguori             *pheads = heads;
1468f3d54fc4Saliguori             *psectors = sectors;
1469f3d54fc4Saliguori             *pcylinders = cylinders;
1470f3d54fc4Saliguori #if 0
1471f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1472f3d54fc4Saliguori                    cylinders, heads, sectors);
1473f3d54fc4Saliguori #endif
1474f3d54fc4Saliguori             return 0;
1475f3d54fc4Saliguori         }
1476f3d54fc4Saliguori     }
1477f3d54fc4Saliguori     return -1;
1478f3d54fc4Saliguori }
1479f3d54fc4Saliguori 
1480f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1481f3d54fc4Saliguori {
1482f3d54fc4Saliguori     int translation, lba_detected = 0;
1483f3d54fc4Saliguori     int cylinders, heads, secs;
1484a38131b6Sblueswir1     uint64_t nb_sectors;
1485f3d54fc4Saliguori 
1486f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1487f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1488f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1489f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1490f3d54fc4Saliguori     if (cylinders != 0) {
1491f3d54fc4Saliguori         *pcyls = cylinders;
1492f3d54fc4Saliguori         *pheads = heads;
1493f3d54fc4Saliguori         *psecs = secs;
1494f3d54fc4Saliguori     } else {
1495f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1496f3d54fc4Saliguori             if (heads > 16) {
1497f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1498f3d54fc4Saliguori                    translation was active, so the default
1499f3d54fc4Saliguori                    hardware geometry is OK */
1500f3d54fc4Saliguori                 lba_detected = 1;
1501f3d54fc4Saliguori                 goto default_geometry;
1502f3d54fc4Saliguori             } else {
1503f3d54fc4Saliguori                 *pcyls = cylinders;
1504f3d54fc4Saliguori                 *pheads = heads;
1505f3d54fc4Saliguori                 *psecs = secs;
1506f3d54fc4Saliguori                 /* disable any translation to be in sync with
1507f3d54fc4Saliguori                    the logical geometry */
1508f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1509f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1510f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1511f3d54fc4Saliguori                 }
1512f3d54fc4Saliguori             }
1513f3d54fc4Saliguori         } else {
1514f3d54fc4Saliguori         default_geometry:
1515f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1516f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1517f3d54fc4Saliguori 
1518f3d54fc4Saliguori             if (cylinders > 16383)
1519f3d54fc4Saliguori                 cylinders = 16383;
1520f3d54fc4Saliguori             else if (cylinders < 2)
1521f3d54fc4Saliguori                 cylinders = 2;
1522f3d54fc4Saliguori             *pcyls = cylinders;
1523f3d54fc4Saliguori             *pheads = 16;
1524f3d54fc4Saliguori             *psecs = 63;
1525f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1526f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1527f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1528f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1529f3d54fc4Saliguori                 } else {
1530f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1531f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1532f3d54fc4Saliguori                 }
1533f3d54fc4Saliguori             }
1534f3d54fc4Saliguori         }
1535f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1536f3d54fc4Saliguori     }
1537f3d54fc4Saliguori }
1538f3d54fc4Saliguori 
1539b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1540b338082bSbellard                             int cyls, int heads, int secs)
1541b338082bSbellard {
1542b338082bSbellard     bs->cyls = cyls;
1543b338082bSbellard     bs->heads = heads;
1544b338082bSbellard     bs->secs = secs;
1545b338082bSbellard }
1546b338082bSbellard 
154746d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
154846d4767dSbellard {
154946d4767dSbellard     bs->translation = translation;
155046d4767dSbellard }
155146d4767dSbellard 
1552b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1553b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1554b338082bSbellard {
1555b338082bSbellard     *pcyls = bs->cyls;
1556b338082bSbellard     *pheads = bs->heads;
1557b338082bSbellard     *psecs = bs->secs;
1558b338082bSbellard }
1559b338082bSbellard 
1560*0563e191SZhi Yong Wu /* throttling disk io limits */
1561*0563e191SZhi Yong Wu void bdrv_set_io_limits(BlockDriverState *bs,
1562*0563e191SZhi Yong Wu                         BlockIOLimit *io_limits)
1563*0563e191SZhi Yong Wu {
1564*0563e191SZhi Yong Wu     bs->io_limits = *io_limits;
1565*0563e191SZhi Yong Wu     bs->io_limits_enabled = bdrv_io_limits_enabled(bs);
1566*0563e191SZhi Yong Wu }
1567*0563e191SZhi Yong Wu 
15685bbdbb46SBlue Swirl /* Recognize floppy formats */
15695bbdbb46SBlue Swirl typedef struct FDFormat {
15705bbdbb46SBlue Swirl     FDriveType drive;
15715bbdbb46SBlue Swirl     uint8_t last_sect;
15725bbdbb46SBlue Swirl     uint8_t max_track;
15735bbdbb46SBlue Swirl     uint8_t max_head;
15745bbdbb46SBlue Swirl } FDFormat;
15755bbdbb46SBlue Swirl 
15765bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15775bbdbb46SBlue Swirl     /* First entry is default format */
15785bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15795bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15805bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15815bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15825bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15835bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15845bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15855bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15865bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15875bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15885bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15895bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15905bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15915bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15925bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15935bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15945bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15955bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15965bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15975bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15985bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15995bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
16005bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
16015bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
16025bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
16035bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
16045bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
16055bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
16065bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
16075bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
16085bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
16095bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
16105bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
16115bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
16125bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
16135bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
16145bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
16155bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
16165bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
16175bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
16185bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
16195bbdbb46SBlue Swirl     /* end */
16205bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
16215bbdbb46SBlue Swirl };
16225bbdbb46SBlue Swirl 
16235bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
16245bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
16255bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
16265bbdbb46SBlue Swirl {
16275bbdbb46SBlue Swirl     const FDFormat *parse;
16285bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
16295bbdbb46SBlue Swirl     int i, first_match, match;
16305bbdbb46SBlue Swirl 
16315bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
16325bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
16335bbdbb46SBlue Swirl         /* User defined disk */
16345bbdbb46SBlue Swirl     } else {
16355bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
16365bbdbb46SBlue Swirl         match = -1;
16375bbdbb46SBlue Swirl         first_match = -1;
16385bbdbb46SBlue Swirl         for (i = 0; ; i++) {
16395bbdbb46SBlue Swirl             parse = &fd_formats[i];
16405bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
16415bbdbb46SBlue Swirl                 break;
16425bbdbb46SBlue Swirl             }
16435bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
16445bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
16455bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
16465bbdbb46SBlue Swirl                     parse->last_sect;
16475bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16485bbdbb46SBlue Swirl                     match = i;
16495bbdbb46SBlue Swirl                     break;
16505bbdbb46SBlue Swirl                 }
16515bbdbb46SBlue Swirl                 if (first_match == -1) {
16525bbdbb46SBlue Swirl                     first_match = i;
16535bbdbb46SBlue Swirl                 }
16545bbdbb46SBlue Swirl             }
16555bbdbb46SBlue Swirl         }
16565bbdbb46SBlue Swirl         if (match == -1) {
16575bbdbb46SBlue Swirl             if (first_match == -1) {
16585bbdbb46SBlue Swirl                 match = 1;
16595bbdbb46SBlue Swirl             } else {
16605bbdbb46SBlue Swirl                 match = first_match;
16615bbdbb46SBlue Swirl             }
16625bbdbb46SBlue Swirl             parse = &fd_formats[match];
16635bbdbb46SBlue Swirl         }
16645bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16655bbdbb46SBlue Swirl         *max_track = parse->max_track;
16665bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16675bbdbb46SBlue Swirl         *drive = parse->drive;
16685bbdbb46SBlue Swirl     }
16695bbdbb46SBlue Swirl }
16705bbdbb46SBlue Swirl 
167146d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
167246d4767dSbellard {
167346d4767dSbellard     return bs->translation;
167446d4767dSbellard }
167546d4767dSbellard 
1676abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1677abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1678abd7f68dSMarkus Armbruster {
1679abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1680abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1681abd7f68dSMarkus Armbruster }
1682abd7f68dSMarkus Armbruster 
1683abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1684abd7f68dSMarkus Armbruster {
1685abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1686abd7f68dSMarkus Armbruster }
1687abd7f68dSMarkus Armbruster 
1688b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1689b338082bSbellard {
1690b338082bSbellard     return bs->read_only;
1691b338082bSbellard }
1692b338082bSbellard 
1693985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1694985a03b0Sths {
1695985a03b0Sths     return bs->sg;
1696985a03b0Sths }
1697985a03b0Sths 
1698e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1699e900a7b7SChristoph Hellwig {
1700e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1701e900a7b7SChristoph Hellwig }
1702e900a7b7SChristoph Hellwig 
1703ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1704ea2384d3Sbellard {
1705ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1706ea2384d3Sbellard         return 1;
1707ea2384d3Sbellard     return bs->encrypted;
1708ea2384d3Sbellard }
1709ea2384d3Sbellard 
1710c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1711c0f4ce77Saliguori {
1712c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1713c0f4ce77Saliguori 
1714c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1715c0f4ce77Saliguori         return 1;
1716c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1717c0f4ce77Saliguori }
1718c0f4ce77Saliguori 
1719ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1720ea2384d3Sbellard {
1721ea2384d3Sbellard     int ret;
1722ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1723ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1724ea2384d3Sbellard         if (ret < 0)
1725ea2384d3Sbellard             return ret;
1726ea2384d3Sbellard         if (!bs->encrypted)
1727ea2384d3Sbellard             return 0;
1728ea2384d3Sbellard     }
1729fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1730fd04a2aeSShahar Havivi         return -EINVAL;
1731fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1732fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1733fd04a2aeSShahar Havivi     }
1734c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1735bb5fc20fSaliguori     if (ret < 0) {
1736bb5fc20fSaliguori         bs->valid_key = 0;
1737bb5fc20fSaliguori     } else if (!bs->valid_key) {
1738bb5fc20fSaliguori         bs->valid_key = 1;
1739bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
17407d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1741bb5fc20fSaliguori     }
1742c0f4ce77Saliguori     return ret;
1743ea2384d3Sbellard }
1744ea2384d3Sbellard 
1745ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1746ea2384d3Sbellard {
174719cb3738Sbellard     if (!bs->drv) {
1748ea2384d3Sbellard         buf[0] = '\0';
1749ea2384d3Sbellard     } else {
1750ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1751ea2384d3Sbellard     }
1752ea2384d3Sbellard }
1753ea2384d3Sbellard 
1754ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1755ea2384d3Sbellard                          void *opaque)
1756ea2384d3Sbellard {
1757ea2384d3Sbellard     BlockDriver *drv;
1758ea2384d3Sbellard 
17598a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1760ea2384d3Sbellard         it(opaque, drv->format_name);
1761ea2384d3Sbellard     }
1762ea2384d3Sbellard }
1763ea2384d3Sbellard 
1764b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1765b338082bSbellard {
1766b338082bSbellard     BlockDriverState *bs;
1767b338082bSbellard 
17681b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17691b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1770b338082bSbellard             return bs;
1771b338082bSbellard         }
17721b7bdbc1SStefan Hajnoczi     }
1773b338082bSbellard     return NULL;
1774b338082bSbellard }
1775b338082bSbellard 
17762f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17772f399b0aSMarkus Armbruster {
17782f399b0aSMarkus Armbruster     if (!bs) {
17792f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17802f399b0aSMarkus Armbruster     }
17812f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17822f399b0aSMarkus Armbruster }
17832f399b0aSMarkus Armbruster 
178451de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
178581d0912dSbellard {
178681d0912dSbellard     BlockDriverState *bs;
178781d0912dSbellard 
17881b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
178951de9760Saliguori         it(opaque, bs);
179081d0912dSbellard     }
179181d0912dSbellard }
179281d0912dSbellard 
1793ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1794ea2384d3Sbellard {
1795ea2384d3Sbellard     return bs->device_name;
1796ea2384d3Sbellard }
1797ea2384d3Sbellard 
1798c6ca28d6Saliguori void bdrv_flush_all(void)
1799c6ca28d6Saliguori {
1800c6ca28d6Saliguori     BlockDriverState *bs;
1801c6ca28d6Saliguori 
18021b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1803c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1804c6ca28d6Saliguori             bdrv_flush(bs);
1805c6ca28d6Saliguori         }
18061b7bdbc1SStefan Hajnoczi     }
18071b7bdbc1SStefan Hajnoczi }
1808c6ca28d6Saliguori 
1809f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1810f2feebbdSKevin Wolf {
1811f2feebbdSKevin Wolf     assert(bs->drv);
1812f2feebbdSKevin Wolf 
1813336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1814336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1815f2feebbdSKevin Wolf     }
1816f2feebbdSKevin Wolf 
1817f2feebbdSKevin Wolf     return 1;
1818f2feebbdSKevin Wolf }
1819f2feebbdSKevin Wolf 
1820f58c7b35Sths /*
1821f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1822f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1823f58c7b35Sths  * hence all their sectors are reported as allocated.
1824f58c7b35Sths  *
1825f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1826f58c7b35Sths  * the specified sector) that are known to be in the same
1827f58c7b35Sths  * allocated/unallocated state.
1828f58c7b35Sths  *
1829f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1830f58c7b35Sths  */
1831f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1832f58c7b35Sths 	int *pnum)
1833f58c7b35Sths {
1834f58c7b35Sths     int64_t n;
1835f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1836f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1837f58c7b35Sths             *pnum = 0;
1838f58c7b35Sths             return 0;
1839f58c7b35Sths         }
1840f58c7b35Sths         n = bs->total_sectors - sector_num;
1841f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1842f58c7b35Sths         return 1;
1843f58c7b35Sths     }
1844f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1845f58c7b35Sths }
1846f58c7b35Sths 
18472582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18482582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18492582bfedSLuiz Capitulino {
18502582bfedSLuiz Capitulino     QObject *data;
18512582bfedSLuiz Capitulino     const char *action_str;
18522582bfedSLuiz Capitulino 
18532582bfedSLuiz Capitulino     switch (action) {
18542582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18552582bfedSLuiz Capitulino         action_str = "report";
18562582bfedSLuiz Capitulino         break;
18572582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18582582bfedSLuiz Capitulino         action_str = "ignore";
18592582bfedSLuiz Capitulino         break;
18602582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18612582bfedSLuiz Capitulino         action_str = "stop";
18622582bfedSLuiz Capitulino         break;
18632582bfedSLuiz Capitulino     default:
18642582bfedSLuiz Capitulino         abort();
18652582bfedSLuiz Capitulino     }
18662582bfedSLuiz Capitulino 
18672582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18682582bfedSLuiz Capitulino                               bdrv->device_name,
18692582bfedSLuiz Capitulino                               action_str,
18702582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18712582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18722582bfedSLuiz Capitulino 
18732582bfedSLuiz Capitulino     qobject_decref(data);
18742582bfedSLuiz Capitulino }
18752582bfedSLuiz Capitulino 
1876b2023818SLuiz Capitulino BlockInfoList *qmp_query_block(Error **errp)
1877b338082bSbellard {
1878b2023818SLuiz Capitulino     BlockInfoList *head = NULL, *cur_item = NULL;
1879d15e5465SLuiz Capitulino     BlockDriverState *bs;
1880d15e5465SLuiz Capitulino 
18811b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1882b2023818SLuiz Capitulino         BlockInfoList *info = g_malloc0(sizeof(*info));
1883d15e5465SLuiz Capitulino 
1884b2023818SLuiz Capitulino         info->value = g_malloc0(sizeof(*info->value));
1885b2023818SLuiz Capitulino         info->value->device = g_strdup(bs->device_name);
1886b2023818SLuiz Capitulino         info->value->type = g_strdup("unknown");
1887b2023818SLuiz Capitulino         info->value->locked = bdrv_dev_is_medium_locked(bs);
1888b2023818SLuiz Capitulino         info->value->removable = bdrv_dev_has_removable_media(bs);
1889d15e5465SLuiz Capitulino 
1890e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1891b2023818SLuiz Capitulino             info->value->has_tray_open = true;
1892b2023818SLuiz Capitulino             info->value->tray_open = bdrv_dev_is_tray_open(bs);
1893e4def80bSMarkus Armbruster         }
1894f04ef601SLuiz Capitulino 
1895f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1896b2023818SLuiz Capitulino             info->value->has_io_status = true;
1897b2023818SLuiz Capitulino             info->value->io_status = bs->iostatus;
1898f04ef601SLuiz Capitulino         }
1899f04ef601SLuiz Capitulino 
1900d15e5465SLuiz Capitulino         if (bs->drv) {
1901b2023818SLuiz Capitulino             info->value->has_inserted = true;
1902b2023818SLuiz Capitulino             info->value->inserted = g_malloc0(sizeof(*info->value->inserted));
1903b2023818SLuiz Capitulino             info->value->inserted->file = g_strdup(bs->filename);
1904b2023818SLuiz Capitulino             info->value->inserted->ro = bs->read_only;
1905b2023818SLuiz Capitulino             info->value->inserted->drv = g_strdup(bs->drv->format_name);
1906b2023818SLuiz Capitulino             info->value->inserted->encrypted = bs->encrypted;
1907b2023818SLuiz Capitulino             if (bs->backing_file[0]) {
1908b2023818SLuiz Capitulino                 info->value->inserted->has_backing_file = true;
1909b2023818SLuiz Capitulino                 info->value->inserted->backing_file = g_strdup(bs->backing_file);
1910b2023818SLuiz Capitulino             }
1911d15e5465SLuiz Capitulino         }
1912d15e5465SLuiz Capitulino 
1913b2023818SLuiz Capitulino         /* XXX: waiting for the qapi to support GSList */
1914b2023818SLuiz Capitulino         if (!cur_item) {
1915b2023818SLuiz Capitulino             head = cur_item = info;
1916b2023818SLuiz Capitulino         } else {
1917b2023818SLuiz Capitulino             cur_item->next = info;
1918b2023818SLuiz Capitulino             cur_item = info;
1919d15e5465SLuiz Capitulino         }
1920d15e5465SLuiz Capitulino     }
1921d15e5465SLuiz Capitulino 
1922b2023818SLuiz Capitulino     return head;
1923b338082bSbellard }
1924a36e69ddSths 
1925f11f57e4SLuiz Capitulino /* Consider exposing this as a full fledged QMP command */
1926f11f57e4SLuiz Capitulino static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp)
1927a36e69ddSths {
1928f11f57e4SLuiz Capitulino     BlockStats *s;
1929218a536aSLuiz Capitulino 
1930f11f57e4SLuiz Capitulino     s = g_malloc0(sizeof(*s));
1931218a536aSLuiz Capitulino 
1932f11f57e4SLuiz Capitulino     if (bs->device_name[0]) {
1933f11f57e4SLuiz Capitulino         s->has_device = true;
1934f11f57e4SLuiz Capitulino         s->device = g_strdup(bs->device_name);
1935218a536aSLuiz Capitulino     }
1936218a536aSLuiz Capitulino 
1937f11f57e4SLuiz Capitulino     s->stats = g_malloc0(sizeof(*s->stats));
1938f11f57e4SLuiz Capitulino     s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
1939f11f57e4SLuiz Capitulino     s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
1940f11f57e4SLuiz Capitulino     s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
1941f11f57e4SLuiz Capitulino     s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
1942f11f57e4SLuiz Capitulino     s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
1943f11f57e4SLuiz Capitulino     s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
1944f11f57e4SLuiz Capitulino     s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
1945f11f57e4SLuiz Capitulino     s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
1946f11f57e4SLuiz Capitulino     s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
1947294cc35fSKevin Wolf 
1948294cc35fSKevin Wolf     if (bs->file) {
1949f11f57e4SLuiz Capitulino         s->has_parent = true;
1950f11f57e4SLuiz Capitulino         s->parent = qmp_query_blockstat(bs->file, NULL);
1951294cc35fSKevin Wolf     }
1952294cc35fSKevin Wolf 
1953f11f57e4SLuiz Capitulino     return s;
1954294cc35fSKevin Wolf }
1955294cc35fSKevin Wolf 
1956f11f57e4SLuiz Capitulino BlockStatsList *qmp_query_blockstats(Error **errp)
1957218a536aSLuiz Capitulino {
1958f11f57e4SLuiz Capitulino     BlockStatsList *head = NULL, *cur_item = NULL;
1959a36e69ddSths     BlockDriverState *bs;
1960a36e69ddSths 
19611b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1962f11f57e4SLuiz Capitulino         BlockStatsList *info = g_malloc0(sizeof(*info));
1963f11f57e4SLuiz Capitulino         info->value = qmp_query_blockstat(bs, NULL);
1964f11f57e4SLuiz Capitulino 
1965f11f57e4SLuiz Capitulino         /* XXX: waiting for the qapi to support GSList */
1966f11f57e4SLuiz Capitulino         if (!cur_item) {
1967f11f57e4SLuiz Capitulino             head = cur_item = info;
1968f11f57e4SLuiz Capitulino         } else {
1969f11f57e4SLuiz Capitulino             cur_item->next = info;
1970f11f57e4SLuiz Capitulino             cur_item = info;
1971f11f57e4SLuiz Capitulino         }
1972a36e69ddSths     }
1973218a536aSLuiz Capitulino 
1974f11f57e4SLuiz Capitulino     return head;
1975a36e69ddSths }
1976ea2384d3Sbellard 
1977045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1978045df330Saliguori {
1979045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
1980045df330Saliguori         return bs->backing_file;
1981045df330Saliguori     else if (bs->encrypted)
1982045df330Saliguori         return bs->filename;
1983045df330Saliguori     else
1984045df330Saliguori         return NULL;
1985045df330Saliguori }
1986045df330Saliguori 
198783f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
198883f64091Sbellard                                char *filename, int filename_size)
198983f64091Sbellard {
199083f64091Sbellard     pstrcpy(filename, filename_size, bs->backing_file);
199183f64091Sbellard }
199283f64091Sbellard 
1993faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1994faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
1995faea38e7Sbellard {
1996faea38e7Sbellard     BlockDriver *drv = bs->drv;
1997faea38e7Sbellard     if (!drv)
199819cb3738Sbellard         return -ENOMEDIUM;
1999faea38e7Sbellard     if (!drv->bdrv_write_compressed)
2000faea38e7Sbellard         return -ENOTSUP;
2001fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
2002fbb7b4e0SKevin Wolf         return -EIO;
20037cd1e32aSlirans@il.ibm.com 
2004c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
20057cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
20067cd1e32aSlirans@il.ibm.com     }
20077cd1e32aSlirans@il.ibm.com 
2008faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2009faea38e7Sbellard }
2010faea38e7Sbellard 
2011faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2012faea38e7Sbellard {
2013faea38e7Sbellard     BlockDriver *drv = bs->drv;
2014faea38e7Sbellard     if (!drv)
201519cb3738Sbellard         return -ENOMEDIUM;
2016faea38e7Sbellard     if (!drv->bdrv_get_info)
2017faea38e7Sbellard         return -ENOTSUP;
2018faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2019faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2020faea38e7Sbellard }
2021faea38e7Sbellard 
202245566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
202345566e9cSChristoph Hellwig                       int64_t pos, int size)
2024178e08a5Saliguori {
2025178e08a5Saliguori     BlockDriver *drv = bs->drv;
2026178e08a5Saliguori     if (!drv)
2027178e08a5Saliguori         return -ENOMEDIUM;
20287cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
202945566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
20307cdb1f6dSMORITA Kazutaka     if (bs->file)
20317cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
20327cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2033178e08a5Saliguori }
2034178e08a5Saliguori 
203545566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
203645566e9cSChristoph Hellwig                       int64_t pos, int size)
2037178e08a5Saliguori {
2038178e08a5Saliguori     BlockDriver *drv = bs->drv;
2039178e08a5Saliguori     if (!drv)
2040178e08a5Saliguori         return -ENOMEDIUM;
20417cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
204245566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
20437cdb1f6dSMORITA Kazutaka     if (bs->file)
20447cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
20457cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2046178e08a5Saliguori }
2047178e08a5Saliguori 
20488b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
20498b9b0cc2SKevin Wolf {
20508b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
20518b9b0cc2SKevin Wolf 
20528b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
20538b9b0cc2SKevin Wolf         return;
20548b9b0cc2SKevin Wolf     }
20558b9b0cc2SKevin Wolf 
20568b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
20578b9b0cc2SKevin Wolf 
20588b9b0cc2SKevin Wolf }
20598b9b0cc2SKevin Wolf 
2060faea38e7Sbellard /**************************************************************/
2061faea38e7Sbellard /* handling of snapshots */
2062faea38e7Sbellard 
2063feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2064feeee5acSMiguel Di Ciurcio Filho {
2065feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
206607b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2067feeee5acSMiguel Di Ciurcio Filho         return 0;
2068feeee5acSMiguel Di Ciurcio Filho     }
2069feeee5acSMiguel Di Ciurcio Filho 
2070feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2071feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2072feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2073feeee5acSMiguel Di Ciurcio Filho         }
2074feeee5acSMiguel Di Ciurcio Filho         return 0;
2075feeee5acSMiguel Di Ciurcio Filho     }
2076feeee5acSMiguel Di Ciurcio Filho 
2077feeee5acSMiguel Di Ciurcio Filho     return 1;
2078feeee5acSMiguel Di Ciurcio Filho }
2079feeee5acSMiguel Di Ciurcio Filho 
2080199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2081199630b6SBlue Swirl {
2082199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2083199630b6SBlue Swirl }
2084199630b6SBlue Swirl 
2085f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2086f9092b10SMarkus Armbruster {
2087f9092b10SMarkus Armbruster     BlockDriverState *bs;
2088f9092b10SMarkus Armbruster 
20893ac906f7SMarkus Armbruster     if (bs_snapshots) {
2090f9092b10SMarkus Armbruster         return bs_snapshots;
20913ac906f7SMarkus Armbruster     }
2092f9092b10SMarkus Armbruster 
2093f9092b10SMarkus Armbruster     bs = NULL;
2094f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2095f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
20963ac906f7SMarkus Armbruster             bs_snapshots = bs;
20973ac906f7SMarkus Armbruster             return bs;
2098f9092b10SMarkus Armbruster         }
2099f9092b10SMarkus Armbruster     }
2100f9092b10SMarkus Armbruster     return NULL;
2101f9092b10SMarkus Armbruster }
2102f9092b10SMarkus Armbruster 
2103faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2104faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2105faea38e7Sbellard {
2106faea38e7Sbellard     BlockDriver *drv = bs->drv;
2107faea38e7Sbellard     if (!drv)
210819cb3738Sbellard         return -ENOMEDIUM;
21097cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2110faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
21117cdb1f6dSMORITA Kazutaka     if (bs->file)
21127cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
21137cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2114faea38e7Sbellard }
2115faea38e7Sbellard 
2116faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2117faea38e7Sbellard                        const char *snapshot_id)
2118faea38e7Sbellard {
2119faea38e7Sbellard     BlockDriver *drv = bs->drv;
21207cdb1f6dSMORITA Kazutaka     int ret, open_ret;
21217cdb1f6dSMORITA Kazutaka 
2122faea38e7Sbellard     if (!drv)
212319cb3738Sbellard         return -ENOMEDIUM;
21247cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2125faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
21267cdb1f6dSMORITA Kazutaka 
21277cdb1f6dSMORITA Kazutaka     if (bs->file) {
21287cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
21297cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
21307cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
21317cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
21327cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
21337cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
21347cdb1f6dSMORITA Kazutaka             return open_ret;
21357cdb1f6dSMORITA Kazutaka         }
21367cdb1f6dSMORITA Kazutaka         return ret;
21377cdb1f6dSMORITA Kazutaka     }
21387cdb1f6dSMORITA Kazutaka 
21397cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2140faea38e7Sbellard }
2141faea38e7Sbellard 
2142faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2143faea38e7Sbellard {
2144faea38e7Sbellard     BlockDriver *drv = bs->drv;
2145faea38e7Sbellard     if (!drv)
214619cb3738Sbellard         return -ENOMEDIUM;
21477cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2148faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
21497cdb1f6dSMORITA Kazutaka     if (bs->file)
21507cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
21517cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2152faea38e7Sbellard }
2153faea38e7Sbellard 
2154faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2155faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2156faea38e7Sbellard {
2157faea38e7Sbellard     BlockDriver *drv = bs->drv;
2158faea38e7Sbellard     if (!drv)
215919cb3738Sbellard         return -ENOMEDIUM;
21607cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2161faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
21627cdb1f6dSMORITA Kazutaka     if (bs->file)
21637cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
21647cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2165faea38e7Sbellard }
2166faea38e7Sbellard 
216751ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
216851ef6727Sedison         const char *snapshot_name)
216951ef6727Sedison {
217051ef6727Sedison     BlockDriver *drv = bs->drv;
217151ef6727Sedison     if (!drv) {
217251ef6727Sedison         return -ENOMEDIUM;
217351ef6727Sedison     }
217451ef6727Sedison     if (!bs->read_only) {
217551ef6727Sedison         return -EINVAL;
217651ef6727Sedison     }
217751ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
217851ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
217951ef6727Sedison     }
218051ef6727Sedison     return -ENOTSUP;
218151ef6727Sedison }
218251ef6727Sedison 
2183faea38e7Sbellard #define NB_SUFFIXES 4
2184faea38e7Sbellard 
2185faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2186faea38e7Sbellard {
2187faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2188faea38e7Sbellard     int64_t base;
2189faea38e7Sbellard     int i;
2190faea38e7Sbellard 
2191faea38e7Sbellard     if (size <= 999) {
2192faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2193faea38e7Sbellard     } else {
2194faea38e7Sbellard         base = 1024;
2195faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2196faea38e7Sbellard             if (size < (10 * base)) {
2197faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2198faea38e7Sbellard                          (double)size / base,
2199faea38e7Sbellard                          suffixes[i]);
2200faea38e7Sbellard                 break;
2201faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2202faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2203faea38e7Sbellard                          ((size + (base >> 1)) / base),
2204faea38e7Sbellard                          suffixes[i]);
2205faea38e7Sbellard                 break;
2206faea38e7Sbellard             }
2207faea38e7Sbellard             base = base * 1024;
2208faea38e7Sbellard         }
2209faea38e7Sbellard     }
2210faea38e7Sbellard     return buf;
2211faea38e7Sbellard }
2212faea38e7Sbellard 
2213faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2214faea38e7Sbellard {
2215faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
22163b9f94e1Sbellard #ifdef _WIN32
22173b9f94e1Sbellard     struct tm *ptm;
22183b9f94e1Sbellard #else
2219faea38e7Sbellard     struct tm tm;
22203b9f94e1Sbellard #endif
2221faea38e7Sbellard     time_t ti;
2222faea38e7Sbellard     int64_t secs;
2223faea38e7Sbellard 
2224faea38e7Sbellard     if (!sn) {
2225faea38e7Sbellard         snprintf(buf, buf_size,
2226faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2227faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2228faea38e7Sbellard     } else {
2229faea38e7Sbellard         ti = sn->date_sec;
22303b9f94e1Sbellard #ifdef _WIN32
22313b9f94e1Sbellard         ptm = localtime(&ti);
22323b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
22333b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
22343b9f94e1Sbellard #else
2235faea38e7Sbellard         localtime_r(&ti, &tm);
2236faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2237faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
22383b9f94e1Sbellard #endif
2239faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2240faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2241faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2242faea38e7Sbellard                  (int)(secs / 3600),
2243faea38e7Sbellard                  (int)((secs / 60) % 60),
2244faea38e7Sbellard                  (int)(secs % 60),
2245faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2246faea38e7Sbellard         snprintf(buf, buf_size,
2247faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2248faea38e7Sbellard                  sn->id_str, sn->name,
2249faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2250faea38e7Sbellard                  date_buf,
2251faea38e7Sbellard                  clock_buf);
2252faea38e7Sbellard     }
2253faea38e7Sbellard     return buf;
2254faea38e7Sbellard }
2255faea38e7Sbellard 
2256ea2384d3Sbellard /**************************************************************/
225783f64091Sbellard /* async I/Os */
2258ea2384d3Sbellard 
22593b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2260f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
226183f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2262ea2384d3Sbellard {
2263bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2264bbf0a440SStefan Hajnoczi 
2265b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22668c5873d6SStefan Hajnoczi                                  cb, opaque, false);
226783f64091Sbellard }
226883f64091Sbellard 
2269f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2270f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
227183f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
22727674e7bfSbellard {
2273bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2274bbf0a440SStefan Hajnoczi 
22751a6e115bSStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22768c5873d6SStefan Hajnoczi                                  cb, opaque, true);
227783f64091Sbellard }
227883f64091Sbellard 
227940b4f539SKevin Wolf 
228040b4f539SKevin Wolf typedef struct MultiwriteCB {
228140b4f539SKevin Wolf     int error;
228240b4f539SKevin Wolf     int num_requests;
228340b4f539SKevin Wolf     int num_callbacks;
228440b4f539SKevin Wolf     struct {
228540b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
228640b4f539SKevin Wolf         void *opaque;
228740b4f539SKevin Wolf         QEMUIOVector *free_qiov;
228840b4f539SKevin Wolf         void *free_buf;
228940b4f539SKevin Wolf     } callbacks[];
229040b4f539SKevin Wolf } MultiwriteCB;
229140b4f539SKevin Wolf 
229240b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
229340b4f539SKevin Wolf {
229440b4f539SKevin Wolf     int i;
229540b4f539SKevin Wolf 
229640b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
229740b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
22981e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
22991e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
23001e1ea48dSStefan Hajnoczi         }
23017267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2302f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
230340b4f539SKevin Wolf     }
230440b4f539SKevin Wolf }
230540b4f539SKevin Wolf 
230640b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
230740b4f539SKevin Wolf {
230840b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
230940b4f539SKevin Wolf 
23106d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
23116d519a5fSStefan Hajnoczi 
2312cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
231340b4f539SKevin Wolf         mcb->error = ret;
231440b4f539SKevin Wolf     }
231540b4f539SKevin Wolf 
231640b4f539SKevin Wolf     mcb->num_requests--;
231740b4f539SKevin Wolf     if (mcb->num_requests == 0) {
231840b4f539SKevin Wolf         multiwrite_user_cb(mcb);
23197267c094SAnthony Liguori         g_free(mcb);
232040b4f539SKevin Wolf     }
232140b4f539SKevin Wolf }
232240b4f539SKevin Wolf 
232340b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
232440b4f539SKevin Wolf {
232577be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
232677be4366SChristoph Hellwig 
232777be4366SChristoph Hellwig     /*
232877be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
232977be4366SChristoph Hellwig      * here as that could overflow the return value.
233077be4366SChristoph Hellwig      */
233177be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
233277be4366SChristoph Hellwig         return 1;
233377be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
233477be4366SChristoph Hellwig         return -1;
233577be4366SChristoph Hellwig     } else {
233677be4366SChristoph Hellwig         return 0;
233777be4366SChristoph Hellwig     }
233840b4f539SKevin Wolf }
233940b4f539SKevin Wolf 
234040b4f539SKevin Wolf /*
234140b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
234240b4f539SKevin Wolf  * requests that remain after merging.
234340b4f539SKevin Wolf  */
234440b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
234540b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
234640b4f539SKevin Wolf {
234740b4f539SKevin Wolf     int i, outidx;
234840b4f539SKevin Wolf 
234940b4f539SKevin Wolf     // Sort requests by start sector
235040b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
235140b4f539SKevin Wolf 
235240b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
235340b4f539SKevin Wolf     // filling up gaps with zero sectors.
235440b4f539SKevin Wolf     outidx = 0;
235540b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
235640b4f539SKevin Wolf         int merge = 0;
235740b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
235840b4f539SKevin Wolf 
235940b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
236040b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
236140b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
236240b4f539SKevin Wolf             merge = 1;
236340b4f539SKevin Wolf         }
236440b4f539SKevin Wolf 
236540b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
236640b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
236740b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
236840b4f539SKevin Wolf         // unused space in format like qcow2).
236940b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
237040b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
237140b4f539SKevin Wolf         }
237240b4f539SKevin Wolf 
2373e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2374e2a305fbSChristoph Hellwig             merge = 0;
2375e2a305fbSChristoph Hellwig         }
2376e2a305fbSChristoph Hellwig 
237740b4f539SKevin Wolf         if (merge) {
237840b4f539SKevin Wolf             size_t size;
23797267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
238040b4f539SKevin Wolf             qemu_iovec_init(qiov,
238140b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
238240b4f539SKevin Wolf 
238340b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
238440b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
238540b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
238640b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
238740b4f539SKevin Wolf 
238840b4f539SKevin Wolf             // We might need to add some zeros between the two requests
238940b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
239040b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
239140b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
239240b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
239340b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
239440b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
239540b4f539SKevin Wolf             }
239640b4f539SKevin Wolf 
239740b4f539SKevin Wolf             // Add the second request
239840b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
239940b4f539SKevin Wolf 
2400cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
240140b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
240240b4f539SKevin Wolf 
240340b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
240440b4f539SKevin Wolf         } else {
240540b4f539SKevin Wolf             outidx++;
240640b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
240740b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
240840b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
240940b4f539SKevin Wolf         }
241040b4f539SKevin Wolf     }
241140b4f539SKevin Wolf 
241240b4f539SKevin Wolf     return outidx + 1;
241340b4f539SKevin Wolf }
241440b4f539SKevin Wolf 
241540b4f539SKevin Wolf /*
241640b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
241740b4f539SKevin Wolf  *
241840b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
241940b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
242040b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
242140b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
242240b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
242340b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
242440b4f539SKevin Wolf  *
242540b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
242640b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
242740b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
242840b4f539SKevin Wolf  */
242940b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
243040b4f539SKevin Wolf {
243140b4f539SKevin Wolf     BlockDriverAIOCB *acb;
243240b4f539SKevin Wolf     MultiwriteCB *mcb;
243340b4f539SKevin Wolf     int i;
243440b4f539SKevin Wolf 
2435301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2436301db7c2SRyan Harper     if (bs->drv == NULL) {
2437301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2438301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2439301db7c2SRyan Harper         }
2440301db7c2SRyan Harper         return -1;
2441301db7c2SRyan Harper     }
2442301db7c2SRyan Harper 
244340b4f539SKevin Wolf     if (num_reqs == 0) {
244440b4f539SKevin Wolf         return 0;
244540b4f539SKevin Wolf     }
244640b4f539SKevin Wolf 
244740b4f539SKevin Wolf     // Create MultiwriteCB structure
24487267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
244940b4f539SKevin Wolf     mcb->num_requests = 0;
245040b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
245140b4f539SKevin Wolf 
245240b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
245340b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
245440b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
245540b4f539SKevin Wolf     }
245640b4f539SKevin Wolf 
245740b4f539SKevin Wolf     // Check for mergable requests
245840b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
245940b4f539SKevin Wolf 
24606d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
24616d519a5fSStefan Hajnoczi 
2462453f9a16SKevin Wolf     /*
2463453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2464453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2465453f9a16SKevin Wolf      * return failure for all requests anyway)
2466453f9a16SKevin Wolf      *
2467453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2468453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2469453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2470453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2471453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2472453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2473453f9a16SKevin Wolf      * incremented for each request that is submitted.
2474453f9a16SKevin Wolf      *
2475453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2476453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2477453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2478453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2479453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2480453f9a16SKevin Wolf      */
2481453f9a16SKevin Wolf     mcb->num_requests = 1;
2482453f9a16SKevin Wolf 
24836d519a5fSStefan Hajnoczi     // Run the aio requests
248440b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2485453f9a16SKevin Wolf         mcb->num_requests++;
248640b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
248740b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
248840b4f539SKevin Wolf 
248940b4f539SKevin Wolf         if (acb == NULL) {
249040b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
249140b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
249240b4f539SKevin Wolf             // complete and report the error in the callback.
2493453f9a16SKevin Wolf             if (i == 0) {
24946d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
249540b4f539SKevin Wolf                 goto fail;
249640b4f539SKevin Wolf             } else {
24976d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
24987eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
249940b4f539SKevin Wolf                 break;
250040b4f539SKevin Wolf             }
250140b4f539SKevin Wolf         }
250240b4f539SKevin Wolf     }
250340b4f539SKevin Wolf 
2504453f9a16SKevin Wolf     /* Complete the dummy request */
2505453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2506453f9a16SKevin Wolf 
250740b4f539SKevin Wolf     return 0;
250840b4f539SKevin Wolf 
250940b4f539SKevin Wolf fail:
2510453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2511453f9a16SKevin Wolf         reqs[i].error = -EIO;
2512453f9a16SKevin Wolf     }
25137267c094SAnthony Liguori     g_free(mcb);
251440b4f539SKevin Wolf     return -1;
251540b4f539SKevin Wolf }
251640b4f539SKevin Wolf 
251783f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
251883f64091Sbellard {
25196bbff9a0Saliguori     acb->pool->cancel(acb);
252083f64091Sbellard }
252183f64091Sbellard 
252283f64091Sbellard 
252383f64091Sbellard /**************************************************************/
252483f64091Sbellard /* async block device emulation */
252583f64091Sbellard 
2526c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2527c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2528c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2529c16b5a2cSChristoph Hellwig     int ret;
2530c16b5a2cSChristoph Hellwig     /* vector translation state */
2531c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2532c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2533c16b5a2cSChristoph Hellwig     int is_write;
2534c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2535c16b5a2cSChristoph Hellwig 
2536c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2537c16b5a2cSChristoph Hellwig {
2538b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2539b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
25406a7ad299SDor Laor     qemu_bh_delete(acb->bh);
254136afc451SAvi Kivity     acb->bh = NULL;
2542c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2543c16b5a2cSChristoph Hellwig }
2544c16b5a2cSChristoph Hellwig 
2545c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2546c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2547c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2548c16b5a2cSChristoph Hellwig };
2549c16b5a2cSChristoph Hellwig 
255083f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2551beac80cdSbellard {
2552ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2553f141eafeSaliguori 
2554f141eafeSaliguori     if (!acb->is_write)
2555f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2556ceb42de8Saliguori     qemu_vfree(acb->bounce);
2557ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
25586a7ad299SDor Laor     qemu_bh_delete(acb->bh);
255936afc451SAvi Kivity     acb->bh = NULL;
2560ce1a14dcSpbrook     qemu_aio_release(acb);
2561beac80cdSbellard }
2562beac80cdSbellard 
2563f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2564f141eafeSaliguori                                             int64_t sector_num,
2565f141eafeSaliguori                                             QEMUIOVector *qiov,
2566f141eafeSaliguori                                             int nb_sectors,
2567f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2568f141eafeSaliguori                                             void *opaque,
2569f141eafeSaliguori                                             int is_write)
2570f141eafeSaliguori 
2571ea2384d3Sbellard {
2572ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
257383f64091Sbellard 
2574c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2575f141eafeSaliguori     acb->is_write = is_write;
2576f141eafeSaliguori     acb->qiov = qiov;
2577e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2578f141eafeSaliguori 
2579ce1a14dcSpbrook     if (!acb->bh)
2580ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2581f141eafeSaliguori 
2582f141eafeSaliguori     if (is_write) {
2583f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
25841ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2585f141eafeSaliguori     } else {
25861ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2587f141eafeSaliguori     }
2588f141eafeSaliguori 
2589ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2590f141eafeSaliguori 
2591ce1a14dcSpbrook     return &acb->common;
25927a6cba61Spbrook }
25937a6cba61Spbrook 
2594f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2595f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2596ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
259783f64091Sbellard {
2598f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
259983f64091Sbellard }
260083f64091Sbellard 
2601f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2602f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2603f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2604f141eafeSaliguori {
2605f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2606f141eafeSaliguori }
2607f141eafeSaliguori 
260868485420SKevin Wolf 
260968485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
261068485420SKevin Wolf     BlockDriverAIOCB common;
261168485420SKevin Wolf     BlockRequest req;
261268485420SKevin Wolf     bool is_write;
261368485420SKevin Wolf     QEMUBH* bh;
261468485420SKevin Wolf } BlockDriverAIOCBCoroutine;
261568485420SKevin Wolf 
261668485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
261768485420SKevin Wolf {
261868485420SKevin Wolf     qemu_aio_flush();
261968485420SKevin Wolf }
262068485420SKevin Wolf 
262168485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
262268485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
262368485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
262468485420SKevin Wolf };
262568485420SKevin Wolf 
262635246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque)
262768485420SKevin Wolf {
262868485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
262968485420SKevin Wolf 
263068485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
263168485420SKevin Wolf     qemu_bh_delete(acb->bh);
263268485420SKevin Wolf     qemu_aio_release(acb);
263368485420SKevin Wolf }
263468485420SKevin Wolf 
2635b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2636b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2637b2a61371SStefan Hajnoczi {
2638b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2639b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2640b2a61371SStefan Hajnoczi 
2641b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2642b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2643b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2644b2a61371SStefan Hajnoczi     } else {
2645b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2646b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2647b2a61371SStefan Hajnoczi     }
2648b2a61371SStefan Hajnoczi 
264935246a68SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2650b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2651b2a61371SStefan Hajnoczi }
2652b2a61371SStefan Hajnoczi 
265368485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
265468485420SKevin Wolf                                                int64_t sector_num,
265568485420SKevin Wolf                                                QEMUIOVector *qiov,
265668485420SKevin Wolf                                                int nb_sectors,
265768485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
265868485420SKevin Wolf                                                void *opaque,
26598c5873d6SStefan Hajnoczi                                                bool is_write)
266068485420SKevin Wolf {
266168485420SKevin Wolf     Coroutine *co;
266268485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
266368485420SKevin Wolf 
266468485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
266568485420SKevin Wolf     acb->req.sector = sector_num;
266668485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
266768485420SKevin Wolf     acb->req.qiov = qiov;
266868485420SKevin Wolf     acb->is_write = is_write;
266968485420SKevin Wolf 
26708c5873d6SStefan Hajnoczi     co = qemu_coroutine_create(bdrv_co_do_rw);
267168485420SKevin Wolf     qemu_coroutine_enter(co, acb);
267268485420SKevin Wolf 
267368485420SKevin Wolf     return &acb->common;
267468485420SKevin Wolf }
267568485420SKevin Wolf 
267607f07615SPaolo Bonzini static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
2677b2e12bc6SChristoph Hellwig {
267807f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
267907f07615SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
2680b2e12bc6SChristoph Hellwig 
268107f07615SPaolo Bonzini     acb->req.error = bdrv_co_flush(bs);
268207f07615SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2683b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2684b2e12bc6SChristoph Hellwig }
2685b2e12bc6SChristoph Hellwig 
268607f07615SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2687016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2688016f5cf6SAlexander Graf {
268907f07615SPaolo Bonzini     trace_bdrv_aio_flush(bs, opaque);
2690016f5cf6SAlexander Graf 
269107f07615SPaolo Bonzini     Coroutine *co;
269207f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
2693016f5cf6SAlexander Graf 
269407f07615SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
269507f07615SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
269607f07615SPaolo Bonzini     qemu_coroutine_enter(co, acb);
2697016f5cf6SAlexander Graf 
2698016f5cf6SAlexander Graf     return &acb->common;
2699016f5cf6SAlexander Graf }
2700016f5cf6SAlexander Graf 
27014265d620SPaolo Bonzini static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
27024265d620SPaolo Bonzini {
27034265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
27044265d620SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
27054265d620SPaolo Bonzini 
27064265d620SPaolo Bonzini     acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
27074265d620SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
27084265d620SPaolo Bonzini     qemu_bh_schedule(acb->bh);
27094265d620SPaolo Bonzini }
27104265d620SPaolo Bonzini 
27114265d620SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
27124265d620SPaolo Bonzini         int64_t sector_num, int nb_sectors,
27134265d620SPaolo Bonzini         BlockDriverCompletionFunc *cb, void *opaque)
27144265d620SPaolo Bonzini {
27154265d620SPaolo Bonzini     Coroutine *co;
27164265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
27174265d620SPaolo Bonzini 
27184265d620SPaolo Bonzini     trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
27194265d620SPaolo Bonzini 
27204265d620SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
27214265d620SPaolo Bonzini     acb->req.sector = sector_num;
27224265d620SPaolo Bonzini     acb->req.nb_sectors = nb_sectors;
27234265d620SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
27244265d620SPaolo Bonzini     qemu_coroutine_enter(co, acb);
27254265d620SPaolo Bonzini 
27264265d620SPaolo Bonzini     return &acb->common;
27274265d620SPaolo Bonzini }
27284265d620SPaolo Bonzini 
2729ea2384d3Sbellard void bdrv_init(void)
2730ea2384d3Sbellard {
27315efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2732ea2384d3Sbellard }
2733ce1a14dcSpbrook 
2734eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2735eb852011SMarkus Armbruster {
2736eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2737eb852011SMarkus Armbruster     bdrv_init();
2738eb852011SMarkus Armbruster }
2739eb852011SMarkus Armbruster 
2740c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
27416bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
27426bbff9a0Saliguori {
2743ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2744ce1a14dcSpbrook 
27456bbff9a0Saliguori     if (pool->free_aiocb) {
27466bbff9a0Saliguori         acb = pool->free_aiocb;
27476bbff9a0Saliguori         pool->free_aiocb = acb->next;
2748ce1a14dcSpbrook     } else {
27497267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
27506bbff9a0Saliguori         acb->pool = pool;
2751ce1a14dcSpbrook     }
2752ce1a14dcSpbrook     acb->bs = bs;
2753ce1a14dcSpbrook     acb->cb = cb;
2754ce1a14dcSpbrook     acb->opaque = opaque;
2755ce1a14dcSpbrook     return acb;
2756ce1a14dcSpbrook }
2757ce1a14dcSpbrook 
2758ce1a14dcSpbrook void qemu_aio_release(void *p)
2759ce1a14dcSpbrook {
27606bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
27616bbff9a0Saliguori     AIOPool *pool = acb->pool;
27626bbff9a0Saliguori     acb->next = pool->free_aiocb;
27636bbff9a0Saliguori     pool->free_aiocb = acb;
2764ce1a14dcSpbrook }
276519cb3738Sbellard 
276619cb3738Sbellard /**************************************************************/
2767f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2768f9f05dc5SKevin Wolf 
2769f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2770f9f05dc5SKevin Wolf     Coroutine *coroutine;
2771f9f05dc5SKevin Wolf     int ret;
2772f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2773f9f05dc5SKevin Wolf 
2774f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2775f9f05dc5SKevin Wolf {
2776f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2777f9f05dc5SKevin Wolf 
2778f9f05dc5SKevin Wolf     co->ret = ret;
2779f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
2780f9f05dc5SKevin Wolf }
2781f9f05dc5SKevin Wolf 
2782f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
2783f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
2784f9f05dc5SKevin Wolf                                       bool is_write)
2785f9f05dc5SKevin Wolf {
2786f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
2787f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
2788f9f05dc5SKevin Wolf     };
2789f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
2790f9f05dc5SKevin Wolf 
2791f9f05dc5SKevin Wolf     if (is_write) {
2792a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
2793f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
2794f9f05dc5SKevin Wolf     } else {
2795a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
2796f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
2797f9f05dc5SKevin Wolf     }
2798f9f05dc5SKevin Wolf 
279959370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
2800f9f05dc5SKevin Wolf     if (!acb) {
2801f9f05dc5SKevin Wolf         return -EIO;
2802f9f05dc5SKevin Wolf     }
2803f9f05dc5SKevin Wolf     qemu_coroutine_yield();
2804f9f05dc5SKevin Wolf 
2805f9f05dc5SKevin Wolf     return co.ret;
2806f9f05dc5SKevin Wolf }
2807f9f05dc5SKevin Wolf 
2808f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
2809f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2810f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2811f9f05dc5SKevin Wolf {
2812f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
2813f9f05dc5SKevin Wolf }
2814f9f05dc5SKevin Wolf 
2815f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
2816f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2817f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2818f9f05dc5SKevin Wolf {
2819f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
2820f9f05dc5SKevin Wolf }
2821f9f05dc5SKevin Wolf 
282207f07615SPaolo Bonzini static void coroutine_fn bdrv_flush_co_entry(void *opaque)
2823e7a8a783SKevin Wolf {
282407f07615SPaolo Bonzini     RwCo *rwco = opaque;
282507f07615SPaolo Bonzini 
282607f07615SPaolo Bonzini     rwco->ret = bdrv_co_flush(rwco->bs);
282707f07615SPaolo Bonzini }
282807f07615SPaolo Bonzini 
282907f07615SPaolo Bonzini int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
283007f07615SPaolo Bonzini {
2831eb489bb1SKevin Wolf     int ret;
2832eb489bb1SKevin Wolf 
2833ca716364SKevin Wolf     if (!bs->drv) {
283407f07615SPaolo Bonzini         return 0;
2835eb489bb1SKevin Wolf     }
2836eb489bb1SKevin Wolf 
2837ca716364SKevin Wolf     /* Write back cached data to the OS even with cache=unsafe */
2838eb489bb1SKevin Wolf     if (bs->drv->bdrv_co_flush_to_os) {
2839eb489bb1SKevin Wolf         ret = bs->drv->bdrv_co_flush_to_os(bs);
2840eb489bb1SKevin Wolf         if (ret < 0) {
2841eb489bb1SKevin Wolf             return ret;
2842eb489bb1SKevin Wolf         }
2843eb489bb1SKevin Wolf     }
2844eb489bb1SKevin Wolf 
2845ca716364SKevin Wolf     /* But don't actually force it to the disk with cache=unsafe */
2846ca716364SKevin Wolf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
2847ca716364SKevin Wolf         return 0;
2848ca716364SKevin Wolf     }
2849ca716364SKevin Wolf 
2850eb489bb1SKevin Wolf     if (bs->drv->bdrv_co_flush_to_disk) {
2851c68b89acSKevin Wolf         return bs->drv->bdrv_co_flush_to_disk(bs);
285207f07615SPaolo Bonzini     } else if (bs->drv->bdrv_aio_flush) {
285307f07615SPaolo Bonzini         BlockDriverAIOCB *acb;
2854e7a8a783SKevin Wolf         CoroutineIOCompletion co = {
2855e7a8a783SKevin Wolf             .coroutine = qemu_coroutine_self(),
2856e7a8a783SKevin Wolf         };
2857e7a8a783SKevin Wolf 
285807f07615SPaolo Bonzini         acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
285907f07615SPaolo Bonzini         if (acb == NULL) {
2860e7a8a783SKevin Wolf             return -EIO;
286107f07615SPaolo Bonzini         } else {
2862e7a8a783SKevin Wolf             qemu_coroutine_yield();
2863e7a8a783SKevin Wolf             return co.ret;
2864e7a8a783SKevin Wolf         }
286507f07615SPaolo Bonzini     } else {
286607f07615SPaolo Bonzini         /*
286707f07615SPaolo Bonzini          * Some block drivers always operate in either writethrough or unsafe
286807f07615SPaolo Bonzini          * mode and don't support bdrv_flush therefore. Usually qemu doesn't
286907f07615SPaolo Bonzini          * know how the server works (because the behaviour is hardcoded or
287007f07615SPaolo Bonzini          * depends on server-side configuration), so we can't ensure that
287107f07615SPaolo Bonzini          * everything is safe on disk. Returning an error doesn't work because
287207f07615SPaolo Bonzini          * that would break guests even if the server operates in writethrough
287307f07615SPaolo Bonzini          * mode.
287407f07615SPaolo Bonzini          *
287507f07615SPaolo Bonzini          * Let's hope the user knows what he's doing.
287607f07615SPaolo Bonzini          */
287707f07615SPaolo Bonzini         return 0;
287807f07615SPaolo Bonzini     }
287907f07615SPaolo Bonzini }
288007f07615SPaolo Bonzini 
28810f15423cSAnthony Liguori void bdrv_invalidate_cache(BlockDriverState *bs)
28820f15423cSAnthony Liguori {
28830f15423cSAnthony Liguori     if (bs->drv && bs->drv->bdrv_invalidate_cache) {
28840f15423cSAnthony Liguori         bs->drv->bdrv_invalidate_cache(bs);
28850f15423cSAnthony Liguori     }
28860f15423cSAnthony Liguori }
28870f15423cSAnthony Liguori 
28880f15423cSAnthony Liguori void bdrv_invalidate_cache_all(void)
28890f15423cSAnthony Liguori {
28900f15423cSAnthony Liguori     BlockDriverState *bs;
28910f15423cSAnthony Liguori 
28920f15423cSAnthony Liguori     QTAILQ_FOREACH(bs, &bdrv_states, list) {
28930f15423cSAnthony Liguori         bdrv_invalidate_cache(bs);
28940f15423cSAnthony Liguori     }
28950f15423cSAnthony Liguori }
28960f15423cSAnthony Liguori 
289707f07615SPaolo Bonzini int bdrv_flush(BlockDriverState *bs)
289807f07615SPaolo Bonzini {
289907f07615SPaolo Bonzini     Coroutine *co;
290007f07615SPaolo Bonzini     RwCo rwco = {
290107f07615SPaolo Bonzini         .bs = bs,
290207f07615SPaolo Bonzini         .ret = NOT_DONE,
290307f07615SPaolo Bonzini     };
290407f07615SPaolo Bonzini 
290507f07615SPaolo Bonzini     if (qemu_in_coroutine()) {
290607f07615SPaolo Bonzini         /* Fast-path if already in coroutine context */
290707f07615SPaolo Bonzini         bdrv_flush_co_entry(&rwco);
290807f07615SPaolo Bonzini     } else {
290907f07615SPaolo Bonzini         co = qemu_coroutine_create(bdrv_flush_co_entry);
291007f07615SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
291107f07615SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
291207f07615SPaolo Bonzini             qemu_aio_wait();
291307f07615SPaolo Bonzini         }
291407f07615SPaolo Bonzini     }
291507f07615SPaolo Bonzini 
291607f07615SPaolo Bonzini     return rwco.ret;
291707f07615SPaolo Bonzini }
2918e7a8a783SKevin Wolf 
29194265d620SPaolo Bonzini static void coroutine_fn bdrv_discard_co_entry(void *opaque)
29204265d620SPaolo Bonzini {
29214265d620SPaolo Bonzini     RwCo *rwco = opaque;
29224265d620SPaolo Bonzini 
29234265d620SPaolo Bonzini     rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
29244265d620SPaolo Bonzini }
29254265d620SPaolo Bonzini 
29264265d620SPaolo Bonzini int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
29274265d620SPaolo Bonzini                                  int nb_sectors)
29284265d620SPaolo Bonzini {
29294265d620SPaolo Bonzini     if (!bs->drv) {
29304265d620SPaolo Bonzini         return -ENOMEDIUM;
29314265d620SPaolo Bonzini     } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
29324265d620SPaolo Bonzini         return -EIO;
29334265d620SPaolo Bonzini     } else if (bs->read_only) {
29344265d620SPaolo Bonzini         return -EROFS;
29354265d620SPaolo Bonzini     } else if (bs->drv->bdrv_co_discard) {
29364265d620SPaolo Bonzini         return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
29374265d620SPaolo Bonzini     } else if (bs->drv->bdrv_aio_discard) {
29384265d620SPaolo Bonzini         BlockDriverAIOCB *acb;
29394265d620SPaolo Bonzini         CoroutineIOCompletion co = {
29404265d620SPaolo Bonzini             .coroutine = qemu_coroutine_self(),
29414265d620SPaolo Bonzini         };
29424265d620SPaolo Bonzini 
29434265d620SPaolo Bonzini         acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
29444265d620SPaolo Bonzini                                         bdrv_co_io_em_complete, &co);
29454265d620SPaolo Bonzini         if (acb == NULL) {
29464265d620SPaolo Bonzini             return -EIO;
29474265d620SPaolo Bonzini         } else {
29484265d620SPaolo Bonzini             qemu_coroutine_yield();
29494265d620SPaolo Bonzini             return co.ret;
29504265d620SPaolo Bonzini         }
29514265d620SPaolo Bonzini     } else {
29524265d620SPaolo Bonzini         return 0;
29534265d620SPaolo Bonzini     }
29544265d620SPaolo Bonzini }
29554265d620SPaolo Bonzini 
29564265d620SPaolo Bonzini int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
29574265d620SPaolo Bonzini {
29584265d620SPaolo Bonzini     Coroutine *co;
29594265d620SPaolo Bonzini     RwCo rwco = {
29604265d620SPaolo Bonzini         .bs = bs,
29614265d620SPaolo Bonzini         .sector_num = sector_num,
29624265d620SPaolo Bonzini         .nb_sectors = nb_sectors,
29634265d620SPaolo Bonzini         .ret = NOT_DONE,
29644265d620SPaolo Bonzini     };
29654265d620SPaolo Bonzini 
29664265d620SPaolo Bonzini     if (qemu_in_coroutine()) {
29674265d620SPaolo Bonzini         /* Fast-path if already in coroutine context */
29684265d620SPaolo Bonzini         bdrv_discard_co_entry(&rwco);
29694265d620SPaolo Bonzini     } else {
29704265d620SPaolo Bonzini         co = qemu_coroutine_create(bdrv_discard_co_entry);
29714265d620SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
29724265d620SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
29734265d620SPaolo Bonzini             qemu_aio_wait();
29744265d620SPaolo Bonzini         }
29754265d620SPaolo Bonzini     }
29764265d620SPaolo Bonzini 
29774265d620SPaolo Bonzini     return rwco.ret;
29784265d620SPaolo Bonzini }
29794265d620SPaolo Bonzini 
2980f9f05dc5SKevin Wolf /**************************************************************/
298119cb3738Sbellard /* removable device support */
298219cb3738Sbellard 
298319cb3738Sbellard /**
298419cb3738Sbellard  * Return TRUE if the media is present
298519cb3738Sbellard  */
298619cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
298719cb3738Sbellard {
298819cb3738Sbellard     BlockDriver *drv = bs->drv;
2989a1aff5bfSMarkus Armbruster 
299019cb3738Sbellard     if (!drv)
299119cb3738Sbellard         return 0;
299219cb3738Sbellard     if (!drv->bdrv_is_inserted)
2993a1aff5bfSMarkus Armbruster         return 1;
2994a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
299519cb3738Sbellard }
299619cb3738Sbellard 
299719cb3738Sbellard /**
29988e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
29998e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
300019cb3738Sbellard  */
300119cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
300219cb3738Sbellard {
300319cb3738Sbellard     BlockDriver *drv = bs->drv;
300419cb3738Sbellard 
30058e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
30068e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
30078e49ca46SMarkus Armbruster     }
30088e49ca46SMarkus Armbruster     return -ENOTSUP;
300919cb3738Sbellard }
301019cb3738Sbellard 
301119cb3738Sbellard /**
301219cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
301319cb3738Sbellard  */
3014fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
301519cb3738Sbellard {
301619cb3738Sbellard     BlockDriver *drv = bs->drv;
301719cb3738Sbellard 
3018822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
3019822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
302019cb3738Sbellard     }
302119cb3738Sbellard }
302219cb3738Sbellard 
302319cb3738Sbellard /**
302419cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
302519cb3738Sbellard  * to eject it manually).
302619cb3738Sbellard  */
3027025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
302819cb3738Sbellard {
302919cb3738Sbellard     BlockDriver *drv = bs->drv;
303019cb3738Sbellard 
3031025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
3032b8c6d095SStefan Hajnoczi 
3033025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
3034025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
303519cb3738Sbellard     }
303619cb3738Sbellard }
3037985a03b0Sths 
3038985a03b0Sths /* needed for generic scsi interface */
3039985a03b0Sths 
3040985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3041985a03b0Sths {
3042985a03b0Sths     BlockDriver *drv = bs->drv;
3043985a03b0Sths 
3044985a03b0Sths     if (drv && drv->bdrv_ioctl)
3045985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3046985a03b0Sths     return -ENOTSUP;
3047985a03b0Sths }
30487d780669Saliguori 
3049221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3050221f715dSaliguori         unsigned long int req, void *buf,
30517d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
30527d780669Saliguori {
3053221f715dSaliguori     BlockDriver *drv = bs->drv;
30547d780669Saliguori 
3055221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3056221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3057221f715dSaliguori     return NULL;
30587d780669Saliguori }
3059e268ca52Saliguori 
30607b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
30617b6f9300SMarkus Armbruster {
30627b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
30637b6f9300SMarkus Armbruster }
30647cd1e32aSlirans@il.ibm.com 
3065e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3066e268ca52Saliguori {
3067e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3068e268ca52Saliguori }
30697cd1e32aSlirans@il.ibm.com 
30707cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
30717cd1e32aSlirans@il.ibm.com {
30727cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3073a55eb92cSJan Kiszka 
3074aaa0eb75SLiran Schour     bs->dirty_count = 0;
30757cd1e32aSlirans@il.ibm.com     if (enable) {
3076c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3077c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3078c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3079c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
30807cd1e32aSlirans@il.ibm.com 
30817267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
30827cd1e32aSlirans@il.ibm.com         }
30837cd1e32aSlirans@il.ibm.com     } else {
3084c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
30857267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3086c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
30877cd1e32aSlirans@il.ibm.com         }
30887cd1e32aSlirans@il.ibm.com     }
30897cd1e32aSlirans@il.ibm.com }
30907cd1e32aSlirans@il.ibm.com 
30917cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
30927cd1e32aSlirans@il.ibm.com {
30936ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
30947cd1e32aSlirans@il.ibm.com 
3095c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3096c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
30976d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
30986d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
30997cd1e32aSlirans@il.ibm.com     } else {
31007cd1e32aSlirans@il.ibm.com         return 0;
31017cd1e32aSlirans@il.ibm.com     }
31027cd1e32aSlirans@il.ibm.com }
31037cd1e32aSlirans@il.ibm.com 
31047cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
31057cd1e32aSlirans@il.ibm.com                       int nr_sectors)
31067cd1e32aSlirans@il.ibm.com {
31077cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
31087cd1e32aSlirans@il.ibm.com }
3109aaa0eb75SLiran Schour 
3110aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3111aaa0eb75SLiran Schour {
3112aaa0eb75SLiran Schour     return bs->dirty_count;
3113aaa0eb75SLiran Schour }
3114f88e1a42SJes Sorensen 
3115db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3116db593f25SMarcelo Tosatti {
3117db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3118db593f25SMarcelo Tosatti     bs->in_use = in_use;
3119db593f25SMarcelo Tosatti }
3120db593f25SMarcelo Tosatti 
3121db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3122db593f25SMarcelo Tosatti {
3123db593f25SMarcelo Tosatti     return bs->in_use;
3124db593f25SMarcelo Tosatti }
3125db593f25SMarcelo Tosatti 
312628a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
312728a7282aSLuiz Capitulino {
3128d6bf279eSLuiz Capitulino     bs->iostatus_enabled = true;
312958e21ef5SLuiz Capitulino     bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
313028a7282aSLuiz Capitulino }
313128a7282aSLuiz Capitulino 
313228a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
313328a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
313428a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
313528a7282aSLuiz Capitulino {
3136d6bf279eSLuiz Capitulino     return (bs->iostatus_enabled &&
313728a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
313828a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
313928a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
314028a7282aSLuiz Capitulino }
314128a7282aSLuiz Capitulino 
314228a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
314328a7282aSLuiz Capitulino {
3144d6bf279eSLuiz Capitulino     bs->iostatus_enabled = false;
314528a7282aSLuiz Capitulino }
314628a7282aSLuiz Capitulino 
314728a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
314828a7282aSLuiz Capitulino {
314928a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
315058e21ef5SLuiz Capitulino         bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
315128a7282aSLuiz Capitulino     }
315228a7282aSLuiz Capitulino }
315328a7282aSLuiz Capitulino 
315428a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
315528a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
315628a7282aSLuiz Capitulino    possible to implement this without device models being involved */
315728a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
315828a7282aSLuiz Capitulino {
315958e21ef5SLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) &&
316058e21ef5SLuiz Capitulino         bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
316128a7282aSLuiz Capitulino         assert(error >= 0);
316258e21ef5SLuiz Capitulino         bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
316358e21ef5SLuiz Capitulino                                          BLOCK_DEVICE_IO_STATUS_FAILED;
316428a7282aSLuiz Capitulino     }
316528a7282aSLuiz Capitulino }
316628a7282aSLuiz Capitulino 
3167a597e79cSChristoph Hellwig void
3168a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3169a597e79cSChristoph Hellwig         enum BlockAcctType type)
3170a597e79cSChristoph Hellwig {
3171a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3172a597e79cSChristoph Hellwig 
3173a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3174c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3175a597e79cSChristoph Hellwig     cookie->type = type;
3176a597e79cSChristoph Hellwig }
3177a597e79cSChristoph Hellwig 
3178a597e79cSChristoph Hellwig void
3179a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3180a597e79cSChristoph Hellwig {
3181a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3182a597e79cSChristoph Hellwig 
3183a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3184a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3185c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3186a597e79cSChristoph Hellwig }
3187a597e79cSChristoph Hellwig 
3188f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3189f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3190f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3191f88e1a42SJes Sorensen {
3192f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3193d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3194f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3195f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
319696df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3197f88e1a42SJes Sorensen     int ret = 0;
3198f88e1a42SJes Sorensen 
3199f88e1a42SJes Sorensen     /* Find driver and parse its options */
3200f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3201f88e1a42SJes Sorensen     if (!drv) {
3202f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
32034f70f249SJes Sorensen         ret = -EINVAL;
3204f88e1a42SJes Sorensen         goto out;
3205f88e1a42SJes Sorensen     }
3206f88e1a42SJes Sorensen 
3207f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3208f88e1a42SJes Sorensen     if (!proto_drv) {
3209f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
32104f70f249SJes Sorensen         ret = -EINVAL;
3211f88e1a42SJes Sorensen         goto out;
3212f88e1a42SJes Sorensen     }
3213f88e1a42SJes Sorensen 
3214f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3215f88e1a42SJes Sorensen                                               drv->create_options);
3216f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3217f88e1a42SJes Sorensen                                               proto_drv->create_options);
3218f88e1a42SJes Sorensen 
3219f88e1a42SJes Sorensen     /* Create parameter list with default values */
3220f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3221f88e1a42SJes Sorensen 
3222f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3223f88e1a42SJes Sorensen 
3224f88e1a42SJes Sorensen     /* Parse -o options */
3225f88e1a42SJes Sorensen     if (options) {
3226f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3227f88e1a42SJes Sorensen         if (param == NULL) {
3228f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
32294f70f249SJes Sorensen             ret = -EINVAL;
3230f88e1a42SJes Sorensen             goto out;
3231f88e1a42SJes Sorensen         }
3232f88e1a42SJes Sorensen     }
3233f88e1a42SJes Sorensen 
3234f88e1a42SJes Sorensen     if (base_filename) {
3235f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3236f88e1a42SJes Sorensen                                  base_filename)) {
3237f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3238f88e1a42SJes Sorensen                          fmt);
32394f70f249SJes Sorensen             ret = -EINVAL;
3240f88e1a42SJes Sorensen             goto out;
3241f88e1a42SJes Sorensen         }
3242f88e1a42SJes Sorensen     }
3243f88e1a42SJes Sorensen 
3244f88e1a42SJes Sorensen     if (base_fmt) {
3245f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3246f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3247f88e1a42SJes Sorensen                          "format '%s'", fmt);
32484f70f249SJes Sorensen             ret = -EINVAL;
3249f88e1a42SJes Sorensen             goto out;
3250f88e1a42SJes Sorensen         }
3251f88e1a42SJes Sorensen     }
3252f88e1a42SJes Sorensen 
3253792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3254792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3255792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3256792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3257792da93aSJes Sorensen                          "same filename as the backing file");
32584f70f249SJes Sorensen             ret = -EINVAL;
3259792da93aSJes Sorensen             goto out;
3260792da93aSJes Sorensen         }
3261792da93aSJes Sorensen     }
3262792da93aSJes Sorensen 
3263f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3264f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
326596df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
326696df67d1SStefan Hajnoczi         if (!backing_drv) {
3267f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3268f88e1a42SJes Sorensen                          backing_fmt->value.s);
32694f70f249SJes Sorensen             ret = -EINVAL;
3270f88e1a42SJes Sorensen             goto out;
3271f88e1a42SJes Sorensen         }
3272f88e1a42SJes Sorensen     }
3273f88e1a42SJes Sorensen 
3274f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3275f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3276d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3277d220894eSKevin Wolf     if (size && size->value.n == -1) {
3278f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3279f88e1a42SJes Sorensen             uint64_t size;
3280f88e1a42SJes Sorensen             char buf[32];
3281f88e1a42SJes Sorensen 
3282f88e1a42SJes Sorensen             bs = bdrv_new("");
3283f88e1a42SJes Sorensen 
328496df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3285f88e1a42SJes Sorensen             if (ret < 0) {
328696df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3287f88e1a42SJes Sorensen                 goto out;
3288f88e1a42SJes Sorensen             }
3289f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3290f88e1a42SJes Sorensen             size *= 512;
3291f88e1a42SJes Sorensen 
3292f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3293f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3294f88e1a42SJes Sorensen         } else {
3295f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
32964f70f249SJes Sorensen             ret = -EINVAL;
3297f88e1a42SJes Sorensen             goto out;
3298f88e1a42SJes Sorensen         }
3299f88e1a42SJes Sorensen     }
3300f88e1a42SJes Sorensen 
3301f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3302f88e1a42SJes Sorensen     print_option_parameters(param);
3303f88e1a42SJes Sorensen     puts("");
3304f88e1a42SJes Sorensen 
3305f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3306f88e1a42SJes Sorensen 
3307f88e1a42SJes Sorensen     if (ret < 0) {
3308f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3309f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3310f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3311f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3312f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3313f88e1a42SJes Sorensen                          fmt);
3314f88e1a42SJes Sorensen         } else {
3315f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3316f88e1a42SJes Sorensen                          strerror(-ret));
3317f88e1a42SJes Sorensen         }
3318f88e1a42SJes Sorensen     }
3319f88e1a42SJes Sorensen 
3320f88e1a42SJes Sorensen out:
3321f88e1a42SJes Sorensen     free_option_parameters(create_options);
3322f88e1a42SJes Sorensen     free_option_parameters(param);
3323f88e1a42SJes Sorensen 
3324f88e1a42SJes Sorensen     if (bs) {
3325f88e1a42SJes Sorensen         bdrv_delete(bs);
3326f88e1a42SJes Sorensen     }
33274f70f249SJes Sorensen 
33284f70f249SJes Sorensen     return ret;
3329f88e1a42SJes Sorensen }
3330