xref: /openbmc/qemu/block.c (revision 03f541bd6eacdc6c2893f72b975257c89cab2b74)
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"
30d15e5465SLuiz Capitulino #include "qemu-objects.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32fc01f7e7Sbellard 
3371e72a19SJuan Quintela #ifdef CONFIG_BSD
347674e7bfSbellard #include <sys/types.h>
357674e7bfSbellard #include <sys/stat.h>
367674e7bfSbellard #include <sys/ioctl.h>
3772cf2d4fSBlue Swirl #include <sys/queue.h>
38c5e97233Sblueswir1 #ifndef __DragonFly__
397674e7bfSbellard #include <sys/disk.h>
407674e7bfSbellard #endif
41c5e97233Sblueswir1 #endif
427674e7bfSbellard 
4349dc768dSaliguori #ifdef _WIN32
4449dc768dSaliguori #include <windows.h>
4549dc768dSaliguori #endif
4649dc768dSaliguori 
471c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
481c9805a3SStefan Hajnoczi 
497d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
50f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
51f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
52c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
53f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
54f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
55ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
56f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
57f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
58f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
59f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
60f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
61f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
62c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
63c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
641c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
651c9805a3SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
66b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
67b2a61371SStefan Hajnoczi                                                int64_t sector_num,
68b2a61371SStefan Hajnoczi                                                QEMUIOVector *qiov,
69b2a61371SStefan Hajnoczi                                                int nb_sectors,
70b2a61371SStefan Hajnoczi                                                BlockDriverCompletionFunc *cb,
71b2a61371SStefan Hajnoczi                                                void *opaque,
728c5873d6SStefan Hajnoczi                                                bool is_write);
73b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque);
74ec530c81Sbellard 
751b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
761b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
777ee930d0Sblueswir1 
788a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
798a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
80ea2384d3Sbellard 
81f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
82f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
83f9092b10SMarkus Armbruster 
84eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
85eb852011SMarkus Armbruster static int use_bdrv_whitelist;
86eb852011SMarkus Armbruster 
879e0b22f4SStefan Hajnoczi #ifdef _WIN32
889e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
899e0b22f4SStefan Hajnoczi {
909e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
919e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
929e0b22f4SStefan Hajnoczi             filename[1] == ':');
939e0b22f4SStefan Hajnoczi }
949e0b22f4SStefan Hajnoczi 
959e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
969e0b22f4SStefan Hajnoczi {
979e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
989e0b22f4SStefan Hajnoczi         filename[2] == '\0')
999e0b22f4SStefan Hajnoczi         return 1;
1009e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1019e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1029e0b22f4SStefan Hajnoczi         return 1;
1039e0b22f4SStefan Hajnoczi     return 0;
1049e0b22f4SStefan Hajnoczi }
1059e0b22f4SStefan Hajnoczi #endif
1069e0b22f4SStefan Hajnoczi 
1079e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1089e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1099e0b22f4SStefan Hajnoczi {
1109e0b22f4SStefan Hajnoczi #ifdef _WIN32
1119e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1129e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1139e0b22f4SStefan Hajnoczi         return 0;
1149e0b22f4SStefan Hajnoczi     }
1159e0b22f4SStefan Hajnoczi #endif
1169e0b22f4SStefan Hajnoczi 
1179e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1189e0b22f4SStefan Hajnoczi }
1199e0b22f4SStefan Hajnoczi 
12083f64091Sbellard int path_is_absolute(const char *path)
12183f64091Sbellard {
12283f64091Sbellard     const char *p;
12321664424Sbellard #ifdef _WIN32
12421664424Sbellard     /* specific case for names like: "\\.\d:" */
12521664424Sbellard     if (*path == '/' || *path == '\\')
12621664424Sbellard         return 1;
12721664424Sbellard #endif
12883f64091Sbellard     p = strchr(path, ':');
12983f64091Sbellard     if (p)
13083f64091Sbellard         p++;
13183f64091Sbellard     else
13283f64091Sbellard         p = path;
1333b9f94e1Sbellard #ifdef _WIN32
1343b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1353b9f94e1Sbellard #else
1363b9f94e1Sbellard     return (*p == '/');
1373b9f94e1Sbellard #endif
13883f64091Sbellard }
13983f64091Sbellard 
14083f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
14183f64091Sbellard    path to it by considering it is relative to base_path. URL are
14283f64091Sbellard    supported. */
14383f64091Sbellard void path_combine(char *dest, int dest_size,
14483f64091Sbellard                   const char *base_path,
14583f64091Sbellard                   const char *filename)
14683f64091Sbellard {
14783f64091Sbellard     const char *p, *p1;
14883f64091Sbellard     int len;
14983f64091Sbellard 
15083f64091Sbellard     if (dest_size <= 0)
15183f64091Sbellard         return;
15283f64091Sbellard     if (path_is_absolute(filename)) {
15383f64091Sbellard         pstrcpy(dest, dest_size, filename);
15483f64091Sbellard     } else {
15583f64091Sbellard         p = strchr(base_path, ':');
15683f64091Sbellard         if (p)
15783f64091Sbellard             p++;
15883f64091Sbellard         else
15983f64091Sbellard             p = base_path;
1603b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1613b9f94e1Sbellard #ifdef _WIN32
1623b9f94e1Sbellard         {
1633b9f94e1Sbellard             const char *p2;
1643b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1653b9f94e1Sbellard             if (!p1 || p2 > p1)
1663b9f94e1Sbellard                 p1 = p2;
1673b9f94e1Sbellard         }
1683b9f94e1Sbellard #endif
16983f64091Sbellard         if (p1)
17083f64091Sbellard             p1++;
17183f64091Sbellard         else
17283f64091Sbellard             p1 = base_path;
17383f64091Sbellard         if (p1 > p)
17483f64091Sbellard             p = p1;
17583f64091Sbellard         len = p - base_path;
17683f64091Sbellard         if (len > dest_size - 1)
17783f64091Sbellard             len = dest_size - 1;
17883f64091Sbellard         memcpy(dest, base_path, len);
17983f64091Sbellard         dest[len] = '\0';
18083f64091Sbellard         pstrcat(dest, dest_size, filename);
18183f64091Sbellard     }
18283f64091Sbellard }
18383f64091Sbellard 
1845efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
185ea2384d3Sbellard {
1868c5873d6SStefan Hajnoczi     /* Block drivers without coroutine functions need emulation */
1878c5873d6SStefan Hajnoczi     if (!bdrv->bdrv_co_readv) {
188f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
189f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
190f9f05dc5SKevin Wolf 
191f8c35c1dSStefan Hajnoczi         /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
192f8c35c1dSStefan Hajnoczi          * the block driver lacks aio we need to emulate that too.
193f8c35c1dSStefan Hajnoczi          */
194f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
19583f64091Sbellard             /* add AIO emulation layer */
196f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
197f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
19883f64091Sbellard         }
199f9f05dc5SKevin Wolf     }
200b2e12bc6SChristoph Hellwig 
2018a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
202ea2384d3Sbellard }
203b338082bSbellard 
204b338082bSbellard /* create a new block device (by default it is empty) */
205b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
206fc01f7e7Sbellard {
2071b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
208b338082bSbellard 
2097267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
210b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
211ea2384d3Sbellard     if (device_name[0] != '\0') {
2121b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
213ea2384d3Sbellard     }
21428a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
215b338082bSbellard     return bs;
216b338082bSbellard }
217b338082bSbellard 
218ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
219ea2384d3Sbellard {
220ea2384d3Sbellard     BlockDriver *drv1;
2218a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2228a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
223ea2384d3Sbellard             return drv1;
224ea2384d3Sbellard         }
2258a22f02aSStefan Hajnoczi     }
226ea2384d3Sbellard     return NULL;
227ea2384d3Sbellard }
228ea2384d3Sbellard 
229eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
230eb852011SMarkus Armbruster {
231eb852011SMarkus Armbruster     static const char *whitelist[] = {
232eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
233eb852011SMarkus Armbruster     };
234eb852011SMarkus Armbruster     const char **p;
235eb852011SMarkus Armbruster 
236eb852011SMarkus Armbruster     if (!whitelist[0])
237eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
238eb852011SMarkus Armbruster 
239eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
240eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
241eb852011SMarkus Armbruster             return 1;
242eb852011SMarkus Armbruster         }
243eb852011SMarkus Armbruster     }
244eb852011SMarkus Armbruster     return 0;
245eb852011SMarkus Armbruster }
246eb852011SMarkus Armbruster 
247eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
248eb852011SMarkus Armbruster {
249eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
250eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
251eb852011SMarkus Armbruster }
252eb852011SMarkus Armbruster 
2530e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2540e7e1989SKevin Wolf     QEMUOptionParameter *options)
255ea2384d3Sbellard {
256ea2384d3Sbellard     if (!drv->bdrv_create)
257ea2384d3Sbellard         return -ENOTSUP;
2580e7e1989SKevin Wolf 
2590e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
260ea2384d3Sbellard }
261ea2384d3Sbellard 
26284a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
26384a12e66SChristoph Hellwig {
26484a12e66SChristoph Hellwig     BlockDriver *drv;
26584a12e66SChristoph Hellwig 
266b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
26784a12e66SChristoph Hellwig     if (drv == NULL) {
26816905d71SStefan Hajnoczi         return -ENOENT;
26984a12e66SChristoph Hellwig     }
27084a12e66SChristoph Hellwig 
27184a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
27284a12e66SChristoph Hellwig }
27384a12e66SChristoph Hellwig 
274d5249393Sbellard #ifdef _WIN32
27595389c86Sbellard void get_tmp_filename(char *filename, int size)
276d5249393Sbellard {
2773b9f94e1Sbellard     char temp_dir[MAX_PATH];
2783b9f94e1Sbellard 
2793b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
2803b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
281d5249393Sbellard }
282d5249393Sbellard #else
28395389c86Sbellard void get_tmp_filename(char *filename, int size)
284ea2384d3Sbellard {
285ea2384d3Sbellard     int fd;
2867ccfb2ebSblueswir1     const char *tmpdir;
287d5249393Sbellard     /* XXX: race condition possible */
2880badc1eeSaurel32     tmpdir = getenv("TMPDIR");
2890badc1eeSaurel32     if (!tmpdir)
2900badc1eeSaurel32         tmpdir = "/tmp";
2910badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
292ea2384d3Sbellard     fd = mkstemp(filename);
293ea2384d3Sbellard     close(fd);
294ea2384d3Sbellard }
295d5249393Sbellard #endif
296ea2384d3Sbellard 
297f3a5d3f8SChristoph Hellwig /*
298f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
299f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
300f3a5d3f8SChristoph Hellwig  */
301f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
302f3a5d3f8SChristoph Hellwig {
303508c7cb3SChristoph Hellwig     int score_max = 0, score;
304508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
305f3a5d3f8SChristoph Hellwig 
3068a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
307508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
308508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
309508c7cb3SChristoph Hellwig             if (score > score_max) {
310508c7cb3SChristoph Hellwig                 score_max = score;
311508c7cb3SChristoph Hellwig                 drv = d;
312f3a5d3f8SChristoph Hellwig             }
313508c7cb3SChristoph Hellwig         }
314f3a5d3f8SChristoph Hellwig     }
315f3a5d3f8SChristoph Hellwig 
316508c7cb3SChristoph Hellwig     return drv;
317f3a5d3f8SChristoph Hellwig }
318f3a5d3f8SChristoph Hellwig 
319b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
32084a12e66SChristoph Hellwig {
32184a12e66SChristoph Hellwig     BlockDriver *drv1;
32284a12e66SChristoph Hellwig     char protocol[128];
32384a12e66SChristoph Hellwig     int len;
32484a12e66SChristoph Hellwig     const char *p;
32584a12e66SChristoph Hellwig 
32666f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
32766f82ceeSKevin Wolf 
32839508e7aSChristoph Hellwig     /*
32939508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
33039508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
33139508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
33239508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
33339508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
33439508e7aSChristoph Hellwig      */
33584a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
33639508e7aSChristoph Hellwig     if (drv1) {
33784a12e66SChristoph Hellwig         return drv1;
33884a12e66SChristoph Hellwig     }
33939508e7aSChristoph Hellwig 
3409e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
34139508e7aSChristoph Hellwig         return bdrv_find_format("file");
34239508e7aSChristoph Hellwig     }
3439e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3449e0b22f4SStefan Hajnoczi     assert(p != NULL);
34584a12e66SChristoph Hellwig     len = p - filename;
34684a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
34784a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
34884a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
34984a12e66SChristoph Hellwig     protocol[len] = '\0';
35084a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
35184a12e66SChristoph Hellwig         if (drv1->protocol_name &&
35284a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
35384a12e66SChristoph Hellwig             return drv1;
35484a12e66SChristoph Hellwig         }
35584a12e66SChristoph Hellwig     }
35684a12e66SChristoph Hellwig     return NULL;
35784a12e66SChristoph Hellwig }
35884a12e66SChristoph Hellwig 
359c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
360ea2384d3Sbellard {
36183f64091Sbellard     int ret, score, score_max;
362ea2384d3Sbellard     BlockDriver *drv1, *drv;
36383f64091Sbellard     uint8_t buf[2048];
36483f64091Sbellard     BlockDriverState *bs;
365ea2384d3Sbellard 
366f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
367c98ac35dSStefan Weil     if (ret < 0) {
368c98ac35dSStefan Weil         *pdrv = NULL;
369c98ac35dSStefan Weil         return ret;
370c98ac35dSStefan Weil     }
371f8ea0b00SNicholas Bellinger 
37208a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
37308a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
3741a396859SNicholas A. Bellinger         bdrv_delete(bs);
375c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
376c98ac35dSStefan Weil         if (!drv) {
377c98ac35dSStefan Weil             ret = -ENOENT;
378c98ac35dSStefan Weil         }
379c98ac35dSStefan Weil         *pdrv = drv;
380c98ac35dSStefan Weil         return ret;
3811a396859SNicholas A. Bellinger     }
382f8ea0b00SNicholas Bellinger 
38383f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
38483f64091Sbellard     bdrv_delete(bs);
385ea2384d3Sbellard     if (ret < 0) {
386c98ac35dSStefan Weil         *pdrv = NULL;
387c98ac35dSStefan Weil         return ret;
388ea2384d3Sbellard     }
389ea2384d3Sbellard 
390ea2384d3Sbellard     score_max = 0;
39184a12e66SChristoph Hellwig     drv = NULL;
3928a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
39383f64091Sbellard         if (drv1->bdrv_probe) {
394ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
395ea2384d3Sbellard             if (score > score_max) {
396ea2384d3Sbellard                 score_max = score;
397ea2384d3Sbellard                 drv = drv1;
398ea2384d3Sbellard             }
399ea2384d3Sbellard         }
40083f64091Sbellard     }
401c98ac35dSStefan Weil     if (!drv) {
402c98ac35dSStefan Weil         ret = -ENOENT;
403c98ac35dSStefan Weil     }
404c98ac35dSStefan Weil     *pdrv = drv;
405c98ac35dSStefan Weil     return ret;
406ea2384d3Sbellard }
407ea2384d3Sbellard 
40851762288SStefan Hajnoczi /**
40951762288SStefan Hajnoczi  * Set the current 'total_sectors' value
41051762288SStefan Hajnoczi  */
41151762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
41251762288SStefan Hajnoczi {
41351762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
41451762288SStefan Hajnoczi 
415396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
416396759adSNicholas Bellinger     if (bs->sg)
417396759adSNicholas Bellinger         return 0;
418396759adSNicholas Bellinger 
41951762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
42051762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
42151762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
42251762288SStefan Hajnoczi         if (length < 0) {
42351762288SStefan Hajnoczi             return length;
42451762288SStefan Hajnoczi         }
42551762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
42651762288SStefan Hajnoczi     }
42751762288SStefan Hajnoczi 
42851762288SStefan Hajnoczi     bs->total_sectors = hint;
42951762288SStefan Hajnoczi     return 0;
43051762288SStefan Hajnoczi }
43151762288SStefan Hajnoczi 
432c3993cdcSStefan Hajnoczi /**
433c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
434c3993cdcSStefan Hajnoczi  *
435c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
436c3993cdcSStefan Hajnoczi  */
437c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
438c3993cdcSStefan Hajnoczi {
439c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
440c3993cdcSStefan Hajnoczi 
441c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
442c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
44392196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
44492196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
445c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
446c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
447c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
448c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
449c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
450c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
451c3993cdcSStefan Hajnoczi         /* this is the default */
452c3993cdcSStefan Hajnoczi     } else {
453c3993cdcSStefan Hajnoczi         return -1;
454c3993cdcSStefan Hajnoczi     }
455c3993cdcSStefan Hajnoczi 
456c3993cdcSStefan Hajnoczi     return 0;
457c3993cdcSStefan Hajnoczi }
458c3993cdcSStefan Hajnoczi 
459b6ce07aaSKevin Wolf /*
46057915332SKevin Wolf  * Common part for opening disk images and files
46157915332SKevin Wolf  */
46257915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
46357915332SKevin Wolf     int flags, BlockDriver *drv)
46457915332SKevin Wolf {
46557915332SKevin Wolf     int ret, open_flags;
46657915332SKevin Wolf 
46757915332SKevin Wolf     assert(drv != NULL);
46857915332SKevin Wolf 
46928dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
47028dcee10SStefan Hajnoczi 
47166f82ceeSKevin Wolf     bs->file = NULL;
47251762288SStefan Hajnoczi     bs->total_sectors = 0;
47357915332SKevin Wolf     bs->encrypted = 0;
47457915332SKevin Wolf     bs->valid_key = 0;
475*03f541bdSStefan Hajnoczi     bs->sg = 0;
47657915332SKevin Wolf     bs->open_flags = flags;
477*03f541bdSStefan Hajnoczi     bs->growable = 0;
47857915332SKevin Wolf     bs->buffer_alignment = 512;
47957915332SKevin Wolf 
48057915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
481*03f541bdSStefan Hajnoczi     bs->backing_file[0] = '\0';
48257915332SKevin Wolf 
48357915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
48457915332SKevin Wolf         return -ENOTSUP;
48557915332SKevin Wolf     }
48657915332SKevin Wolf 
48757915332SKevin Wolf     bs->drv = drv;
4887267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
48957915332SKevin Wolf 
490*03f541bdSStefan Hajnoczi     bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
49157915332SKevin Wolf 
49257915332SKevin Wolf     /*
49357915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
49457915332SKevin Wolf      * image.
49557915332SKevin Wolf      */
49657915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
49757915332SKevin Wolf 
49857915332SKevin Wolf     /*
499ebabb67aSStefan Weil      * Snapshots should be writable.
50057915332SKevin Wolf      */
50157915332SKevin Wolf     if (bs->is_temporary) {
50257915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
50357915332SKevin Wolf     }
50457915332SKevin Wolf 
505e7c63796SStefan Hajnoczi     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
506e7c63796SStefan Hajnoczi 
50766f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
50866f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
50966f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
51066f82ceeSKevin Wolf     } else {
51166f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
51266f82ceeSKevin Wolf         if (ret >= 0) {
51366f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
51466f82ceeSKevin Wolf         }
51566f82ceeSKevin Wolf     }
51666f82ceeSKevin Wolf 
51757915332SKevin Wolf     if (ret < 0) {
51857915332SKevin Wolf         goto free_and_fail;
51957915332SKevin Wolf     }
52057915332SKevin Wolf 
52151762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
52251762288SStefan Hajnoczi     if (ret < 0) {
52351762288SStefan Hajnoczi         goto free_and_fail;
52457915332SKevin Wolf     }
52551762288SStefan Hajnoczi 
52657915332SKevin Wolf #ifndef _WIN32
52757915332SKevin Wolf     if (bs->is_temporary) {
52857915332SKevin Wolf         unlink(filename);
52957915332SKevin Wolf     }
53057915332SKevin Wolf #endif
53157915332SKevin Wolf     return 0;
53257915332SKevin Wolf 
53357915332SKevin Wolf free_and_fail:
53466f82ceeSKevin Wolf     if (bs->file) {
53566f82ceeSKevin Wolf         bdrv_delete(bs->file);
53666f82ceeSKevin Wolf         bs->file = NULL;
53766f82ceeSKevin Wolf     }
5387267c094SAnthony Liguori     g_free(bs->opaque);
53957915332SKevin Wolf     bs->opaque = NULL;
54057915332SKevin Wolf     bs->drv = NULL;
54157915332SKevin Wolf     return ret;
54257915332SKevin Wolf }
54357915332SKevin Wolf 
54457915332SKevin Wolf /*
545b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
546b6ce07aaSKevin Wolf  */
54783f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
548b338082bSbellard {
54983f64091Sbellard     BlockDriverState *bs;
5506db95603SChristoph Hellwig     BlockDriver *drv;
55183f64091Sbellard     int ret;
5523b0d4f61Sbellard 
553b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5546db95603SChristoph Hellwig     if (!drv) {
5556db95603SChristoph Hellwig         return -ENOENT;
5566db95603SChristoph Hellwig     }
5576db95603SChristoph Hellwig 
55883f64091Sbellard     bs = bdrv_new("");
559b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
56083f64091Sbellard     if (ret < 0) {
56183f64091Sbellard         bdrv_delete(bs);
56283f64091Sbellard         return ret;
5633b0d4f61Sbellard     }
56471d0770cSaliguori     bs->growable = 1;
56583f64091Sbellard     *pbs = bs;
56683f64091Sbellard     return 0;
5673b0d4f61Sbellard }
5683b0d4f61Sbellard 
569b6ce07aaSKevin Wolf /*
570b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
571b6ce07aaSKevin Wolf  */
572d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
573ea2384d3Sbellard               BlockDriver *drv)
574ea2384d3Sbellard {
575b6ce07aaSKevin Wolf     int ret;
5762b572816SKevin Wolf     char tmp_filename[PATH_MAX];
57733e3963eSbellard 
57883f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
579ea2384d3Sbellard         BlockDriverState *bs1;
580ea2384d3Sbellard         int64_t total_size;
5817c96d46eSaliguori         int is_protocol = 0;
58291a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
58391a073a9SKevin Wolf         QEMUOptionParameter *options;
584b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
58533e3963eSbellard 
586ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
587ea2384d3Sbellard            instead of opening 'filename' directly */
588ea2384d3Sbellard 
589ea2384d3Sbellard         /* if there is a backing file, use it */
590ea2384d3Sbellard         bs1 = bdrv_new("");
591d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
59251d7c00cSaliguori         if (ret < 0) {
593ea2384d3Sbellard             bdrv_delete(bs1);
59451d7c00cSaliguori             return ret;
595ea2384d3Sbellard         }
5963e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
5977c96d46eSaliguori 
5987c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
5997c96d46eSaliguori             is_protocol = 1;
6007c96d46eSaliguori 
601ea2384d3Sbellard         bdrv_delete(bs1);
602ea2384d3Sbellard 
603ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6047c96d46eSaliguori 
6057c96d46eSaliguori         /* Real path is meaningless for protocols */
6067c96d46eSaliguori         if (is_protocol)
6077c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6087c96d46eSaliguori                      "%s", filename);
609114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
610114cdfa9SKirill A. Shutemov             return -errno;
6117c96d46eSaliguori 
61291a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
61391a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
61491a073a9SKevin Wolf 
6153e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
61691a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
61791a073a9SKevin Wolf         if (drv) {
61891a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
61991a073a9SKevin Wolf                 drv->format_name);
62091a073a9SKevin Wolf         }
62191a073a9SKevin Wolf 
62291a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
623d748768cSJan Kiszka         free_option_parameters(options);
62451d7c00cSaliguori         if (ret < 0) {
62551d7c00cSaliguori             return ret;
626ea2384d3Sbellard         }
62791a073a9SKevin Wolf 
628ea2384d3Sbellard         filename = tmp_filename;
62991a073a9SKevin Wolf         drv = bdrv_qcow2;
630ea2384d3Sbellard         bs->is_temporary = 1;
631ea2384d3Sbellard     }
632ea2384d3Sbellard 
633b6ce07aaSKevin Wolf     /* Find the right image format driver */
6346db95603SChristoph Hellwig     if (!drv) {
635c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
636ea2384d3Sbellard     }
6376987307cSChristoph Hellwig 
63851d7c00cSaliguori     if (!drv) {
63951d7c00cSaliguori         goto unlink_and_fail;
64083f64091Sbellard     }
641b6ce07aaSKevin Wolf 
642b6ce07aaSKevin Wolf     /* Open the image */
643b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
644b6ce07aaSKevin Wolf     if (ret < 0) {
6456987307cSChristoph Hellwig         goto unlink_and_fail;
6466987307cSChristoph Hellwig     }
6476987307cSChristoph Hellwig 
648b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
649b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
650b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
651b6ce07aaSKevin Wolf         int back_flags;
652b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
653b6ce07aaSKevin Wolf 
654b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
655df2dbb4aSStefan Hajnoczi 
656df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
657df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
658df2dbb4aSStefan Hajnoczi                     bs->backing_file);
659df2dbb4aSStefan Hajnoczi         } else {
660b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
661b6ce07aaSKevin Wolf                          filename, bs->backing_file);
662df2dbb4aSStefan Hajnoczi         }
663df2dbb4aSStefan Hajnoczi 
664df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
665b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
666df2dbb4aSStefan Hajnoczi         }
667b6ce07aaSKevin Wolf 
668b6ce07aaSKevin Wolf         /* backing files always opened read-only */
669b6ce07aaSKevin Wolf         back_flags =
670b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
671b6ce07aaSKevin Wolf 
672b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
673b6ce07aaSKevin Wolf         if (ret < 0) {
674b6ce07aaSKevin Wolf             bdrv_close(bs);
675b6ce07aaSKevin Wolf             return ret;
676b6ce07aaSKevin Wolf         }
677b6ce07aaSKevin Wolf         if (bs->is_temporary) {
678b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
679b6ce07aaSKevin Wolf         } else {
680b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
681b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
682b6ce07aaSKevin Wolf         }
683b6ce07aaSKevin Wolf     }
684b6ce07aaSKevin Wolf 
685b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
6867d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
687b6ce07aaSKevin Wolf     }
688b6ce07aaSKevin Wolf 
689b6ce07aaSKevin Wolf     return 0;
690b6ce07aaSKevin Wolf 
691b6ce07aaSKevin Wolf unlink_and_fail:
692b6ce07aaSKevin Wolf     if (bs->is_temporary) {
693b6ce07aaSKevin Wolf         unlink(filename);
694b6ce07aaSKevin Wolf     }
695b6ce07aaSKevin Wolf     return ret;
696b6ce07aaSKevin Wolf }
697b6ce07aaSKevin Wolf 
698fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
699fc01f7e7Sbellard {
70019cb3738Sbellard     if (bs->drv) {
701f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
702f9092b10SMarkus Armbruster             bs_snapshots = NULL;
703f9092b10SMarkus Armbruster         }
704557df6acSStefan Hajnoczi         if (bs->backing_hd) {
705ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
706557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
707557df6acSStefan Hajnoczi         }
708ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7097267c094SAnthony Liguori         g_free(bs->opaque);
710ea2384d3Sbellard #ifdef _WIN32
711ea2384d3Sbellard         if (bs->is_temporary) {
712ea2384d3Sbellard             unlink(bs->filename);
713ea2384d3Sbellard         }
71467b915a5Sbellard #endif
715ea2384d3Sbellard         bs->opaque = NULL;
716ea2384d3Sbellard         bs->drv = NULL;
717b338082bSbellard 
71866f82ceeSKevin Wolf         if (bs->file != NULL) {
71966f82ceeSKevin Wolf             bdrv_close(bs->file);
72066f82ceeSKevin Wolf         }
72166f82ceeSKevin Wolf 
7227d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
723b338082bSbellard     }
724b338082bSbellard }
725b338082bSbellard 
7262bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7272bc93fedSMORITA Kazutaka {
7282bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7292bc93fedSMORITA Kazutaka 
7302bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7312bc93fedSMORITA Kazutaka         bdrv_close(bs);
7322bc93fedSMORITA Kazutaka     }
7332bc93fedSMORITA Kazutaka }
7342bc93fedSMORITA Kazutaka 
735d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
736d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
737d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
738d22b2f41SRyan Harper {
739d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
740d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
741d22b2f41SRyan Harper     }
742d22b2f41SRyan Harper     bs->device_name[0] = '\0';
743d22b2f41SRyan Harper }
744d22b2f41SRyan Harper 
745b338082bSbellard void bdrv_delete(BlockDriverState *bs)
746b338082bSbellard {
747fa879d62SMarkus Armbruster     assert(!bs->dev);
74818846deeSMarkus Armbruster 
7491b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
750d22b2f41SRyan Harper     bdrv_make_anon(bs);
75134c6f050Saurel32 
752b338082bSbellard     bdrv_close(bs);
75366f82ceeSKevin Wolf     if (bs->file != NULL) {
75466f82ceeSKevin Wolf         bdrv_delete(bs->file);
75566f82ceeSKevin Wolf     }
75666f82ceeSKevin Wolf 
757f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7587267c094SAnthony Liguori     g_free(bs);
759fc01f7e7Sbellard }
760fc01f7e7Sbellard 
761fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
762fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
76318846deeSMarkus Armbruster {
764fa879d62SMarkus Armbruster     if (bs->dev) {
76518846deeSMarkus Armbruster         return -EBUSY;
76618846deeSMarkus Armbruster     }
767fa879d62SMarkus Armbruster     bs->dev = dev;
76828a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
76918846deeSMarkus Armbruster     return 0;
77018846deeSMarkus Armbruster }
77118846deeSMarkus Armbruster 
772fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
773fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
77418846deeSMarkus Armbruster {
775fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
776fa879d62SMarkus Armbruster         abort();
777fa879d62SMarkus Armbruster     }
778fa879d62SMarkus Armbruster }
779fa879d62SMarkus Armbruster 
780fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
781fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
782fa879d62SMarkus Armbruster {
783fa879d62SMarkus Armbruster     assert(bs->dev == dev);
784fa879d62SMarkus Armbruster     bs->dev = NULL;
7850e49de52SMarkus Armbruster     bs->dev_ops = NULL;
7860e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
78729e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
78818846deeSMarkus Armbruster }
78918846deeSMarkus Armbruster 
790fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
791fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
79218846deeSMarkus Armbruster {
793fa879d62SMarkus Armbruster     return bs->dev;
79418846deeSMarkus Armbruster }
79518846deeSMarkus Armbruster 
7960e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
7970e49de52SMarkus Armbruster                       void *opaque)
7980e49de52SMarkus Armbruster {
7990e49de52SMarkus Armbruster     bs->dev_ops = ops;
8000e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8012c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8022c6942faSMarkus Armbruster         bs_snapshots = NULL;
8032c6942faSMarkus Armbruster     }
8040e49de52SMarkus Armbruster }
8050e49de52SMarkus Armbruster 
8067d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8070e49de52SMarkus Armbruster {
808145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8097d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
810145feb17SMarkus Armbruster     }
811145feb17SMarkus Armbruster }
812145feb17SMarkus Armbruster 
8132c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8142c6942faSMarkus Armbruster {
8152c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8162c6942faSMarkus Armbruster }
8172c6942faSMarkus Armbruster 
818e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
819e4def80bSMarkus Armbruster {
820e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
821e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
822e4def80bSMarkus Armbruster     }
823e4def80bSMarkus Armbruster     return false;
824e4def80bSMarkus Armbruster }
825e4def80bSMarkus Armbruster 
826145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
827145feb17SMarkus Armbruster {
828145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
829145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8300e49de52SMarkus Armbruster     }
8310e49de52SMarkus Armbruster }
8320e49de52SMarkus Armbruster 
833f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
834f107639aSMarkus Armbruster {
835f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
836f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
837f107639aSMarkus Armbruster     }
838f107639aSMarkus Armbruster     return false;
839f107639aSMarkus Armbruster }
840f107639aSMarkus Armbruster 
841e97fc193Saliguori /*
842e97fc193Saliguori  * Run consistency checks on an image
843e97fc193Saliguori  *
844e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
845a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
846e076f338SKevin Wolf  * check are stored in res.
847e97fc193Saliguori  */
848e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
849e97fc193Saliguori {
850e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
851e97fc193Saliguori         return -ENOTSUP;
852e97fc193Saliguori     }
853e97fc193Saliguori 
854e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8559ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
856e97fc193Saliguori }
857e97fc193Saliguori 
8588a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8598a426614SKevin Wolf 
86033e3963eSbellard /* commit COW file into the raw image */
86133e3963eSbellard int bdrv_commit(BlockDriverState *bs)
86233e3963eSbellard {
86319cb3738Sbellard     BlockDriver *drv = bs->drv;
864ee181196SKevin Wolf     BlockDriver *backing_drv;
8658a426614SKevin Wolf     int64_t sector, total_sectors;
8668a426614SKevin Wolf     int n, ro, open_flags;
8674dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8688a426614SKevin Wolf     uint8_t *buf;
8694dca4b63SNaphtali Sprei     char filename[1024];
8704dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
87133e3963eSbellard 
87219cb3738Sbellard     if (!drv)
87319cb3738Sbellard         return -ENOMEDIUM;
87433e3963eSbellard 
8754dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8764dca4b63SNaphtali Sprei         return -ENOTSUP;
8774dca4b63SNaphtali Sprei     }
8784dca4b63SNaphtali Sprei 
8794dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
880ea2384d3Sbellard         return -EACCES;
88133e3963eSbellard     }
88233e3963eSbellard 
883ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
8844dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
8854dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
8864dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
8874dca4b63SNaphtali Sprei 
8884dca4b63SNaphtali Sprei     if (ro) {
8894dca4b63SNaphtali Sprei         /* re-open as RW */
8904dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
8914dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
8924dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
893ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
894ee181196SKevin Wolf             backing_drv);
8954dca4b63SNaphtali Sprei         if (rw_ret < 0) {
8964dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
8974dca4b63SNaphtali Sprei             /* try to re-open read-only */
8984dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
899ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
900ee181196SKevin Wolf                 backing_drv);
9014dca4b63SNaphtali Sprei             if (ret < 0) {
9024dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9034dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9044dca4b63SNaphtali Sprei                 bs->drv = NULL;
9054dca4b63SNaphtali Sprei                 return ret;
9064dca4b63SNaphtali Sprei             }
9074dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9084dca4b63SNaphtali Sprei             return rw_ret;
9094dca4b63SNaphtali Sprei         }
9104dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
911ea2384d3Sbellard     }
912ea2384d3Sbellard 
9136ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9147267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9158a426614SKevin Wolf 
9168a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9178a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9188a426614SKevin Wolf 
9198a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9204dca4b63SNaphtali Sprei                 ret = -EIO;
9214dca4b63SNaphtali Sprei                 goto ro_cleanup;
92233e3963eSbellard             }
92333e3963eSbellard 
9248a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9254dca4b63SNaphtali Sprei                 ret = -EIO;
9264dca4b63SNaphtali Sprei                 goto ro_cleanup;
92733e3963eSbellard             }
92833e3963eSbellard         }
92933e3963eSbellard     }
93095389c86Sbellard 
9311d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9321d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9331d44952fSChristoph Hellwig         bdrv_flush(bs);
9341d44952fSChristoph Hellwig     }
93595389c86Sbellard 
9363f5075aeSChristoph Hellwig     /*
9373f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9383f5075aeSChristoph Hellwig      * stable on disk.
9393f5075aeSChristoph Hellwig      */
9403f5075aeSChristoph Hellwig     if (bs->backing_hd)
9413f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9424dca4b63SNaphtali Sprei 
9434dca4b63SNaphtali Sprei ro_cleanup:
9447267c094SAnthony Liguori     g_free(buf);
9454dca4b63SNaphtali Sprei 
9464dca4b63SNaphtali Sprei     if (ro) {
9474dca4b63SNaphtali Sprei         /* re-open as RO */
9484dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9494dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9504dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
951ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
952ee181196SKevin Wolf             backing_drv);
9534dca4b63SNaphtali Sprei         if (ret < 0) {
9544dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9554dca4b63SNaphtali Sprei             /* drive not functional anymore */
9564dca4b63SNaphtali Sprei             bs->drv = NULL;
9574dca4b63SNaphtali Sprei             return ret;
9584dca4b63SNaphtali Sprei         }
9594dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9604dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9614dca4b63SNaphtali Sprei     }
9624dca4b63SNaphtali Sprei 
9631d44952fSChristoph Hellwig     return ret;
96433e3963eSbellard }
96533e3963eSbellard 
9666ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9676ab4b5abSMarkus Armbruster {
9686ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9696ab4b5abSMarkus Armbruster 
9706ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9716ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9726ab4b5abSMarkus Armbruster     }
9736ab4b5abSMarkus Armbruster }
9746ab4b5abSMarkus Armbruster 
975756e6736SKevin Wolf /*
976756e6736SKevin Wolf  * Return values:
977756e6736SKevin Wolf  * 0        - success
978756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
979756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
980756e6736SKevin Wolf  *            image file header
981756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
982756e6736SKevin Wolf  */
983756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
984756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
985756e6736SKevin Wolf {
986756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
987756e6736SKevin Wolf 
988756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
989756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
990756e6736SKevin Wolf     } else {
991756e6736SKevin Wolf         return -ENOTSUP;
992756e6736SKevin Wolf     }
993756e6736SKevin Wolf }
994756e6736SKevin Wolf 
99571d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
99671d0770cSaliguori                                    size_t size)
99771d0770cSaliguori {
99871d0770cSaliguori     int64_t len;
99971d0770cSaliguori 
100071d0770cSaliguori     if (!bdrv_is_inserted(bs))
100171d0770cSaliguori         return -ENOMEDIUM;
100271d0770cSaliguori 
100371d0770cSaliguori     if (bs->growable)
100471d0770cSaliguori         return 0;
100571d0770cSaliguori 
100671d0770cSaliguori     len = bdrv_getlength(bs);
100771d0770cSaliguori 
1008fbb7b4e0SKevin Wolf     if (offset < 0)
1009fbb7b4e0SKevin Wolf         return -EIO;
1010fbb7b4e0SKevin Wolf 
1011fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
101271d0770cSaliguori         return -EIO;
101371d0770cSaliguori 
101471d0770cSaliguori     return 0;
101571d0770cSaliguori }
101671d0770cSaliguori 
101771d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
101871d0770cSaliguori                               int nb_sectors)
101971d0770cSaliguori {
1020eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1021eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
102271d0770cSaliguori }
102371d0770cSaliguori 
10241c9805a3SStefan Hajnoczi typedef struct RwCo {
10251c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10261c9805a3SStefan Hajnoczi     int64_t sector_num;
10271c9805a3SStefan Hajnoczi     int nb_sectors;
10281c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10291c9805a3SStefan Hajnoczi     bool is_write;
10301c9805a3SStefan Hajnoczi     int ret;
10311c9805a3SStefan Hajnoczi } RwCo;
10321c9805a3SStefan Hajnoczi 
10331c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1034fc01f7e7Sbellard {
10351c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1036fc01f7e7Sbellard 
10371c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10381c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10391c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10401c9805a3SStefan Hajnoczi     } else {
10411c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10421c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10431c9805a3SStefan Hajnoczi     }
10441c9805a3SStefan Hajnoczi }
1045e7a8a783SKevin Wolf 
10461c9805a3SStefan Hajnoczi /*
10471c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10481c9805a3SStefan Hajnoczi  */
10491c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10501c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10511c9805a3SStefan Hajnoczi {
1052e7a8a783SKevin Wolf     QEMUIOVector qiov;
1053e7a8a783SKevin Wolf     struct iovec iov = {
1054e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1055e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1056e7a8a783SKevin Wolf     };
10571c9805a3SStefan Hajnoczi     Coroutine *co;
10581c9805a3SStefan Hajnoczi     RwCo rwco = {
10591c9805a3SStefan Hajnoczi         .bs = bs,
10601c9805a3SStefan Hajnoczi         .sector_num = sector_num,
10611c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
10621c9805a3SStefan Hajnoczi         .qiov = &qiov,
10631c9805a3SStefan Hajnoczi         .is_write = is_write,
10641c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
10651c9805a3SStefan Hajnoczi     };
1066e7a8a783SKevin Wolf 
1067e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
10681c9805a3SStefan Hajnoczi 
10691c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
10701c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
10711c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
10721c9805a3SStefan Hajnoczi     } else {
10731c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
10741c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
10751c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
10761c9805a3SStefan Hajnoczi             qemu_aio_wait();
10771c9805a3SStefan Hajnoczi         }
10781c9805a3SStefan Hajnoczi     }
10791c9805a3SStefan Hajnoczi     return rwco.ret;
1080e7a8a783SKevin Wolf }
1081e7a8a783SKevin Wolf 
10821c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
10831c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
10841c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
10851c9805a3SStefan Hajnoczi {
10861c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
108783f64091Sbellard }
1088fc01f7e7Sbellard 
10897cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
10907cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
10917cd1e32aSlirans@il.ibm.com {
10927cd1e32aSlirans@il.ibm.com     int64_t start, end;
1093c6d22830SJan Kiszka     unsigned long val, idx, bit;
1094a55eb92cSJan Kiszka 
10956ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1096c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
10977cd1e32aSlirans@il.ibm.com 
10987cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1099c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1100c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1101c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1102c6d22830SJan Kiszka         if (dirty) {
11036d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1104aaa0eb75SLiran Schour                 bs->dirty_count++;
11056d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1106aaa0eb75SLiran Schour             }
1107c6d22830SJan Kiszka         } else {
11086d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1109aaa0eb75SLiran Schour                 bs->dirty_count--;
11106d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1111c6d22830SJan Kiszka             }
1112aaa0eb75SLiran Schour         }
1113c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11147cd1e32aSlirans@il.ibm.com     }
11157cd1e32aSlirans@il.ibm.com }
11167cd1e32aSlirans@il.ibm.com 
111719cb3738Sbellard /* Return < 0 if error. Important errors are:
111819cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
111919cb3738Sbellard   -ENOMEDIUM   No media inserted.
112019cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
112119cb3738Sbellard   -EACCES      Trying to write a read-only device
112219cb3738Sbellard */
1123fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1124fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1125fc01f7e7Sbellard {
11261c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
112783f64091Sbellard }
112883f64091Sbellard 
1129eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1130eda578e5Saliguori                void *buf, int count1)
113183f64091Sbellard {
11326ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
113383f64091Sbellard     int len, nb_sectors, count;
113483f64091Sbellard     int64_t sector_num;
11359a8c4cceSKevin Wolf     int ret;
113683f64091Sbellard 
113783f64091Sbellard     count = count1;
113883f64091Sbellard     /* first read to align to sector start */
11396ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
114083f64091Sbellard     if (len > count)
114183f64091Sbellard         len = count;
11426ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
114383f64091Sbellard     if (len > 0) {
11449a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11459a8c4cceSKevin Wolf             return ret;
11466ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
114783f64091Sbellard         count -= len;
114883f64091Sbellard         if (count == 0)
114983f64091Sbellard             return count1;
115083f64091Sbellard         sector_num++;
115183f64091Sbellard         buf += len;
115283f64091Sbellard     }
115383f64091Sbellard 
115483f64091Sbellard     /* read the sectors "in place" */
11556ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
115683f64091Sbellard     if (nb_sectors > 0) {
11579a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11589a8c4cceSKevin Wolf             return ret;
115983f64091Sbellard         sector_num += nb_sectors;
11606ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
116183f64091Sbellard         buf += len;
116283f64091Sbellard         count -= len;
116383f64091Sbellard     }
116483f64091Sbellard 
116583f64091Sbellard     /* add data from the last sector */
116683f64091Sbellard     if (count > 0) {
11679a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11689a8c4cceSKevin Wolf             return ret;
116983f64091Sbellard         memcpy(buf, tmp_buf, count);
117083f64091Sbellard     }
117183f64091Sbellard     return count1;
117283f64091Sbellard }
117383f64091Sbellard 
1174eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1175eda578e5Saliguori                 const void *buf, int count1)
117683f64091Sbellard {
11776ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
117883f64091Sbellard     int len, nb_sectors, count;
117983f64091Sbellard     int64_t sector_num;
11809a8c4cceSKevin Wolf     int ret;
118183f64091Sbellard 
118283f64091Sbellard     count = count1;
118383f64091Sbellard     /* first write to align to sector start */
11846ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
118583f64091Sbellard     if (len > count)
118683f64091Sbellard         len = count;
11876ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
118883f64091Sbellard     if (len > 0) {
11899a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11909a8c4cceSKevin Wolf             return ret;
11916ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
11929a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
11939a8c4cceSKevin Wolf             return ret;
119483f64091Sbellard         count -= len;
119583f64091Sbellard         if (count == 0)
119683f64091Sbellard             return count1;
119783f64091Sbellard         sector_num++;
119883f64091Sbellard         buf += len;
119983f64091Sbellard     }
120083f64091Sbellard 
120183f64091Sbellard     /* write the sectors "in place" */
12026ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
120383f64091Sbellard     if (nb_sectors > 0) {
12049a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12059a8c4cceSKevin Wolf             return ret;
120683f64091Sbellard         sector_num += nb_sectors;
12076ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
120883f64091Sbellard         buf += len;
120983f64091Sbellard         count -= len;
121083f64091Sbellard     }
121183f64091Sbellard 
121283f64091Sbellard     /* add data from the last sector */
121383f64091Sbellard     if (count > 0) {
12149a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12159a8c4cceSKevin Wolf             return ret;
121683f64091Sbellard         memcpy(tmp_buf, buf, count);
12179a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12189a8c4cceSKevin Wolf             return ret;
121983f64091Sbellard     }
122083f64091Sbellard     return count1;
122183f64091Sbellard }
122283f64091Sbellard 
1223f08145feSKevin Wolf /*
1224f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1225f08145feSKevin Wolf  * request (acts as a barrier)
1226f08145feSKevin Wolf  *
1227f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1228f08145feSKevin Wolf  */
1229f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1230f08145feSKevin Wolf     const void *buf, int count)
1231f08145feSKevin Wolf {
1232f08145feSKevin Wolf     int ret;
1233f08145feSKevin Wolf 
1234f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1235f08145feSKevin Wolf     if (ret < 0) {
1236f08145feSKevin Wolf         return ret;
1237f08145feSKevin Wolf     }
1238f08145feSKevin Wolf 
123992196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
124092196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1241f08145feSKevin Wolf         bdrv_flush(bs);
1242f08145feSKevin Wolf     }
1243f08145feSKevin Wolf 
1244f08145feSKevin Wolf     return 0;
1245f08145feSKevin Wolf }
1246f08145feSKevin Wolf 
1247c5fbe571SStefan Hajnoczi /*
1248c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1249c5fbe571SStefan Hajnoczi  */
1250c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1251c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1252da1fa91dSKevin Wolf {
1253da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1254da1fa91dSKevin Wolf 
1255da1fa91dSKevin Wolf     if (!drv) {
1256da1fa91dSKevin Wolf         return -ENOMEDIUM;
1257da1fa91dSKevin Wolf     }
1258da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1259da1fa91dSKevin Wolf         return -EIO;
1260da1fa91dSKevin Wolf     }
1261da1fa91dSKevin Wolf 
1262da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1263da1fa91dSKevin Wolf }
1264da1fa91dSKevin Wolf 
1265c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1266da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1267da1fa91dSKevin Wolf {
1268c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1269da1fa91dSKevin Wolf 
1270c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1271c5fbe571SStefan Hajnoczi }
1272c5fbe571SStefan Hajnoczi 
1273c5fbe571SStefan Hajnoczi /*
1274c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1275c5fbe571SStefan Hajnoczi  */
1276c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1277c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1278c5fbe571SStefan Hajnoczi {
1279c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
12806b7cb247SStefan Hajnoczi     int ret;
1281da1fa91dSKevin Wolf 
1282da1fa91dSKevin Wolf     if (!bs->drv) {
1283da1fa91dSKevin Wolf         return -ENOMEDIUM;
1284da1fa91dSKevin Wolf     }
1285da1fa91dSKevin Wolf     if (bs->read_only) {
1286da1fa91dSKevin Wolf         return -EACCES;
1287da1fa91dSKevin Wolf     }
1288da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1289da1fa91dSKevin Wolf         return -EIO;
1290da1fa91dSKevin Wolf     }
1291da1fa91dSKevin Wolf 
12926b7cb247SStefan Hajnoczi     ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
12936b7cb247SStefan Hajnoczi 
1294da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1295da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1296da1fa91dSKevin Wolf     }
1297da1fa91dSKevin Wolf 
1298da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1299da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1300da1fa91dSKevin Wolf     }
1301da1fa91dSKevin Wolf 
13026b7cb247SStefan Hajnoczi     return ret;
1303da1fa91dSKevin Wolf }
1304da1fa91dSKevin Wolf 
1305c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1306c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1307c5fbe571SStefan Hajnoczi {
1308c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1309c5fbe571SStefan Hajnoczi 
1310c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1311c5fbe571SStefan Hajnoczi }
1312c5fbe571SStefan Hajnoczi 
131383f64091Sbellard /**
131483f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
131583f64091Sbellard  */
131683f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
131783f64091Sbellard {
131883f64091Sbellard     BlockDriver *drv = bs->drv;
131951762288SStefan Hajnoczi     int ret;
132083f64091Sbellard     if (!drv)
132119cb3738Sbellard         return -ENOMEDIUM;
132283f64091Sbellard     if (!drv->bdrv_truncate)
132383f64091Sbellard         return -ENOTSUP;
132459f2689dSNaphtali Sprei     if (bs->read_only)
132559f2689dSNaphtali Sprei         return -EACCES;
13268591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13278591675fSMarcelo Tosatti         return -EBUSY;
132851762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
132951762288SStefan Hajnoczi     if (ret == 0) {
133051762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1331145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
133251762288SStefan Hajnoczi     }
133351762288SStefan Hajnoczi     return ret;
133483f64091Sbellard }
133583f64091Sbellard 
133683f64091Sbellard /**
13374a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13384a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13394a1d5e1fSFam Zheng  */
13404a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13414a1d5e1fSFam Zheng {
13424a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13434a1d5e1fSFam Zheng     if (!drv) {
13444a1d5e1fSFam Zheng         return -ENOMEDIUM;
13454a1d5e1fSFam Zheng     }
13464a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13474a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13484a1d5e1fSFam Zheng     }
13494a1d5e1fSFam Zheng     if (bs->file) {
13504a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13514a1d5e1fSFam Zheng     }
13524a1d5e1fSFam Zheng     return -ENOTSUP;
13534a1d5e1fSFam Zheng }
13544a1d5e1fSFam Zheng 
13554a1d5e1fSFam Zheng /**
135683f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
135783f64091Sbellard  */
135883f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
135983f64091Sbellard {
136083f64091Sbellard     BlockDriver *drv = bs->drv;
136183f64091Sbellard     if (!drv)
136219cb3738Sbellard         return -ENOMEDIUM;
136351762288SStefan Hajnoczi 
13642c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
136546a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
136683f64091Sbellard             return drv->bdrv_getlength(bs);
1367fc01f7e7Sbellard         }
136846a4e4e6SStefan Hajnoczi     }
136946a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
137046a4e4e6SStefan Hajnoczi }
1371fc01f7e7Sbellard 
137219cb3738Sbellard /* return 0 as number of sectors if no device present or error */
137396b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1374fc01f7e7Sbellard {
137519cb3738Sbellard     int64_t length;
137619cb3738Sbellard     length = bdrv_getlength(bs);
137719cb3738Sbellard     if (length < 0)
137819cb3738Sbellard         length = 0;
137919cb3738Sbellard     else
13806ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
138119cb3738Sbellard     *nb_sectors_ptr = length;
1382fc01f7e7Sbellard }
1383cf98951bSbellard 
1384f3d54fc4Saliguori struct partition {
1385f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1386f3d54fc4Saliguori         uint8_t head;               /* starting head */
1387f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1388f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1389f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1390f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1391f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1392f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1393f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1394f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1395541dc0d4SStefan Weil } QEMU_PACKED;
1396f3d54fc4Saliguori 
1397f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1398f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1399f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1400f3d54fc4Saliguori {
1401eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1402f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1403f3d54fc4Saliguori     struct partition *p;
1404f3d54fc4Saliguori     uint32_t nr_sects;
1405a38131b6Sblueswir1     uint64_t nb_sectors;
1406f3d54fc4Saliguori 
1407f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1408f3d54fc4Saliguori 
1409f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1410f3d54fc4Saliguori     if (ret < 0)
1411f3d54fc4Saliguori         return -1;
1412f3d54fc4Saliguori     /* test msdos magic */
1413f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1414f3d54fc4Saliguori         return -1;
1415f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1416f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1417f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1418f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1419f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1420f3d54fc4Saliguori                a cylinder boundary */
1421f3d54fc4Saliguori             heads = p->end_head + 1;
1422f3d54fc4Saliguori             sectors = p->end_sector & 63;
1423f3d54fc4Saliguori             if (sectors == 0)
1424f3d54fc4Saliguori                 continue;
1425f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1426f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1427f3d54fc4Saliguori                 continue;
1428f3d54fc4Saliguori             *pheads = heads;
1429f3d54fc4Saliguori             *psectors = sectors;
1430f3d54fc4Saliguori             *pcylinders = cylinders;
1431f3d54fc4Saliguori #if 0
1432f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1433f3d54fc4Saliguori                    cylinders, heads, sectors);
1434f3d54fc4Saliguori #endif
1435f3d54fc4Saliguori             return 0;
1436f3d54fc4Saliguori         }
1437f3d54fc4Saliguori     }
1438f3d54fc4Saliguori     return -1;
1439f3d54fc4Saliguori }
1440f3d54fc4Saliguori 
1441f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1442f3d54fc4Saliguori {
1443f3d54fc4Saliguori     int translation, lba_detected = 0;
1444f3d54fc4Saliguori     int cylinders, heads, secs;
1445a38131b6Sblueswir1     uint64_t nb_sectors;
1446f3d54fc4Saliguori 
1447f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1448f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1449f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1450f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1451f3d54fc4Saliguori     if (cylinders != 0) {
1452f3d54fc4Saliguori         *pcyls = cylinders;
1453f3d54fc4Saliguori         *pheads = heads;
1454f3d54fc4Saliguori         *psecs = secs;
1455f3d54fc4Saliguori     } else {
1456f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1457f3d54fc4Saliguori             if (heads > 16) {
1458f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1459f3d54fc4Saliguori                    translation was active, so the default
1460f3d54fc4Saliguori                    hardware geometry is OK */
1461f3d54fc4Saliguori                 lba_detected = 1;
1462f3d54fc4Saliguori                 goto default_geometry;
1463f3d54fc4Saliguori             } else {
1464f3d54fc4Saliguori                 *pcyls = cylinders;
1465f3d54fc4Saliguori                 *pheads = heads;
1466f3d54fc4Saliguori                 *psecs = secs;
1467f3d54fc4Saliguori                 /* disable any translation to be in sync with
1468f3d54fc4Saliguori                    the logical geometry */
1469f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1470f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1471f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1472f3d54fc4Saliguori                 }
1473f3d54fc4Saliguori             }
1474f3d54fc4Saliguori         } else {
1475f3d54fc4Saliguori         default_geometry:
1476f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1477f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1478f3d54fc4Saliguori 
1479f3d54fc4Saliguori             if (cylinders > 16383)
1480f3d54fc4Saliguori                 cylinders = 16383;
1481f3d54fc4Saliguori             else if (cylinders < 2)
1482f3d54fc4Saliguori                 cylinders = 2;
1483f3d54fc4Saliguori             *pcyls = cylinders;
1484f3d54fc4Saliguori             *pheads = 16;
1485f3d54fc4Saliguori             *psecs = 63;
1486f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1487f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1488f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1489f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1490f3d54fc4Saliguori                 } else {
1491f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1492f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1493f3d54fc4Saliguori                 }
1494f3d54fc4Saliguori             }
1495f3d54fc4Saliguori         }
1496f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1497f3d54fc4Saliguori     }
1498f3d54fc4Saliguori }
1499f3d54fc4Saliguori 
1500b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1501b338082bSbellard                             int cyls, int heads, int secs)
1502b338082bSbellard {
1503b338082bSbellard     bs->cyls = cyls;
1504b338082bSbellard     bs->heads = heads;
1505b338082bSbellard     bs->secs = secs;
1506b338082bSbellard }
1507b338082bSbellard 
150846d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
150946d4767dSbellard {
151046d4767dSbellard     bs->translation = translation;
151146d4767dSbellard }
151246d4767dSbellard 
1513b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1514b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1515b338082bSbellard {
1516b338082bSbellard     *pcyls = bs->cyls;
1517b338082bSbellard     *pheads = bs->heads;
1518b338082bSbellard     *psecs = bs->secs;
1519b338082bSbellard }
1520b338082bSbellard 
15215bbdbb46SBlue Swirl /* Recognize floppy formats */
15225bbdbb46SBlue Swirl typedef struct FDFormat {
15235bbdbb46SBlue Swirl     FDriveType drive;
15245bbdbb46SBlue Swirl     uint8_t last_sect;
15255bbdbb46SBlue Swirl     uint8_t max_track;
15265bbdbb46SBlue Swirl     uint8_t max_head;
15275bbdbb46SBlue Swirl } FDFormat;
15285bbdbb46SBlue Swirl 
15295bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15305bbdbb46SBlue Swirl     /* First entry is default format */
15315bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15325bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15335bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15345bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15355bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15365bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15375bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15385bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15395bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15405bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15415bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15425bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15435bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15445bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15455bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15465bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15475bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15485bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15495bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15505bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15515bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15525bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15535bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15545bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15555bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15565bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15575bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15585bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15595bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15605bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15615bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15625bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15635bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15645bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15655bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15665bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15675bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15685bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
15695bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
15705bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
15715bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
15725bbdbb46SBlue Swirl     /* end */
15735bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
15745bbdbb46SBlue Swirl };
15755bbdbb46SBlue Swirl 
15765bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
15775bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
15785bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
15795bbdbb46SBlue Swirl {
15805bbdbb46SBlue Swirl     const FDFormat *parse;
15815bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
15825bbdbb46SBlue Swirl     int i, first_match, match;
15835bbdbb46SBlue Swirl 
15845bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
15855bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
15865bbdbb46SBlue Swirl         /* User defined disk */
15875bbdbb46SBlue Swirl     } else {
15885bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
15895bbdbb46SBlue Swirl         match = -1;
15905bbdbb46SBlue Swirl         first_match = -1;
15915bbdbb46SBlue Swirl         for (i = 0; ; i++) {
15925bbdbb46SBlue Swirl             parse = &fd_formats[i];
15935bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
15945bbdbb46SBlue Swirl                 break;
15955bbdbb46SBlue Swirl             }
15965bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
15975bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
15985bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
15995bbdbb46SBlue Swirl                     parse->last_sect;
16005bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16015bbdbb46SBlue Swirl                     match = i;
16025bbdbb46SBlue Swirl                     break;
16035bbdbb46SBlue Swirl                 }
16045bbdbb46SBlue Swirl                 if (first_match == -1) {
16055bbdbb46SBlue Swirl                     first_match = i;
16065bbdbb46SBlue Swirl                 }
16075bbdbb46SBlue Swirl             }
16085bbdbb46SBlue Swirl         }
16095bbdbb46SBlue Swirl         if (match == -1) {
16105bbdbb46SBlue Swirl             if (first_match == -1) {
16115bbdbb46SBlue Swirl                 match = 1;
16125bbdbb46SBlue Swirl             } else {
16135bbdbb46SBlue Swirl                 match = first_match;
16145bbdbb46SBlue Swirl             }
16155bbdbb46SBlue Swirl             parse = &fd_formats[match];
16165bbdbb46SBlue Swirl         }
16175bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16185bbdbb46SBlue Swirl         *max_track = parse->max_track;
16195bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16205bbdbb46SBlue Swirl         *drive = parse->drive;
16215bbdbb46SBlue Swirl     }
16225bbdbb46SBlue Swirl }
16235bbdbb46SBlue Swirl 
162446d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
162546d4767dSbellard {
162646d4767dSbellard     return bs->translation;
162746d4767dSbellard }
162846d4767dSbellard 
1629abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1630abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1631abd7f68dSMarkus Armbruster {
1632abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1633abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1634abd7f68dSMarkus Armbruster }
1635abd7f68dSMarkus Armbruster 
1636abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1637abd7f68dSMarkus Armbruster {
1638abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1639abd7f68dSMarkus Armbruster }
1640abd7f68dSMarkus Armbruster 
1641b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1642b338082bSbellard {
1643b338082bSbellard     return bs->read_only;
1644b338082bSbellard }
1645b338082bSbellard 
1646985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1647985a03b0Sths {
1648985a03b0Sths     return bs->sg;
1649985a03b0Sths }
1650985a03b0Sths 
1651e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1652e900a7b7SChristoph Hellwig {
1653e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1654e900a7b7SChristoph Hellwig }
1655e900a7b7SChristoph Hellwig 
1656ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1657ea2384d3Sbellard {
1658ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1659ea2384d3Sbellard         return 1;
1660ea2384d3Sbellard     return bs->encrypted;
1661ea2384d3Sbellard }
1662ea2384d3Sbellard 
1663c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1664c0f4ce77Saliguori {
1665c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1666c0f4ce77Saliguori 
1667c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1668c0f4ce77Saliguori         return 1;
1669c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1670c0f4ce77Saliguori }
1671c0f4ce77Saliguori 
1672ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1673ea2384d3Sbellard {
1674ea2384d3Sbellard     int ret;
1675ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1676ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1677ea2384d3Sbellard         if (ret < 0)
1678ea2384d3Sbellard             return ret;
1679ea2384d3Sbellard         if (!bs->encrypted)
1680ea2384d3Sbellard             return 0;
1681ea2384d3Sbellard     }
1682fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1683fd04a2aeSShahar Havivi         return -EINVAL;
1684fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1685fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1686fd04a2aeSShahar Havivi     }
1687c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1688bb5fc20fSaliguori     if (ret < 0) {
1689bb5fc20fSaliguori         bs->valid_key = 0;
1690bb5fc20fSaliguori     } else if (!bs->valid_key) {
1691bb5fc20fSaliguori         bs->valid_key = 1;
1692bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
16937d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1694bb5fc20fSaliguori     }
1695c0f4ce77Saliguori     return ret;
1696ea2384d3Sbellard }
1697ea2384d3Sbellard 
1698ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1699ea2384d3Sbellard {
170019cb3738Sbellard     if (!bs->drv) {
1701ea2384d3Sbellard         buf[0] = '\0';
1702ea2384d3Sbellard     } else {
1703ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1704ea2384d3Sbellard     }
1705ea2384d3Sbellard }
1706ea2384d3Sbellard 
1707ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1708ea2384d3Sbellard                          void *opaque)
1709ea2384d3Sbellard {
1710ea2384d3Sbellard     BlockDriver *drv;
1711ea2384d3Sbellard 
17128a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1713ea2384d3Sbellard         it(opaque, drv->format_name);
1714ea2384d3Sbellard     }
1715ea2384d3Sbellard }
1716ea2384d3Sbellard 
1717b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1718b338082bSbellard {
1719b338082bSbellard     BlockDriverState *bs;
1720b338082bSbellard 
17211b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17221b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1723b338082bSbellard             return bs;
1724b338082bSbellard         }
17251b7bdbc1SStefan Hajnoczi     }
1726b338082bSbellard     return NULL;
1727b338082bSbellard }
1728b338082bSbellard 
17292f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17302f399b0aSMarkus Armbruster {
17312f399b0aSMarkus Armbruster     if (!bs) {
17322f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17332f399b0aSMarkus Armbruster     }
17342f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17352f399b0aSMarkus Armbruster }
17362f399b0aSMarkus Armbruster 
173751de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
173881d0912dSbellard {
173981d0912dSbellard     BlockDriverState *bs;
174081d0912dSbellard 
17411b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
174251de9760Saliguori         it(opaque, bs);
174381d0912dSbellard     }
174481d0912dSbellard }
174581d0912dSbellard 
1746ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1747ea2384d3Sbellard {
1748ea2384d3Sbellard     return bs->device_name;
1749ea2384d3Sbellard }
1750ea2384d3Sbellard 
1751c6ca28d6Saliguori void bdrv_flush_all(void)
1752c6ca28d6Saliguori {
1753c6ca28d6Saliguori     BlockDriverState *bs;
1754c6ca28d6Saliguori 
17551b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1756c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1757c6ca28d6Saliguori             bdrv_flush(bs);
1758c6ca28d6Saliguori         }
17591b7bdbc1SStefan Hajnoczi     }
17601b7bdbc1SStefan Hajnoczi }
1761c6ca28d6Saliguori 
1762f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1763f2feebbdSKevin Wolf {
1764f2feebbdSKevin Wolf     assert(bs->drv);
1765f2feebbdSKevin Wolf 
1766336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1767336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1768f2feebbdSKevin Wolf     }
1769f2feebbdSKevin Wolf 
1770f2feebbdSKevin Wolf     return 1;
1771f2feebbdSKevin Wolf }
1772f2feebbdSKevin Wolf 
1773f58c7b35Sths /*
1774f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1775f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1776f58c7b35Sths  * hence all their sectors are reported as allocated.
1777f58c7b35Sths  *
1778f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1779f58c7b35Sths  * the specified sector) that are known to be in the same
1780f58c7b35Sths  * allocated/unallocated state.
1781f58c7b35Sths  *
1782f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1783f58c7b35Sths  */
1784f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1785f58c7b35Sths 	int *pnum)
1786f58c7b35Sths {
1787f58c7b35Sths     int64_t n;
1788f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1789f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1790f58c7b35Sths             *pnum = 0;
1791f58c7b35Sths             return 0;
1792f58c7b35Sths         }
1793f58c7b35Sths         n = bs->total_sectors - sector_num;
1794f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1795f58c7b35Sths         return 1;
1796f58c7b35Sths     }
1797f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1798f58c7b35Sths }
1799f58c7b35Sths 
18002582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18012582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18022582bfedSLuiz Capitulino {
18032582bfedSLuiz Capitulino     QObject *data;
18042582bfedSLuiz Capitulino     const char *action_str;
18052582bfedSLuiz Capitulino 
18062582bfedSLuiz Capitulino     switch (action) {
18072582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18082582bfedSLuiz Capitulino         action_str = "report";
18092582bfedSLuiz Capitulino         break;
18102582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18112582bfedSLuiz Capitulino         action_str = "ignore";
18122582bfedSLuiz Capitulino         break;
18132582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18142582bfedSLuiz Capitulino         action_str = "stop";
18152582bfedSLuiz Capitulino         break;
18162582bfedSLuiz Capitulino     default:
18172582bfedSLuiz Capitulino         abort();
18182582bfedSLuiz Capitulino     }
18192582bfedSLuiz Capitulino 
18202582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18212582bfedSLuiz Capitulino                               bdrv->device_name,
18222582bfedSLuiz Capitulino                               action_str,
18232582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18242582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18252582bfedSLuiz Capitulino 
18262582bfedSLuiz Capitulino     qobject_decref(data);
18272582bfedSLuiz Capitulino }
18282582bfedSLuiz Capitulino 
1829d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque)
1830b338082bSbellard {
1831d15e5465SLuiz Capitulino     QDict *bs_dict;
1832d15e5465SLuiz Capitulino     Monitor *mon = opaque;
1833b338082bSbellard 
1834d15e5465SLuiz Capitulino     bs_dict = qobject_to_qdict(obj);
1835d15e5465SLuiz Capitulino 
1836d8aeeb31SMarkus Armbruster     monitor_printf(mon, "%s: removable=%d",
1837d15e5465SLuiz Capitulino                         qdict_get_str(bs_dict, "device"),
1838d15e5465SLuiz Capitulino                         qdict_get_bool(bs_dict, "removable"));
1839d15e5465SLuiz Capitulino 
1840d15e5465SLuiz Capitulino     if (qdict_get_bool(bs_dict, "removable")) {
1841d15e5465SLuiz Capitulino         monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
1842e4def80bSMarkus Armbruster         monitor_printf(mon, " tray-open=%d",
1843e4def80bSMarkus Armbruster                        qdict_get_bool(bs_dict, "tray-open"));
1844b338082bSbellard     }
1845d2078cc2SLuiz Capitulino 
1846d2078cc2SLuiz Capitulino     if (qdict_haskey(bs_dict, "io-status")) {
1847d2078cc2SLuiz Capitulino         monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
1848d2078cc2SLuiz Capitulino     }
1849d2078cc2SLuiz Capitulino 
1850d15e5465SLuiz Capitulino     if (qdict_haskey(bs_dict, "inserted")) {
1851d15e5465SLuiz Capitulino         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
1852d15e5465SLuiz Capitulino 
1853376253ecSaliguori         monitor_printf(mon, " file=");
1854d15e5465SLuiz Capitulino         monitor_print_filename(mon, qdict_get_str(qdict, "file"));
1855d15e5465SLuiz Capitulino         if (qdict_haskey(qdict, "backing_file")) {
1856376253ecSaliguori             monitor_printf(mon, " backing_file=");
1857d15e5465SLuiz Capitulino             monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
1858fef30743Sths         }
1859d15e5465SLuiz Capitulino         monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
1860d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "ro"),
1861d15e5465SLuiz Capitulino                             qdict_get_str(qdict, "drv"),
1862d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "encrypted"));
1863b338082bSbellard     } else {
1864376253ecSaliguori         monitor_printf(mon, " [not inserted]");
1865b338082bSbellard     }
1866d15e5465SLuiz Capitulino 
1867376253ecSaliguori     monitor_printf(mon, "\n");
1868b338082bSbellard }
1869d15e5465SLuiz Capitulino 
1870d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data)
1871d15e5465SLuiz Capitulino {
1872d15e5465SLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
1873d15e5465SLuiz Capitulino }
1874d15e5465SLuiz Capitulino 
1875f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = {
1876f04ef601SLuiz Capitulino     [BDRV_IOS_OK] = "ok",
1877f04ef601SLuiz Capitulino     [BDRV_IOS_FAILED] = "failed",
1878f04ef601SLuiz Capitulino     [BDRV_IOS_ENOSPC] = "nospace",
1879f04ef601SLuiz Capitulino };
1880f04ef601SLuiz Capitulino 
1881d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data)
1882d15e5465SLuiz Capitulino {
1883d15e5465SLuiz Capitulino     QList *bs_list;
1884d15e5465SLuiz Capitulino     BlockDriverState *bs;
1885d15e5465SLuiz Capitulino 
1886d15e5465SLuiz Capitulino     bs_list = qlist_new();
1887d15e5465SLuiz Capitulino 
18881b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1889d15e5465SLuiz Capitulino         QObject *bs_obj;
1890e4def80bSMarkus Armbruster         QDict *bs_dict;
1891d15e5465SLuiz Capitulino 
1892d8aeeb31SMarkus Armbruster         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
1893d15e5465SLuiz Capitulino                                     "'removable': %i, 'locked': %i }",
18942c6942faSMarkus Armbruster                                     bs->device_name,
18952c6942faSMarkus Armbruster                                     bdrv_dev_has_removable_media(bs),
1896f107639aSMarkus Armbruster                                     bdrv_dev_is_medium_locked(bs));
1897e4def80bSMarkus Armbruster         bs_dict = qobject_to_qdict(bs_obj);
1898d15e5465SLuiz Capitulino 
1899e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1900e4def80bSMarkus Armbruster             qdict_put(bs_dict, "tray-open",
1901e4def80bSMarkus Armbruster                       qbool_from_int(bdrv_dev_is_tray_open(bs)));
1902e4def80bSMarkus Armbruster         }
1903f04ef601SLuiz Capitulino 
1904f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1905f04ef601SLuiz Capitulino             qdict_put(bs_dict, "io-status",
1906f04ef601SLuiz Capitulino                       qstring_from_str(io_status_name[bs->iostatus]));
1907f04ef601SLuiz Capitulino         }
1908f04ef601SLuiz Capitulino 
1909d15e5465SLuiz Capitulino         if (bs->drv) {
1910d15e5465SLuiz Capitulino             QObject *obj;
1911d15e5465SLuiz Capitulino 
1912d15e5465SLuiz Capitulino             obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
1913d15e5465SLuiz Capitulino                                      "'encrypted': %i }",
1914d15e5465SLuiz Capitulino                                      bs->filename, bs->read_only,
1915d15e5465SLuiz Capitulino                                      bs->drv->format_name,
1916d15e5465SLuiz Capitulino                                      bdrv_is_encrypted(bs));
1917d15e5465SLuiz Capitulino             if (bs->backing_file[0] != '\0') {
1918d15e5465SLuiz Capitulino                 QDict *qdict = qobject_to_qdict(obj);
1919d15e5465SLuiz Capitulino                 qdict_put(qdict, "backing_file",
1920d15e5465SLuiz Capitulino                           qstring_from_str(bs->backing_file));
1921d15e5465SLuiz Capitulino             }
1922d15e5465SLuiz Capitulino 
1923d15e5465SLuiz Capitulino             qdict_put_obj(bs_dict, "inserted", obj);
1924d15e5465SLuiz Capitulino         }
1925d15e5465SLuiz Capitulino         qlist_append_obj(bs_list, bs_obj);
1926d15e5465SLuiz Capitulino     }
1927d15e5465SLuiz Capitulino 
1928d15e5465SLuiz Capitulino     *ret_data = QOBJECT(bs_list);
1929b338082bSbellard }
1930a36e69ddSths 
1931218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque)
1932a36e69ddSths {
1933218a536aSLuiz Capitulino     QDict *qdict;
1934218a536aSLuiz Capitulino     Monitor *mon = opaque;
1935218a536aSLuiz Capitulino 
1936218a536aSLuiz Capitulino     qdict = qobject_to_qdict(data);
1937218a536aSLuiz Capitulino     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
1938218a536aSLuiz Capitulino 
1939218a536aSLuiz Capitulino     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
1940218a536aSLuiz Capitulino     monitor_printf(mon, " rd_bytes=%" PRId64
1941218a536aSLuiz Capitulino                         " wr_bytes=%" PRId64
1942218a536aSLuiz Capitulino                         " rd_operations=%" PRId64
1943218a536aSLuiz Capitulino                         " wr_operations=%" PRId64
1944e8045d67SChristoph Hellwig                         " flush_operations=%" PRId64
1945c488c7f6SChristoph Hellwig                         " wr_total_time_ns=%" PRId64
1946c488c7f6SChristoph Hellwig                         " rd_total_time_ns=%" PRId64
1947c488c7f6SChristoph Hellwig                         " flush_total_time_ns=%" PRId64
1948218a536aSLuiz Capitulino                         "\n",
1949218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_bytes"),
1950218a536aSLuiz Capitulino                         qdict_get_int(qdict, "wr_bytes"),
1951218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_operations"),
1952e8045d67SChristoph Hellwig                         qdict_get_int(qdict, "wr_operations"),
1953c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_operations"),
1954c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "wr_total_time_ns"),
1955c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "rd_total_time_ns"),
1956c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_total_time_ns"));
1957218a536aSLuiz Capitulino }
1958218a536aSLuiz Capitulino 
1959218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data)
1960218a536aSLuiz Capitulino {
1961218a536aSLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
1962218a536aSLuiz Capitulino }
1963218a536aSLuiz Capitulino 
1964294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
1965294cc35fSKevin Wolf {
1966294cc35fSKevin Wolf     QObject *res;
1967294cc35fSKevin Wolf     QDict *dict;
1968294cc35fSKevin Wolf 
1969294cc35fSKevin Wolf     res = qobject_from_jsonf("{ 'stats': {"
1970294cc35fSKevin Wolf                              "'rd_bytes': %" PRId64 ","
1971294cc35fSKevin Wolf                              "'wr_bytes': %" PRId64 ","
1972294cc35fSKevin Wolf                              "'rd_operations': %" PRId64 ","
1973294cc35fSKevin Wolf                              "'wr_operations': %" PRId64 ","
1974e8045d67SChristoph Hellwig                              "'wr_highest_offset': %" PRId64 ","
1975c488c7f6SChristoph Hellwig                              "'flush_operations': %" PRId64 ","
1976c488c7f6SChristoph Hellwig                              "'wr_total_time_ns': %" PRId64 ","
1977c488c7f6SChristoph Hellwig                              "'rd_total_time_ns': %" PRId64 ","
1978c488c7f6SChristoph Hellwig                              "'flush_total_time_ns': %" PRId64
1979294cc35fSKevin Wolf                              "} }",
1980a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_READ],
1981a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_WRITE],
1982a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_READ],
1983a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_WRITE],
19845ffbbc67SBlue Swirl                              bs->wr_highest_sector *
1985e8045d67SChristoph Hellwig                              (uint64_t)BDRV_SECTOR_SIZE,
1986c488c7f6SChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_FLUSH],
1987c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_WRITE],
1988c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_READ],
1989c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_FLUSH]);
1990294cc35fSKevin Wolf     dict  = qobject_to_qdict(res);
1991294cc35fSKevin Wolf 
1992294cc35fSKevin Wolf     if (*bs->device_name) {
1993294cc35fSKevin Wolf         qdict_put(dict, "device", qstring_from_str(bs->device_name));
1994294cc35fSKevin Wolf     }
1995294cc35fSKevin Wolf 
1996294cc35fSKevin Wolf     if (bs->file) {
1997294cc35fSKevin Wolf         QObject *parent = bdrv_info_stats_bs(bs->file);
1998294cc35fSKevin Wolf         qdict_put_obj(dict, "parent", parent);
1999294cc35fSKevin Wolf     }
2000294cc35fSKevin Wolf 
2001294cc35fSKevin Wolf     return res;
2002294cc35fSKevin Wolf }
2003294cc35fSKevin Wolf 
2004218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data)
2005218a536aSLuiz Capitulino {
2006218a536aSLuiz Capitulino     QObject *obj;
2007218a536aSLuiz Capitulino     QList *devices;
2008a36e69ddSths     BlockDriverState *bs;
2009a36e69ddSths 
2010218a536aSLuiz Capitulino     devices = qlist_new();
2011218a536aSLuiz Capitulino 
20121b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
2013294cc35fSKevin Wolf         obj = bdrv_info_stats_bs(bs);
2014218a536aSLuiz Capitulino         qlist_append_obj(devices, obj);
2015a36e69ddSths     }
2016218a536aSLuiz Capitulino 
2017218a536aSLuiz Capitulino     *ret_data = QOBJECT(devices);
2018a36e69ddSths }
2019ea2384d3Sbellard 
2020045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
2021045df330Saliguori {
2022045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
2023045df330Saliguori         return bs->backing_file;
2024045df330Saliguori     else if (bs->encrypted)
2025045df330Saliguori         return bs->filename;
2026045df330Saliguori     else
2027045df330Saliguori         return NULL;
2028045df330Saliguori }
2029045df330Saliguori 
203083f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
203183f64091Sbellard                                char *filename, int filename_size)
203283f64091Sbellard {
203383f64091Sbellard     pstrcpy(filename, filename_size, bs->backing_file);
203483f64091Sbellard }
203583f64091Sbellard 
2036faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
2037faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
2038faea38e7Sbellard {
2039faea38e7Sbellard     BlockDriver *drv = bs->drv;
2040faea38e7Sbellard     if (!drv)
204119cb3738Sbellard         return -ENOMEDIUM;
2042faea38e7Sbellard     if (!drv->bdrv_write_compressed)
2043faea38e7Sbellard         return -ENOTSUP;
2044fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
2045fbb7b4e0SKevin Wolf         return -EIO;
20467cd1e32aSlirans@il.ibm.com 
2047c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
20487cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
20497cd1e32aSlirans@il.ibm.com     }
20507cd1e32aSlirans@il.ibm.com 
2051faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2052faea38e7Sbellard }
2053faea38e7Sbellard 
2054faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2055faea38e7Sbellard {
2056faea38e7Sbellard     BlockDriver *drv = bs->drv;
2057faea38e7Sbellard     if (!drv)
205819cb3738Sbellard         return -ENOMEDIUM;
2059faea38e7Sbellard     if (!drv->bdrv_get_info)
2060faea38e7Sbellard         return -ENOTSUP;
2061faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2062faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2063faea38e7Sbellard }
2064faea38e7Sbellard 
206545566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
206645566e9cSChristoph Hellwig                       int64_t pos, int size)
2067178e08a5Saliguori {
2068178e08a5Saliguori     BlockDriver *drv = bs->drv;
2069178e08a5Saliguori     if (!drv)
2070178e08a5Saliguori         return -ENOMEDIUM;
20717cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
207245566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
20737cdb1f6dSMORITA Kazutaka     if (bs->file)
20747cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
20757cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2076178e08a5Saliguori }
2077178e08a5Saliguori 
207845566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
207945566e9cSChristoph Hellwig                       int64_t pos, int size)
2080178e08a5Saliguori {
2081178e08a5Saliguori     BlockDriver *drv = bs->drv;
2082178e08a5Saliguori     if (!drv)
2083178e08a5Saliguori         return -ENOMEDIUM;
20847cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
208545566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
20867cdb1f6dSMORITA Kazutaka     if (bs->file)
20877cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
20887cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2089178e08a5Saliguori }
2090178e08a5Saliguori 
20918b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
20928b9b0cc2SKevin Wolf {
20938b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
20948b9b0cc2SKevin Wolf 
20958b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
20968b9b0cc2SKevin Wolf         return;
20978b9b0cc2SKevin Wolf     }
20988b9b0cc2SKevin Wolf 
20998b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
21008b9b0cc2SKevin Wolf 
21018b9b0cc2SKevin Wolf }
21028b9b0cc2SKevin Wolf 
2103faea38e7Sbellard /**************************************************************/
2104faea38e7Sbellard /* handling of snapshots */
2105faea38e7Sbellard 
2106feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2107feeee5acSMiguel Di Ciurcio Filho {
2108feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
210907b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2110feeee5acSMiguel Di Ciurcio Filho         return 0;
2111feeee5acSMiguel Di Ciurcio Filho     }
2112feeee5acSMiguel Di Ciurcio Filho 
2113feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2114feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2115feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2116feeee5acSMiguel Di Ciurcio Filho         }
2117feeee5acSMiguel Di Ciurcio Filho         return 0;
2118feeee5acSMiguel Di Ciurcio Filho     }
2119feeee5acSMiguel Di Ciurcio Filho 
2120feeee5acSMiguel Di Ciurcio Filho     return 1;
2121feeee5acSMiguel Di Ciurcio Filho }
2122feeee5acSMiguel Di Ciurcio Filho 
2123199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2124199630b6SBlue Swirl {
2125199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2126199630b6SBlue Swirl }
2127199630b6SBlue Swirl 
2128f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2129f9092b10SMarkus Armbruster {
2130f9092b10SMarkus Armbruster     BlockDriverState *bs;
2131f9092b10SMarkus Armbruster 
21323ac906f7SMarkus Armbruster     if (bs_snapshots) {
2133f9092b10SMarkus Armbruster         return bs_snapshots;
21343ac906f7SMarkus Armbruster     }
2135f9092b10SMarkus Armbruster 
2136f9092b10SMarkus Armbruster     bs = NULL;
2137f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2138f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
21393ac906f7SMarkus Armbruster             bs_snapshots = bs;
21403ac906f7SMarkus Armbruster             return bs;
2141f9092b10SMarkus Armbruster         }
2142f9092b10SMarkus Armbruster     }
2143f9092b10SMarkus Armbruster     return NULL;
2144f9092b10SMarkus Armbruster }
2145f9092b10SMarkus Armbruster 
2146faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2147faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2148faea38e7Sbellard {
2149faea38e7Sbellard     BlockDriver *drv = bs->drv;
2150faea38e7Sbellard     if (!drv)
215119cb3738Sbellard         return -ENOMEDIUM;
21527cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2153faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
21547cdb1f6dSMORITA Kazutaka     if (bs->file)
21557cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
21567cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2157faea38e7Sbellard }
2158faea38e7Sbellard 
2159faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2160faea38e7Sbellard                        const char *snapshot_id)
2161faea38e7Sbellard {
2162faea38e7Sbellard     BlockDriver *drv = bs->drv;
21637cdb1f6dSMORITA Kazutaka     int ret, open_ret;
21647cdb1f6dSMORITA Kazutaka 
2165faea38e7Sbellard     if (!drv)
216619cb3738Sbellard         return -ENOMEDIUM;
21677cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2168faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
21697cdb1f6dSMORITA Kazutaka 
21707cdb1f6dSMORITA Kazutaka     if (bs->file) {
21717cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
21727cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
21737cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
21747cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
21757cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
21767cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
21777cdb1f6dSMORITA Kazutaka             return open_ret;
21787cdb1f6dSMORITA Kazutaka         }
21797cdb1f6dSMORITA Kazutaka         return ret;
21807cdb1f6dSMORITA Kazutaka     }
21817cdb1f6dSMORITA Kazutaka 
21827cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2183faea38e7Sbellard }
2184faea38e7Sbellard 
2185faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2186faea38e7Sbellard {
2187faea38e7Sbellard     BlockDriver *drv = bs->drv;
2188faea38e7Sbellard     if (!drv)
218919cb3738Sbellard         return -ENOMEDIUM;
21907cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2191faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
21927cdb1f6dSMORITA Kazutaka     if (bs->file)
21937cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
21947cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2195faea38e7Sbellard }
2196faea38e7Sbellard 
2197faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2198faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2199faea38e7Sbellard {
2200faea38e7Sbellard     BlockDriver *drv = bs->drv;
2201faea38e7Sbellard     if (!drv)
220219cb3738Sbellard         return -ENOMEDIUM;
22037cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2204faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
22057cdb1f6dSMORITA Kazutaka     if (bs->file)
22067cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
22077cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2208faea38e7Sbellard }
2209faea38e7Sbellard 
221051ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
221151ef6727Sedison         const char *snapshot_name)
221251ef6727Sedison {
221351ef6727Sedison     BlockDriver *drv = bs->drv;
221451ef6727Sedison     if (!drv) {
221551ef6727Sedison         return -ENOMEDIUM;
221651ef6727Sedison     }
221751ef6727Sedison     if (!bs->read_only) {
221851ef6727Sedison         return -EINVAL;
221951ef6727Sedison     }
222051ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
222151ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
222251ef6727Sedison     }
222351ef6727Sedison     return -ENOTSUP;
222451ef6727Sedison }
222551ef6727Sedison 
2226faea38e7Sbellard #define NB_SUFFIXES 4
2227faea38e7Sbellard 
2228faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2229faea38e7Sbellard {
2230faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2231faea38e7Sbellard     int64_t base;
2232faea38e7Sbellard     int i;
2233faea38e7Sbellard 
2234faea38e7Sbellard     if (size <= 999) {
2235faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2236faea38e7Sbellard     } else {
2237faea38e7Sbellard         base = 1024;
2238faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2239faea38e7Sbellard             if (size < (10 * base)) {
2240faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2241faea38e7Sbellard                          (double)size / base,
2242faea38e7Sbellard                          suffixes[i]);
2243faea38e7Sbellard                 break;
2244faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2245faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2246faea38e7Sbellard                          ((size + (base >> 1)) / base),
2247faea38e7Sbellard                          suffixes[i]);
2248faea38e7Sbellard                 break;
2249faea38e7Sbellard             }
2250faea38e7Sbellard             base = base * 1024;
2251faea38e7Sbellard         }
2252faea38e7Sbellard     }
2253faea38e7Sbellard     return buf;
2254faea38e7Sbellard }
2255faea38e7Sbellard 
2256faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2257faea38e7Sbellard {
2258faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
22593b9f94e1Sbellard #ifdef _WIN32
22603b9f94e1Sbellard     struct tm *ptm;
22613b9f94e1Sbellard #else
2262faea38e7Sbellard     struct tm tm;
22633b9f94e1Sbellard #endif
2264faea38e7Sbellard     time_t ti;
2265faea38e7Sbellard     int64_t secs;
2266faea38e7Sbellard 
2267faea38e7Sbellard     if (!sn) {
2268faea38e7Sbellard         snprintf(buf, buf_size,
2269faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2270faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2271faea38e7Sbellard     } else {
2272faea38e7Sbellard         ti = sn->date_sec;
22733b9f94e1Sbellard #ifdef _WIN32
22743b9f94e1Sbellard         ptm = localtime(&ti);
22753b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
22763b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
22773b9f94e1Sbellard #else
2278faea38e7Sbellard         localtime_r(&ti, &tm);
2279faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2280faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
22813b9f94e1Sbellard #endif
2282faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2283faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2284faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2285faea38e7Sbellard                  (int)(secs / 3600),
2286faea38e7Sbellard                  (int)((secs / 60) % 60),
2287faea38e7Sbellard                  (int)(secs % 60),
2288faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2289faea38e7Sbellard         snprintf(buf, buf_size,
2290faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2291faea38e7Sbellard                  sn->id_str, sn->name,
2292faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2293faea38e7Sbellard                  date_buf,
2294faea38e7Sbellard                  clock_buf);
2295faea38e7Sbellard     }
2296faea38e7Sbellard     return buf;
2297faea38e7Sbellard }
2298faea38e7Sbellard 
2299ea2384d3Sbellard /**************************************************************/
230083f64091Sbellard /* async I/Os */
2301ea2384d3Sbellard 
23023b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2303f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
230483f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2305ea2384d3Sbellard {
2306bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2307bbf0a440SStefan Hajnoczi 
2308b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
23098c5873d6SStefan Hajnoczi                                  cb, opaque, false);
231083f64091Sbellard }
231183f64091Sbellard 
2312f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2313f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
231483f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
23157674e7bfSbellard {
2316bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2317bbf0a440SStefan Hajnoczi 
23181a6e115bSStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
23198c5873d6SStefan Hajnoczi                                  cb, opaque, true);
232083f64091Sbellard }
232183f64091Sbellard 
232240b4f539SKevin Wolf 
232340b4f539SKevin Wolf typedef struct MultiwriteCB {
232440b4f539SKevin Wolf     int error;
232540b4f539SKevin Wolf     int num_requests;
232640b4f539SKevin Wolf     int num_callbacks;
232740b4f539SKevin Wolf     struct {
232840b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
232940b4f539SKevin Wolf         void *opaque;
233040b4f539SKevin Wolf         QEMUIOVector *free_qiov;
233140b4f539SKevin Wolf         void *free_buf;
233240b4f539SKevin Wolf     } callbacks[];
233340b4f539SKevin Wolf } MultiwriteCB;
233440b4f539SKevin Wolf 
233540b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
233640b4f539SKevin Wolf {
233740b4f539SKevin Wolf     int i;
233840b4f539SKevin Wolf 
233940b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
234040b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
23411e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
23421e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
23431e1ea48dSStefan Hajnoczi         }
23447267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2345f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
234640b4f539SKevin Wolf     }
234740b4f539SKevin Wolf }
234840b4f539SKevin Wolf 
234940b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
235040b4f539SKevin Wolf {
235140b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
235240b4f539SKevin Wolf 
23536d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
23546d519a5fSStefan Hajnoczi 
2355cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
235640b4f539SKevin Wolf         mcb->error = ret;
235740b4f539SKevin Wolf     }
235840b4f539SKevin Wolf 
235940b4f539SKevin Wolf     mcb->num_requests--;
236040b4f539SKevin Wolf     if (mcb->num_requests == 0) {
236140b4f539SKevin Wolf         multiwrite_user_cb(mcb);
23627267c094SAnthony Liguori         g_free(mcb);
236340b4f539SKevin Wolf     }
236440b4f539SKevin Wolf }
236540b4f539SKevin Wolf 
236640b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
236740b4f539SKevin Wolf {
236877be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
236977be4366SChristoph Hellwig 
237077be4366SChristoph Hellwig     /*
237177be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
237277be4366SChristoph Hellwig      * here as that could overflow the return value.
237377be4366SChristoph Hellwig      */
237477be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
237577be4366SChristoph Hellwig         return 1;
237677be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
237777be4366SChristoph Hellwig         return -1;
237877be4366SChristoph Hellwig     } else {
237977be4366SChristoph Hellwig         return 0;
238077be4366SChristoph Hellwig     }
238140b4f539SKevin Wolf }
238240b4f539SKevin Wolf 
238340b4f539SKevin Wolf /*
238440b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
238540b4f539SKevin Wolf  * requests that remain after merging.
238640b4f539SKevin Wolf  */
238740b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
238840b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
238940b4f539SKevin Wolf {
239040b4f539SKevin Wolf     int i, outidx;
239140b4f539SKevin Wolf 
239240b4f539SKevin Wolf     // Sort requests by start sector
239340b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
239440b4f539SKevin Wolf 
239540b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
239640b4f539SKevin Wolf     // filling up gaps with zero sectors.
239740b4f539SKevin Wolf     outidx = 0;
239840b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
239940b4f539SKevin Wolf         int merge = 0;
240040b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
240140b4f539SKevin Wolf 
240240b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
240340b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
240440b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
240540b4f539SKevin Wolf             merge = 1;
240640b4f539SKevin Wolf         }
240740b4f539SKevin Wolf 
240840b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
240940b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
241040b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
241140b4f539SKevin Wolf         // unused space in format like qcow2).
241240b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
241340b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
241440b4f539SKevin Wolf         }
241540b4f539SKevin Wolf 
2416e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2417e2a305fbSChristoph Hellwig             merge = 0;
2418e2a305fbSChristoph Hellwig         }
2419e2a305fbSChristoph Hellwig 
242040b4f539SKevin Wolf         if (merge) {
242140b4f539SKevin Wolf             size_t size;
24227267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
242340b4f539SKevin Wolf             qemu_iovec_init(qiov,
242440b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
242540b4f539SKevin Wolf 
242640b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
242740b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
242840b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
242940b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
243040b4f539SKevin Wolf 
243140b4f539SKevin Wolf             // We might need to add some zeros between the two requests
243240b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
243340b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
243440b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
243540b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
243640b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
243740b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
243840b4f539SKevin Wolf             }
243940b4f539SKevin Wolf 
244040b4f539SKevin Wolf             // Add the second request
244140b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
244240b4f539SKevin Wolf 
2443cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
244440b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
244540b4f539SKevin Wolf 
244640b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
244740b4f539SKevin Wolf         } else {
244840b4f539SKevin Wolf             outidx++;
244940b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
245040b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
245140b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
245240b4f539SKevin Wolf         }
245340b4f539SKevin Wolf     }
245440b4f539SKevin Wolf 
245540b4f539SKevin Wolf     return outidx + 1;
245640b4f539SKevin Wolf }
245740b4f539SKevin Wolf 
245840b4f539SKevin Wolf /*
245940b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
246040b4f539SKevin Wolf  *
246140b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
246240b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
246340b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
246440b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
246540b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
246640b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
246740b4f539SKevin Wolf  *
246840b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
246940b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
247040b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
247140b4f539SKevin Wolf  */
247240b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
247340b4f539SKevin Wolf {
247440b4f539SKevin Wolf     BlockDriverAIOCB *acb;
247540b4f539SKevin Wolf     MultiwriteCB *mcb;
247640b4f539SKevin Wolf     int i;
247740b4f539SKevin Wolf 
2478301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2479301db7c2SRyan Harper     if (bs->drv == NULL) {
2480301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2481301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2482301db7c2SRyan Harper         }
2483301db7c2SRyan Harper         return -1;
2484301db7c2SRyan Harper     }
2485301db7c2SRyan Harper 
248640b4f539SKevin Wolf     if (num_reqs == 0) {
248740b4f539SKevin Wolf         return 0;
248840b4f539SKevin Wolf     }
248940b4f539SKevin Wolf 
249040b4f539SKevin Wolf     // Create MultiwriteCB structure
24917267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
249240b4f539SKevin Wolf     mcb->num_requests = 0;
249340b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
249440b4f539SKevin Wolf 
249540b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
249640b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
249740b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
249840b4f539SKevin Wolf     }
249940b4f539SKevin Wolf 
250040b4f539SKevin Wolf     // Check for mergable requests
250140b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
250240b4f539SKevin Wolf 
25036d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
25046d519a5fSStefan Hajnoczi 
2505453f9a16SKevin Wolf     /*
2506453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2507453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2508453f9a16SKevin Wolf      * return failure for all requests anyway)
2509453f9a16SKevin Wolf      *
2510453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2511453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2512453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2513453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2514453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2515453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2516453f9a16SKevin Wolf      * incremented for each request that is submitted.
2517453f9a16SKevin Wolf      *
2518453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2519453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2520453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2521453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2522453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2523453f9a16SKevin Wolf      */
2524453f9a16SKevin Wolf     mcb->num_requests = 1;
2525453f9a16SKevin Wolf 
25266d519a5fSStefan Hajnoczi     // Run the aio requests
252740b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2528453f9a16SKevin Wolf         mcb->num_requests++;
252940b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
253040b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
253140b4f539SKevin Wolf 
253240b4f539SKevin Wolf         if (acb == NULL) {
253340b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
253440b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
253540b4f539SKevin Wolf             // complete and report the error in the callback.
2536453f9a16SKevin Wolf             if (i == 0) {
25376d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
253840b4f539SKevin Wolf                 goto fail;
253940b4f539SKevin Wolf             } else {
25406d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
25417eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
254240b4f539SKevin Wolf                 break;
254340b4f539SKevin Wolf             }
254440b4f539SKevin Wolf         }
254540b4f539SKevin Wolf     }
254640b4f539SKevin Wolf 
2547453f9a16SKevin Wolf     /* Complete the dummy request */
2548453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2549453f9a16SKevin Wolf 
255040b4f539SKevin Wolf     return 0;
255140b4f539SKevin Wolf 
255240b4f539SKevin Wolf fail:
2553453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2554453f9a16SKevin Wolf         reqs[i].error = -EIO;
2555453f9a16SKevin Wolf     }
25567267c094SAnthony Liguori     g_free(mcb);
255740b4f539SKevin Wolf     return -1;
255840b4f539SKevin Wolf }
255940b4f539SKevin Wolf 
256083f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
256183f64091Sbellard {
25626bbff9a0Saliguori     acb->pool->cancel(acb);
256383f64091Sbellard }
256483f64091Sbellard 
256583f64091Sbellard 
256683f64091Sbellard /**************************************************************/
256783f64091Sbellard /* async block device emulation */
256883f64091Sbellard 
2569c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2570c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2571c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2572c16b5a2cSChristoph Hellwig     int ret;
2573c16b5a2cSChristoph Hellwig     /* vector translation state */
2574c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2575c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2576c16b5a2cSChristoph Hellwig     int is_write;
2577c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2578c16b5a2cSChristoph Hellwig 
2579c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2580c16b5a2cSChristoph Hellwig {
2581b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2582b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
25836a7ad299SDor Laor     qemu_bh_delete(acb->bh);
258436afc451SAvi Kivity     acb->bh = NULL;
2585c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2586c16b5a2cSChristoph Hellwig }
2587c16b5a2cSChristoph Hellwig 
2588c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2589c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2590c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2591c16b5a2cSChristoph Hellwig };
2592c16b5a2cSChristoph Hellwig 
259383f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2594beac80cdSbellard {
2595ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2596f141eafeSaliguori 
2597f141eafeSaliguori     if (!acb->is_write)
2598f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2599ceb42de8Saliguori     qemu_vfree(acb->bounce);
2600ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
26016a7ad299SDor Laor     qemu_bh_delete(acb->bh);
260236afc451SAvi Kivity     acb->bh = NULL;
2603ce1a14dcSpbrook     qemu_aio_release(acb);
2604beac80cdSbellard }
2605beac80cdSbellard 
2606f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2607f141eafeSaliguori                                             int64_t sector_num,
2608f141eafeSaliguori                                             QEMUIOVector *qiov,
2609f141eafeSaliguori                                             int nb_sectors,
2610f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2611f141eafeSaliguori                                             void *opaque,
2612f141eafeSaliguori                                             int is_write)
2613f141eafeSaliguori 
2614ea2384d3Sbellard {
2615ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
261683f64091Sbellard 
2617c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2618f141eafeSaliguori     acb->is_write = is_write;
2619f141eafeSaliguori     acb->qiov = qiov;
2620e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2621f141eafeSaliguori 
2622ce1a14dcSpbrook     if (!acb->bh)
2623ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2624f141eafeSaliguori 
2625f141eafeSaliguori     if (is_write) {
2626f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
26271ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2628f141eafeSaliguori     } else {
26291ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2630f141eafeSaliguori     }
2631f141eafeSaliguori 
2632ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2633f141eafeSaliguori 
2634ce1a14dcSpbrook     return &acb->common;
26357a6cba61Spbrook }
26367a6cba61Spbrook 
2637f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2638f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2639ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
264083f64091Sbellard {
2641f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
264283f64091Sbellard }
264383f64091Sbellard 
2644f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2645f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2646f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2647f141eafeSaliguori {
2648f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2649f141eafeSaliguori }
2650f141eafeSaliguori 
265168485420SKevin Wolf 
265268485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
265368485420SKevin Wolf     BlockDriverAIOCB common;
265468485420SKevin Wolf     BlockRequest req;
265568485420SKevin Wolf     bool is_write;
265668485420SKevin Wolf     QEMUBH* bh;
265768485420SKevin Wolf } BlockDriverAIOCBCoroutine;
265868485420SKevin Wolf 
265968485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
266068485420SKevin Wolf {
266168485420SKevin Wolf     qemu_aio_flush();
266268485420SKevin Wolf }
266368485420SKevin Wolf 
266468485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
266568485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
266668485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
266768485420SKevin Wolf };
266868485420SKevin Wolf 
266935246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque)
267068485420SKevin Wolf {
267168485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
267268485420SKevin Wolf 
267368485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
267468485420SKevin Wolf     qemu_bh_delete(acb->bh);
267568485420SKevin Wolf     qemu_aio_release(acb);
267668485420SKevin Wolf }
267768485420SKevin Wolf 
2678b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2679b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2680b2a61371SStefan Hajnoczi {
2681b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2682b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2683b2a61371SStefan Hajnoczi 
2684b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2685b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2686b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2687b2a61371SStefan Hajnoczi     } else {
2688b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2689b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2690b2a61371SStefan Hajnoczi     }
2691b2a61371SStefan Hajnoczi 
269235246a68SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2693b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2694b2a61371SStefan Hajnoczi }
2695b2a61371SStefan Hajnoczi 
269668485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
269768485420SKevin Wolf                                                int64_t sector_num,
269868485420SKevin Wolf                                                QEMUIOVector *qiov,
269968485420SKevin Wolf                                                int nb_sectors,
270068485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
270168485420SKevin Wolf                                                void *opaque,
27028c5873d6SStefan Hajnoczi                                                bool is_write)
270368485420SKevin Wolf {
270468485420SKevin Wolf     Coroutine *co;
270568485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
270668485420SKevin Wolf 
270768485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
270868485420SKevin Wolf     acb->req.sector = sector_num;
270968485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
271068485420SKevin Wolf     acb->req.qiov = qiov;
271168485420SKevin Wolf     acb->is_write = is_write;
271268485420SKevin Wolf 
27138c5873d6SStefan Hajnoczi     co = qemu_coroutine_create(bdrv_co_do_rw);
271468485420SKevin Wolf     qemu_coroutine_enter(co, acb);
271568485420SKevin Wolf 
271668485420SKevin Wolf     return &acb->common;
271768485420SKevin Wolf }
271868485420SKevin Wolf 
271907f07615SPaolo Bonzini static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
2720b2e12bc6SChristoph Hellwig {
272107f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
272207f07615SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
2723b2e12bc6SChristoph Hellwig 
272407f07615SPaolo Bonzini     acb->req.error = bdrv_co_flush(bs);
272507f07615SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2726b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2727b2e12bc6SChristoph Hellwig }
2728b2e12bc6SChristoph Hellwig 
272907f07615SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2730016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2731016f5cf6SAlexander Graf {
273207f07615SPaolo Bonzini     trace_bdrv_aio_flush(bs, opaque);
2733016f5cf6SAlexander Graf 
273407f07615SPaolo Bonzini     Coroutine *co;
273507f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
2736016f5cf6SAlexander Graf 
273707f07615SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
273807f07615SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
273907f07615SPaolo Bonzini     qemu_coroutine_enter(co, acb);
2740016f5cf6SAlexander Graf 
2741016f5cf6SAlexander Graf     return &acb->common;
2742016f5cf6SAlexander Graf }
2743016f5cf6SAlexander Graf 
27444265d620SPaolo Bonzini static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
27454265d620SPaolo Bonzini {
27464265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
27474265d620SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
27484265d620SPaolo Bonzini 
27494265d620SPaolo Bonzini     acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
27504265d620SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
27514265d620SPaolo Bonzini     qemu_bh_schedule(acb->bh);
27524265d620SPaolo Bonzini }
27534265d620SPaolo Bonzini 
27544265d620SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
27554265d620SPaolo Bonzini         int64_t sector_num, int nb_sectors,
27564265d620SPaolo Bonzini         BlockDriverCompletionFunc *cb, void *opaque)
27574265d620SPaolo Bonzini {
27584265d620SPaolo Bonzini     Coroutine *co;
27594265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
27604265d620SPaolo Bonzini 
27614265d620SPaolo Bonzini     trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
27624265d620SPaolo Bonzini 
27634265d620SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
27644265d620SPaolo Bonzini     acb->req.sector = sector_num;
27654265d620SPaolo Bonzini     acb->req.nb_sectors = nb_sectors;
27664265d620SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
27674265d620SPaolo Bonzini     qemu_coroutine_enter(co, acb);
27684265d620SPaolo Bonzini 
27694265d620SPaolo Bonzini     return &acb->common;
27704265d620SPaolo Bonzini }
27714265d620SPaolo Bonzini 
2772ea2384d3Sbellard void bdrv_init(void)
2773ea2384d3Sbellard {
27745efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2775ea2384d3Sbellard }
2776ce1a14dcSpbrook 
2777eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2778eb852011SMarkus Armbruster {
2779eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2780eb852011SMarkus Armbruster     bdrv_init();
2781eb852011SMarkus Armbruster }
2782eb852011SMarkus Armbruster 
2783c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
27846bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
27856bbff9a0Saliguori {
2786ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2787ce1a14dcSpbrook 
27886bbff9a0Saliguori     if (pool->free_aiocb) {
27896bbff9a0Saliguori         acb = pool->free_aiocb;
27906bbff9a0Saliguori         pool->free_aiocb = acb->next;
2791ce1a14dcSpbrook     } else {
27927267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
27936bbff9a0Saliguori         acb->pool = pool;
2794ce1a14dcSpbrook     }
2795ce1a14dcSpbrook     acb->bs = bs;
2796ce1a14dcSpbrook     acb->cb = cb;
2797ce1a14dcSpbrook     acb->opaque = opaque;
2798ce1a14dcSpbrook     return acb;
2799ce1a14dcSpbrook }
2800ce1a14dcSpbrook 
2801ce1a14dcSpbrook void qemu_aio_release(void *p)
2802ce1a14dcSpbrook {
28036bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
28046bbff9a0Saliguori     AIOPool *pool = acb->pool;
28056bbff9a0Saliguori     acb->next = pool->free_aiocb;
28066bbff9a0Saliguori     pool->free_aiocb = acb;
2807ce1a14dcSpbrook }
280819cb3738Sbellard 
280919cb3738Sbellard /**************************************************************/
2810f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2811f9f05dc5SKevin Wolf 
2812f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2813f9f05dc5SKevin Wolf     Coroutine *coroutine;
2814f9f05dc5SKevin Wolf     int ret;
2815f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2816f9f05dc5SKevin Wolf 
2817f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2818f9f05dc5SKevin Wolf {
2819f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2820f9f05dc5SKevin Wolf 
2821f9f05dc5SKevin Wolf     co->ret = ret;
2822f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
2823f9f05dc5SKevin Wolf }
2824f9f05dc5SKevin Wolf 
2825f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
2826f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
2827f9f05dc5SKevin Wolf                                       bool is_write)
2828f9f05dc5SKevin Wolf {
2829f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
2830f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
2831f9f05dc5SKevin Wolf     };
2832f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
2833f9f05dc5SKevin Wolf 
2834f9f05dc5SKevin Wolf     if (is_write) {
2835a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
2836f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
2837f9f05dc5SKevin Wolf     } else {
2838a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
2839f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
2840f9f05dc5SKevin Wolf     }
2841f9f05dc5SKevin Wolf 
284259370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
2843f9f05dc5SKevin Wolf     if (!acb) {
2844f9f05dc5SKevin Wolf         return -EIO;
2845f9f05dc5SKevin Wolf     }
2846f9f05dc5SKevin Wolf     qemu_coroutine_yield();
2847f9f05dc5SKevin Wolf 
2848f9f05dc5SKevin Wolf     return co.ret;
2849f9f05dc5SKevin Wolf }
2850f9f05dc5SKevin Wolf 
2851f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
2852f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2853f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2854f9f05dc5SKevin Wolf {
2855f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
2856f9f05dc5SKevin Wolf }
2857f9f05dc5SKevin Wolf 
2858f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
2859f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2860f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2861f9f05dc5SKevin Wolf {
2862f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
2863f9f05dc5SKevin Wolf }
2864f9f05dc5SKevin Wolf 
286507f07615SPaolo Bonzini static void coroutine_fn bdrv_flush_co_entry(void *opaque)
2866e7a8a783SKevin Wolf {
286707f07615SPaolo Bonzini     RwCo *rwco = opaque;
286807f07615SPaolo Bonzini 
286907f07615SPaolo Bonzini     rwco->ret = bdrv_co_flush(rwco->bs);
287007f07615SPaolo Bonzini }
287107f07615SPaolo Bonzini 
287207f07615SPaolo Bonzini int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
287307f07615SPaolo Bonzini {
287407f07615SPaolo Bonzini     if (bs->open_flags & BDRV_O_NO_FLUSH) {
287507f07615SPaolo Bonzini         return 0;
287607f07615SPaolo Bonzini     } else if (!bs->drv) {
287707f07615SPaolo Bonzini         return 0;
287807f07615SPaolo Bonzini     } else if (bs->drv->bdrv_co_flush) {
287907f07615SPaolo Bonzini         return bs->drv->bdrv_co_flush(bs);
288007f07615SPaolo Bonzini     } else if (bs->drv->bdrv_aio_flush) {
288107f07615SPaolo Bonzini         BlockDriverAIOCB *acb;
2882e7a8a783SKevin Wolf         CoroutineIOCompletion co = {
2883e7a8a783SKevin Wolf             .coroutine = qemu_coroutine_self(),
2884e7a8a783SKevin Wolf         };
2885e7a8a783SKevin Wolf 
288607f07615SPaolo Bonzini         acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
288707f07615SPaolo Bonzini         if (acb == NULL) {
2888e7a8a783SKevin Wolf             return -EIO;
288907f07615SPaolo Bonzini         } else {
2890e7a8a783SKevin Wolf             qemu_coroutine_yield();
2891e7a8a783SKevin Wolf             return co.ret;
2892e7a8a783SKevin Wolf         }
289307f07615SPaolo Bonzini     } else {
289407f07615SPaolo Bonzini         /*
289507f07615SPaolo Bonzini          * Some block drivers always operate in either writethrough or unsafe
289607f07615SPaolo Bonzini          * mode and don't support bdrv_flush therefore. Usually qemu doesn't
289707f07615SPaolo Bonzini          * know how the server works (because the behaviour is hardcoded or
289807f07615SPaolo Bonzini          * depends on server-side configuration), so we can't ensure that
289907f07615SPaolo Bonzini          * everything is safe on disk. Returning an error doesn't work because
290007f07615SPaolo Bonzini          * that would break guests even if the server operates in writethrough
290107f07615SPaolo Bonzini          * mode.
290207f07615SPaolo Bonzini          *
290307f07615SPaolo Bonzini          * Let's hope the user knows what he's doing.
290407f07615SPaolo Bonzini          */
290507f07615SPaolo Bonzini         return 0;
290607f07615SPaolo Bonzini     }
290707f07615SPaolo Bonzini }
290807f07615SPaolo Bonzini 
290907f07615SPaolo Bonzini int bdrv_flush(BlockDriverState *bs)
291007f07615SPaolo Bonzini {
291107f07615SPaolo Bonzini     Coroutine *co;
291207f07615SPaolo Bonzini     RwCo rwco = {
291307f07615SPaolo Bonzini         .bs = bs,
291407f07615SPaolo Bonzini         .ret = NOT_DONE,
291507f07615SPaolo Bonzini     };
291607f07615SPaolo Bonzini 
291707f07615SPaolo Bonzini     if (qemu_in_coroutine()) {
291807f07615SPaolo Bonzini         /* Fast-path if already in coroutine context */
291907f07615SPaolo Bonzini         bdrv_flush_co_entry(&rwco);
292007f07615SPaolo Bonzini     } else {
292107f07615SPaolo Bonzini         co = qemu_coroutine_create(bdrv_flush_co_entry);
292207f07615SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
292307f07615SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
292407f07615SPaolo Bonzini             qemu_aio_wait();
292507f07615SPaolo Bonzini         }
292607f07615SPaolo Bonzini     }
292707f07615SPaolo Bonzini 
292807f07615SPaolo Bonzini     return rwco.ret;
292907f07615SPaolo Bonzini }
2930e7a8a783SKevin Wolf 
29314265d620SPaolo Bonzini static void coroutine_fn bdrv_discard_co_entry(void *opaque)
29324265d620SPaolo Bonzini {
29334265d620SPaolo Bonzini     RwCo *rwco = opaque;
29344265d620SPaolo Bonzini 
29354265d620SPaolo Bonzini     rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
29364265d620SPaolo Bonzini }
29374265d620SPaolo Bonzini 
29384265d620SPaolo Bonzini int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
29394265d620SPaolo Bonzini                                  int nb_sectors)
29404265d620SPaolo Bonzini {
29414265d620SPaolo Bonzini     if (!bs->drv) {
29424265d620SPaolo Bonzini         return -ENOMEDIUM;
29434265d620SPaolo Bonzini     } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
29444265d620SPaolo Bonzini         return -EIO;
29454265d620SPaolo Bonzini     } else if (bs->read_only) {
29464265d620SPaolo Bonzini         return -EROFS;
29474265d620SPaolo Bonzini     } else if (bs->drv->bdrv_co_discard) {
29484265d620SPaolo Bonzini         return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
29494265d620SPaolo Bonzini     } else if (bs->drv->bdrv_aio_discard) {
29504265d620SPaolo Bonzini         BlockDriverAIOCB *acb;
29514265d620SPaolo Bonzini         CoroutineIOCompletion co = {
29524265d620SPaolo Bonzini             .coroutine = qemu_coroutine_self(),
29534265d620SPaolo Bonzini         };
29544265d620SPaolo Bonzini 
29554265d620SPaolo Bonzini         acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
29564265d620SPaolo Bonzini                                         bdrv_co_io_em_complete, &co);
29574265d620SPaolo Bonzini         if (acb == NULL) {
29584265d620SPaolo Bonzini             return -EIO;
29594265d620SPaolo Bonzini         } else {
29604265d620SPaolo Bonzini             qemu_coroutine_yield();
29614265d620SPaolo Bonzini             return co.ret;
29624265d620SPaolo Bonzini         }
29634265d620SPaolo Bonzini     } else {
29644265d620SPaolo Bonzini         return 0;
29654265d620SPaolo Bonzini     }
29664265d620SPaolo Bonzini }
29674265d620SPaolo Bonzini 
29684265d620SPaolo Bonzini int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
29694265d620SPaolo Bonzini {
29704265d620SPaolo Bonzini     Coroutine *co;
29714265d620SPaolo Bonzini     RwCo rwco = {
29724265d620SPaolo Bonzini         .bs = bs,
29734265d620SPaolo Bonzini         .sector_num = sector_num,
29744265d620SPaolo Bonzini         .nb_sectors = nb_sectors,
29754265d620SPaolo Bonzini         .ret = NOT_DONE,
29764265d620SPaolo Bonzini     };
29774265d620SPaolo Bonzini 
29784265d620SPaolo Bonzini     if (qemu_in_coroutine()) {
29794265d620SPaolo Bonzini         /* Fast-path if already in coroutine context */
29804265d620SPaolo Bonzini         bdrv_discard_co_entry(&rwco);
29814265d620SPaolo Bonzini     } else {
29824265d620SPaolo Bonzini         co = qemu_coroutine_create(bdrv_discard_co_entry);
29834265d620SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
29844265d620SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
29854265d620SPaolo Bonzini             qemu_aio_wait();
29864265d620SPaolo Bonzini         }
29874265d620SPaolo Bonzini     }
29884265d620SPaolo Bonzini 
29894265d620SPaolo Bonzini     return rwco.ret;
29904265d620SPaolo Bonzini }
29914265d620SPaolo Bonzini 
2992f9f05dc5SKevin Wolf /**************************************************************/
299319cb3738Sbellard /* removable device support */
299419cb3738Sbellard 
299519cb3738Sbellard /**
299619cb3738Sbellard  * Return TRUE if the media is present
299719cb3738Sbellard  */
299819cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
299919cb3738Sbellard {
300019cb3738Sbellard     BlockDriver *drv = bs->drv;
3001a1aff5bfSMarkus Armbruster 
300219cb3738Sbellard     if (!drv)
300319cb3738Sbellard         return 0;
300419cb3738Sbellard     if (!drv->bdrv_is_inserted)
3005a1aff5bfSMarkus Armbruster         return 1;
3006a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
300719cb3738Sbellard }
300819cb3738Sbellard 
300919cb3738Sbellard /**
30108e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
30118e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
301219cb3738Sbellard  */
301319cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
301419cb3738Sbellard {
301519cb3738Sbellard     BlockDriver *drv = bs->drv;
301619cb3738Sbellard 
30178e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
30188e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
30198e49ca46SMarkus Armbruster     }
30208e49ca46SMarkus Armbruster     return -ENOTSUP;
302119cb3738Sbellard }
302219cb3738Sbellard 
302319cb3738Sbellard /**
302419cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
302519cb3738Sbellard  */
3026fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
302719cb3738Sbellard {
302819cb3738Sbellard     BlockDriver *drv = bs->drv;
302919cb3738Sbellard 
3030822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
3031822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
303219cb3738Sbellard     }
303319cb3738Sbellard }
303419cb3738Sbellard 
303519cb3738Sbellard /**
303619cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
303719cb3738Sbellard  * to eject it manually).
303819cb3738Sbellard  */
3039025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
304019cb3738Sbellard {
304119cb3738Sbellard     BlockDriver *drv = bs->drv;
304219cb3738Sbellard 
3043025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
3044b8c6d095SStefan Hajnoczi 
3045025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
3046025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
304719cb3738Sbellard     }
304819cb3738Sbellard }
3049985a03b0Sths 
3050985a03b0Sths /* needed for generic scsi interface */
3051985a03b0Sths 
3052985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3053985a03b0Sths {
3054985a03b0Sths     BlockDriver *drv = bs->drv;
3055985a03b0Sths 
3056985a03b0Sths     if (drv && drv->bdrv_ioctl)
3057985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3058985a03b0Sths     return -ENOTSUP;
3059985a03b0Sths }
30607d780669Saliguori 
3061221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3062221f715dSaliguori         unsigned long int req, void *buf,
30637d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
30647d780669Saliguori {
3065221f715dSaliguori     BlockDriver *drv = bs->drv;
30667d780669Saliguori 
3067221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3068221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3069221f715dSaliguori     return NULL;
30707d780669Saliguori }
3071e268ca52Saliguori 
30727b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
30737b6f9300SMarkus Armbruster {
30747b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
30757b6f9300SMarkus Armbruster }
30767cd1e32aSlirans@il.ibm.com 
3077e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3078e268ca52Saliguori {
3079e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3080e268ca52Saliguori }
30817cd1e32aSlirans@il.ibm.com 
30827cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
30837cd1e32aSlirans@il.ibm.com {
30847cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3085a55eb92cSJan Kiszka 
3086aaa0eb75SLiran Schour     bs->dirty_count = 0;
30877cd1e32aSlirans@il.ibm.com     if (enable) {
3088c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3089c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3090c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3091c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
30927cd1e32aSlirans@il.ibm.com 
30937267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
30947cd1e32aSlirans@il.ibm.com         }
30957cd1e32aSlirans@il.ibm.com     } else {
3096c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
30977267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3098c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
30997cd1e32aSlirans@il.ibm.com         }
31007cd1e32aSlirans@il.ibm.com     }
31017cd1e32aSlirans@il.ibm.com }
31027cd1e32aSlirans@il.ibm.com 
31037cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
31047cd1e32aSlirans@il.ibm.com {
31056ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
31067cd1e32aSlirans@il.ibm.com 
3107c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3108c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
31096d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
31106d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
31117cd1e32aSlirans@il.ibm.com     } else {
31127cd1e32aSlirans@il.ibm.com         return 0;
31137cd1e32aSlirans@il.ibm.com     }
31147cd1e32aSlirans@il.ibm.com }
31157cd1e32aSlirans@il.ibm.com 
31167cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
31177cd1e32aSlirans@il.ibm.com                       int nr_sectors)
31187cd1e32aSlirans@il.ibm.com {
31197cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
31207cd1e32aSlirans@il.ibm.com }
3121aaa0eb75SLiran Schour 
3122aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3123aaa0eb75SLiran Schour {
3124aaa0eb75SLiran Schour     return bs->dirty_count;
3125aaa0eb75SLiran Schour }
3126f88e1a42SJes Sorensen 
3127db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3128db593f25SMarcelo Tosatti {
3129db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3130db593f25SMarcelo Tosatti     bs->in_use = in_use;
3131db593f25SMarcelo Tosatti }
3132db593f25SMarcelo Tosatti 
3133db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3134db593f25SMarcelo Tosatti {
3135db593f25SMarcelo Tosatti     return bs->in_use;
3136db593f25SMarcelo Tosatti }
3137db593f25SMarcelo Tosatti 
313828a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
313928a7282aSLuiz Capitulino {
314028a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_OK;
314128a7282aSLuiz Capitulino }
314228a7282aSLuiz Capitulino 
314328a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
314428a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
314528a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
314628a7282aSLuiz Capitulino {
314728a7282aSLuiz Capitulino     return (bs->iostatus != BDRV_IOS_INVAL &&
314828a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
314928a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
315028a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
315128a7282aSLuiz Capitulino }
315228a7282aSLuiz Capitulino 
315328a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
315428a7282aSLuiz Capitulino {
315528a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_INVAL;
315628a7282aSLuiz Capitulino }
315728a7282aSLuiz Capitulino 
315828a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
315928a7282aSLuiz Capitulino {
316028a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
316128a7282aSLuiz Capitulino         bs->iostatus = BDRV_IOS_OK;
316228a7282aSLuiz Capitulino     }
316328a7282aSLuiz Capitulino }
316428a7282aSLuiz Capitulino 
316528a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
316628a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
316728a7282aSLuiz Capitulino    possible to implement this without device models being involved */
316828a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
316928a7282aSLuiz Capitulino {
317028a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
317128a7282aSLuiz Capitulino         assert(error >= 0);
317228a7282aSLuiz Capitulino         bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
317328a7282aSLuiz Capitulino     }
317428a7282aSLuiz Capitulino }
317528a7282aSLuiz Capitulino 
3176a597e79cSChristoph Hellwig void
3177a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3178a597e79cSChristoph Hellwig         enum BlockAcctType type)
3179a597e79cSChristoph Hellwig {
3180a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3181a597e79cSChristoph Hellwig 
3182a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3183c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3184a597e79cSChristoph Hellwig     cookie->type = type;
3185a597e79cSChristoph Hellwig }
3186a597e79cSChristoph Hellwig 
3187a597e79cSChristoph Hellwig void
3188a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3189a597e79cSChristoph Hellwig {
3190a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3191a597e79cSChristoph Hellwig 
3192a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3193a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3194c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3195a597e79cSChristoph Hellwig }
3196a597e79cSChristoph Hellwig 
3197f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3198f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3199f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3200f88e1a42SJes Sorensen {
3201f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3202d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3203f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3204f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
320596df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3206f88e1a42SJes Sorensen     int ret = 0;
3207f88e1a42SJes Sorensen 
3208f88e1a42SJes Sorensen     /* Find driver and parse its options */
3209f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3210f88e1a42SJes Sorensen     if (!drv) {
3211f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
32124f70f249SJes Sorensen         ret = -EINVAL;
3213f88e1a42SJes Sorensen         goto out;
3214f88e1a42SJes Sorensen     }
3215f88e1a42SJes Sorensen 
3216f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3217f88e1a42SJes Sorensen     if (!proto_drv) {
3218f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
32194f70f249SJes Sorensen         ret = -EINVAL;
3220f88e1a42SJes Sorensen         goto out;
3221f88e1a42SJes Sorensen     }
3222f88e1a42SJes Sorensen 
3223f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3224f88e1a42SJes Sorensen                                               drv->create_options);
3225f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3226f88e1a42SJes Sorensen                                               proto_drv->create_options);
3227f88e1a42SJes Sorensen 
3228f88e1a42SJes Sorensen     /* Create parameter list with default values */
3229f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3230f88e1a42SJes Sorensen 
3231f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3232f88e1a42SJes Sorensen 
3233f88e1a42SJes Sorensen     /* Parse -o options */
3234f88e1a42SJes Sorensen     if (options) {
3235f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3236f88e1a42SJes Sorensen         if (param == NULL) {
3237f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
32384f70f249SJes Sorensen             ret = -EINVAL;
3239f88e1a42SJes Sorensen             goto out;
3240f88e1a42SJes Sorensen         }
3241f88e1a42SJes Sorensen     }
3242f88e1a42SJes Sorensen 
3243f88e1a42SJes Sorensen     if (base_filename) {
3244f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3245f88e1a42SJes Sorensen                                  base_filename)) {
3246f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3247f88e1a42SJes Sorensen                          fmt);
32484f70f249SJes Sorensen             ret = -EINVAL;
3249f88e1a42SJes Sorensen             goto out;
3250f88e1a42SJes Sorensen         }
3251f88e1a42SJes Sorensen     }
3252f88e1a42SJes Sorensen 
3253f88e1a42SJes Sorensen     if (base_fmt) {
3254f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3255f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3256f88e1a42SJes Sorensen                          "format '%s'", fmt);
32574f70f249SJes Sorensen             ret = -EINVAL;
3258f88e1a42SJes Sorensen             goto out;
3259f88e1a42SJes Sorensen         }
3260f88e1a42SJes Sorensen     }
3261f88e1a42SJes Sorensen 
3262792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3263792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3264792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3265792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3266792da93aSJes Sorensen                          "same filename as the backing file");
32674f70f249SJes Sorensen             ret = -EINVAL;
3268792da93aSJes Sorensen             goto out;
3269792da93aSJes Sorensen         }
3270792da93aSJes Sorensen     }
3271792da93aSJes Sorensen 
3272f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3273f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
327496df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
327596df67d1SStefan Hajnoczi         if (!backing_drv) {
3276f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3277f88e1a42SJes Sorensen                          backing_fmt->value.s);
32784f70f249SJes Sorensen             ret = -EINVAL;
3279f88e1a42SJes Sorensen             goto out;
3280f88e1a42SJes Sorensen         }
3281f88e1a42SJes Sorensen     }
3282f88e1a42SJes Sorensen 
3283f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3284f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3285d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3286d220894eSKevin Wolf     if (size && size->value.n == -1) {
3287f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3288f88e1a42SJes Sorensen             uint64_t size;
3289f88e1a42SJes Sorensen             char buf[32];
3290f88e1a42SJes Sorensen 
3291f88e1a42SJes Sorensen             bs = bdrv_new("");
3292f88e1a42SJes Sorensen 
329396df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3294f88e1a42SJes Sorensen             if (ret < 0) {
329596df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3296f88e1a42SJes Sorensen                 goto out;
3297f88e1a42SJes Sorensen             }
3298f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3299f88e1a42SJes Sorensen             size *= 512;
3300f88e1a42SJes Sorensen 
3301f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3302f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3303f88e1a42SJes Sorensen         } else {
3304f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
33054f70f249SJes Sorensen             ret = -EINVAL;
3306f88e1a42SJes Sorensen             goto out;
3307f88e1a42SJes Sorensen         }
3308f88e1a42SJes Sorensen     }
3309f88e1a42SJes Sorensen 
3310f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3311f88e1a42SJes Sorensen     print_option_parameters(param);
3312f88e1a42SJes Sorensen     puts("");
3313f88e1a42SJes Sorensen 
3314f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3315f88e1a42SJes Sorensen 
3316f88e1a42SJes Sorensen     if (ret < 0) {
3317f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3318f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3319f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3320f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3321f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3322f88e1a42SJes Sorensen                          fmt);
3323f88e1a42SJes Sorensen         } else {
3324f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3325f88e1a42SJes Sorensen                          strerror(-ret));
3326f88e1a42SJes Sorensen         }
3327f88e1a42SJes Sorensen     }
3328f88e1a42SJes Sorensen 
3329f88e1a42SJes Sorensen out:
3330f88e1a42SJes Sorensen     free_option_parameters(create_options);
3331f88e1a42SJes Sorensen     free_option_parameters(param);
3332f88e1a42SJes Sorensen 
3333f88e1a42SJes Sorensen     if (bs) {
3334f88e1a42SJes Sorensen         bdrv_delete(bs);
3335f88e1a42SJes Sorensen     }
33364f70f249SJes Sorensen 
33374f70f249SJes Sorensen     return ret;
3338f88e1a42SJes Sorensen }
3339