xref: /openbmc/qemu/block.c (revision a652d16025030013116c4d63883b9e1ec08a4359)
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 
477d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
48f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
49f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
50c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
51f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
52f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
53ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
54b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
55b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque);
56016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
57016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque);
5883f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
5983f64091Sbellard                         uint8_t *buf, int nb_sectors);
6083f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
6183f64091Sbellard                          const uint8_t *buf, int nb_sectors);
6268485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
6368485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
6468485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque);
6568485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
6668485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
6768485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque);
68f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
69f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
70f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
71f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
72f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
73f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
74e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
75ec530c81Sbellard 
761b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
771b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
787ee930d0Sblueswir1 
798a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
808a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
81ea2384d3Sbellard 
82f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
83f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
84f9092b10SMarkus Armbruster 
85eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
86eb852011SMarkus Armbruster static int use_bdrv_whitelist;
87eb852011SMarkus Armbruster 
889e0b22f4SStefan Hajnoczi #ifdef _WIN32
899e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
909e0b22f4SStefan Hajnoczi {
919e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
929e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
939e0b22f4SStefan Hajnoczi             filename[1] == ':');
949e0b22f4SStefan Hajnoczi }
959e0b22f4SStefan Hajnoczi 
969e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
979e0b22f4SStefan Hajnoczi {
989e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
999e0b22f4SStefan Hajnoczi         filename[2] == '\0')
1009e0b22f4SStefan Hajnoczi         return 1;
1019e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1029e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1039e0b22f4SStefan Hajnoczi         return 1;
1049e0b22f4SStefan Hajnoczi     return 0;
1059e0b22f4SStefan Hajnoczi }
1069e0b22f4SStefan Hajnoczi #endif
1079e0b22f4SStefan Hajnoczi 
1089e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1099e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1109e0b22f4SStefan Hajnoczi {
1119e0b22f4SStefan Hajnoczi #ifdef _WIN32
1129e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1139e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1149e0b22f4SStefan Hajnoczi         return 0;
1159e0b22f4SStefan Hajnoczi     }
1169e0b22f4SStefan Hajnoczi #endif
1179e0b22f4SStefan Hajnoczi 
1189e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1199e0b22f4SStefan Hajnoczi }
1209e0b22f4SStefan Hajnoczi 
12183f64091Sbellard int path_is_absolute(const char *path)
12283f64091Sbellard {
12383f64091Sbellard     const char *p;
12421664424Sbellard #ifdef _WIN32
12521664424Sbellard     /* specific case for names like: "\\.\d:" */
12621664424Sbellard     if (*path == '/' || *path == '\\')
12721664424Sbellard         return 1;
12821664424Sbellard #endif
12983f64091Sbellard     p = strchr(path, ':');
13083f64091Sbellard     if (p)
13183f64091Sbellard         p++;
13283f64091Sbellard     else
13383f64091Sbellard         p = path;
1343b9f94e1Sbellard #ifdef _WIN32
1353b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1363b9f94e1Sbellard #else
1373b9f94e1Sbellard     return (*p == '/');
1383b9f94e1Sbellard #endif
13983f64091Sbellard }
14083f64091Sbellard 
14183f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
14283f64091Sbellard    path to it by considering it is relative to base_path. URL are
14383f64091Sbellard    supported. */
14483f64091Sbellard void path_combine(char *dest, int dest_size,
14583f64091Sbellard                   const char *base_path,
14683f64091Sbellard                   const char *filename)
14783f64091Sbellard {
14883f64091Sbellard     const char *p, *p1;
14983f64091Sbellard     int len;
15083f64091Sbellard 
15183f64091Sbellard     if (dest_size <= 0)
15283f64091Sbellard         return;
15383f64091Sbellard     if (path_is_absolute(filename)) {
15483f64091Sbellard         pstrcpy(dest, dest_size, filename);
15583f64091Sbellard     } else {
15683f64091Sbellard         p = strchr(base_path, ':');
15783f64091Sbellard         if (p)
15883f64091Sbellard             p++;
15983f64091Sbellard         else
16083f64091Sbellard             p = base_path;
1613b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1623b9f94e1Sbellard #ifdef _WIN32
1633b9f94e1Sbellard         {
1643b9f94e1Sbellard             const char *p2;
1653b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1663b9f94e1Sbellard             if (!p1 || p2 > p1)
1673b9f94e1Sbellard                 p1 = p2;
1683b9f94e1Sbellard         }
1693b9f94e1Sbellard #endif
17083f64091Sbellard         if (p1)
17183f64091Sbellard             p1++;
17283f64091Sbellard         else
17383f64091Sbellard             p1 = base_path;
17483f64091Sbellard         if (p1 > p)
17583f64091Sbellard             p = p1;
17683f64091Sbellard         len = p - base_path;
17783f64091Sbellard         if (len > dest_size - 1)
17883f64091Sbellard             len = dest_size - 1;
17983f64091Sbellard         memcpy(dest, base_path, len);
18083f64091Sbellard         dest[len] = '\0';
18183f64091Sbellard         pstrcat(dest, dest_size, filename);
18283f64091Sbellard     }
18383f64091Sbellard }
18483f64091Sbellard 
1855efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
186ea2384d3Sbellard {
18768485420SKevin Wolf     if (bdrv->bdrv_co_readv) {
18868485420SKevin Wolf         /* Emulate AIO by coroutines, and sync by AIO */
18968485420SKevin Wolf         bdrv->bdrv_aio_readv = bdrv_co_aio_readv_em;
19068485420SKevin Wolf         bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em;
19168485420SKevin Wolf         bdrv->bdrv_read = bdrv_read_em;
19268485420SKevin Wolf         bdrv->bdrv_write = bdrv_write_em;
193f9f05dc5SKevin Wolf      } else {
194f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
195f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
196f9f05dc5SKevin Wolf 
197f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
19883f64091Sbellard             /* add AIO emulation layer */
199f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
200f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
201eda578e5Saliguori         } else if (!bdrv->bdrv_read) {
20283f64091Sbellard             /* add synchronous IO emulation layer */
20383f64091Sbellard             bdrv->bdrv_read = bdrv_read_em;
20483f64091Sbellard             bdrv->bdrv_write = bdrv_write_em;
20583f64091Sbellard         }
206f9f05dc5SKevin Wolf     }
207b2e12bc6SChristoph Hellwig 
208b2e12bc6SChristoph Hellwig     if (!bdrv->bdrv_aio_flush)
209b2e12bc6SChristoph Hellwig         bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
210b2e12bc6SChristoph Hellwig 
2118a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
212ea2384d3Sbellard }
213b338082bSbellard 
214b338082bSbellard /* create a new block device (by default it is empty) */
215b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
216fc01f7e7Sbellard {
2171b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
218b338082bSbellard 
2197267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
220b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
221ea2384d3Sbellard     if (device_name[0] != '\0') {
2221b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
223ea2384d3Sbellard     }
22428a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
225b338082bSbellard     return bs;
226b338082bSbellard }
227b338082bSbellard 
228ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
229ea2384d3Sbellard {
230ea2384d3Sbellard     BlockDriver *drv1;
2318a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2328a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
233ea2384d3Sbellard             return drv1;
234ea2384d3Sbellard         }
2358a22f02aSStefan Hajnoczi     }
236ea2384d3Sbellard     return NULL;
237ea2384d3Sbellard }
238ea2384d3Sbellard 
239eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
240eb852011SMarkus Armbruster {
241eb852011SMarkus Armbruster     static const char *whitelist[] = {
242eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
243eb852011SMarkus Armbruster     };
244eb852011SMarkus Armbruster     const char **p;
245eb852011SMarkus Armbruster 
246eb852011SMarkus Armbruster     if (!whitelist[0])
247eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
248eb852011SMarkus Armbruster 
249eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
250eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
251eb852011SMarkus Armbruster             return 1;
252eb852011SMarkus Armbruster         }
253eb852011SMarkus Armbruster     }
254eb852011SMarkus Armbruster     return 0;
255eb852011SMarkus Armbruster }
256eb852011SMarkus Armbruster 
257eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
258eb852011SMarkus Armbruster {
259eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
260eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
261eb852011SMarkus Armbruster }
262eb852011SMarkus Armbruster 
2630e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2640e7e1989SKevin Wolf     QEMUOptionParameter *options)
265ea2384d3Sbellard {
266ea2384d3Sbellard     if (!drv->bdrv_create)
267ea2384d3Sbellard         return -ENOTSUP;
2680e7e1989SKevin Wolf 
2690e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
270ea2384d3Sbellard }
271ea2384d3Sbellard 
27284a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
27384a12e66SChristoph Hellwig {
27484a12e66SChristoph Hellwig     BlockDriver *drv;
27584a12e66SChristoph Hellwig 
276b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
27784a12e66SChristoph Hellwig     if (drv == NULL) {
27816905d71SStefan Hajnoczi         return -ENOENT;
27984a12e66SChristoph Hellwig     }
28084a12e66SChristoph Hellwig 
28184a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
28284a12e66SChristoph Hellwig }
28384a12e66SChristoph Hellwig 
284d5249393Sbellard #ifdef _WIN32
28595389c86Sbellard void get_tmp_filename(char *filename, int size)
286d5249393Sbellard {
2873b9f94e1Sbellard     char temp_dir[MAX_PATH];
2883b9f94e1Sbellard 
2893b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
2903b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
291d5249393Sbellard }
292d5249393Sbellard #else
29395389c86Sbellard void get_tmp_filename(char *filename, int size)
294ea2384d3Sbellard {
295ea2384d3Sbellard     int fd;
2967ccfb2ebSblueswir1     const char *tmpdir;
297d5249393Sbellard     /* XXX: race condition possible */
2980badc1eeSaurel32     tmpdir = getenv("TMPDIR");
2990badc1eeSaurel32     if (!tmpdir)
3000badc1eeSaurel32         tmpdir = "/tmp";
3010badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
302ea2384d3Sbellard     fd = mkstemp(filename);
303ea2384d3Sbellard     close(fd);
304ea2384d3Sbellard }
305d5249393Sbellard #endif
306ea2384d3Sbellard 
307f3a5d3f8SChristoph Hellwig /*
308f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
309f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
310f3a5d3f8SChristoph Hellwig  */
311f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
312f3a5d3f8SChristoph Hellwig {
313508c7cb3SChristoph Hellwig     int score_max = 0, score;
314508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
315f3a5d3f8SChristoph Hellwig 
3168a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
317508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
318508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
319508c7cb3SChristoph Hellwig             if (score > score_max) {
320508c7cb3SChristoph Hellwig                 score_max = score;
321508c7cb3SChristoph Hellwig                 drv = d;
322f3a5d3f8SChristoph Hellwig             }
323508c7cb3SChristoph Hellwig         }
324f3a5d3f8SChristoph Hellwig     }
325f3a5d3f8SChristoph Hellwig 
326508c7cb3SChristoph Hellwig     return drv;
327f3a5d3f8SChristoph Hellwig }
328f3a5d3f8SChristoph Hellwig 
329b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
33084a12e66SChristoph Hellwig {
33184a12e66SChristoph Hellwig     BlockDriver *drv1;
33284a12e66SChristoph Hellwig     char protocol[128];
33384a12e66SChristoph Hellwig     int len;
33484a12e66SChristoph Hellwig     const char *p;
33584a12e66SChristoph Hellwig 
33666f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
33766f82ceeSKevin Wolf 
33839508e7aSChristoph Hellwig     /*
33939508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
34039508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
34139508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
34239508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
34339508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
34439508e7aSChristoph Hellwig      */
34584a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
34639508e7aSChristoph Hellwig     if (drv1) {
34784a12e66SChristoph Hellwig         return drv1;
34884a12e66SChristoph Hellwig     }
34939508e7aSChristoph Hellwig 
3509e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
35139508e7aSChristoph Hellwig         return bdrv_find_format("file");
35239508e7aSChristoph Hellwig     }
3539e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3549e0b22f4SStefan Hajnoczi     assert(p != NULL);
35584a12e66SChristoph Hellwig     len = p - filename;
35684a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
35784a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
35884a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
35984a12e66SChristoph Hellwig     protocol[len] = '\0';
36084a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
36184a12e66SChristoph Hellwig         if (drv1->protocol_name &&
36284a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
36384a12e66SChristoph Hellwig             return drv1;
36484a12e66SChristoph Hellwig         }
36584a12e66SChristoph Hellwig     }
36684a12e66SChristoph Hellwig     return NULL;
36784a12e66SChristoph Hellwig }
36884a12e66SChristoph Hellwig 
369c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
370ea2384d3Sbellard {
37183f64091Sbellard     int ret, score, score_max;
372ea2384d3Sbellard     BlockDriver *drv1, *drv;
37383f64091Sbellard     uint8_t buf[2048];
37483f64091Sbellard     BlockDriverState *bs;
375ea2384d3Sbellard 
376f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
377c98ac35dSStefan Weil     if (ret < 0) {
378c98ac35dSStefan Weil         *pdrv = NULL;
379c98ac35dSStefan Weil         return ret;
380c98ac35dSStefan Weil     }
381f8ea0b00SNicholas Bellinger 
38208a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
38308a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
3841a396859SNicholas A. Bellinger         bdrv_delete(bs);
385c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
386c98ac35dSStefan Weil         if (!drv) {
387c98ac35dSStefan Weil             ret = -ENOENT;
388c98ac35dSStefan Weil         }
389c98ac35dSStefan Weil         *pdrv = drv;
390c98ac35dSStefan Weil         return ret;
3911a396859SNicholas A. Bellinger     }
392f8ea0b00SNicholas Bellinger 
39383f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
39483f64091Sbellard     bdrv_delete(bs);
395ea2384d3Sbellard     if (ret < 0) {
396c98ac35dSStefan Weil         *pdrv = NULL;
397c98ac35dSStefan Weil         return ret;
398ea2384d3Sbellard     }
399ea2384d3Sbellard 
400ea2384d3Sbellard     score_max = 0;
40184a12e66SChristoph Hellwig     drv = NULL;
4028a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
40383f64091Sbellard         if (drv1->bdrv_probe) {
404ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
405ea2384d3Sbellard             if (score > score_max) {
406ea2384d3Sbellard                 score_max = score;
407ea2384d3Sbellard                 drv = drv1;
408ea2384d3Sbellard             }
409ea2384d3Sbellard         }
41083f64091Sbellard     }
411c98ac35dSStefan Weil     if (!drv) {
412c98ac35dSStefan Weil         ret = -ENOENT;
413c98ac35dSStefan Weil     }
414c98ac35dSStefan Weil     *pdrv = drv;
415c98ac35dSStefan Weil     return ret;
416ea2384d3Sbellard }
417ea2384d3Sbellard 
41851762288SStefan Hajnoczi /**
41951762288SStefan Hajnoczi  * Set the current 'total_sectors' value
42051762288SStefan Hajnoczi  */
42151762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
42251762288SStefan Hajnoczi {
42351762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
42451762288SStefan Hajnoczi 
425396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
426396759adSNicholas Bellinger     if (bs->sg)
427396759adSNicholas Bellinger         return 0;
428396759adSNicholas Bellinger 
42951762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
43051762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
43151762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
43251762288SStefan Hajnoczi         if (length < 0) {
43351762288SStefan Hajnoczi             return length;
43451762288SStefan Hajnoczi         }
43551762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
43651762288SStefan Hajnoczi     }
43751762288SStefan Hajnoczi 
43851762288SStefan Hajnoczi     bs->total_sectors = hint;
43951762288SStefan Hajnoczi     return 0;
44051762288SStefan Hajnoczi }
44151762288SStefan Hajnoczi 
442c3993cdcSStefan Hajnoczi /**
443c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
444c3993cdcSStefan Hajnoczi  *
445c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
446c3993cdcSStefan Hajnoczi  */
447c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
448c3993cdcSStefan Hajnoczi {
449c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
450c3993cdcSStefan Hajnoczi 
451c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
452c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
45392196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
45492196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
455c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
456c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
457c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
458c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
459c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
460c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
461c3993cdcSStefan Hajnoczi         /* this is the default */
462c3993cdcSStefan Hajnoczi     } else {
463c3993cdcSStefan Hajnoczi         return -1;
464c3993cdcSStefan Hajnoczi     }
465c3993cdcSStefan Hajnoczi 
466c3993cdcSStefan Hajnoczi     return 0;
467c3993cdcSStefan Hajnoczi }
468c3993cdcSStefan Hajnoczi 
469b6ce07aaSKevin Wolf /*
47057915332SKevin Wolf  * Common part for opening disk images and files
47157915332SKevin Wolf  */
47257915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
47357915332SKevin Wolf     int flags, BlockDriver *drv)
47457915332SKevin Wolf {
47557915332SKevin Wolf     int ret, open_flags;
47657915332SKevin Wolf 
47757915332SKevin Wolf     assert(drv != NULL);
47857915332SKevin Wolf 
47928dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
48028dcee10SStefan Hajnoczi 
48166f82ceeSKevin Wolf     bs->file = NULL;
48251762288SStefan Hajnoczi     bs->total_sectors = 0;
48357915332SKevin Wolf     bs->encrypted = 0;
48457915332SKevin Wolf     bs->valid_key = 0;
48557915332SKevin Wolf     bs->open_flags = flags;
48657915332SKevin Wolf     bs->buffer_alignment = 512;
48757915332SKevin Wolf 
48857915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
48957915332SKevin Wolf 
49057915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
49157915332SKevin Wolf         return -ENOTSUP;
49257915332SKevin Wolf     }
49357915332SKevin Wolf 
49457915332SKevin Wolf     bs->drv = drv;
4957267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
49657915332SKevin Wolf 
497a6599793SChristoph Hellwig     if (flags & BDRV_O_CACHE_WB)
49857915332SKevin Wolf         bs->enable_write_cache = 1;
49957915332SKevin Wolf 
50057915332SKevin Wolf     /*
50157915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
50257915332SKevin Wolf      * image.
50357915332SKevin Wolf      */
50457915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
50557915332SKevin Wolf 
50657915332SKevin Wolf     /*
507ebabb67aSStefan Weil      * Snapshots should be writable.
50857915332SKevin Wolf      */
50957915332SKevin Wolf     if (bs->is_temporary) {
51057915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
51157915332SKevin Wolf     }
51257915332SKevin Wolf 
51366f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
51466f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
51566f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
51666f82ceeSKevin Wolf     } else {
51766f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
51866f82ceeSKevin Wolf         if (ret >= 0) {
51966f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
52066f82ceeSKevin Wolf         }
52166f82ceeSKevin Wolf     }
52266f82ceeSKevin Wolf 
52357915332SKevin Wolf     if (ret < 0) {
52457915332SKevin Wolf         goto free_and_fail;
52557915332SKevin Wolf     }
52657915332SKevin Wolf 
52757915332SKevin Wolf     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
52851762288SStefan Hajnoczi 
52951762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
53051762288SStefan Hajnoczi     if (ret < 0) {
53151762288SStefan Hajnoczi         goto free_and_fail;
53257915332SKevin Wolf     }
53351762288SStefan Hajnoczi 
53457915332SKevin Wolf #ifndef _WIN32
53557915332SKevin Wolf     if (bs->is_temporary) {
53657915332SKevin Wolf         unlink(filename);
53757915332SKevin Wolf     }
53857915332SKevin Wolf #endif
53957915332SKevin Wolf     return 0;
54057915332SKevin Wolf 
54157915332SKevin Wolf free_and_fail:
54266f82ceeSKevin Wolf     if (bs->file) {
54366f82ceeSKevin Wolf         bdrv_delete(bs->file);
54466f82ceeSKevin Wolf         bs->file = NULL;
54566f82ceeSKevin Wolf     }
5467267c094SAnthony Liguori     g_free(bs->opaque);
54757915332SKevin Wolf     bs->opaque = NULL;
54857915332SKevin Wolf     bs->drv = NULL;
54957915332SKevin Wolf     return ret;
55057915332SKevin Wolf }
55157915332SKevin Wolf 
55257915332SKevin Wolf /*
553b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
554b6ce07aaSKevin Wolf  */
55583f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
556b338082bSbellard {
55783f64091Sbellard     BlockDriverState *bs;
5586db95603SChristoph Hellwig     BlockDriver *drv;
55983f64091Sbellard     int ret;
5603b0d4f61Sbellard 
561b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5626db95603SChristoph Hellwig     if (!drv) {
5636db95603SChristoph Hellwig         return -ENOENT;
5646db95603SChristoph Hellwig     }
5656db95603SChristoph Hellwig 
56683f64091Sbellard     bs = bdrv_new("");
567b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
56883f64091Sbellard     if (ret < 0) {
56983f64091Sbellard         bdrv_delete(bs);
57083f64091Sbellard         return ret;
5713b0d4f61Sbellard     }
57271d0770cSaliguori     bs->growable = 1;
57383f64091Sbellard     *pbs = bs;
57483f64091Sbellard     return 0;
5753b0d4f61Sbellard }
5763b0d4f61Sbellard 
577b6ce07aaSKevin Wolf /*
578b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
579b6ce07aaSKevin Wolf  */
580d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
581ea2384d3Sbellard               BlockDriver *drv)
582ea2384d3Sbellard {
583b6ce07aaSKevin Wolf     int ret;
58433e3963eSbellard 
58583f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
586ea2384d3Sbellard         BlockDriverState *bs1;
587ea2384d3Sbellard         int64_t total_size;
5887c96d46eSaliguori         int is_protocol = 0;
58991a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
59091a073a9SKevin Wolf         QEMUOptionParameter *options;
591b6ce07aaSKevin Wolf         char tmp_filename[PATH_MAX];
592b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
59333e3963eSbellard 
594ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
595ea2384d3Sbellard            instead of opening 'filename' directly */
596ea2384d3Sbellard 
597ea2384d3Sbellard         /* if there is a backing file, use it */
598ea2384d3Sbellard         bs1 = bdrv_new("");
599d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
60051d7c00cSaliguori         if (ret < 0) {
601ea2384d3Sbellard             bdrv_delete(bs1);
60251d7c00cSaliguori             return ret;
603ea2384d3Sbellard         }
6043e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
6057c96d46eSaliguori 
6067c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
6077c96d46eSaliguori             is_protocol = 1;
6087c96d46eSaliguori 
609ea2384d3Sbellard         bdrv_delete(bs1);
610ea2384d3Sbellard 
611ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6127c96d46eSaliguori 
6137c96d46eSaliguori         /* Real path is meaningless for protocols */
6147c96d46eSaliguori         if (is_protocol)
6157c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6167c96d46eSaliguori                      "%s", filename);
617114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
618114cdfa9SKirill A. Shutemov             return -errno;
6197c96d46eSaliguori 
62091a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
62191a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
62291a073a9SKevin Wolf 
6233e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
62491a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
62591a073a9SKevin Wolf         if (drv) {
62691a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
62791a073a9SKevin Wolf                 drv->format_name);
62891a073a9SKevin Wolf         }
62991a073a9SKevin Wolf 
63091a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
631d748768cSJan Kiszka         free_option_parameters(options);
63251d7c00cSaliguori         if (ret < 0) {
63351d7c00cSaliguori             return ret;
634ea2384d3Sbellard         }
63591a073a9SKevin Wolf 
636ea2384d3Sbellard         filename = tmp_filename;
63791a073a9SKevin Wolf         drv = bdrv_qcow2;
638ea2384d3Sbellard         bs->is_temporary = 1;
639ea2384d3Sbellard     }
640ea2384d3Sbellard 
641b6ce07aaSKevin Wolf     /* Find the right image format driver */
6426db95603SChristoph Hellwig     if (!drv) {
643c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
644ea2384d3Sbellard     }
6456987307cSChristoph Hellwig 
64651d7c00cSaliguori     if (!drv) {
64751d7c00cSaliguori         goto unlink_and_fail;
64883f64091Sbellard     }
649b6ce07aaSKevin Wolf 
650b6ce07aaSKevin Wolf     /* Open the image */
651b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
652b6ce07aaSKevin Wolf     if (ret < 0) {
6536987307cSChristoph Hellwig         goto unlink_and_fail;
6546987307cSChristoph Hellwig     }
6556987307cSChristoph Hellwig 
656b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
657b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
658b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
659b6ce07aaSKevin Wolf         int back_flags;
660b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
661b6ce07aaSKevin Wolf 
662b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
663df2dbb4aSStefan Hajnoczi 
664df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
665df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
666df2dbb4aSStefan Hajnoczi                     bs->backing_file);
667df2dbb4aSStefan Hajnoczi         } else {
668b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
669b6ce07aaSKevin Wolf                          filename, bs->backing_file);
670df2dbb4aSStefan Hajnoczi         }
671df2dbb4aSStefan Hajnoczi 
672df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
673b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
674df2dbb4aSStefan Hajnoczi         }
675b6ce07aaSKevin Wolf 
676b6ce07aaSKevin Wolf         /* backing files always opened read-only */
677b6ce07aaSKevin Wolf         back_flags =
678b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
679b6ce07aaSKevin Wolf 
680b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
681b6ce07aaSKevin Wolf         if (ret < 0) {
682b6ce07aaSKevin Wolf             bdrv_close(bs);
683b6ce07aaSKevin Wolf             return ret;
684b6ce07aaSKevin Wolf         }
685b6ce07aaSKevin Wolf         if (bs->is_temporary) {
686b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
687b6ce07aaSKevin Wolf         } else {
688b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
689b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
690b6ce07aaSKevin Wolf         }
691b6ce07aaSKevin Wolf     }
692b6ce07aaSKevin Wolf 
693b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
6947d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
695b6ce07aaSKevin Wolf     }
696b6ce07aaSKevin Wolf 
697b6ce07aaSKevin Wolf     return 0;
698b6ce07aaSKevin Wolf 
699b6ce07aaSKevin Wolf unlink_and_fail:
700b6ce07aaSKevin Wolf     if (bs->is_temporary) {
701b6ce07aaSKevin Wolf         unlink(filename);
702b6ce07aaSKevin Wolf     }
703b6ce07aaSKevin Wolf     return ret;
704b6ce07aaSKevin Wolf }
705b6ce07aaSKevin Wolf 
706fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
707fc01f7e7Sbellard {
70819cb3738Sbellard     if (bs->drv) {
709f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
710f9092b10SMarkus Armbruster             bs_snapshots = NULL;
711f9092b10SMarkus Armbruster         }
712557df6acSStefan Hajnoczi         if (bs->backing_hd) {
713ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
714557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
715557df6acSStefan Hajnoczi         }
716ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7177267c094SAnthony Liguori         g_free(bs->opaque);
718ea2384d3Sbellard #ifdef _WIN32
719ea2384d3Sbellard         if (bs->is_temporary) {
720ea2384d3Sbellard             unlink(bs->filename);
721ea2384d3Sbellard         }
72267b915a5Sbellard #endif
723ea2384d3Sbellard         bs->opaque = NULL;
724ea2384d3Sbellard         bs->drv = NULL;
725b338082bSbellard 
72666f82ceeSKevin Wolf         if (bs->file != NULL) {
72766f82ceeSKevin Wolf             bdrv_close(bs->file);
72866f82ceeSKevin Wolf         }
72966f82ceeSKevin Wolf 
7307d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
731b338082bSbellard     }
732b338082bSbellard }
733b338082bSbellard 
7342bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7352bc93fedSMORITA Kazutaka {
7362bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7372bc93fedSMORITA Kazutaka 
7382bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7392bc93fedSMORITA Kazutaka         bdrv_close(bs);
7402bc93fedSMORITA Kazutaka     }
7412bc93fedSMORITA Kazutaka }
7422bc93fedSMORITA Kazutaka 
743d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
744d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
745d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
746d22b2f41SRyan Harper {
747d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
748d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
749d22b2f41SRyan Harper     }
750d22b2f41SRyan Harper     bs->device_name[0] = '\0';
751d22b2f41SRyan Harper }
752d22b2f41SRyan Harper 
753b338082bSbellard void bdrv_delete(BlockDriverState *bs)
754b338082bSbellard {
755fa879d62SMarkus Armbruster     assert(!bs->dev);
75618846deeSMarkus Armbruster 
7571b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
758d22b2f41SRyan Harper     bdrv_make_anon(bs);
75934c6f050Saurel32 
760b338082bSbellard     bdrv_close(bs);
76166f82ceeSKevin Wolf     if (bs->file != NULL) {
76266f82ceeSKevin Wolf         bdrv_delete(bs->file);
76366f82ceeSKevin Wolf     }
76466f82ceeSKevin Wolf 
765f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7667267c094SAnthony Liguori     g_free(bs);
767fc01f7e7Sbellard }
768fc01f7e7Sbellard 
769fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
770fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
77118846deeSMarkus Armbruster {
772fa879d62SMarkus Armbruster     if (bs->dev) {
77318846deeSMarkus Armbruster         return -EBUSY;
77418846deeSMarkus Armbruster     }
775fa879d62SMarkus Armbruster     bs->dev = dev;
77628a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
77718846deeSMarkus Armbruster     return 0;
77818846deeSMarkus Armbruster }
77918846deeSMarkus Armbruster 
780fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
781fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
78218846deeSMarkus Armbruster {
783fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
784fa879d62SMarkus Armbruster         abort();
785fa879d62SMarkus Armbruster     }
786fa879d62SMarkus Armbruster }
787fa879d62SMarkus Armbruster 
788fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
789fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
790fa879d62SMarkus Armbruster {
791fa879d62SMarkus Armbruster     assert(bs->dev == dev);
792fa879d62SMarkus Armbruster     bs->dev = NULL;
7930e49de52SMarkus Armbruster     bs->dev_ops = NULL;
7940e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
79529e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
79618846deeSMarkus Armbruster }
79718846deeSMarkus Armbruster 
798fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
799fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
80018846deeSMarkus Armbruster {
801fa879d62SMarkus Armbruster     return bs->dev;
80218846deeSMarkus Armbruster }
80318846deeSMarkus Armbruster 
8040e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
8050e49de52SMarkus Armbruster                       void *opaque)
8060e49de52SMarkus Armbruster {
8070e49de52SMarkus Armbruster     bs->dev_ops = ops;
8080e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8092c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8102c6942faSMarkus Armbruster         bs_snapshots = NULL;
8112c6942faSMarkus Armbruster     }
8120e49de52SMarkus Armbruster }
8130e49de52SMarkus Armbruster 
8147d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8150e49de52SMarkus Armbruster {
816145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8177d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
818145feb17SMarkus Armbruster     }
819145feb17SMarkus Armbruster }
820145feb17SMarkus Armbruster 
8212c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8222c6942faSMarkus Armbruster {
8232c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8242c6942faSMarkus Armbruster }
8252c6942faSMarkus Armbruster 
826e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
827e4def80bSMarkus Armbruster {
828e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
829e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
830e4def80bSMarkus Armbruster     }
831e4def80bSMarkus Armbruster     return false;
832e4def80bSMarkus Armbruster }
833e4def80bSMarkus Armbruster 
834145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
835145feb17SMarkus Armbruster {
836145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
837145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8380e49de52SMarkus Armbruster     }
8390e49de52SMarkus Armbruster }
8400e49de52SMarkus Armbruster 
841f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
842f107639aSMarkus Armbruster {
843f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
844f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
845f107639aSMarkus Armbruster     }
846f107639aSMarkus Armbruster     return false;
847f107639aSMarkus Armbruster }
848f107639aSMarkus Armbruster 
849e97fc193Saliguori /*
850e97fc193Saliguori  * Run consistency checks on an image
851e97fc193Saliguori  *
852e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
853a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
854e076f338SKevin Wolf  * check are stored in res.
855e97fc193Saliguori  */
856e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
857e97fc193Saliguori {
858e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
859e97fc193Saliguori         return -ENOTSUP;
860e97fc193Saliguori     }
861e97fc193Saliguori 
862e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8639ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
864e97fc193Saliguori }
865e97fc193Saliguori 
8668a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8678a426614SKevin Wolf 
86833e3963eSbellard /* commit COW file into the raw image */
86933e3963eSbellard int bdrv_commit(BlockDriverState *bs)
87033e3963eSbellard {
87119cb3738Sbellard     BlockDriver *drv = bs->drv;
872ee181196SKevin Wolf     BlockDriver *backing_drv;
8738a426614SKevin Wolf     int64_t sector, total_sectors;
8748a426614SKevin Wolf     int n, ro, open_flags;
8754dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8768a426614SKevin Wolf     uint8_t *buf;
8774dca4b63SNaphtali Sprei     char filename[1024];
8784dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
87933e3963eSbellard 
88019cb3738Sbellard     if (!drv)
88119cb3738Sbellard         return -ENOMEDIUM;
88233e3963eSbellard 
8834dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8844dca4b63SNaphtali Sprei         return -ENOTSUP;
8854dca4b63SNaphtali Sprei     }
8864dca4b63SNaphtali Sprei 
8874dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
888ea2384d3Sbellard         return -EACCES;
88933e3963eSbellard     }
89033e3963eSbellard 
891ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
8924dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
8934dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
8944dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
8954dca4b63SNaphtali Sprei 
8964dca4b63SNaphtali Sprei     if (ro) {
8974dca4b63SNaphtali Sprei         /* re-open as RW */
8984dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
8994dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9004dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
901ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
902ee181196SKevin Wolf             backing_drv);
9034dca4b63SNaphtali Sprei         if (rw_ret < 0) {
9044dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
9054dca4b63SNaphtali Sprei             /* try to re-open read-only */
9064dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
907ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
908ee181196SKevin Wolf                 backing_drv);
9094dca4b63SNaphtali Sprei             if (ret < 0) {
9104dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9114dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9124dca4b63SNaphtali Sprei                 bs->drv = NULL;
9134dca4b63SNaphtali Sprei                 return ret;
9144dca4b63SNaphtali Sprei             }
9154dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9164dca4b63SNaphtali Sprei             return rw_ret;
9174dca4b63SNaphtali Sprei         }
9184dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
919ea2384d3Sbellard     }
920ea2384d3Sbellard 
9216ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9227267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9238a426614SKevin Wolf 
9248a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9258a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9268a426614SKevin Wolf 
9278a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9284dca4b63SNaphtali Sprei                 ret = -EIO;
9294dca4b63SNaphtali Sprei                 goto ro_cleanup;
93033e3963eSbellard             }
93133e3963eSbellard 
9328a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9334dca4b63SNaphtali Sprei                 ret = -EIO;
9344dca4b63SNaphtali Sprei                 goto ro_cleanup;
93533e3963eSbellard             }
93633e3963eSbellard         }
93733e3963eSbellard     }
93895389c86Sbellard 
9391d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9401d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9411d44952fSChristoph Hellwig         bdrv_flush(bs);
9421d44952fSChristoph Hellwig     }
94395389c86Sbellard 
9443f5075aeSChristoph Hellwig     /*
9453f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9463f5075aeSChristoph Hellwig      * stable on disk.
9473f5075aeSChristoph Hellwig      */
9483f5075aeSChristoph Hellwig     if (bs->backing_hd)
9493f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9504dca4b63SNaphtali Sprei 
9514dca4b63SNaphtali Sprei ro_cleanup:
9527267c094SAnthony Liguori     g_free(buf);
9534dca4b63SNaphtali Sprei 
9544dca4b63SNaphtali Sprei     if (ro) {
9554dca4b63SNaphtali Sprei         /* re-open as RO */
9564dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9574dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9584dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
959ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
960ee181196SKevin Wolf             backing_drv);
9614dca4b63SNaphtali Sprei         if (ret < 0) {
9624dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9634dca4b63SNaphtali Sprei             /* drive not functional anymore */
9644dca4b63SNaphtali Sprei             bs->drv = NULL;
9654dca4b63SNaphtali Sprei             return ret;
9664dca4b63SNaphtali Sprei         }
9674dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9684dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9694dca4b63SNaphtali Sprei     }
9704dca4b63SNaphtali Sprei 
9711d44952fSChristoph Hellwig     return ret;
97233e3963eSbellard }
97333e3963eSbellard 
9746ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9756ab4b5abSMarkus Armbruster {
9766ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9776ab4b5abSMarkus Armbruster 
9786ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9796ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9806ab4b5abSMarkus Armbruster     }
9816ab4b5abSMarkus Armbruster }
9826ab4b5abSMarkus Armbruster 
983756e6736SKevin Wolf /*
984756e6736SKevin Wolf  * Return values:
985756e6736SKevin Wolf  * 0        - success
986756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
987756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
988756e6736SKevin Wolf  *            image file header
989756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
990756e6736SKevin Wolf  */
991756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
992756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
993756e6736SKevin Wolf {
994756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
995756e6736SKevin Wolf 
996756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
997756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
998756e6736SKevin Wolf     } else {
999756e6736SKevin Wolf         return -ENOTSUP;
1000756e6736SKevin Wolf     }
1001756e6736SKevin Wolf }
1002756e6736SKevin Wolf 
100371d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
100471d0770cSaliguori                                    size_t size)
100571d0770cSaliguori {
100671d0770cSaliguori     int64_t len;
100771d0770cSaliguori 
100871d0770cSaliguori     if (!bdrv_is_inserted(bs))
100971d0770cSaliguori         return -ENOMEDIUM;
101071d0770cSaliguori 
101171d0770cSaliguori     if (bs->growable)
101271d0770cSaliguori         return 0;
101371d0770cSaliguori 
101471d0770cSaliguori     len = bdrv_getlength(bs);
101571d0770cSaliguori 
1016fbb7b4e0SKevin Wolf     if (offset < 0)
1017fbb7b4e0SKevin Wolf         return -EIO;
1018fbb7b4e0SKevin Wolf 
1019fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
102071d0770cSaliguori         return -EIO;
102171d0770cSaliguori 
102271d0770cSaliguori     return 0;
102371d0770cSaliguori }
102471d0770cSaliguori 
102571d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
102671d0770cSaliguori                               int nb_sectors)
102771d0770cSaliguori {
1028eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1029eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
103071d0770cSaliguori }
103171d0770cSaliguori 
1032e7a8a783SKevin Wolf static inline bool bdrv_has_async_rw(BlockDriver *drv)
1033e7a8a783SKevin Wolf {
1034e7a8a783SKevin Wolf     return drv->bdrv_co_readv != bdrv_co_readv_em
1035e7a8a783SKevin Wolf         || drv->bdrv_aio_readv != bdrv_aio_readv_em;
1036e7a8a783SKevin Wolf }
1037e7a8a783SKevin Wolf 
1038e7a8a783SKevin Wolf static inline bool bdrv_has_async_flush(BlockDriver *drv)
1039e7a8a783SKevin Wolf {
1040e7a8a783SKevin Wolf     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
1041e7a8a783SKevin Wolf }
1042e7a8a783SKevin Wolf 
104319cb3738Sbellard /* return < 0 if error. See bdrv_write() for the return codes */
1044fc01f7e7Sbellard int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1045fc01f7e7Sbellard               uint8_t *buf, int nb_sectors)
1046fc01f7e7Sbellard {
1047ea2384d3Sbellard     BlockDriver *drv = bs->drv;
1048fc01f7e7Sbellard 
104919cb3738Sbellard     if (!drv)
105019cb3738Sbellard         return -ENOMEDIUM;
1051e7a8a783SKevin Wolf 
1052e7a8a783SKevin Wolf     if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
1053e7a8a783SKevin Wolf         QEMUIOVector qiov;
1054e7a8a783SKevin Wolf         struct iovec iov = {
1055e7a8a783SKevin Wolf             .iov_base = (void *)buf,
1056e7a8a783SKevin Wolf             .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1057e7a8a783SKevin Wolf         };
1058e7a8a783SKevin Wolf 
1059e7a8a783SKevin Wolf         qemu_iovec_init_external(&qiov, &iov, 1);
1060e7a8a783SKevin Wolf         return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
1061e7a8a783SKevin Wolf     }
1062e7a8a783SKevin Wolf 
106371d0770cSaliguori     if (bdrv_check_request(bs, sector_num, nb_sectors))
106471d0770cSaliguori         return -EIO;
1065b338082bSbellard 
106683f64091Sbellard     return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
106783f64091Sbellard }
1068fc01f7e7Sbellard 
10697cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
10707cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
10717cd1e32aSlirans@il.ibm.com {
10727cd1e32aSlirans@il.ibm.com     int64_t start, end;
1073c6d22830SJan Kiszka     unsigned long val, idx, bit;
1074a55eb92cSJan Kiszka 
10756ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1076c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
10777cd1e32aSlirans@il.ibm.com 
10787cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1079c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1080c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1081c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1082c6d22830SJan Kiszka         if (dirty) {
10836d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1084aaa0eb75SLiran Schour                 bs->dirty_count++;
10856d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1086aaa0eb75SLiran Schour             }
1087c6d22830SJan Kiszka         } else {
10886d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1089aaa0eb75SLiran Schour                 bs->dirty_count--;
10906d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1091c6d22830SJan Kiszka             }
1092aaa0eb75SLiran Schour         }
1093c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
10947cd1e32aSlirans@il.ibm.com     }
10957cd1e32aSlirans@il.ibm.com }
10967cd1e32aSlirans@il.ibm.com 
109719cb3738Sbellard /* Return < 0 if error. Important errors are:
109819cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
109919cb3738Sbellard   -ENOMEDIUM   No media inserted.
110019cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
110119cb3738Sbellard   -EACCES      Trying to write a read-only device
110219cb3738Sbellard */
1103fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1104fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1105fc01f7e7Sbellard {
110683f64091Sbellard     BlockDriver *drv = bs->drv;
1107e7a8a783SKevin Wolf 
110819cb3738Sbellard     if (!bs->drv)
110919cb3738Sbellard         return -ENOMEDIUM;
1110e7a8a783SKevin Wolf 
1111e7a8a783SKevin Wolf     if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
1112e7a8a783SKevin Wolf         QEMUIOVector qiov;
1113e7a8a783SKevin Wolf         struct iovec iov = {
1114e7a8a783SKevin Wolf             .iov_base = (void *)buf,
1115e7a8a783SKevin Wolf             .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1116e7a8a783SKevin Wolf         };
1117e7a8a783SKevin Wolf 
1118e7a8a783SKevin Wolf         qemu_iovec_init_external(&qiov, &iov, 1);
1119e7a8a783SKevin Wolf         return bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
1120e7a8a783SKevin Wolf     }
1121e7a8a783SKevin Wolf 
11220849bf08Sbellard     if (bs->read_only)
112319cb3738Sbellard         return -EACCES;
112471d0770cSaliguori     if (bdrv_check_request(bs, sector_num, nb_sectors))
112571d0770cSaliguori         return -EIO;
112671d0770cSaliguori 
1127c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
11287cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
11297cd1e32aSlirans@il.ibm.com     }
11307cd1e32aSlirans@il.ibm.com 
1131294cc35fSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1132294cc35fSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1133294cc35fSKevin Wolf     }
1134294cc35fSKevin Wolf 
113583f64091Sbellard     return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
113683f64091Sbellard }
113783f64091Sbellard 
1138eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1139eda578e5Saliguori                void *buf, int count1)
114083f64091Sbellard {
11416ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
114283f64091Sbellard     int len, nb_sectors, count;
114383f64091Sbellard     int64_t sector_num;
11449a8c4cceSKevin Wolf     int ret;
114583f64091Sbellard 
114683f64091Sbellard     count = count1;
114783f64091Sbellard     /* first read to align to sector start */
11486ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
114983f64091Sbellard     if (len > count)
115083f64091Sbellard         len = count;
11516ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
115283f64091Sbellard     if (len > 0) {
11539a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11549a8c4cceSKevin Wolf             return ret;
11556ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
115683f64091Sbellard         count -= len;
115783f64091Sbellard         if (count == 0)
115883f64091Sbellard             return count1;
115983f64091Sbellard         sector_num++;
116083f64091Sbellard         buf += len;
116183f64091Sbellard     }
116283f64091Sbellard 
116383f64091Sbellard     /* read the sectors "in place" */
11646ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
116583f64091Sbellard     if (nb_sectors > 0) {
11669a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11679a8c4cceSKevin Wolf             return ret;
116883f64091Sbellard         sector_num += nb_sectors;
11696ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
117083f64091Sbellard         buf += len;
117183f64091Sbellard         count -= len;
117283f64091Sbellard     }
117383f64091Sbellard 
117483f64091Sbellard     /* add data from the last sector */
117583f64091Sbellard     if (count > 0) {
11769a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11779a8c4cceSKevin Wolf             return ret;
117883f64091Sbellard         memcpy(buf, tmp_buf, count);
117983f64091Sbellard     }
118083f64091Sbellard     return count1;
118183f64091Sbellard }
118283f64091Sbellard 
1183eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1184eda578e5Saliguori                 const void *buf, int count1)
118583f64091Sbellard {
11866ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
118783f64091Sbellard     int len, nb_sectors, count;
118883f64091Sbellard     int64_t sector_num;
11899a8c4cceSKevin Wolf     int ret;
119083f64091Sbellard 
119183f64091Sbellard     count = count1;
119283f64091Sbellard     /* first write to align to sector start */
11936ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
119483f64091Sbellard     if (len > count)
119583f64091Sbellard         len = count;
11966ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
119783f64091Sbellard     if (len > 0) {
11989a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11999a8c4cceSKevin Wolf             return ret;
12006ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
12019a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12029a8c4cceSKevin Wolf             return ret;
120383f64091Sbellard         count -= len;
120483f64091Sbellard         if (count == 0)
120583f64091Sbellard             return count1;
120683f64091Sbellard         sector_num++;
120783f64091Sbellard         buf += len;
120883f64091Sbellard     }
120983f64091Sbellard 
121083f64091Sbellard     /* write the sectors "in place" */
12116ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
121283f64091Sbellard     if (nb_sectors > 0) {
12139a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12149a8c4cceSKevin Wolf             return ret;
121583f64091Sbellard         sector_num += nb_sectors;
12166ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
121783f64091Sbellard         buf += len;
121883f64091Sbellard         count -= len;
121983f64091Sbellard     }
122083f64091Sbellard 
122183f64091Sbellard     /* add data from the last sector */
122283f64091Sbellard     if (count > 0) {
12239a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12249a8c4cceSKevin Wolf             return ret;
122583f64091Sbellard         memcpy(tmp_buf, buf, count);
12269a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12279a8c4cceSKevin Wolf             return ret;
122883f64091Sbellard     }
122983f64091Sbellard     return count1;
123083f64091Sbellard }
123183f64091Sbellard 
1232f08145feSKevin Wolf /*
1233f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1234f08145feSKevin Wolf  * request (acts as a barrier)
1235f08145feSKevin Wolf  *
1236f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1237f08145feSKevin Wolf  */
1238f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1239f08145feSKevin Wolf     const void *buf, int count)
1240f08145feSKevin Wolf {
1241f08145feSKevin Wolf     int ret;
1242f08145feSKevin Wolf 
1243f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1244f08145feSKevin Wolf     if (ret < 0) {
1245f08145feSKevin Wolf         return ret;
1246f08145feSKevin Wolf     }
1247f08145feSKevin Wolf 
124892196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
124992196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1250f08145feSKevin Wolf         bdrv_flush(bs);
1251f08145feSKevin Wolf     }
1252f08145feSKevin Wolf 
1253f08145feSKevin Wolf     return 0;
1254f08145feSKevin Wolf }
1255f08145feSKevin Wolf 
1256da1fa91dSKevin Wolf int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1257da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1258da1fa91dSKevin Wolf {
1259da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1260da1fa91dSKevin Wolf 
1261da1fa91dSKevin Wolf     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1262da1fa91dSKevin Wolf 
1263da1fa91dSKevin Wolf     if (!drv) {
1264da1fa91dSKevin Wolf         return -ENOMEDIUM;
1265da1fa91dSKevin Wolf     }
1266da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1267da1fa91dSKevin Wolf         return -EIO;
1268da1fa91dSKevin Wolf     }
1269da1fa91dSKevin Wolf 
1270da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1271da1fa91dSKevin Wolf }
1272da1fa91dSKevin Wolf 
1273da1fa91dSKevin Wolf int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1274da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1275da1fa91dSKevin Wolf {
1276da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1277da1fa91dSKevin Wolf 
1278da1fa91dSKevin Wolf     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1279da1fa91dSKevin Wolf 
1280da1fa91dSKevin Wolf     if (!bs->drv) {
1281da1fa91dSKevin Wolf         return -ENOMEDIUM;
1282da1fa91dSKevin Wolf     }
1283da1fa91dSKevin Wolf     if (bs->read_only) {
1284da1fa91dSKevin Wolf         return -EACCES;
1285da1fa91dSKevin Wolf     }
1286da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1287da1fa91dSKevin Wolf         return -EIO;
1288da1fa91dSKevin Wolf     }
1289da1fa91dSKevin Wolf 
1290da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1291da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1292da1fa91dSKevin Wolf     }
1293da1fa91dSKevin Wolf 
1294da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1295da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1296da1fa91dSKevin Wolf     }
1297da1fa91dSKevin Wolf 
1298da1fa91dSKevin Wolf     return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
1299da1fa91dSKevin Wolf }
1300da1fa91dSKevin Wolf 
130183f64091Sbellard /**
130283f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
130383f64091Sbellard  */
130483f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
130583f64091Sbellard {
130683f64091Sbellard     BlockDriver *drv = bs->drv;
130751762288SStefan Hajnoczi     int ret;
130883f64091Sbellard     if (!drv)
130919cb3738Sbellard         return -ENOMEDIUM;
131083f64091Sbellard     if (!drv->bdrv_truncate)
131183f64091Sbellard         return -ENOTSUP;
131259f2689dSNaphtali Sprei     if (bs->read_only)
131359f2689dSNaphtali Sprei         return -EACCES;
13148591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13158591675fSMarcelo Tosatti         return -EBUSY;
131651762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
131751762288SStefan Hajnoczi     if (ret == 0) {
131851762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1319145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
132051762288SStefan Hajnoczi     }
132151762288SStefan Hajnoczi     return ret;
132283f64091Sbellard }
132383f64091Sbellard 
132483f64091Sbellard /**
13254a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13264a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13274a1d5e1fSFam Zheng  */
13284a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13294a1d5e1fSFam Zheng {
13304a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13314a1d5e1fSFam Zheng     if (!drv) {
13324a1d5e1fSFam Zheng         return -ENOMEDIUM;
13334a1d5e1fSFam Zheng     }
13344a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13354a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13364a1d5e1fSFam Zheng     }
13374a1d5e1fSFam Zheng     if (bs->file) {
13384a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13394a1d5e1fSFam Zheng     }
13404a1d5e1fSFam Zheng     return -ENOTSUP;
13414a1d5e1fSFam Zheng }
13424a1d5e1fSFam Zheng 
13434a1d5e1fSFam Zheng /**
134483f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
134583f64091Sbellard  */
134683f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
134783f64091Sbellard {
134883f64091Sbellard     BlockDriver *drv = bs->drv;
134983f64091Sbellard     if (!drv)
135019cb3738Sbellard         return -ENOMEDIUM;
135151762288SStefan Hajnoczi 
13522c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
135346a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
135483f64091Sbellard             return drv->bdrv_getlength(bs);
1355fc01f7e7Sbellard         }
135646a4e4e6SStefan Hajnoczi     }
135746a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
135846a4e4e6SStefan Hajnoczi }
1359fc01f7e7Sbellard 
136019cb3738Sbellard /* return 0 as number of sectors if no device present or error */
136196b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1362fc01f7e7Sbellard {
136319cb3738Sbellard     int64_t length;
136419cb3738Sbellard     length = bdrv_getlength(bs);
136519cb3738Sbellard     if (length < 0)
136619cb3738Sbellard         length = 0;
136719cb3738Sbellard     else
13686ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
136919cb3738Sbellard     *nb_sectors_ptr = length;
1370fc01f7e7Sbellard }
1371cf98951bSbellard 
1372f3d54fc4Saliguori struct partition {
1373f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1374f3d54fc4Saliguori         uint8_t head;               /* starting head */
1375f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1376f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1377f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1378f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1379f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1380f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1381f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1382f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1383541dc0d4SStefan Weil } QEMU_PACKED;
1384f3d54fc4Saliguori 
1385f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1386f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1387f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1388f3d54fc4Saliguori {
1389eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1390f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1391f3d54fc4Saliguori     struct partition *p;
1392f3d54fc4Saliguori     uint32_t nr_sects;
1393a38131b6Sblueswir1     uint64_t nb_sectors;
1394f3d54fc4Saliguori 
1395f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1396f3d54fc4Saliguori 
1397f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1398f3d54fc4Saliguori     if (ret < 0)
1399f3d54fc4Saliguori         return -1;
1400f3d54fc4Saliguori     /* test msdos magic */
1401f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1402f3d54fc4Saliguori         return -1;
1403f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1404f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1405f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1406f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1407f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1408f3d54fc4Saliguori                a cylinder boundary */
1409f3d54fc4Saliguori             heads = p->end_head + 1;
1410f3d54fc4Saliguori             sectors = p->end_sector & 63;
1411f3d54fc4Saliguori             if (sectors == 0)
1412f3d54fc4Saliguori                 continue;
1413f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1414f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1415f3d54fc4Saliguori                 continue;
1416f3d54fc4Saliguori             *pheads = heads;
1417f3d54fc4Saliguori             *psectors = sectors;
1418f3d54fc4Saliguori             *pcylinders = cylinders;
1419f3d54fc4Saliguori #if 0
1420f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1421f3d54fc4Saliguori                    cylinders, heads, sectors);
1422f3d54fc4Saliguori #endif
1423f3d54fc4Saliguori             return 0;
1424f3d54fc4Saliguori         }
1425f3d54fc4Saliguori     }
1426f3d54fc4Saliguori     return -1;
1427f3d54fc4Saliguori }
1428f3d54fc4Saliguori 
1429f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1430f3d54fc4Saliguori {
1431f3d54fc4Saliguori     int translation, lba_detected = 0;
1432f3d54fc4Saliguori     int cylinders, heads, secs;
1433a38131b6Sblueswir1     uint64_t nb_sectors;
1434f3d54fc4Saliguori 
1435f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1436f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1437f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1438f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1439f3d54fc4Saliguori     if (cylinders != 0) {
1440f3d54fc4Saliguori         *pcyls = cylinders;
1441f3d54fc4Saliguori         *pheads = heads;
1442f3d54fc4Saliguori         *psecs = secs;
1443f3d54fc4Saliguori     } else {
1444f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1445f3d54fc4Saliguori             if (heads > 16) {
1446f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1447f3d54fc4Saliguori                    translation was active, so the default
1448f3d54fc4Saliguori                    hardware geometry is OK */
1449f3d54fc4Saliguori                 lba_detected = 1;
1450f3d54fc4Saliguori                 goto default_geometry;
1451f3d54fc4Saliguori             } else {
1452f3d54fc4Saliguori                 *pcyls = cylinders;
1453f3d54fc4Saliguori                 *pheads = heads;
1454f3d54fc4Saliguori                 *psecs = secs;
1455f3d54fc4Saliguori                 /* disable any translation to be in sync with
1456f3d54fc4Saliguori                    the logical geometry */
1457f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1458f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1459f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1460f3d54fc4Saliguori                 }
1461f3d54fc4Saliguori             }
1462f3d54fc4Saliguori         } else {
1463f3d54fc4Saliguori         default_geometry:
1464f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1465f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1466f3d54fc4Saliguori 
1467f3d54fc4Saliguori             if (cylinders > 16383)
1468f3d54fc4Saliguori                 cylinders = 16383;
1469f3d54fc4Saliguori             else if (cylinders < 2)
1470f3d54fc4Saliguori                 cylinders = 2;
1471f3d54fc4Saliguori             *pcyls = cylinders;
1472f3d54fc4Saliguori             *pheads = 16;
1473f3d54fc4Saliguori             *psecs = 63;
1474f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1475f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1476f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1477f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1478f3d54fc4Saliguori                 } else {
1479f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1480f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1481f3d54fc4Saliguori                 }
1482f3d54fc4Saliguori             }
1483f3d54fc4Saliguori         }
1484f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1485f3d54fc4Saliguori     }
1486f3d54fc4Saliguori }
1487f3d54fc4Saliguori 
1488b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1489b338082bSbellard                             int cyls, int heads, int secs)
1490b338082bSbellard {
1491b338082bSbellard     bs->cyls = cyls;
1492b338082bSbellard     bs->heads = heads;
1493b338082bSbellard     bs->secs = secs;
1494b338082bSbellard }
1495b338082bSbellard 
149646d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
149746d4767dSbellard {
149846d4767dSbellard     bs->translation = translation;
149946d4767dSbellard }
150046d4767dSbellard 
1501b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1502b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1503b338082bSbellard {
1504b338082bSbellard     *pcyls = bs->cyls;
1505b338082bSbellard     *pheads = bs->heads;
1506b338082bSbellard     *psecs = bs->secs;
1507b338082bSbellard }
1508b338082bSbellard 
15095bbdbb46SBlue Swirl /* Recognize floppy formats */
15105bbdbb46SBlue Swirl typedef struct FDFormat {
15115bbdbb46SBlue Swirl     FDriveType drive;
15125bbdbb46SBlue Swirl     uint8_t last_sect;
15135bbdbb46SBlue Swirl     uint8_t max_track;
15145bbdbb46SBlue Swirl     uint8_t max_head;
15155bbdbb46SBlue Swirl } FDFormat;
15165bbdbb46SBlue Swirl 
15175bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15185bbdbb46SBlue Swirl     /* First entry is default format */
15195bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15205bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15215bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15225bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15235bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15245bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15255bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15265bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15275bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15285bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15295bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15305bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15315bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15325bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15335bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15345bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15355bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15365bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15375bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15385bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15395bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15405bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15415bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15425bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15435bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15445bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15455bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15465bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15475bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15485bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15495bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15505bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15515bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15525bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15535bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15545bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15555bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15565bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
15575bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
15585bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
15595bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
15605bbdbb46SBlue Swirl     /* end */
15615bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
15625bbdbb46SBlue Swirl };
15635bbdbb46SBlue Swirl 
15645bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
15655bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
15665bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
15675bbdbb46SBlue Swirl {
15685bbdbb46SBlue Swirl     const FDFormat *parse;
15695bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
15705bbdbb46SBlue Swirl     int i, first_match, match;
15715bbdbb46SBlue Swirl 
15725bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
15735bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
15745bbdbb46SBlue Swirl         /* User defined disk */
15755bbdbb46SBlue Swirl     } else {
15765bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
15775bbdbb46SBlue Swirl         match = -1;
15785bbdbb46SBlue Swirl         first_match = -1;
15795bbdbb46SBlue Swirl         for (i = 0; ; i++) {
15805bbdbb46SBlue Swirl             parse = &fd_formats[i];
15815bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
15825bbdbb46SBlue Swirl                 break;
15835bbdbb46SBlue Swirl             }
15845bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
15855bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
15865bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
15875bbdbb46SBlue Swirl                     parse->last_sect;
15885bbdbb46SBlue Swirl                 if (nb_sectors == size) {
15895bbdbb46SBlue Swirl                     match = i;
15905bbdbb46SBlue Swirl                     break;
15915bbdbb46SBlue Swirl                 }
15925bbdbb46SBlue Swirl                 if (first_match == -1) {
15935bbdbb46SBlue Swirl                     first_match = i;
15945bbdbb46SBlue Swirl                 }
15955bbdbb46SBlue Swirl             }
15965bbdbb46SBlue Swirl         }
15975bbdbb46SBlue Swirl         if (match == -1) {
15985bbdbb46SBlue Swirl             if (first_match == -1) {
15995bbdbb46SBlue Swirl                 match = 1;
16005bbdbb46SBlue Swirl             } else {
16015bbdbb46SBlue Swirl                 match = first_match;
16025bbdbb46SBlue Swirl             }
16035bbdbb46SBlue Swirl             parse = &fd_formats[match];
16045bbdbb46SBlue Swirl         }
16055bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16065bbdbb46SBlue Swirl         *max_track = parse->max_track;
16075bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16085bbdbb46SBlue Swirl         *drive = parse->drive;
16095bbdbb46SBlue Swirl     }
16105bbdbb46SBlue Swirl }
16115bbdbb46SBlue Swirl 
161246d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
161346d4767dSbellard {
161446d4767dSbellard     return bs->translation;
161546d4767dSbellard }
161646d4767dSbellard 
1617abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1618abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1619abd7f68dSMarkus Armbruster {
1620abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1621abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1622abd7f68dSMarkus Armbruster }
1623abd7f68dSMarkus Armbruster 
1624abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1625abd7f68dSMarkus Armbruster {
1626abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1627abd7f68dSMarkus Armbruster }
1628abd7f68dSMarkus Armbruster 
1629b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1630b338082bSbellard {
1631b338082bSbellard     return bs->read_only;
1632b338082bSbellard }
1633b338082bSbellard 
1634985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1635985a03b0Sths {
1636985a03b0Sths     return bs->sg;
1637985a03b0Sths }
1638985a03b0Sths 
1639e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1640e900a7b7SChristoph Hellwig {
1641e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1642e900a7b7SChristoph Hellwig }
1643e900a7b7SChristoph Hellwig 
1644ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1645ea2384d3Sbellard {
1646ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1647ea2384d3Sbellard         return 1;
1648ea2384d3Sbellard     return bs->encrypted;
1649ea2384d3Sbellard }
1650ea2384d3Sbellard 
1651c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1652c0f4ce77Saliguori {
1653c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1654c0f4ce77Saliguori 
1655c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1656c0f4ce77Saliguori         return 1;
1657c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1658c0f4ce77Saliguori }
1659c0f4ce77Saliguori 
1660ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1661ea2384d3Sbellard {
1662ea2384d3Sbellard     int ret;
1663ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1664ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1665ea2384d3Sbellard         if (ret < 0)
1666ea2384d3Sbellard             return ret;
1667ea2384d3Sbellard         if (!bs->encrypted)
1668ea2384d3Sbellard             return 0;
1669ea2384d3Sbellard     }
1670fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1671fd04a2aeSShahar Havivi         return -EINVAL;
1672fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1673fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1674fd04a2aeSShahar Havivi     }
1675c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1676bb5fc20fSaliguori     if (ret < 0) {
1677bb5fc20fSaliguori         bs->valid_key = 0;
1678bb5fc20fSaliguori     } else if (!bs->valid_key) {
1679bb5fc20fSaliguori         bs->valid_key = 1;
1680bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
16817d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1682bb5fc20fSaliguori     }
1683c0f4ce77Saliguori     return ret;
1684ea2384d3Sbellard }
1685ea2384d3Sbellard 
1686ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1687ea2384d3Sbellard {
168819cb3738Sbellard     if (!bs->drv) {
1689ea2384d3Sbellard         buf[0] = '\0';
1690ea2384d3Sbellard     } else {
1691ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1692ea2384d3Sbellard     }
1693ea2384d3Sbellard }
1694ea2384d3Sbellard 
1695ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1696ea2384d3Sbellard                          void *opaque)
1697ea2384d3Sbellard {
1698ea2384d3Sbellard     BlockDriver *drv;
1699ea2384d3Sbellard 
17008a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1701ea2384d3Sbellard         it(opaque, drv->format_name);
1702ea2384d3Sbellard     }
1703ea2384d3Sbellard }
1704ea2384d3Sbellard 
1705b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1706b338082bSbellard {
1707b338082bSbellard     BlockDriverState *bs;
1708b338082bSbellard 
17091b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17101b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1711b338082bSbellard             return bs;
1712b338082bSbellard         }
17131b7bdbc1SStefan Hajnoczi     }
1714b338082bSbellard     return NULL;
1715b338082bSbellard }
1716b338082bSbellard 
17172f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17182f399b0aSMarkus Armbruster {
17192f399b0aSMarkus Armbruster     if (!bs) {
17202f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17212f399b0aSMarkus Armbruster     }
17222f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17232f399b0aSMarkus Armbruster }
17242f399b0aSMarkus Armbruster 
172551de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
172681d0912dSbellard {
172781d0912dSbellard     BlockDriverState *bs;
172881d0912dSbellard 
17291b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
173051de9760Saliguori         it(opaque, bs);
173181d0912dSbellard     }
173281d0912dSbellard }
173381d0912dSbellard 
1734ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1735ea2384d3Sbellard {
1736ea2384d3Sbellard     return bs->device_name;
1737ea2384d3Sbellard }
1738ea2384d3Sbellard 
1739205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs)
17407a6cba61Spbrook {
1741016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
1742205ef796SKevin Wolf         return 0;
1743016f5cf6SAlexander Graf     }
1744016f5cf6SAlexander Graf 
1745e7a8a783SKevin Wolf     if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) {
1746e7a8a783SKevin Wolf         return bdrv_co_flush_em(bs);
1747e7a8a783SKevin Wolf     }
1748e7a8a783SKevin Wolf 
1749205ef796SKevin Wolf     if (bs->drv && bs->drv->bdrv_flush) {
1750205ef796SKevin Wolf         return bs->drv->bdrv_flush(bs);
1751205ef796SKevin Wolf     }
1752205ef796SKevin Wolf 
1753205ef796SKevin Wolf     /*
1754205ef796SKevin Wolf      * Some block drivers always operate in either writethrough or unsafe mode
1755205ef796SKevin Wolf      * and don't support bdrv_flush therefore. Usually qemu doesn't know how
1756205ef796SKevin Wolf      * the server works (because the behaviour is hardcoded or depends on
1757205ef796SKevin Wolf      * server-side configuration), so we can't ensure that everything is safe
1758205ef796SKevin Wolf      * on disk. Returning an error doesn't work because that would break guests
1759205ef796SKevin Wolf      * even if the server operates in writethrough mode.
1760205ef796SKevin Wolf      *
1761205ef796SKevin Wolf      * Let's hope the user knows what he's doing.
1762205ef796SKevin Wolf      */
1763205ef796SKevin Wolf     return 0;
17647a6cba61Spbrook }
17657a6cba61Spbrook 
1766c6ca28d6Saliguori void bdrv_flush_all(void)
1767c6ca28d6Saliguori {
1768c6ca28d6Saliguori     BlockDriverState *bs;
1769c6ca28d6Saliguori 
17701b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1771c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1772c6ca28d6Saliguori             bdrv_flush(bs);
1773c6ca28d6Saliguori         }
17741b7bdbc1SStefan Hajnoczi     }
17751b7bdbc1SStefan Hajnoczi }
1776c6ca28d6Saliguori 
1777f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1778f2feebbdSKevin Wolf {
1779f2feebbdSKevin Wolf     assert(bs->drv);
1780f2feebbdSKevin Wolf 
1781336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1782336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1783f2feebbdSKevin Wolf     }
1784f2feebbdSKevin Wolf 
1785f2feebbdSKevin Wolf     return 1;
1786f2feebbdSKevin Wolf }
1787f2feebbdSKevin Wolf 
1788bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
1789bb8bf76fSChristoph Hellwig {
1790bb8bf76fSChristoph Hellwig     if (!bs->drv) {
1791bb8bf76fSChristoph Hellwig         return -ENOMEDIUM;
1792bb8bf76fSChristoph Hellwig     }
1793bb8bf76fSChristoph Hellwig     if (!bs->drv->bdrv_discard) {
1794bb8bf76fSChristoph Hellwig         return 0;
1795bb8bf76fSChristoph Hellwig     }
1796bb8bf76fSChristoph Hellwig     return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
1797bb8bf76fSChristoph Hellwig }
1798bb8bf76fSChristoph Hellwig 
1799f58c7b35Sths /*
1800f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1801f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1802f58c7b35Sths  * hence all their sectors are reported as allocated.
1803f58c7b35Sths  *
1804f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1805f58c7b35Sths  * the specified sector) that are known to be in the same
1806f58c7b35Sths  * allocated/unallocated state.
1807f58c7b35Sths  *
1808f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1809f58c7b35Sths  */
1810f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1811f58c7b35Sths 	int *pnum)
1812f58c7b35Sths {
1813f58c7b35Sths     int64_t n;
1814f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1815f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1816f58c7b35Sths             *pnum = 0;
1817f58c7b35Sths             return 0;
1818f58c7b35Sths         }
1819f58c7b35Sths         n = bs->total_sectors - sector_num;
1820f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1821f58c7b35Sths         return 1;
1822f58c7b35Sths     }
1823f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1824f58c7b35Sths }
1825f58c7b35Sths 
18262582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18272582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18282582bfedSLuiz Capitulino {
18292582bfedSLuiz Capitulino     QObject *data;
18302582bfedSLuiz Capitulino     const char *action_str;
18312582bfedSLuiz Capitulino 
18322582bfedSLuiz Capitulino     switch (action) {
18332582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18342582bfedSLuiz Capitulino         action_str = "report";
18352582bfedSLuiz Capitulino         break;
18362582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18372582bfedSLuiz Capitulino         action_str = "ignore";
18382582bfedSLuiz Capitulino         break;
18392582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18402582bfedSLuiz Capitulino         action_str = "stop";
18412582bfedSLuiz Capitulino         break;
18422582bfedSLuiz Capitulino     default:
18432582bfedSLuiz Capitulino         abort();
18442582bfedSLuiz Capitulino     }
18452582bfedSLuiz Capitulino 
18462582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18472582bfedSLuiz Capitulino                               bdrv->device_name,
18482582bfedSLuiz Capitulino                               action_str,
18492582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18502582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18512582bfedSLuiz Capitulino 
18522582bfedSLuiz Capitulino     qobject_decref(data);
18532582bfedSLuiz Capitulino }
18542582bfedSLuiz Capitulino 
1855d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque)
1856b338082bSbellard {
1857d15e5465SLuiz Capitulino     QDict *bs_dict;
1858d15e5465SLuiz Capitulino     Monitor *mon = opaque;
1859b338082bSbellard 
1860d15e5465SLuiz Capitulino     bs_dict = qobject_to_qdict(obj);
1861d15e5465SLuiz Capitulino 
1862d8aeeb31SMarkus Armbruster     monitor_printf(mon, "%s: removable=%d",
1863d15e5465SLuiz Capitulino                         qdict_get_str(bs_dict, "device"),
1864d15e5465SLuiz Capitulino                         qdict_get_bool(bs_dict, "removable"));
1865d15e5465SLuiz Capitulino 
1866d15e5465SLuiz Capitulino     if (qdict_get_bool(bs_dict, "removable")) {
1867d15e5465SLuiz Capitulino         monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
1868e4def80bSMarkus Armbruster         monitor_printf(mon, " tray-open=%d",
1869e4def80bSMarkus Armbruster                        qdict_get_bool(bs_dict, "tray-open"));
1870b338082bSbellard     }
1871d2078cc2SLuiz Capitulino 
1872d2078cc2SLuiz Capitulino     if (qdict_haskey(bs_dict, "io-status")) {
1873d2078cc2SLuiz Capitulino         monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
1874d2078cc2SLuiz Capitulino     }
1875d2078cc2SLuiz Capitulino 
1876d15e5465SLuiz Capitulino     if (qdict_haskey(bs_dict, "inserted")) {
1877d15e5465SLuiz Capitulino         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
1878d15e5465SLuiz Capitulino 
1879376253ecSaliguori         monitor_printf(mon, " file=");
1880d15e5465SLuiz Capitulino         monitor_print_filename(mon, qdict_get_str(qdict, "file"));
1881d15e5465SLuiz Capitulino         if (qdict_haskey(qdict, "backing_file")) {
1882376253ecSaliguori             monitor_printf(mon, " backing_file=");
1883d15e5465SLuiz Capitulino             monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
1884fef30743Sths         }
1885d15e5465SLuiz Capitulino         monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
1886d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "ro"),
1887d15e5465SLuiz Capitulino                             qdict_get_str(qdict, "drv"),
1888d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "encrypted"));
1889b338082bSbellard     } else {
1890376253ecSaliguori         monitor_printf(mon, " [not inserted]");
1891b338082bSbellard     }
1892d15e5465SLuiz Capitulino 
1893376253ecSaliguori     monitor_printf(mon, "\n");
1894b338082bSbellard }
1895d15e5465SLuiz Capitulino 
1896d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data)
1897d15e5465SLuiz Capitulino {
1898d15e5465SLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
1899d15e5465SLuiz Capitulino }
1900d15e5465SLuiz Capitulino 
1901f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = {
1902f04ef601SLuiz Capitulino     [BDRV_IOS_OK] = "ok",
1903f04ef601SLuiz Capitulino     [BDRV_IOS_FAILED] = "failed",
1904f04ef601SLuiz Capitulino     [BDRV_IOS_ENOSPC] = "nospace",
1905f04ef601SLuiz Capitulino };
1906f04ef601SLuiz Capitulino 
1907d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data)
1908d15e5465SLuiz Capitulino {
1909d15e5465SLuiz Capitulino     QList *bs_list;
1910d15e5465SLuiz Capitulino     BlockDriverState *bs;
1911d15e5465SLuiz Capitulino 
1912d15e5465SLuiz Capitulino     bs_list = qlist_new();
1913d15e5465SLuiz Capitulino 
19141b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1915d15e5465SLuiz Capitulino         QObject *bs_obj;
1916e4def80bSMarkus Armbruster         QDict *bs_dict;
1917d15e5465SLuiz Capitulino 
1918d8aeeb31SMarkus Armbruster         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
1919d15e5465SLuiz Capitulino                                     "'removable': %i, 'locked': %i }",
19202c6942faSMarkus Armbruster                                     bs->device_name,
19212c6942faSMarkus Armbruster                                     bdrv_dev_has_removable_media(bs),
1922f107639aSMarkus Armbruster                                     bdrv_dev_is_medium_locked(bs));
1923e4def80bSMarkus Armbruster         bs_dict = qobject_to_qdict(bs_obj);
1924d15e5465SLuiz Capitulino 
1925e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1926e4def80bSMarkus Armbruster             qdict_put(bs_dict, "tray-open",
1927e4def80bSMarkus Armbruster                       qbool_from_int(bdrv_dev_is_tray_open(bs)));
1928e4def80bSMarkus Armbruster         }
1929f04ef601SLuiz Capitulino 
1930f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1931f04ef601SLuiz Capitulino             qdict_put(bs_dict, "io-status",
1932f04ef601SLuiz Capitulino                       qstring_from_str(io_status_name[bs->iostatus]));
1933f04ef601SLuiz Capitulino         }
1934f04ef601SLuiz Capitulino 
1935d15e5465SLuiz Capitulino         if (bs->drv) {
1936d15e5465SLuiz Capitulino             QObject *obj;
1937d15e5465SLuiz Capitulino 
1938d15e5465SLuiz Capitulino             obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
1939d15e5465SLuiz Capitulino                                      "'encrypted': %i }",
1940d15e5465SLuiz Capitulino                                      bs->filename, bs->read_only,
1941d15e5465SLuiz Capitulino                                      bs->drv->format_name,
1942d15e5465SLuiz Capitulino                                      bdrv_is_encrypted(bs));
1943d15e5465SLuiz Capitulino             if (bs->backing_file[0] != '\0') {
1944d15e5465SLuiz Capitulino                 QDict *qdict = qobject_to_qdict(obj);
1945d15e5465SLuiz Capitulino                 qdict_put(qdict, "backing_file",
1946d15e5465SLuiz Capitulino                           qstring_from_str(bs->backing_file));
1947d15e5465SLuiz Capitulino             }
1948d15e5465SLuiz Capitulino 
1949d15e5465SLuiz Capitulino             qdict_put_obj(bs_dict, "inserted", obj);
1950d15e5465SLuiz Capitulino         }
1951d15e5465SLuiz Capitulino         qlist_append_obj(bs_list, bs_obj);
1952d15e5465SLuiz Capitulino     }
1953d15e5465SLuiz Capitulino 
1954d15e5465SLuiz Capitulino     *ret_data = QOBJECT(bs_list);
1955b338082bSbellard }
1956a36e69ddSths 
1957218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque)
1958a36e69ddSths {
1959218a536aSLuiz Capitulino     QDict *qdict;
1960218a536aSLuiz Capitulino     Monitor *mon = opaque;
1961218a536aSLuiz Capitulino 
1962218a536aSLuiz Capitulino     qdict = qobject_to_qdict(data);
1963218a536aSLuiz Capitulino     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
1964218a536aSLuiz Capitulino 
1965218a536aSLuiz Capitulino     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
1966218a536aSLuiz Capitulino     monitor_printf(mon, " rd_bytes=%" PRId64
1967218a536aSLuiz Capitulino                         " wr_bytes=%" PRId64
1968218a536aSLuiz Capitulino                         " rd_operations=%" PRId64
1969218a536aSLuiz Capitulino                         " wr_operations=%" PRId64
1970e8045d67SChristoph Hellwig                         " flush_operations=%" PRId64
1971c488c7f6SChristoph Hellwig                         " wr_total_time_ns=%" PRId64
1972c488c7f6SChristoph Hellwig                         " rd_total_time_ns=%" PRId64
1973c488c7f6SChristoph Hellwig                         " flush_total_time_ns=%" PRId64
1974218a536aSLuiz Capitulino                         "\n",
1975218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_bytes"),
1976218a536aSLuiz Capitulino                         qdict_get_int(qdict, "wr_bytes"),
1977218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_operations"),
1978e8045d67SChristoph Hellwig                         qdict_get_int(qdict, "wr_operations"),
1979c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_operations"),
1980c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "wr_total_time_ns"),
1981c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "rd_total_time_ns"),
1982c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_total_time_ns"));
1983218a536aSLuiz Capitulino }
1984218a536aSLuiz Capitulino 
1985218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data)
1986218a536aSLuiz Capitulino {
1987218a536aSLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
1988218a536aSLuiz Capitulino }
1989218a536aSLuiz Capitulino 
1990294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
1991294cc35fSKevin Wolf {
1992294cc35fSKevin Wolf     QObject *res;
1993294cc35fSKevin Wolf     QDict *dict;
1994294cc35fSKevin Wolf 
1995294cc35fSKevin Wolf     res = qobject_from_jsonf("{ 'stats': {"
1996294cc35fSKevin Wolf                              "'rd_bytes': %" PRId64 ","
1997294cc35fSKevin Wolf                              "'wr_bytes': %" PRId64 ","
1998294cc35fSKevin Wolf                              "'rd_operations': %" PRId64 ","
1999294cc35fSKevin Wolf                              "'wr_operations': %" PRId64 ","
2000e8045d67SChristoph Hellwig                              "'wr_highest_offset': %" PRId64 ","
2001c488c7f6SChristoph Hellwig                              "'flush_operations': %" PRId64 ","
2002c488c7f6SChristoph Hellwig                              "'wr_total_time_ns': %" PRId64 ","
2003c488c7f6SChristoph Hellwig                              "'rd_total_time_ns': %" PRId64 ","
2004c488c7f6SChristoph Hellwig                              "'flush_total_time_ns': %" PRId64
2005294cc35fSKevin Wolf                              "} }",
2006a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_READ],
2007a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_WRITE],
2008a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_READ],
2009a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_WRITE],
20105ffbbc67SBlue Swirl                              bs->wr_highest_sector *
2011e8045d67SChristoph Hellwig                              (uint64_t)BDRV_SECTOR_SIZE,
2012c488c7f6SChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_FLUSH],
2013c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_WRITE],
2014c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_READ],
2015c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_FLUSH]);
2016294cc35fSKevin Wolf     dict  = qobject_to_qdict(res);
2017294cc35fSKevin Wolf 
2018294cc35fSKevin Wolf     if (*bs->device_name) {
2019294cc35fSKevin Wolf         qdict_put(dict, "device", qstring_from_str(bs->device_name));
2020294cc35fSKevin Wolf     }
2021294cc35fSKevin Wolf 
2022294cc35fSKevin Wolf     if (bs->file) {
2023294cc35fSKevin Wolf         QObject *parent = bdrv_info_stats_bs(bs->file);
2024294cc35fSKevin Wolf         qdict_put_obj(dict, "parent", parent);
2025294cc35fSKevin Wolf     }
2026294cc35fSKevin Wolf 
2027294cc35fSKevin Wolf     return res;
2028294cc35fSKevin Wolf }
2029294cc35fSKevin Wolf 
2030218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data)
2031218a536aSLuiz Capitulino {
2032218a536aSLuiz Capitulino     QObject *obj;
2033218a536aSLuiz Capitulino     QList *devices;
2034a36e69ddSths     BlockDriverState *bs;
2035a36e69ddSths 
2036218a536aSLuiz Capitulino     devices = qlist_new();
2037218a536aSLuiz Capitulino 
20381b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
2039294cc35fSKevin Wolf         obj = bdrv_info_stats_bs(bs);
2040218a536aSLuiz Capitulino         qlist_append_obj(devices, obj);
2041a36e69ddSths     }
2042218a536aSLuiz Capitulino 
2043218a536aSLuiz Capitulino     *ret_data = QOBJECT(devices);
2044a36e69ddSths }
2045ea2384d3Sbellard 
2046045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
2047045df330Saliguori {
2048045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
2049045df330Saliguori         return bs->backing_file;
2050045df330Saliguori     else if (bs->encrypted)
2051045df330Saliguori         return bs->filename;
2052045df330Saliguori     else
2053045df330Saliguori         return NULL;
2054045df330Saliguori }
2055045df330Saliguori 
205683f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
205783f64091Sbellard                                char *filename, int filename_size)
205883f64091Sbellard {
2059b783e409SKevin Wolf     if (!bs->backing_file) {
206083f64091Sbellard         pstrcpy(filename, filename_size, "");
206183f64091Sbellard     } else {
206283f64091Sbellard         pstrcpy(filename, filename_size, bs->backing_file);
206383f64091Sbellard     }
206483f64091Sbellard }
206583f64091Sbellard 
2066faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
2067faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
2068faea38e7Sbellard {
2069faea38e7Sbellard     BlockDriver *drv = bs->drv;
2070faea38e7Sbellard     if (!drv)
207119cb3738Sbellard         return -ENOMEDIUM;
2072faea38e7Sbellard     if (!drv->bdrv_write_compressed)
2073faea38e7Sbellard         return -ENOTSUP;
2074fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
2075fbb7b4e0SKevin Wolf         return -EIO;
20767cd1e32aSlirans@il.ibm.com 
2077c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
20787cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
20797cd1e32aSlirans@il.ibm.com     }
20807cd1e32aSlirans@il.ibm.com 
2081faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2082faea38e7Sbellard }
2083faea38e7Sbellard 
2084faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2085faea38e7Sbellard {
2086faea38e7Sbellard     BlockDriver *drv = bs->drv;
2087faea38e7Sbellard     if (!drv)
208819cb3738Sbellard         return -ENOMEDIUM;
2089faea38e7Sbellard     if (!drv->bdrv_get_info)
2090faea38e7Sbellard         return -ENOTSUP;
2091faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2092faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2093faea38e7Sbellard }
2094faea38e7Sbellard 
209545566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
209645566e9cSChristoph Hellwig                       int64_t pos, int size)
2097178e08a5Saliguori {
2098178e08a5Saliguori     BlockDriver *drv = bs->drv;
2099178e08a5Saliguori     if (!drv)
2100178e08a5Saliguori         return -ENOMEDIUM;
21017cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
210245566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
21037cdb1f6dSMORITA Kazutaka     if (bs->file)
21047cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
21057cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2106178e08a5Saliguori }
2107178e08a5Saliguori 
210845566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
210945566e9cSChristoph Hellwig                       int64_t pos, int size)
2110178e08a5Saliguori {
2111178e08a5Saliguori     BlockDriver *drv = bs->drv;
2112178e08a5Saliguori     if (!drv)
2113178e08a5Saliguori         return -ENOMEDIUM;
21147cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
211545566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
21167cdb1f6dSMORITA Kazutaka     if (bs->file)
21177cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
21187cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2119178e08a5Saliguori }
2120178e08a5Saliguori 
21218b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
21228b9b0cc2SKevin Wolf {
21238b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
21248b9b0cc2SKevin Wolf 
21258b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
21268b9b0cc2SKevin Wolf         return;
21278b9b0cc2SKevin Wolf     }
21288b9b0cc2SKevin Wolf 
21298b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
21308b9b0cc2SKevin Wolf 
21318b9b0cc2SKevin Wolf }
21328b9b0cc2SKevin Wolf 
2133faea38e7Sbellard /**************************************************************/
2134faea38e7Sbellard /* handling of snapshots */
2135faea38e7Sbellard 
2136feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2137feeee5acSMiguel Di Ciurcio Filho {
2138feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
213907b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2140feeee5acSMiguel Di Ciurcio Filho         return 0;
2141feeee5acSMiguel Di Ciurcio Filho     }
2142feeee5acSMiguel Di Ciurcio Filho 
2143feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2144feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2145feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2146feeee5acSMiguel Di Ciurcio Filho         }
2147feeee5acSMiguel Di Ciurcio Filho         return 0;
2148feeee5acSMiguel Di Ciurcio Filho     }
2149feeee5acSMiguel Di Ciurcio Filho 
2150feeee5acSMiguel Di Ciurcio Filho     return 1;
2151feeee5acSMiguel Di Ciurcio Filho }
2152feeee5acSMiguel Di Ciurcio Filho 
2153199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2154199630b6SBlue Swirl {
2155199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2156199630b6SBlue Swirl }
2157199630b6SBlue Swirl 
2158f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2159f9092b10SMarkus Armbruster {
2160f9092b10SMarkus Armbruster     BlockDriverState *bs;
2161f9092b10SMarkus Armbruster 
21623ac906f7SMarkus Armbruster     if (bs_snapshots) {
2163f9092b10SMarkus Armbruster         return bs_snapshots;
21643ac906f7SMarkus Armbruster     }
2165f9092b10SMarkus Armbruster 
2166f9092b10SMarkus Armbruster     bs = NULL;
2167f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2168f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
21693ac906f7SMarkus Armbruster             bs_snapshots = bs;
21703ac906f7SMarkus Armbruster             return bs;
2171f9092b10SMarkus Armbruster         }
2172f9092b10SMarkus Armbruster     }
2173f9092b10SMarkus Armbruster     return NULL;
2174f9092b10SMarkus Armbruster }
2175f9092b10SMarkus Armbruster 
2176faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2177faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2178faea38e7Sbellard {
2179faea38e7Sbellard     BlockDriver *drv = bs->drv;
2180faea38e7Sbellard     if (!drv)
218119cb3738Sbellard         return -ENOMEDIUM;
21827cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2183faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
21847cdb1f6dSMORITA Kazutaka     if (bs->file)
21857cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
21867cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2187faea38e7Sbellard }
2188faea38e7Sbellard 
2189faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2190faea38e7Sbellard                        const char *snapshot_id)
2191faea38e7Sbellard {
2192faea38e7Sbellard     BlockDriver *drv = bs->drv;
21937cdb1f6dSMORITA Kazutaka     int ret, open_ret;
21947cdb1f6dSMORITA Kazutaka 
2195faea38e7Sbellard     if (!drv)
219619cb3738Sbellard         return -ENOMEDIUM;
21977cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2198faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
21997cdb1f6dSMORITA Kazutaka 
22007cdb1f6dSMORITA Kazutaka     if (bs->file) {
22017cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
22027cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
22037cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
22047cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
22057cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
22067cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
22077cdb1f6dSMORITA Kazutaka             return open_ret;
22087cdb1f6dSMORITA Kazutaka         }
22097cdb1f6dSMORITA Kazutaka         return ret;
22107cdb1f6dSMORITA Kazutaka     }
22117cdb1f6dSMORITA Kazutaka 
22127cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2213faea38e7Sbellard }
2214faea38e7Sbellard 
2215faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2216faea38e7Sbellard {
2217faea38e7Sbellard     BlockDriver *drv = bs->drv;
2218faea38e7Sbellard     if (!drv)
221919cb3738Sbellard         return -ENOMEDIUM;
22207cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2221faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
22227cdb1f6dSMORITA Kazutaka     if (bs->file)
22237cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
22247cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2225faea38e7Sbellard }
2226faea38e7Sbellard 
2227faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2228faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2229faea38e7Sbellard {
2230faea38e7Sbellard     BlockDriver *drv = bs->drv;
2231faea38e7Sbellard     if (!drv)
223219cb3738Sbellard         return -ENOMEDIUM;
22337cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2234faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
22357cdb1f6dSMORITA Kazutaka     if (bs->file)
22367cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
22377cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2238faea38e7Sbellard }
2239faea38e7Sbellard 
224051ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
224151ef6727Sedison         const char *snapshot_name)
224251ef6727Sedison {
224351ef6727Sedison     BlockDriver *drv = bs->drv;
224451ef6727Sedison     if (!drv) {
224551ef6727Sedison         return -ENOMEDIUM;
224651ef6727Sedison     }
224751ef6727Sedison     if (!bs->read_only) {
224851ef6727Sedison         return -EINVAL;
224951ef6727Sedison     }
225051ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
225151ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
225251ef6727Sedison     }
225351ef6727Sedison     return -ENOTSUP;
225451ef6727Sedison }
225551ef6727Sedison 
2256faea38e7Sbellard #define NB_SUFFIXES 4
2257faea38e7Sbellard 
2258faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2259faea38e7Sbellard {
2260faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2261faea38e7Sbellard     int64_t base;
2262faea38e7Sbellard     int i;
2263faea38e7Sbellard 
2264faea38e7Sbellard     if (size <= 999) {
2265faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2266faea38e7Sbellard     } else {
2267faea38e7Sbellard         base = 1024;
2268faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2269faea38e7Sbellard             if (size < (10 * base)) {
2270faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2271faea38e7Sbellard                          (double)size / base,
2272faea38e7Sbellard                          suffixes[i]);
2273faea38e7Sbellard                 break;
2274faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2275faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2276faea38e7Sbellard                          ((size + (base >> 1)) / base),
2277faea38e7Sbellard                          suffixes[i]);
2278faea38e7Sbellard                 break;
2279faea38e7Sbellard             }
2280faea38e7Sbellard             base = base * 1024;
2281faea38e7Sbellard         }
2282faea38e7Sbellard     }
2283faea38e7Sbellard     return buf;
2284faea38e7Sbellard }
2285faea38e7Sbellard 
2286faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2287faea38e7Sbellard {
2288faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
22893b9f94e1Sbellard #ifdef _WIN32
22903b9f94e1Sbellard     struct tm *ptm;
22913b9f94e1Sbellard #else
2292faea38e7Sbellard     struct tm tm;
22933b9f94e1Sbellard #endif
2294faea38e7Sbellard     time_t ti;
2295faea38e7Sbellard     int64_t secs;
2296faea38e7Sbellard 
2297faea38e7Sbellard     if (!sn) {
2298faea38e7Sbellard         snprintf(buf, buf_size,
2299faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2300faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2301faea38e7Sbellard     } else {
2302faea38e7Sbellard         ti = sn->date_sec;
23033b9f94e1Sbellard #ifdef _WIN32
23043b9f94e1Sbellard         ptm = localtime(&ti);
23053b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
23063b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
23073b9f94e1Sbellard #else
2308faea38e7Sbellard         localtime_r(&ti, &tm);
2309faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2310faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
23113b9f94e1Sbellard #endif
2312faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2313faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2314faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2315faea38e7Sbellard                  (int)(secs / 3600),
2316faea38e7Sbellard                  (int)((secs / 60) % 60),
2317faea38e7Sbellard                  (int)(secs % 60),
2318faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2319faea38e7Sbellard         snprintf(buf, buf_size,
2320faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2321faea38e7Sbellard                  sn->id_str, sn->name,
2322faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2323faea38e7Sbellard                  date_buf,
2324faea38e7Sbellard                  clock_buf);
2325faea38e7Sbellard     }
2326faea38e7Sbellard     return buf;
2327faea38e7Sbellard }
2328faea38e7Sbellard 
2329ea2384d3Sbellard /**************************************************************/
233083f64091Sbellard /* async I/Os */
2331ea2384d3Sbellard 
23323b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2333f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
233483f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2335ea2384d3Sbellard {
233683f64091Sbellard     BlockDriver *drv = bs->drv;
2337ea2384d3Sbellard 
2338bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2339bbf0a440SStefan Hajnoczi 
234019cb3738Sbellard     if (!drv)
2341ce1a14dcSpbrook         return NULL;
234271d0770cSaliguori     if (bdrv_check_request(bs, sector_num, nb_sectors))
234371d0770cSaliguori         return NULL;
234483f64091Sbellard 
2345a597e79cSChristoph Hellwig     return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
2346f141eafeSaliguori                                cb, opaque);
234783f64091Sbellard }
234883f64091Sbellard 
23494dcafbb1SMarcelo Tosatti typedef struct BlockCompleteData {
23504dcafbb1SMarcelo Tosatti     BlockDriverCompletionFunc *cb;
23514dcafbb1SMarcelo Tosatti     void *opaque;
23524dcafbb1SMarcelo Tosatti     BlockDriverState *bs;
23534dcafbb1SMarcelo Tosatti     int64_t sector_num;
23544dcafbb1SMarcelo Tosatti     int nb_sectors;
23554dcafbb1SMarcelo Tosatti } BlockCompleteData;
23564dcafbb1SMarcelo Tosatti 
23574dcafbb1SMarcelo Tosatti static void block_complete_cb(void *opaque, int ret)
23584dcafbb1SMarcelo Tosatti {
23594dcafbb1SMarcelo Tosatti     BlockCompleteData *b = opaque;
23604dcafbb1SMarcelo Tosatti 
23614dcafbb1SMarcelo Tosatti     if (b->bs->dirty_bitmap) {
23624dcafbb1SMarcelo Tosatti         set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1);
23634dcafbb1SMarcelo Tosatti     }
23644dcafbb1SMarcelo Tosatti     b->cb(b->opaque, ret);
23657267c094SAnthony Liguori     g_free(b);
23664dcafbb1SMarcelo Tosatti }
23674dcafbb1SMarcelo Tosatti 
23684dcafbb1SMarcelo Tosatti static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
23694dcafbb1SMarcelo Tosatti                                              int64_t sector_num,
23704dcafbb1SMarcelo Tosatti                                              int nb_sectors,
23714dcafbb1SMarcelo Tosatti                                              BlockDriverCompletionFunc *cb,
23724dcafbb1SMarcelo Tosatti                                              void *opaque)
23734dcafbb1SMarcelo Tosatti {
23747267c094SAnthony Liguori     BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData));
23754dcafbb1SMarcelo Tosatti 
23764dcafbb1SMarcelo Tosatti     blkdata->bs = bs;
23774dcafbb1SMarcelo Tosatti     blkdata->cb = cb;
23784dcafbb1SMarcelo Tosatti     blkdata->opaque = opaque;
23794dcafbb1SMarcelo Tosatti     blkdata->sector_num = sector_num;
23804dcafbb1SMarcelo Tosatti     blkdata->nb_sectors = nb_sectors;
23814dcafbb1SMarcelo Tosatti 
23824dcafbb1SMarcelo Tosatti     return blkdata;
23834dcafbb1SMarcelo Tosatti }
23844dcafbb1SMarcelo Tosatti 
2385f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2386f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
238783f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
23887674e7bfSbellard {
238983f64091Sbellard     BlockDriver *drv = bs->drv;
2390a36e69ddSths     BlockDriverAIOCB *ret;
23914dcafbb1SMarcelo Tosatti     BlockCompleteData *blk_cb_data;
239283f64091Sbellard 
2393bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2394bbf0a440SStefan Hajnoczi 
239519cb3738Sbellard     if (!drv)
2396ce1a14dcSpbrook         return NULL;
239783f64091Sbellard     if (bs->read_only)
2398ce1a14dcSpbrook         return NULL;
239971d0770cSaliguori     if (bdrv_check_request(bs, sector_num, nb_sectors))
240071d0770cSaliguori         return NULL;
240183f64091Sbellard 
2402c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
24034dcafbb1SMarcelo Tosatti         blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb,
24044dcafbb1SMarcelo Tosatti                                          opaque);
24054dcafbb1SMarcelo Tosatti         cb = &block_complete_cb;
24064dcafbb1SMarcelo Tosatti         opaque = blk_cb_data;
24077cd1e32aSlirans@il.ibm.com     }
24087cd1e32aSlirans@il.ibm.com 
2409f141eafeSaliguori     ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
2410f141eafeSaliguori                                cb, opaque);
2411a36e69ddSths 
2412a36e69ddSths     if (ret) {
2413294cc35fSKevin Wolf         if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
2414294cc35fSKevin Wolf             bs->wr_highest_sector = sector_num + nb_sectors - 1;
2415294cc35fSKevin Wolf         }
2416a36e69ddSths     }
2417a36e69ddSths 
2418a36e69ddSths     return ret;
241983f64091Sbellard }
242083f64091Sbellard 
242140b4f539SKevin Wolf 
242240b4f539SKevin Wolf typedef struct MultiwriteCB {
242340b4f539SKevin Wolf     int error;
242440b4f539SKevin Wolf     int num_requests;
242540b4f539SKevin Wolf     int num_callbacks;
242640b4f539SKevin Wolf     struct {
242740b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
242840b4f539SKevin Wolf         void *opaque;
242940b4f539SKevin Wolf         QEMUIOVector *free_qiov;
243040b4f539SKevin Wolf         void *free_buf;
243140b4f539SKevin Wolf     } callbacks[];
243240b4f539SKevin Wolf } MultiwriteCB;
243340b4f539SKevin Wolf 
243440b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
243540b4f539SKevin Wolf {
243640b4f539SKevin Wolf     int i;
243740b4f539SKevin Wolf 
243840b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
243940b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
24401e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
24411e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
24421e1ea48dSStefan Hajnoczi         }
24437267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2444f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
244540b4f539SKevin Wolf     }
244640b4f539SKevin Wolf }
244740b4f539SKevin Wolf 
244840b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
244940b4f539SKevin Wolf {
245040b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
245140b4f539SKevin Wolf 
24526d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
24536d519a5fSStefan Hajnoczi 
2454cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
245540b4f539SKevin Wolf         mcb->error = ret;
245640b4f539SKevin Wolf     }
245740b4f539SKevin Wolf 
245840b4f539SKevin Wolf     mcb->num_requests--;
245940b4f539SKevin Wolf     if (mcb->num_requests == 0) {
246040b4f539SKevin Wolf         multiwrite_user_cb(mcb);
24617267c094SAnthony Liguori         g_free(mcb);
246240b4f539SKevin Wolf     }
246340b4f539SKevin Wolf }
246440b4f539SKevin Wolf 
246540b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
246640b4f539SKevin Wolf {
246777be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
246877be4366SChristoph Hellwig 
246977be4366SChristoph Hellwig     /*
247077be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
247177be4366SChristoph Hellwig      * here as that could overflow the return value.
247277be4366SChristoph Hellwig      */
247377be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
247477be4366SChristoph Hellwig         return 1;
247577be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
247677be4366SChristoph Hellwig         return -1;
247777be4366SChristoph Hellwig     } else {
247877be4366SChristoph Hellwig         return 0;
247977be4366SChristoph Hellwig     }
248040b4f539SKevin Wolf }
248140b4f539SKevin Wolf 
248240b4f539SKevin Wolf /*
248340b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
248440b4f539SKevin Wolf  * requests that remain after merging.
248540b4f539SKevin Wolf  */
248640b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
248740b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
248840b4f539SKevin Wolf {
248940b4f539SKevin Wolf     int i, outidx;
249040b4f539SKevin Wolf 
249140b4f539SKevin Wolf     // Sort requests by start sector
249240b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
249340b4f539SKevin Wolf 
249440b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
249540b4f539SKevin Wolf     // filling up gaps with zero sectors.
249640b4f539SKevin Wolf     outidx = 0;
249740b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
249840b4f539SKevin Wolf         int merge = 0;
249940b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
250040b4f539SKevin Wolf 
250140b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
250240b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
250340b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
250440b4f539SKevin Wolf             merge = 1;
250540b4f539SKevin Wolf         }
250640b4f539SKevin Wolf 
250740b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
250840b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
250940b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
251040b4f539SKevin Wolf         // unused space in format like qcow2).
251140b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
251240b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
251340b4f539SKevin Wolf         }
251440b4f539SKevin Wolf 
2515e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2516e2a305fbSChristoph Hellwig             merge = 0;
2517e2a305fbSChristoph Hellwig         }
2518e2a305fbSChristoph Hellwig 
251940b4f539SKevin Wolf         if (merge) {
252040b4f539SKevin Wolf             size_t size;
25217267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
252240b4f539SKevin Wolf             qemu_iovec_init(qiov,
252340b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
252440b4f539SKevin Wolf 
252540b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
252640b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
252740b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
252840b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
252940b4f539SKevin Wolf 
253040b4f539SKevin Wolf             // We might need to add some zeros between the two requests
253140b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
253240b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
253340b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
253440b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
253540b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
253640b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
253740b4f539SKevin Wolf             }
253840b4f539SKevin Wolf 
253940b4f539SKevin Wolf             // Add the second request
254040b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
254140b4f539SKevin Wolf 
2542cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
254340b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
254440b4f539SKevin Wolf 
254540b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
254640b4f539SKevin Wolf         } else {
254740b4f539SKevin Wolf             outidx++;
254840b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
254940b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
255040b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
255140b4f539SKevin Wolf         }
255240b4f539SKevin Wolf     }
255340b4f539SKevin Wolf 
255440b4f539SKevin Wolf     return outidx + 1;
255540b4f539SKevin Wolf }
255640b4f539SKevin Wolf 
255740b4f539SKevin Wolf /*
255840b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
255940b4f539SKevin Wolf  *
256040b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
256140b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
256240b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
256340b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
256440b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
256540b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
256640b4f539SKevin Wolf  *
256740b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
256840b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
256940b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
257040b4f539SKevin Wolf  */
257140b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
257240b4f539SKevin Wolf {
257340b4f539SKevin Wolf     BlockDriverAIOCB *acb;
257440b4f539SKevin Wolf     MultiwriteCB *mcb;
257540b4f539SKevin Wolf     int i;
257640b4f539SKevin Wolf 
2577301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2578301db7c2SRyan Harper     if (bs->drv == NULL) {
2579301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2580301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2581301db7c2SRyan Harper         }
2582301db7c2SRyan Harper         return -1;
2583301db7c2SRyan Harper     }
2584301db7c2SRyan Harper 
258540b4f539SKevin Wolf     if (num_reqs == 0) {
258640b4f539SKevin Wolf         return 0;
258740b4f539SKevin Wolf     }
258840b4f539SKevin Wolf 
258940b4f539SKevin Wolf     // Create MultiwriteCB structure
25907267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
259140b4f539SKevin Wolf     mcb->num_requests = 0;
259240b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
259340b4f539SKevin Wolf 
259440b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
259540b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
259640b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
259740b4f539SKevin Wolf     }
259840b4f539SKevin Wolf 
259940b4f539SKevin Wolf     // Check for mergable requests
260040b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
260140b4f539SKevin Wolf 
26026d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
26036d519a5fSStefan Hajnoczi 
2604453f9a16SKevin Wolf     /*
2605453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2606453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2607453f9a16SKevin Wolf      * return failure for all requests anyway)
2608453f9a16SKevin Wolf      *
2609453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2610453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2611453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2612453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2613453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2614453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2615453f9a16SKevin Wolf      * incremented for each request that is submitted.
2616453f9a16SKevin Wolf      *
2617453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2618453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2619453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2620453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2621453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2622453f9a16SKevin Wolf      */
2623453f9a16SKevin Wolf     mcb->num_requests = 1;
2624453f9a16SKevin Wolf 
26256d519a5fSStefan Hajnoczi     // Run the aio requests
262640b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2627453f9a16SKevin Wolf         mcb->num_requests++;
262840b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
262940b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
263040b4f539SKevin Wolf 
263140b4f539SKevin Wolf         if (acb == NULL) {
263240b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
263340b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
263440b4f539SKevin Wolf             // complete and report the error in the callback.
2635453f9a16SKevin Wolf             if (i == 0) {
26366d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
263740b4f539SKevin Wolf                 goto fail;
263840b4f539SKevin Wolf             } else {
26396d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
26407eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
264140b4f539SKevin Wolf                 break;
264240b4f539SKevin Wolf             }
264340b4f539SKevin Wolf         }
264440b4f539SKevin Wolf     }
264540b4f539SKevin Wolf 
2646453f9a16SKevin Wolf     /* Complete the dummy request */
2647453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2648453f9a16SKevin Wolf 
264940b4f539SKevin Wolf     return 0;
265040b4f539SKevin Wolf 
265140b4f539SKevin Wolf fail:
2652453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2653453f9a16SKevin Wolf         reqs[i].error = -EIO;
2654453f9a16SKevin Wolf     }
26557267c094SAnthony Liguori     g_free(mcb);
265640b4f539SKevin Wolf     return -1;
265740b4f539SKevin Wolf }
265840b4f539SKevin Wolf 
2659b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2660b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2661b2e12bc6SChristoph Hellwig {
2662b2e12bc6SChristoph Hellwig     BlockDriver *drv = bs->drv;
2663b2e12bc6SChristoph Hellwig 
2664a13aac04SStefan Hajnoczi     trace_bdrv_aio_flush(bs, opaque);
2665a13aac04SStefan Hajnoczi 
2666016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
2667016f5cf6SAlexander Graf         return bdrv_aio_noop_em(bs, cb, opaque);
2668016f5cf6SAlexander Graf     }
2669016f5cf6SAlexander Graf 
2670b2e12bc6SChristoph Hellwig     if (!drv)
2671b2e12bc6SChristoph Hellwig         return NULL;
2672b2e12bc6SChristoph Hellwig     return drv->bdrv_aio_flush(bs, cb, opaque);
2673b2e12bc6SChristoph Hellwig }
2674b2e12bc6SChristoph Hellwig 
267583f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
267683f64091Sbellard {
26776bbff9a0Saliguori     acb->pool->cancel(acb);
267883f64091Sbellard }
267983f64091Sbellard 
268083f64091Sbellard 
268183f64091Sbellard /**************************************************************/
268283f64091Sbellard /* async block device emulation */
268383f64091Sbellard 
2684c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2685c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2686c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2687c16b5a2cSChristoph Hellwig     int ret;
2688c16b5a2cSChristoph Hellwig     /* vector translation state */
2689c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2690c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2691c16b5a2cSChristoph Hellwig     int is_write;
2692c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2693c16b5a2cSChristoph Hellwig 
2694c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2695c16b5a2cSChristoph Hellwig {
2696b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2697b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
26986a7ad299SDor Laor     qemu_bh_delete(acb->bh);
269936afc451SAvi Kivity     acb->bh = NULL;
2700c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2701c16b5a2cSChristoph Hellwig }
2702c16b5a2cSChristoph Hellwig 
2703c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2704c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2705c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2706c16b5a2cSChristoph Hellwig };
2707c16b5a2cSChristoph Hellwig 
270883f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2709beac80cdSbellard {
2710ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2711f141eafeSaliguori 
2712f141eafeSaliguori     if (!acb->is_write)
2713f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2714ceb42de8Saliguori     qemu_vfree(acb->bounce);
2715ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
27166a7ad299SDor Laor     qemu_bh_delete(acb->bh);
271736afc451SAvi Kivity     acb->bh = NULL;
2718ce1a14dcSpbrook     qemu_aio_release(acb);
2719beac80cdSbellard }
2720beac80cdSbellard 
2721f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2722f141eafeSaliguori                                             int64_t sector_num,
2723f141eafeSaliguori                                             QEMUIOVector *qiov,
2724f141eafeSaliguori                                             int nb_sectors,
2725f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2726f141eafeSaliguori                                             void *opaque,
2727f141eafeSaliguori                                             int is_write)
2728f141eafeSaliguori 
2729ea2384d3Sbellard {
2730ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
273183f64091Sbellard 
2732c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2733f141eafeSaliguori     acb->is_write = is_write;
2734f141eafeSaliguori     acb->qiov = qiov;
2735e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2736f141eafeSaliguori 
2737ce1a14dcSpbrook     if (!acb->bh)
2738ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2739f141eafeSaliguori 
2740f141eafeSaliguori     if (is_write) {
2741f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
2742f141eafeSaliguori         acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2743f141eafeSaliguori     } else {
2744f141eafeSaliguori         acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2745f141eafeSaliguori     }
2746f141eafeSaliguori 
2747ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2748f141eafeSaliguori 
2749ce1a14dcSpbrook     return &acb->common;
27507a6cba61Spbrook }
27517a6cba61Spbrook 
2752f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2753f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2754ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
275583f64091Sbellard {
2756f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
275783f64091Sbellard }
275883f64091Sbellard 
2759f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2760f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2761f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2762f141eafeSaliguori {
2763f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2764f141eafeSaliguori }
2765f141eafeSaliguori 
276668485420SKevin Wolf 
276768485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
276868485420SKevin Wolf     BlockDriverAIOCB common;
276968485420SKevin Wolf     BlockRequest req;
277068485420SKevin Wolf     bool is_write;
277168485420SKevin Wolf     QEMUBH* bh;
277268485420SKevin Wolf } BlockDriverAIOCBCoroutine;
277368485420SKevin Wolf 
277468485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
277568485420SKevin Wolf {
277668485420SKevin Wolf     qemu_aio_flush();
277768485420SKevin Wolf }
277868485420SKevin Wolf 
277968485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
278068485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
278168485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
278268485420SKevin Wolf };
278368485420SKevin Wolf 
278468485420SKevin Wolf static void bdrv_co_rw_bh(void *opaque)
278568485420SKevin Wolf {
278668485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
278768485420SKevin Wolf 
278868485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
278968485420SKevin Wolf     qemu_bh_delete(acb->bh);
279068485420SKevin Wolf     qemu_aio_release(acb);
279168485420SKevin Wolf }
279268485420SKevin Wolf 
279368485420SKevin Wolf static void coroutine_fn bdrv_co_rw(void *opaque)
279468485420SKevin Wolf {
279568485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
279668485420SKevin Wolf     BlockDriverState *bs = acb->common.bs;
279768485420SKevin Wolf 
279868485420SKevin Wolf     if (!acb->is_write) {
279968485420SKevin Wolf         acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector,
280068485420SKevin Wolf             acb->req.nb_sectors, acb->req.qiov);
280168485420SKevin Wolf     } else {
280268485420SKevin Wolf         acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector,
280368485420SKevin Wolf             acb->req.nb_sectors, acb->req.qiov);
280468485420SKevin Wolf     }
280568485420SKevin Wolf 
280668485420SKevin Wolf     acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
280768485420SKevin Wolf     qemu_bh_schedule(acb->bh);
280868485420SKevin Wolf }
280968485420SKevin Wolf 
281068485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
281168485420SKevin Wolf                                                int64_t sector_num,
281268485420SKevin Wolf                                                QEMUIOVector *qiov,
281368485420SKevin Wolf                                                int nb_sectors,
281468485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
281568485420SKevin Wolf                                                void *opaque,
281668485420SKevin Wolf                                                bool is_write)
281768485420SKevin Wolf {
281868485420SKevin Wolf     Coroutine *co;
281968485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
282068485420SKevin Wolf 
282168485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
282268485420SKevin Wolf     acb->req.sector = sector_num;
282368485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
282468485420SKevin Wolf     acb->req.qiov = qiov;
282568485420SKevin Wolf     acb->is_write = is_write;
282668485420SKevin Wolf 
282768485420SKevin Wolf     co = qemu_coroutine_create(bdrv_co_rw);
282868485420SKevin Wolf     qemu_coroutine_enter(co, acb);
282968485420SKevin Wolf 
283068485420SKevin Wolf     return &acb->common;
283168485420SKevin Wolf }
283268485420SKevin Wolf 
283368485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
283468485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
283568485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque)
283668485420SKevin Wolf {
283768485420SKevin Wolf     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
283868485420SKevin Wolf                                  false);
283968485420SKevin Wolf }
284068485420SKevin Wolf 
284168485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
284268485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
284368485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque)
284468485420SKevin Wolf {
284568485420SKevin Wolf     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
284668485420SKevin Wolf                                  true);
284768485420SKevin Wolf }
284868485420SKevin Wolf 
2849b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
2850b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2851b2e12bc6SChristoph Hellwig {
2852b2e12bc6SChristoph Hellwig     BlockDriverAIOCBSync *acb;
2853b2e12bc6SChristoph Hellwig 
2854b2e12bc6SChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2855b2e12bc6SChristoph Hellwig     acb->is_write = 1; /* don't bounce in the completion hadler */
2856b2e12bc6SChristoph Hellwig     acb->qiov = NULL;
2857b2e12bc6SChristoph Hellwig     acb->bounce = NULL;
2858b2e12bc6SChristoph Hellwig     acb->ret = 0;
2859b2e12bc6SChristoph Hellwig 
2860b2e12bc6SChristoph Hellwig     if (!acb->bh)
2861b2e12bc6SChristoph Hellwig         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2862b2e12bc6SChristoph Hellwig 
2863b2e12bc6SChristoph Hellwig     bdrv_flush(bs);
2864b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2865b2e12bc6SChristoph Hellwig     return &acb->common;
2866b2e12bc6SChristoph Hellwig }
2867b2e12bc6SChristoph Hellwig 
2868016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
2869016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2870016f5cf6SAlexander Graf {
2871016f5cf6SAlexander Graf     BlockDriverAIOCBSync *acb;
2872016f5cf6SAlexander Graf 
2873016f5cf6SAlexander Graf     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2874016f5cf6SAlexander Graf     acb->is_write = 1; /* don't bounce in the completion handler */
2875016f5cf6SAlexander Graf     acb->qiov = NULL;
2876016f5cf6SAlexander Graf     acb->bounce = NULL;
2877016f5cf6SAlexander Graf     acb->ret = 0;
2878016f5cf6SAlexander Graf 
2879016f5cf6SAlexander Graf     if (!acb->bh) {
2880016f5cf6SAlexander Graf         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2881016f5cf6SAlexander Graf     }
2882016f5cf6SAlexander Graf 
2883016f5cf6SAlexander Graf     qemu_bh_schedule(acb->bh);
2884016f5cf6SAlexander Graf     return &acb->common;
2885016f5cf6SAlexander Graf }
2886016f5cf6SAlexander Graf 
288783f64091Sbellard /**************************************************************/
288883f64091Sbellard /* sync block device emulation */
288983f64091Sbellard 
289083f64091Sbellard static void bdrv_rw_em_cb(void *opaque, int ret)
289183f64091Sbellard {
289283f64091Sbellard     *(int *)opaque = ret;
289383f64091Sbellard }
289483f64091Sbellard 
289583f64091Sbellard #define NOT_DONE 0x7fffffff
289683f64091Sbellard 
289783f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
289883f64091Sbellard                         uint8_t *buf, int nb_sectors)
289983f64091Sbellard {
2900ce1a14dcSpbrook     int async_ret;
2901ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2902f141eafeSaliguori     struct iovec iov;
2903f141eafeSaliguori     QEMUIOVector qiov;
290483f64091Sbellard 
290583f64091Sbellard     async_ret = NOT_DONE;
29063f4cb3d3Sblueswir1     iov.iov_base = (void *)buf;
2907eb5a3165SJes Sorensen     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
2908f141eafeSaliguori     qemu_iovec_init_external(&qiov, &iov, 1);
2909f141eafeSaliguori     acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
291083f64091Sbellard         bdrv_rw_em_cb, &async_ret);
291165d6b3d8SKevin Wolf     if (acb == NULL) {
291265d6b3d8SKevin Wolf         async_ret = -1;
291365d6b3d8SKevin Wolf         goto fail;
291465d6b3d8SKevin Wolf     }
2915baf35cb9Saliguori 
291683f64091Sbellard     while (async_ret == NOT_DONE) {
291783f64091Sbellard         qemu_aio_wait();
291883f64091Sbellard     }
2919baf35cb9Saliguori 
292065d6b3d8SKevin Wolf 
292165d6b3d8SKevin Wolf fail:
292283f64091Sbellard     return async_ret;
292383f64091Sbellard }
292483f64091Sbellard 
292583f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
292683f64091Sbellard                          const uint8_t *buf, int nb_sectors)
292783f64091Sbellard {
2928ce1a14dcSpbrook     int async_ret;
2929ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2930f141eafeSaliguori     struct iovec iov;
2931f141eafeSaliguori     QEMUIOVector qiov;
293283f64091Sbellard 
293383f64091Sbellard     async_ret = NOT_DONE;
2934f141eafeSaliguori     iov.iov_base = (void *)buf;
2935eb5a3165SJes Sorensen     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
2936f141eafeSaliguori     qemu_iovec_init_external(&qiov, &iov, 1);
2937f141eafeSaliguori     acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
293883f64091Sbellard         bdrv_rw_em_cb, &async_ret);
293965d6b3d8SKevin Wolf     if (acb == NULL) {
294065d6b3d8SKevin Wolf         async_ret = -1;
294165d6b3d8SKevin Wolf         goto fail;
294265d6b3d8SKevin Wolf     }
294383f64091Sbellard     while (async_ret == NOT_DONE) {
294483f64091Sbellard         qemu_aio_wait();
294583f64091Sbellard     }
294665d6b3d8SKevin Wolf 
294765d6b3d8SKevin Wolf fail:
294883f64091Sbellard     return async_ret;
294983f64091Sbellard }
2950ea2384d3Sbellard 
2951ea2384d3Sbellard void bdrv_init(void)
2952ea2384d3Sbellard {
29535efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2954ea2384d3Sbellard }
2955ce1a14dcSpbrook 
2956eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2957eb852011SMarkus Armbruster {
2958eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2959eb852011SMarkus Armbruster     bdrv_init();
2960eb852011SMarkus Armbruster }
2961eb852011SMarkus Armbruster 
2962c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
29636bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
29646bbff9a0Saliguori {
2965ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2966ce1a14dcSpbrook 
29676bbff9a0Saliguori     if (pool->free_aiocb) {
29686bbff9a0Saliguori         acb = pool->free_aiocb;
29696bbff9a0Saliguori         pool->free_aiocb = acb->next;
2970ce1a14dcSpbrook     } else {
29717267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
29726bbff9a0Saliguori         acb->pool = pool;
2973ce1a14dcSpbrook     }
2974ce1a14dcSpbrook     acb->bs = bs;
2975ce1a14dcSpbrook     acb->cb = cb;
2976ce1a14dcSpbrook     acb->opaque = opaque;
2977ce1a14dcSpbrook     return acb;
2978ce1a14dcSpbrook }
2979ce1a14dcSpbrook 
2980ce1a14dcSpbrook void qemu_aio_release(void *p)
2981ce1a14dcSpbrook {
29826bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
29836bbff9a0Saliguori     AIOPool *pool = acb->pool;
29846bbff9a0Saliguori     acb->next = pool->free_aiocb;
29856bbff9a0Saliguori     pool->free_aiocb = acb;
2986ce1a14dcSpbrook }
298719cb3738Sbellard 
298819cb3738Sbellard /**************************************************************/
2989f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2990f9f05dc5SKevin Wolf 
2991f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2992f9f05dc5SKevin Wolf     Coroutine *coroutine;
2993f9f05dc5SKevin Wolf     int ret;
2994f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2995f9f05dc5SKevin Wolf 
2996f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2997f9f05dc5SKevin Wolf {
2998f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2999f9f05dc5SKevin Wolf 
3000f9f05dc5SKevin Wolf     co->ret = ret;
3001f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
3002f9f05dc5SKevin Wolf }
3003f9f05dc5SKevin Wolf 
3004f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
3005f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
3006f9f05dc5SKevin Wolf                                       bool is_write)
3007f9f05dc5SKevin Wolf {
3008f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
3009f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
3010f9f05dc5SKevin Wolf     };
3011f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
3012f9f05dc5SKevin Wolf 
3013f9f05dc5SKevin Wolf     if (is_write) {
3014*a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
3015f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
3016f9f05dc5SKevin Wolf     } else {
3017*a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
3018f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
3019f9f05dc5SKevin Wolf     }
3020f9f05dc5SKevin Wolf 
302159370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
3022f9f05dc5SKevin Wolf     if (!acb) {
3023f9f05dc5SKevin Wolf         return -EIO;
3024f9f05dc5SKevin Wolf     }
3025f9f05dc5SKevin Wolf     qemu_coroutine_yield();
3026f9f05dc5SKevin Wolf 
3027f9f05dc5SKevin Wolf     return co.ret;
3028f9f05dc5SKevin Wolf }
3029f9f05dc5SKevin Wolf 
3030f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
3031f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
3032f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
3033f9f05dc5SKevin Wolf {
3034f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
3035f9f05dc5SKevin Wolf }
3036f9f05dc5SKevin Wolf 
3037f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
3038f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
3039f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
3040f9f05dc5SKevin Wolf {
3041f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
3042f9f05dc5SKevin Wolf }
3043f9f05dc5SKevin Wolf 
3044e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
3045e7a8a783SKevin Wolf {
3046e7a8a783SKevin Wolf     CoroutineIOCompletion co = {
3047e7a8a783SKevin Wolf         .coroutine = qemu_coroutine_self(),
3048e7a8a783SKevin Wolf     };
3049e7a8a783SKevin Wolf     BlockDriverAIOCB *acb;
3050e7a8a783SKevin Wolf 
3051e7a8a783SKevin Wolf     acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
3052e7a8a783SKevin Wolf     if (!acb) {
3053e7a8a783SKevin Wolf         return -EIO;
3054e7a8a783SKevin Wolf     }
3055e7a8a783SKevin Wolf     qemu_coroutine_yield();
3056e7a8a783SKevin Wolf     return co.ret;
3057e7a8a783SKevin Wolf }
3058e7a8a783SKevin Wolf 
3059f9f05dc5SKevin Wolf /**************************************************************/
306019cb3738Sbellard /* removable device support */
306119cb3738Sbellard 
306219cb3738Sbellard /**
306319cb3738Sbellard  * Return TRUE if the media is present
306419cb3738Sbellard  */
306519cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
306619cb3738Sbellard {
306719cb3738Sbellard     BlockDriver *drv = bs->drv;
3068a1aff5bfSMarkus Armbruster 
306919cb3738Sbellard     if (!drv)
307019cb3738Sbellard         return 0;
307119cb3738Sbellard     if (!drv->bdrv_is_inserted)
3072a1aff5bfSMarkus Armbruster         return 1;
3073a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
307419cb3738Sbellard }
307519cb3738Sbellard 
307619cb3738Sbellard /**
30778e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
30788e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
307919cb3738Sbellard  */
308019cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
308119cb3738Sbellard {
308219cb3738Sbellard     BlockDriver *drv = bs->drv;
308319cb3738Sbellard 
30848e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
30858e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
30868e49ca46SMarkus Armbruster     }
30878e49ca46SMarkus Armbruster     return -ENOTSUP;
308819cb3738Sbellard }
308919cb3738Sbellard 
309019cb3738Sbellard /**
309119cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
309219cb3738Sbellard  */
3093fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
309419cb3738Sbellard {
309519cb3738Sbellard     BlockDriver *drv = bs->drv;
309619cb3738Sbellard 
3097822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
3098822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
309919cb3738Sbellard     }
310019cb3738Sbellard }
310119cb3738Sbellard 
310219cb3738Sbellard /**
310319cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
310419cb3738Sbellard  * to eject it manually).
310519cb3738Sbellard  */
3106025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
310719cb3738Sbellard {
310819cb3738Sbellard     BlockDriver *drv = bs->drv;
310919cb3738Sbellard 
3110025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
3111b8c6d095SStefan Hajnoczi 
3112025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
3113025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
311419cb3738Sbellard     }
311519cb3738Sbellard }
3116985a03b0Sths 
3117985a03b0Sths /* needed for generic scsi interface */
3118985a03b0Sths 
3119985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3120985a03b0Sths {
3121985a03b0Sths     BlockDriver *drv = bs->drv;
3122985a03b0Sths 
3123985a03b0Sths     if (drv && drv->bdrv_ioctl)
3124985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3125985a03b0Sths     return -ENOTSUP;
3126985a03b0Sths }
31277d780669Saliguori 
3128221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3129221f715dSaliguori         unsigned long int req, void *buf,
31307d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
31317d780669Saliguori {
3132221f715dSaliguori     BlockDriver *drv = bs->drv;
31337d780669Saliguori 
3134221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3135221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3136221f715dSaliguori     return NULL;
31377d780669Saliguori }
3138e268ca52Saliguori 
31397b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
31407b6f9300SMarkus Armbruster {
31417b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
31427b6f9300SMarkus Armbruster }
31437cd1e32aSlirans@il.ibm.com 
3144e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3145e268ca52Saliguori {
3146e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3147e268ca52Saliguori }
31487cd1e32aSlirans@il.ibm.com 
31497cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
31507cd1e32aSlirans@il.ibm.com {
31517cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3152a55eb92cSJan Kiszka 
3153aaa0eb75SLiran Schour     bs->dirty_count = 0;
31547cd1e32aSlirans@il.ibm.com     if (enable) {
3155c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3156c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3157c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3158c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
31597cd1e32aSlirans@il.ibm.com 
31607267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
31617cd1e32aSlirans@il.ibm.com         }
31627cd1e32aSlirans@il.ibm.com     } else {
3163c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
31647267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3165c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
31667cd1e32aSlirans@il.ibm.com         }
31677cd1e32aSlirans@il.ibm.com     }
31687cd1e32aSlirans@il.ibm.com }
31697cd1e32aSlirans@il.ibm.com 
31707cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
31717cd1e32aSlirans@il.ibm.com {
31726ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
31737cd1e32aSlirans@il.ibm.com 
3174c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3175c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
31766d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
31776d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
31787cd1e32aSlirans@il.ibm.com     } else {
31797cd1e32aSlirans@il.ibm.com         return 0;
31807cd1e32aSlirans@il.ibm.com     }
31817cd1e32aSlirans@il.ibm.com }
31827cd1e32aSlirans@il.ibm.com 
31837cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
31847cd1e32aSlirans@il.ibm.com                       int nr_sectors)
31857cd1e32aSlirans@il.ibm.com {
31867cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
31877cd1e32aSlirans@il.ibm.com }
3188aaa0eb75SLiran Schour 
3189aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3190aaa0eb75SLiran Schour {
3191aaa0eb75SLiran Schour     return bs->dirty_count;
3192aaa0eb75SLiran Schour }
3193f88e1a42SJes Sorensen 
3194db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3195db593f25SMarcelo Tosatti {
3196db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3197db593f25SMarcelo Tosatti     bs->in_use = in_use;
3198db593f25SMarcelo Tosatti }
3199db593f25SMarcelo Tosatti 
3200db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3201db593f25SMarcelo Tosatti {
3202db593f25SMarcelo Tosatti     return bs->in_use;
3203db593f25SMarcelo Tosatti }
3204db593f25SMarcelo Tosatti 
320528a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
320628a7282aSLuiz Capitulino {
320728a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_OK;
320828a7282aSLuiz Capitulino }
320928a7282aSLuiz Capitulino 
321028a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
321128a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
321228a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
321328a7282aSLuiz Capitulino {
321428a7282aSLuiz Capitulino     return (bs->iostatus != BDRV_IOS_INVAL &&
321528a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
321628a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
321728a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
321828a7282aSLuiz Capitulino }
321928a7282aSLuiz Capitulino 
322028a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
322128a7282aSLuiz Capitulino {
322228a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_INVAL;
322328a7282aSLuiz Capitulino }
322428a7282aSLuiz Capitulino 
322528a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
322628a7282aSLuiz Capitulino {
322728a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
322828a7282aSLuiz Capitulino         bs->iostatus = BDRV_IOS_OK;
322928a7282aSLuiz Capitulino     }
323028a7282aSLuiz Capitulino }
323128a7282aSLuiz Capitulino 
323228a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
323328a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
323428a7282aSLuiz Capitulino    possible to implement this without device models being involved */
323528a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
323628a7282aSLuiz Capitulino {
323728a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
323828a7282aSLuiz Capitulino         assert(error >= 0);
323928a7282aSLuiz Capitulino         bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
324028a7282aSLuiz Capitulino     }
324128a7282aSLuiz Capitulino }
324228a7282aSLuiz Capitulino 
3243a597e79cSChristoph Hellwig void
3244a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3245a597e79cSChristoph Hellwig         enum BlockAcctType type)
3246a597e79cSChristoph Hellwig {
3247a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3248a597e79cSChristoph Hellwig 
3249a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3250c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3251a597e79cSChristoph Hellwig     cookie->type = type;
3252a597e79cSChristoph Hellwig }
3253a597e79cSChristoph Hellwig 
3254a597e79cSChristoph Hellwig void
3255a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3256a597e79cSChristoph Hellwig {
3257a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3258a597e79cSChristoph Hellwig 
3259a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3260a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3261c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3262a597e79cSChristoph Hellwig }
3263a597e79cSChristoph Hellwig 
3264f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3265f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3266f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3267f88e1a42SJes Sorensen {
3268f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3269d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3270f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3271f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
327296df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3273f88e1a42SJes Sorensen     int ret = 0;
3274f88e1a42SJes Sorensen 
3275f88e1a42SJes Sorensen     /* Find driver and parse its options */
3276f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3277f88e1a42SJes Sorensen     if (!drv) {
3278f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
32794f70f249SJes Sorensen         ret = -EINVAL;
3280f88e1a42SJes Sorensen         goto out;
3281f88e1a42SJes Sorensen     }
3282f88e1a42SJes Sorensen 
3283f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3284f88e1a42SJes Sorensen     if (!proto_drv) {
3285f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
32864f70f249SJes Sorensen         ret = -EINVAL;
3287f88e1a42SJes Sorensen         goto out;
3288f88e1a42SJes Sorensen     }
3289f88e1a42SJes Sorensen 
3290f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3291f88e1a42SJes Sorensen                                               drv->create_options);
3292f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3293f88e1a42SJes Sorensen                                               proto_drv->create_options);
3294f88e1a42SJes Sorensen 
3295f88e1a42SJes Sorensen     /* Create parameter list with default values */
3296f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3297f88e1a42SJes Sorensen 
3298f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3299f88e1a42SJes Sorensen 
3300f88e1a42SJes Sorensen     /* Parse -o options */
3301f88e1a42SJes Sorensen     if (options) {
3302f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3303f88e1a42SJes Sorensen         if (param == NULL) {
3304f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
33054f70f249SJes Sorensen             ret = -EINVAL;
3306f88e1a42SJes Sorensen             goto out;
3307f88e1a42SJes Sorensen         }
3308f88e1a42SJes Sorensen     }
3309f88e1a42SJes Sorensen 
3310f88e1a42SJes Sorensen     if (base_filename) {
3311f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3312f88e1a42SJes Sorensen                                  base_filename)) {
3313f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3314f88e1a42SJes Sorensen                          fmt);
33154f70f249SJes Sorensen             ret = -EINVAL;
3316f88e1a42SJes Sorensen             goto out;
3317f88e1a42SJes Sorensen         }
3318f88e1a42SJes Sorensen     }
3319f88e1a42SJes Sorensen 
3320f88e1a42SJes Sorensen     if (base_fmt) {
3321f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3322f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3323f88e1a42SJes Sorensen                          "format '%s'", fmt);
33244f70f249SJes Sorensen             ret = -EINVAL;
3325f88e1a42SJes Sorensen             goto out;
3326f88e1a42SJes Sorensen         }
3327f88e1a42SJes Sorensen     }
3328f88e1a42SJes Sorensen 
3329792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3330792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3331792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3332792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3333792da93aSJes Sorensen                          "same filename as the backing file");
33344f70f249SJes Sorensen             ret = -EINVAL;
3335792da93aSJes Sorensen             goto out;
3336792da93aSJes Sorensen         }
3337792da93aSJes Sorensen     }
3338792da93aSJes Sorensen 
3339f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3340f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
334196df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
334296df67d1SStefan Hajnoczi         if (!backing_drv) {
3343f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3344f88e1a42SJes Sorensen                          backing_fmt->value.s);
33454f70f249SJes Sorensen             ret = -EINVAL;
3346f88e1a42SJes Sorensen             goto out;
3347f88e1a42SJes Sorensen         }
3348f88e1a42SJes Sorensen     }
3349f88e1a42SJes Sorensen 
3350f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3351f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3352d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3353d220894eSKevin Wolf     if (size && size->value.n == -1) {
3354f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3355f88e1a42SJes Sorensen             uint64_t size;
3356f88e1a42SJes Sorensen             char buf[32];
3357f88e1a42SJes Sorensen 
3358f88e1a42SJes Sorensen             bs = bdrv_new("");
3359f88e1a42SJes Sorensen 
336096df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3361f88e1a42SJes Sorensen             if (ret < 0) {
336296df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3363f88e1a42SJes Sorensen                 goto out;
3364f88e1a42SJes Sorensen             }
3365f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3366f88e1a42SJes Sorensen             size *= 512;
3367f88e1a42SJes Sorensen 
3368f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3369f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3370f88e1a42SJes Sorensen         } else {
3371f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
33724f70f249SJes Sorensen             ret = -EINVAL;
3373f88e1a42SJes Sorensen             goto out;
3374f88e1a42SJes Sorensen         }
3375f88e1a42SJes Sorensen     }
3376f88e1a42SJes Sorensen 
3377f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3378f88e1a42SJes Sorensen     print_option_parameters(param);
3379f88e1a42SJes Sorensen     puts("");
3380f88e1a42SJes Sorensen 
3381f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3382f88e1a42SJes Sorensen 
3383f88e1a42SJes Sorensen     if (ret < 0) {
3384f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3385f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3386f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3387f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3388f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3389f88e1a42SJes Sorensen                          fmt);
3390f88e1a42SJes Sorensen         } else {
3391f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3392f88e1a42SJes Sorensen                          strerror(-ret));
3393f88e1a42SJes Sorensen         }
3394f88e1a42SJes Sorensen     }
3395f88e1a42SJes Sorensen 
3396f88e1a42SJes Sorensen out:
3397f88e1a42SJes Sorensen     free_option_parameters(create_options);
3398f88e1a42SJes Sorensen     free_option_parameters(param);
3399f88e1a42SJes Sorensen 
3400f88e1a42SJes Sorensen     if (bs) {
3401f88e1a42SJes Sorensen         bdrv_delete(bs);
3402f88e1a42SJes Sorensen     }
34034f70f249SJes Sorensen 
34044f70f249SJes Sorensen     return ret;
3405f88e1a42SJes Sorensen }
3406