xref: /openbmc/qemu/block.c (revision f8c35c1d59c9fecf79f6d5a02cd09f472a6f411d)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
243990d09aSblueswir1 #include "config-host.h"
25faf07963Spbrook #include "qemu-common.h"
266d519a5fSStefan Hajnoczi #include "trace.h"
27376253ecSaliguori #include "monitor.h"
28ea2384d3Sbellard #include "block_int.h"
295efa9d5aSAnthony Liguori #include "module.h"
30d15e5465SLuiz Capitulino #include "qemu-objects.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32fc01f7e7Sbellard 
3371e72a19SJuan Quintela #ifdef CONFIG_BSD
347674e7bfSbellard #include <sys/types.h>
357674e7bfSbellard #include <sys/stat.h>
367674e7bfSbellard #include <sys/ioctl.h>
3772cf2d4fSBlue Swirl #include <sys/queue.h>
38c5e97233Sblueswir1 #ifndef __DragonFly__
397674e7bfSbellard #include <sys/disk.h>
407674e7bfSbellard #endif
41c5e97233Sblueswir1 #endif
427674e7bfSbellard 
4349dc768dSaliguori #ifdef _WIN32
4449dc768dSaliguori #include <windows.h>
4549dc768dSaliguori #endif
4649dc768dSaliguori 
471c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
481c9805a3SStefan Hajnoczi 
497d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
50f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
51f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
52c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
53f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
54f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
55ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
56b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
57b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque);
58016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
59016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque);
60f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
61f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
62f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
63f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
64f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
65f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
66e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
67c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
68c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
691c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
701c9805a3SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
71b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
72b2a61371SStefan Hajnoczi                                                int64_t sector_num,
73b2a61371SStefan Hajnoczi                                                QEMUIOVector *qiov,
74b2a61371SStefan Hajnoczi                                                int nb_sectors,
75b2a61371SStefan Hajnoczi                                                BlockDriverCompletionFunc *cb,
76b2a61371SStefan Hajnoczi                                                void *opaque,
778c5873d6SStefan Hajnoczi                                                bool is_write);
78b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque);
79ec530c81Sbellard 
801b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
811b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
827ee930d0Sblueswir1 
838a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
848a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
85ea2384d3Sbellard 
86f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
87f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
88f9092b10SMarkus Armbruster 
89eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
90eb852011SMarkus Armbruster static int use_bdrv_whitelist;
91eb852011SMarkus Armbruster 
929e0b22f4SStefan Hajnoczi #ifdef _WIN32
939e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
949e0b22f4SStefan Hajnoczi {
959e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
969e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
979e0b22f4SStefan Hajnoczi             filename[1] == ':');
989e0b22f4SStefan Hajnoczi }
999e0b22f4SStefan Hajnoczi 
1009e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
1019e0b22f4SStefan Hajnoczi {
1029e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
1039e0b22f4SStefan Hajnoczi         filename[2] == '\0')
1049e0b22f4SStefan Hajnoczi         return 1;
1059e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1069e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1079e0b22f4SStefan Hajnoczi         return 1;
1089e0b22f4SStefan Hajnoczi     return 0;
1099e0b22f4SStefan Hajnoczi }
1109e0b22f4SStefan Hajnoczi #endif
1119e0b22f4SStefan Hajnoczi 
1129e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1139e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1149e0b22f4SStefan Hajnoczi {
1159e0b22f4SStefan Hajnoczi #ifdef _WIN32
1169e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1179e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1189e0b22f4SStefan Hajnoczi         return 0;
1199e0b22f4SStefan Hajnoczi     }
1209e0b22f4SStefan Hajnoczi #endif
1219e0b22f4SStefan Hajnoczi 
1229e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1239e0b22f4SStefan Hajnoczi }
1249e0b22f4SStefan Hajnoczi 
12583f64091Sbellard int path_is_absolute(const char *path)
12683f64091Sbellard {
12783f64091Sbellard     const char *p;
12821664424Sbellard #ifdef _WIN32
12921664424Sbellard     /* specific case for names like: "\\.\d:" */
13021664424Sbellard     if (*path == '/' || *path == '\\')
13121664424Sbellard         return 1;
13221664424Sbellard #endif
13383f64091Sbellard     p = strchr(path, ':');
13483f64091Sbellard     if (p)
13583f64091Sbellard         p++;
13683f64091Sbellard     else
13783f64091Sbellard         p = path;
1383b9f94e1Sbellard #ifdef _WIN32
1393b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1403b9f94e1Sbellard #else
1413b9f94e1Sbellard     return (*p == '/');
1423b9f94e1Sbellard #endif
14383f64091Sbellard }
14483f64091Sbellard 
14583f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
14683f64091Sbellard    path to it by considering it is relative to base_path. URL are
14783f64091Sbellard    supported. */
14883f64091Sbellard void path_combine(char *dest, int dest_size,
14983f64091Sbellard                   const char *base_path,
15083f64091Sbellard                   const char *filename)
15183f64091Sbellard {
15283f64091Sbellard     const char *p, *p1;
15383f64091Sbellard     int len;
15483f64091Sbellard 
15583f64091Sbellard     if (dest_size <= 0)
15683f64091Sbellard         return;
15783f64091Sbellard     if (path_is_absolute(filename)) {
15883f64091Sbellard         pstrcpy(dest, dest_size, filename);
15983f64091Sbellard     } else {
16083f64091Sbellard         p = strchr(base_path, ':');
16183f64091Sbellard         if (p)
16283f64091Sbellard             p++;
16383f64091Sbellard         else
16483f64091Sbellard             p = base_path;
1653b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1663b9f94e1Sbellard #ifdef _WIN32
1673b9f94e1Sbellard         {
1683b9f94e1Sbellard             const char *p2;
1693b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1703b9f94e1Sbellard             if (!p1 || p2 > p1)
1713b9f94e1Sbellard                 p1 = p2;
1723b9f94e1Sbellard         }
1733b9f94e1Sbellard #endif
17483f64091Sbellard         if (p1)
17583f64091Sbellard             p1++;
17683f64091Sbellard         else
17783f64091Sbellard             p1 = base_path;
17883f64091Sbellard         if (p1 > p)
17983f64091Sbellard             p = p1;
18083f64091Sbellard         len = p - base_path;
18183f64091Sbellard         if (len > dest_size - 1)
18283f64091Sbellard             len = dest_size - 1;
18383f64091Sbellard         memcpy(dest, base_path, len);
18483f64091Sbellard         dest[len] = '\0';
18583f64091Sbellard         pstrcat(dest, dest_size, filename);
18683f64091Sbellard     }
18783f64091Sbellard }
18883f64091Sbellard 
1895efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
190ea2384d3Sbellard {
1918c5873d6SStefan Hajnoczi     /* Block drivers without coroutine functions need emulation */
1928c5873d6SStefan Hajnoczi     if (!bdrv->bdrv_co_readv) {
193f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
194f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
195f9f05dc5SKevin Wolf 
196*f8c35c1dSStefan Hajnoczi         /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
197*f8c35c1dSStefan Hajnoczi          * the block driver lacks aio we need to emulate that too.
198*f8c35c1dSStefan Hajnoczi          */
199f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
20083f64091Sbellard             /* add AIO emulation layer */
201f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
202f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
20383f64091Sbellard         }
204f9f05dc5SKevin Wolf     }
205b2e12bc6SChristoph Hellwig 
206b2e12bc6SChristoph Hellwig     if (!bdrv->bdrv_aio_flush)
207b2e12bc6SChristoph Hellwig         bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
208b2e12bc6SChristoph Hellwig 
2098a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
210ea2384d3Sbellard }
211b338082bSbellard 
212b338082bSbellard /* create a new block device (by default it is empty) */
213b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
214fc01f7e7Sbellard {
2151b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
216b338082bSbellard 
2177267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
218b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
219ea2384d3Sbellard     if (device_name[0] != '\0') {
2201b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
221ea2384d3Sbellard     }
22228a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
223b338082bSbellard     return bs;
224b338082bSbellard }
225b338082bSbellard 
226ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
227ea2384d3Sbellard {
228ea2384d3Sbellard     BlockDriver *drv1;
2298a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2308a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
231ea2384d3Sbellard             return drv1;
232ea2384d3Sbellard         }
2338a22f02aSStefan Hajnoczi     }
234ea2384d3Sbellard     return NULL;
235ea2384d3Sbellard }
236ea2384d3Sbellard 
237eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
238eb852011SMarkus Armbruster {
239eb852011SMarkus Armbruster     static const char *whitelist[] = {
240eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
241eb852011SMarkus Armbruster     };
242eb852011SMarkus Armbruster     const char **p;
243eb852011SMarkus Armbruster 
244eb852011SMarkus Armbruster     if (!whitelist[0])
245eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
246eb852011SMarkus Armbruster 
247eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
248eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
249eb852011SMarkus Armbruster             return 1;
250eb852011SMarkus Armbruster         }
251eb852011SMarkus Armbruster     }
252eb852011SMarkus Armbruster     return 0;
253eb852011SMarkus Armbruster }
254eb852011SMarkus Armbruster 
255eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
256eb852011SMarkus Armbruster {
257eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
258eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
259eb852011SMarkus Armbruster }
260eb852011SMarkus Armbruster 
2610e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2620e7e1989SKevin Wolf     QEMUOptionParameter *options)
263ea2384d3Sbellard {
264ea2384d3Sbellard     if (!drv->bdrv_create)
265ea2384d3Sbellard         return -ENOTSUP;
2660e7e1989SKevin Wolf 
2670e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
268ea2384d3Sbellard }
269ea2384d3Sbellard 
27084a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
27184a12e66SChristoph Hellwig {
27284a12e66SChristoph Hellwig     BlockDriver *drv;
27384a12e66SChristoph Hellwig 
274b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
27584a12e66SChristoph Hellwig     if (drv == NULL) {
27616905d71SStefan Hajnoczi         return -ENOENT;
27784a12e66SChristoph Hellwig     }
27884a12e66SChristoph Hellwig 
27984a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
28084a12e66SChristoph Hellwig }
28184a12e66SChristoph Hellwig 
282d5249393Sbellard #ifdef _WIN32
28395389c86Sbellard void get_tmp_filename(char *filename, int size)
284d5249393Sbellard {
2853b9f94e1Sbellard     char temp_dir[MAX_PATH];
2863b9f94e1Sbellard 
2873b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
2883b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
289d5249393Sbellard }
290d5249393Sbellard #else
29195389c86Sbellard void get_tmp_filename(char *filename, int size)
292ea2384d3Sbellard {
293ea2384d3Sbellard     int fd;
2947ccfb2ebSblueswir1     const char *tmpdir;
295d5249393Sbellard     /* XXX: race condition possible */
2960badc1eeSaurel32     tmpdir = getenv("TMPDIR");
2970badc1eeSaurel32     if (!tmpdir)
2980badc1eeSaurel32         tmpdir = "/tmp";
2990badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
300ea2384d3Sbellard     fd = mkstemp(filename);
301ea2384d3Sbellard     close(fd);
302ea2384d3Sbellard }
303d5249393Sbellard #endif
304ea2384d3Sbellard 
305f3a5d3f8SChristoph Hellwig /*
306f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
307f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
308f3a5d3f8SChristoph Hellwig  */
309f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
310f3a5d3f8SChristoph Hellwig {
311508c7cb3SChristoph Hellwig     int score_max = 0, score;
312508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
313f3a5d3f8SChristoph Hellwig 
3148a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
315508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
316508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
317508c7cb3SChristoph Hellwig             if (score > score_max) {
318508c7cb3SChristoph Hellwig                 score_max = score;
319508c7cb3SChristoph Hellwig                 drv = d;
320f3a5d3f8SChristoph Hellwig             }
321508c7cb3SChristoph Hellwig         }
322f3a5d3f8SChristoph Hellwig     }
323f3a5d3f8SChristoph Hellwig 
324508c7cb3SChristoph Hellwig     return drv;
325f3a5d3f8SChristoph Hellwig }
326f3a5d3f8SChristoph Hellwig 
327b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
32884a12e66SChristoph Hellwig {
32984a12e66SChristoph Hellwig     BlockDriver *drv1;
33084a12e66SChristoph Hellwig     char protocol[128];
33184a12e66SChristoph Hellwig     int len;
33284a12e66SChristoph Hellwig     const char *p;
33384a12e66SChristoph Hellwig 
33466f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
33566f82ceeSKevin Wolf 
33639508e7aSChristoph Hellwig     /*
33739508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
33839508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
33939508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
34039508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
34139508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
34239508e7aSChristoph Hellwig      */
34384a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
34439508e7aSChristoph Hellwig     if (drv1) {
34584a12e66SChristoph Hellwig         return drv1;
34684a12e66SChristoph Hellwig     }
34739508e7aSChristoph Hellwig 
3489e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
34939508e7aSChristoph Hellwig         return bdrv_find_format("file");
35039508e7aSChristoph Hellwig     }
3519e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3529e0b22f4SStefan Hajnoczi     assert(p != NULL);
35384a12e66SChristoph Hellwig     len = p - filename;
35484a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
35584a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
35684a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
35784a12e66SChristoph Hellwig     protocol[len] = '\0';
35884a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
35984a12e66SChristoph Hellwig         if (drv1->protocol_name &&
36084a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
36184a12e66SChristoph Hellwig             return drv1;
36284a12e66SChristoph Hellwig         }
36384a12e66SChristoph Hellwig     }
36484a12e66SChristoph Hellwig     return NULL;
36584a12e66SChristoph Hellwig }
36684a12e66SChristoph Hellwig 
367c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
368ea2384d3Sbellard {
36983f64091Sbellard     int ret, score, score_max;
370ea2384d3Sbellard     BlockDriver *drv1, *drv;
37183f64091Sbellard     uint8_t buf[2048];
37283f64091Sbellard     BlockDriverState *bs;
373ea2384d3Sbellard 
374f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
375c98ac35dSStefan Weil     if (ret < 0) {
376c98ac35dSStefan Weil         *pdrv = NULL;
377c98ac35dSStefan Weil         return ret;
378c98ac35dSStefan Weil     }
379f8ea0b00SNicholas Bellinger 
38008a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
38108a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
3821a396859SNicholas A. Bellinger         bdrv_delete(bs);
383c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
384c98ac35dSStefan Weil         if (!drv) {
385c98ac35dSStefan Weil             ret = -ENOENT;
386c98ac35dSStefan Weil         }
387c98ac35dSStefan Weil         *pdrv = drv;
388c98ac35dSStefan Weil         return ret;
3891a396859SNicholas A. Bellinger     }
390f8ea0b00SNicholas Bellinger 
39183f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
39283f64091Sbellard     bdrv_delete(bs);
393ea2384d3Sbellard     if (ret < 0) {
394c98ac35dSStefan Weil         *pdrv = NULL;
395c98ac35dSStefan Weil         return ret;
396ea2384d3Sbellard     }
397ea2384d3Sbellard 
398ea2384d3Sbellard     score_max = 0;
39984a12e66SChristoph Hellwig     drv = NULL;
4008a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
40183f64091Sbellard         if (drv1->bdrv_probe) {
402ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
403ea2384d3Sbellard             if (score > score_max) {
404ea2384d3Sbellard                 score_max = score;
405ea2384d3Sbellard                 drv = drv1;
406ea2384d3Sbellard             }
407ea2384d3Sbellard         }
40883f64091Sbellard     }
409c98ac35dSStefan Weil     if (!drv) {
410c98ac35dSStefan Weil         ret = -ENOENT;
411c98ac35dSStefan Weil     }
412c98ac35dSStefan Weil     *pdrv = drv;
413c98ac35dSStefan Weil     return ret;
414ea2384d3Sbellard }
415ea2384d3Sbellard 
41651762288SStefan Hajnoczi /**
41751762288SStefan Hajnoczi  * Set the current 'total_sectors' value
41851762288SStefan Hajnoczi  */
41951762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
42051762288SStefan Hajnoczi {
42151762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
42251762288SStefan Hajnoczi 
423396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
424396759adSNicholas Bellinger     if (bs->sg)
425396759adSNicholas Bellinger         return 0;
426396759adSNicholas Bellinger 
42751762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
42851762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
42951762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
43051762288SStefan Hajnoczi         if (length < 0) {
43151762288SStefan Hajnoczi             return length;
43251762288SStefan Hajnoczi         }
43351762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
43451762288SStefan Hajnoczi     }
43551762288SStefan Hajnoczi 
43651762288SStefan Hajnoczi     bs->total_sectors = hint;
43751762288SStefan Hajnoczi     return 0;
43851762288SStefan Hajnoczi }
43951762288SStefan Hajnoczi 
440c3993cdcSStefan Hajnoczi /**
441c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
442c3993cdcSStefan Hajnoczi  *
443c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
444c3993cdcSStefan Hajnoczi  */
445c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
446c3993cdcSStefan Hajnoczi {
447c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
448c3993cdcSStefan Hajnoczi 
449c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
450c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
45192196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
45292196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
453c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
454c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
455c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
456c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
457c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
458c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
459c3993cdcSStefan Hajnoczi         /* this is the default */
460c3993cdcSStefan Hajnoczi     } else {
461c3993cdcSStefan Hajnoczi         return -1;
462c3993cdcSStefan Hajnoczi     }
463c3993cdcSStefan Hajnoczi 
464c3993cdcSStefan Hajnoczi     return 0;
465c3993cdcSStefan Hajnoczi }
466c3993cdcSStefan Hajnoczi 
467b6ce07aaSKevin Wolf /*
46857915332SKevin Wolf  * Common part for opening disk images and files
46957915332SKevin Wolf  */
47057915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
47157915332SKevin Wolf     int flags, BlockDriver *drv)
47257915332SKevin Wolf {
47357915332SKevin Wolf     int ret, open_flags;
47457915332SKevin Wolf 
47557915332SKevin Wolf     assert(drv != NULL);
47657915332SKevin Wolf 
47728dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
47828dcee10SStefan Hajnoczi 
47966f82ceeSKevin Wolf     bs->file = NULL;
48051762288SStefan Hajnoczi     bs->total_sectors = 0;
48157915332SKevin Wolf     bs->encrypted = 0;
48257915332SKevin Wolf     bs->valid_key = 0;
48357915332SKevin Wolf     bs->open_flags = flags;
48457915332SKevin Wolf     bs->buffer_alignment = 512;
48557915332SKevin Wolf 
48657915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
48757915332SKevin Wolf 
48857915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
48957915332SKevin Wolf         return -ENOTSUP;
49057915332SKevin Wolf     }
49157915332SKevin Wolf 
49257915332SKevin Wolf     bs->drv = drv;
4937267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
49457915332SKevin Wolf 
495a6599793SChristoph Hellwig     if (flags & BDRV_O_CACHE_WB)
49657915332SKevin Wolf         bs->enable_write_cache = 1;
49757915332SKevin Wolf 
49857915332SKevin Wolf     /*
49957915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
50057915332SKevin Wolf      * image.
50157915332SKevin Wolf      */
50257915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
50357915332SKevin Wolf 
50457915332SKevin Wolf     /*
505ebabb67aSStefan Weil      * Snapshots should be writable.
50657915332SKevin Wolf      */
50757915332SKevin Wolf     if (bs->is_temporary) {
50857915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
50957915332SKevin Wolf     }
51057915332SKevin Wolf 
51166f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
51266f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
51366f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
51466f82ceeSKevin Wolf     } else {
51566f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
51666f82ceeSKevin Wolf         if (ret >= 0) {
51766f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
51866f82ceeSKevin Wolf         }
51966f82ceeSKevin Wolf     }
52066f82ceeSKevin Wolf 
52157915332SKevin Wolf     if (ret < 0) {
52257915332SKevin Wolf         goto free_and_fail;
52357915332SKevin Wolf     }
52457915332SKevin Wolf 
52557915332SKevin Wolf     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
52651762288SStefan Hajnoczi 
52751762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
52851762288SStefan Hajnoczi     if (ret < 0) {
52951762288SStefan Hajnoczi         goto free_and_fail;
53057915332SKevin Wolf     }
53151762288SStefan Hajnoczi 
53257915332SKevin Wolf #ifndef _WIN32
53357915332SKevin Wolf     if (bs->is_temporary) {
53457915332SKevin Wolf         unlink(filename);
53557915332SKevin Wolf     }
53657915332SKevin Wolf #endif
53757915332SKevin Wolf     return 0;
53857915332SKevin Wolf 
53957915332SKevin Wolf free_and_fail:
54066f82ceeSKevin Wolf     if (bs->file) {
54166f82ceeSKevin Wolf         bdrv_delete(bs->file);
54266f82ceeSKevin Wolf         bs->file = NULL;
54366f82ceeSKevin Wolf     }
5447267c094SAnthony Liguori     g_free(bs->opaque);
54557915332SKevin Wolf     bs->opaque = NULL;
54657915332SKevin Wolf     bs->drv = NULL;
54757915332SKevin Wolf     return ret;
54857915332SKevin Wolf }
54957915332SKevin Wolf 
55057915332SKevin Wolf /*
551b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
552b6ce07aaSKevin Wolf  */
55383f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
554b338082bSbellard {
55583f64091Sbellard     BlockDriverState *bs;
5566db95603SChristoph Hellwig     BlockDriver *drv;
55783f64091Sbellard     int ret;
5583b0d4f61Sbellard 
559b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5606db95603SChristoph Hellwig     if (!drv) {
5616db95603SChristoph Hellwig         return -ENOENT;
5626db95603SChristoph Hellwig     }
5636db95603SChristoph Hellwig 
56483f64091Sbellard     bs = bdrv_new("");
565b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
56683f64091Sbellard     if (ret < 0) {
56783f64091Sbellard         bdrv_delete(bs);
56883f64091Sbellard         return ret;
5693b0d4f61Sbellard     }
57071d0770cSaliguori     bs->growable = 1;
57183f64091Sbellard     *pbs = bs;
57283f64091Sbellard     return 0;
5733b0d4f61Sbellard }
5743b0d4f61Sbellard 
575b6ce07aaSKevin Wolf /*
576b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
577b6ce07aaSKevin Wolf  */
578d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
579ea2384d3Sbellard               BlockDriver *drv)
580ea2384d3Sbellard {
581b6ce07aaSKevin Wolf     int ret;
58233e3963eSbellard 
58383f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
584ea2384d3Sbellard         BlockDriverState *bs1;
585ea2384d3Sbellard         int64_t total_size;
5867c96d46eSaliguori         int is_protocol = 0;
58791a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
58891a073a9SKevin Wolf         QEMUOptionParameter *options;
589b6ce07aaSKevin Wolf         char tmp_filename[PATH_MAX];
590b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
59133e3963eSbellard 
592ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
593ea2384d3Sbellard            instead of opening 'filename' directly */
594ea2384d3Sbellard 
595ea2384d3Sbellard         /* if there is a backing file, use it */
596ea2384d3Sbellard         bs1 = bdrv_new("");
597d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
59851d7c00cSaliguori         if (ret < 0) {
599ea2384d3Sbellard             bdrv_delete(bs1);
60051d7c00cSaliguori             return ret;
601ea2384d3Sbellard         }
6023e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
6037c96d46eSaliguori 
6047c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
6057c96d46eSaliguori             is_protocol = 1;
6067c96d46eSaliguori 
607ea2384d3Sbellard         bdrv_delete(bs1);
608ea2384d3Sbellard 
609ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6107c96d46eSaliguori 
6117c96d46eSaliguori         /* Real path is meaningless for protocols */
6127c96d46eSaliguori         if (is_protocol)
6137c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6147c96d46eSaliguori                      "%s", filename);
615114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
616114cdfa9SKirill A. Shutemov             return -errno;
6177c96d46eSaliguori 
61891a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
61991a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
62091a073a9SKevin Wolf 
6213e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
62291a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
62391a073a9SKevin Wolf         if (drv) {
62491a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
62591a073a9SKevin Wolf                 drv->format_name);
62691a073a9SKevin Wolf         }
62791a073a9SKevin Wolf 
62891a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
629d748768cSJan Kiszka         free_option_parameters(options);
63051d7c00cSaliguori         if (ret < 0) {
63151d7c00cSaliguori             return ret;
632ea2384d3Sbellard         }
63391a073a9SKevin Wolf 
634ea2384d3Sbellard         filename = tmp_filename;
63591a073a9SKevin Wolf         drv = bdrv_qcow2;
636ea2384d3Sbellard         bs->is_temporary = 1;
637ea2384d3Sbellard     }
638ea2384d3Sbellard 
639b6ce07aaSKevin Wolf     /* Find the right image format driver */
6406db95603SChristoph Hellwig     if (!drv) {
641c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
642ea2384d3Sbellard     }
6436987307cSChristoph Hellwig 
64451d7c00cSaliguori     if (!drv) {
64551d7c00cSaliguori         goto unlink_and_fail;
64683f64091Sbellard     }
647b6ce07aaSKevin Wolf 
648b6ce07aaSKevin Wolf     /* Open the image */
649b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
650b6ce07aaSKevin Wolf     if (ret < 0) {
6516987307cSChristoph Hellwig         goto unlink_and_fail;
6526987307cSChristoph Hellwig     }
6536987307cSChristoph Hellwig 
654b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
655b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
656b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
657b6ce07aaSKevin Wolf         int back_flags;
658b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
659b6ce07aaSKevin Wolf 
660b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
661df2dbb4aSStefan Hajnoczi 
662df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
663df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
664df2dbb4aSStefan Hajnoczi                     bs->backing_file);
665df2dbb4aSStefan Hajnoczi         } else {
666b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
667b6ce07aaSKevin Wolf                          filename, bs->backing_file);
668df2dbb4aSStefan Hajnoczi         }
669df2dbb4aSStefan Hajnoczi 
670df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
671b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
672df2dbb4aSStefan Hajnoczi         }
673b6ce07aaSKevin Wolf 
674b6ce07aaSKevin Wolf         /* backing files always opened read-only */
675b6ce07aaSKevin Wolf         back_flags =
676b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
677b6ce07aaSKevin Wolf 
678b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
679b6ce07aaSKevin Wolf         if (ret < 0) {
680b6ce07aaSKevin Wolf             bdrv_close(bs);
681b6ce07aaSKevin Wolf             return ret;
682b6ce07aaSKevin Wolf         }
683b6ce07aaSKevin Wolf         if (bs->is_temporary) {
684b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
685b6ce07aaSKevin Wolf         } else {
686b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
687b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
688b6ce07aaSKevin Wolf         }
689b6ce07aaSKevin Wolf     }
690b6ce07aaSKevin Wolf 
691b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
6927d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
693b6ce07aaSKevin Wolf     }
694b6ce07aaSKevin Wolf 
695b6ce07aaSKevin Wolf     return 0;
696b6ce07aaSKevin Wolf 
697b6ce07aaSKevin Wolf unlink_and_fail:
698b6ce07aaSKevin Wolf     if (bs->is_temporary) {
699b6ce07aaSKevin Wolf         unlink(filename);
700b6ce07aaSKevin Wolf     }
701b6ce07aaSKevin Wolf     return ret;
702b6ce07aaSKevin Wolf }
703b6ce07aaSKevin Wolf 
704fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
705fc01f7e7Sbellard {
70619cb3738Sbellard     if (bs->drv) {
707f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
708f9092b10SMarkus Armbruster             bs_snapshots = NULL;
709f9092b10SMarkus Armbruster         }
710557df6acSStefan Hajnoczi         if (bs->backing_hd) {
711ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
712557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
713557df6acSStefan Hajnoczi         }
714ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7157267c094SAnthony Liguori         g_free(bs->opaque);
716ea2384d3Sbellard #ifdef _WIN32
717ea2384d3Sbellard         if (bs->is_temporary) {
718ea2384d3Sbellard             unlink(bs->filename);
719ea2384d3Sbellard         }
72067b915a5Sbellard #endif
721ea2384d3Sbellard         bs->opaque = NULL;
722ea2384d3Sbellard         bs->drv = NULL;
723b338082bSbellard 
72466f82ceeSKevin Wolf         if (bs->file != NULL) {
72566f82ceeSKevin Wolf             bdrv_close(bs->file);
72666f82ceeSKevin Wolf         }
72766f82ceeSKevin Wolf 
7287d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
729b338082bSbellard     }
730b338082bSbellard }
731b338082bSbellard 
7322bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7332bc93fedSMORITA Kazutaka {
7342bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7352bc93fedSMORITA Kazutaka 
7362bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7372bc93fedSMORITA Kazutaka         bdrv_close(bs);
7382bc93fedSMORITA Kazutaka     }
7392bc93fedSMORITA Kazutaka }
7402bc93fedSMORITA Kazutaka 
741d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
742d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
743d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
744d22b2f41SRyan Harper {
745d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
746d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
747d22b2f41SRyan Harper     }
748d22b2f41SRyan Harper     bs->device_name[0] = '\0';
749d22b2f41SRyan Harper }
750d22b2f41SRyan Harper 
751b338082bSbellard void bdrv_delete(BlockDriverState *bs)
752b338082bSbellard {
753fa879d62SMarkus Armbruster     assert(!bs->dev);
75418846deeSMarkus Armbruster 
7551b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
756d22b2f41SRyan Harper     bdrv_make_anon(bs);
75734c6f050Saurel32 
758b338082bSbellard     bdrv_close(bs);
75966f82ceeSKevin Wolf     if (bs->file != NULL) {
76066f82ceeSKevin Wolf         bdrv_delete(bs->file);
76166f82ceeSKevin Wolf     }
76266f82ceeSKevin Wolf 
763f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7647267c094SAnthony Liguori     g_free(bs);
765fc01f7e7Sbellard }
766fc01f7e7Sbellard 
767fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
768fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
76918846deeSMarkus Armbruster {
770fa879d62SMarkus Armbruster     if (bs->dev) {
77118846deeSMarkus Armbruster         return -EBUSY;
77218846deeSMarkus Armbruster     }
773fa879d62SMarkus Armbruster     bs->dev = dev;
77428a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
77518846deeSMarkus Armbruster     return 0;
77618846deeSMarkus Armbruster }
77718846deeSMarkus Armbruster 
778fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
779fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
78018846deeSMarkus Armbruster {
781fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
782fa879d62SMarkus Armbruster         abort();
783fa879d62SMarkus Armbruster     }
784fa879d62SMarkus Armbruster }
785fa879d62SMarkus Armbruster 
786fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
787fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
788fa879d62SMarkus Armbruster {
789fa879d62SMarkus Armbruster     assert(bs->dev == dev);
790fa879d62SMarkus Armbruster     bs->dev = NULL;
7910e49de52SMarkus Armbruster     bs->dev_ops = NULL;
7920e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
79329e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
79418846deeSMarkus Armbruster }
79518846deeSMarkus Armbruster 
796fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
797fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
79818846deeSMarkus Armbruster {
799fa879d62SMarkus Armbruster     return bs->dev;
80018846deeSMarkus Armbruster }
80118846deeSMarkus Armbruster 
8020e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
8030e49de52SMarkus Armbruster                       void *opaque)
8040e49de52SMarkus Armbruster {
8050e49de52SMarkus Armbruster     bs->dev_ops = ops;
8060e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8072c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8082c6942faSMarkus Armbruster         bs_snapshots = NULL;
8092c6942faSMarkus Armbruster     }
8100e49de52SMarkus Armbruster }
8110e49de52SMarkus Armbruster 
8127d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8130e49de52SMarkus Armbruster {
814145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8157d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
816145feb17SMarkus Armbruster     }
817145feb17SMarkus Armbruster }
818145feb17SMarkus Armbruster 
8192c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8202c6942faSMarkus Armbruster {
8212c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8222c6942faSMarkus Armbruster }
8232c6942faSMarkus Armbruster 
824e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
825e4def80bSMarkus Armbruster {
826e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
827e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
828e4def80bSMarkus Armbruster     }
829e4def80bSMarkus Armbruster     return false;
830e4def80bSMarkus Armbruster }
831e4def80bSMarkus Armbruster 
832145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
833145feb17SMarkus Armbruster {
834145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
835145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8360e49de52SMarkus Armbruster     }
8370e49de52SMarkus Armbruster }
8380e49de52SMarkus Armbruster 
839f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
840f107639aSMarkus Armbruster {
841f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
842f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
843f107639aSMarkus Armbruster     }
844f107639aSMarkus Armbruster     return false;
845f107639aSMarkus Armbruster }
846f107639aSMarkus Armbruster 
847e97fc193Saliguori /*
848e97fc193Saliguori  * Run consistency checks on an image
849e97fc193Saliguori  *
850e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
851a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
852e076f338SKevin Wolf  * check are stored in res.
853e97fc193Saliguori  */
854e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
855e97fc193Saliguori {
856e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
857e97fc193Saliguori         return -ENOTSUP;
858e97fc193Saliguori     }
859e97fc193Saliguori 
860e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8619ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
862e97fc193Saliguori }
863e97fc193Saliguori 
8648a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8658a426614SKevin Wolf 
86633e3963eSbellard /* commit COW file into the raw image */
86733e3963eSbellard int bdrv_commit(BlockDriverState *bs)
86833e3963eSbellard {
86919cb3738Sbellard     BlockDriver *drv = bs->drv;
870ee181196SKevin Wolf     BlockDriver *backing_drv;
8718a426614SKevin Wolf     int64_t sector, total_sectors;
8728a426614SKevin Wolf     int n, ro, open_flags;
8734dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8748a426614SKevin Wolf     uint8_t *buf;
8754dca4b63SNaphtali Sprei     char filename[1024];
8764dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
87733e3963eSbellard 
87819cb3738Sbellard     if (!drv)
87919cb3738Sbellard         return -ENOMEDIUM;
88033e3963eSbellard 
8814dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8824dca4b63SNaphtali Sprei         return -ENOTSUP;
8834dca4b63SNaphtali Sprei     }
8844dca4b63SNaphtali Sprei 
8854dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
886ea2384d3Sbellard         return -EACCES;
88733e3963eSbellard     }
88833e3963eSbellard 
889ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
8904dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
8914dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
8924dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
8934dca4b63SNaphtali Sprei 
8944dca4b63SNaphtali Sprei     if (ro) {
8954dca4b63SNaphtali Sprei         /* re-open as RW */
8964dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
8974dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
8984dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
899ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
900ee181196SKevin Wolf             backing_drv);
9014dca4b63SNaphtali Sprei         if (rw_ret < 0) {
9024dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
9034dca4b63SNaphtali Sprei             /* try to re-open read-only */
9044dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
905ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
906ee181196SKevin Wolf                 backing_drv);
9074dca4b63SNaphtali Sprei             if (ret < 0) {
9084dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9094dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9104dca4b63SNaphtali Sprei                 bs->drv = NULL;
9114dca4b63SNaphtali Sprei                 return ret;
9124dca4b63SNaphtali Sprei             }
9134dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9144dca4b63SNaphtali Sprei             return rw_ret;
9154dca4b63SNaphtali Sprei         }
9164dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
917ea2384d3Sbellard     }
918ea2384d3Sbellard 
9196ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9207267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9218a426614SKevin Wolf 
9228a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9238a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9248a426614SKevin Wolf 
9258a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9264dca4b63SNaphtali Sprei                 ret = -EIO;
9274dca4b63SNaphtali Sprei                 goto ro_cleanup;
92833e3963eSbellard             }
92933e3963eSbellard 
9308a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9314dca4b63SNaphtali Sprei                 ret = -EIO;
9324dca4b63SNaphtali Sprei                 goto ro_cleanup;
93333e3963eSbellard             }
93433e3963eSbellard         }
93533e3963eSbellard     }
93695389c86Sbellard 
9371d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9381d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9391d44952fSChristoph Hellwig         bdrv_flush(bs);
9401d44952fSChristoph Hellwig     }
94195389c86Sbellard 
9423f5075aeSChristoph Hellwig     /*
9433f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9443f5075aeSChristoph Hellwig      * stable on disk.
9453f5075aeSChristoph Hellwig      */
9463f5075aeSChristoph Hellwig     if (bs->backing_hd)
9473f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9484dca4b63SNaphtali Sprei 
9494dca4b63SNaphtali Sprei ro_cleanup:
9507267c094SAnthony Liguori     g_free(buf);
9514dca4b63SNaphtali Sprei 
9524dca4b63SNaphtali Sprei     if (ro) {
9534dca4b63SNaphtali Sprei         /* re-open as RO */
9544dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9554dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9564dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
957ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
958ee181196SKevin Wolf             backing_drv);
9594dca4b63SNaphtali Sprei         if (ret < 0) {
9604dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9614dca4b63SNaphtali Sprei             /* drive not functional anymore */
9624dca4b63SNaphtali Sprei             bs->drv = NULL;
9634dca4b63SNaphtali Sprei             return ret;
9644dca4b63SNaphtali Sprei         }
9654dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9664dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9674dca4b63SNaphtali Sprei     }
9684dca4b63SNaphtali Sprei 
9691d44952fSChristoph Hellwig     return ret;
97033e3963eSbellard }
97133e3963eSbellard 
9726ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9736ab4b5abSMarkus Armbruster {
9746ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9756ab4b5abSMarkus Armbruster 
9766ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9776ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9786ab4b5abSMarkus Armbruster     }
9796ab4b5abSMarkus Armbruster }
9806ab4b5abSMarkus Armbruster 
981756e6736SKevin Wolf /*
982756e6736SKevin Wolf  * Return values:
983756e6736SKevin Wolf  * 0        - success
984756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
985756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
986756e6736SKevin Wolf  *            image file header
987756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
988756e6736SKevin Wolf  */
989756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
990756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
991756e6736SKevin Wolf {
992756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
993756e6736SKevin Wolf 
994756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
995756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
996756e6736SKevin Wolf     } else {
997756e6736SKevin Wolf         return -ENOTSUP;
998756e6736SKevin Wolf     }
999756e6736SKevin Wolf }
1000756e6736SKevin Wolf 
100171d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
100271d0770cSaliguori                                    size_t size)
100371d0770cSaliguori {
100471d0770cSaliguori     int64_t len;
100571d0770cSaliguori 
100671d0770cSaliguori     if (!bdrv_is_inserted(bs))
100771d0770cSaliguori         return -ENOMEDIUM;
100871d0770cSaliguori 
100971d0770cSaliguori     if (bs->growable)
101071d0770cSaliguori         return 0;
101171d0770cSaliguori 
101271d0770cSaliguori     len = bdrv_getlength(bs);
101371d0770cSaliguori 
1014fbb7b4e0SKevin Wolf     if (offset < 0)
1015fbb7b4e0SKevin Wolf         return -EIO;
1016fbb7b4e0SKevin Wolf 
1017fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
101871d0770cSaliguori         return -EIO;
101971d0770cSaliguori 
102071d0770cSaliguori     return 0;
102171d0770cSaliguori }
102271d0770cSaliguori 
102371d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
102471d0770cSaliguori                               int nb_sectors)
102571d0770cSaliguori {
1026eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1027eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
102871d0770cSaliguori }
102971d0770cSaliguori 
1030e7a8a783SKevin Wolf static inline bool bdrv_has_async_rw(BlockDriver *drv)
1031e7a8a783SKevin Wolf {
1032e7a8a783SKevin Wolf     return drv->bdrv_co_readv != bdrv_co_readv_em
1033e7a8a783SKevin Wolf         || drv->bdrv_aio_readv != bdrv_aio_readv_em;
1034e7a8a783SKevin Wolf }
1035e7a8a783SKevin Wolf 
1036e7a8a783SKevin Wolf static inline bool bdrv_has_async_flush(BlockDriver *drv)
1037e7a8a783SKevin Wolf {
1038e7a8a783SKevin Wolf     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
1039e7a8a783SKevin Wolf }
1040e7a8a783SKevin Wolf 
10411c9805a3SStefan Hajnoczi typedef struct RwCo {
10421c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10431c9805a3SStefan Hajnoczi     int64_t sector_num;
10441c9805a3SStefan Hajnoczi     int nb_sectors;
10451c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10461c9805a3SStefan Hajnoczi     bool is_write;
10471c9805a3SStefan Hajnoczi     int ret;
10481c9805a3SStefan Hajnoczi } RwCo;
10491c9805a3SStefan Hajnoczi 
10501c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1051fc01f7e7Sbellard {
10521c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1053fc01f7e7Sbellard 
10541c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10551c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10561c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10571c9805a3SStefan Hajnoczi     } else {
10581c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10591c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10601c9805a3SStefan Hajnoczi     }
10611c9805a3SStefan Hajnoczi }
1062e7a8a783SKevin Wolf 
10631c9805a3SStefan Hajnoczi /*
10641c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10651c9805a3SStefan Hajnoczi  */
10661c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10671c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10681c9805a3SStefan Hajnoczi {
1069e7a8a783SKevin Wolf     QEMUIOVector qiov;
1070e7a8a783SKevin Wolf     struct iovec iov = {
1071e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1072e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1073e7a8a783SKevin Wolf     };
10741c9805a3SStefan Hajnoczi     Coroutine *co;
10751c9805a3SStefan Hajnoczi     RwCo rwco = {
10761c9805a3SStefan Hajnoczi         .bs = bs,
10771c9805a3SStefan Hajnoczi         .sector_num = sector_num,
10781c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
10791c9805a3SStefan Hajnoczi         .qiov = &qiov,
10801c9805a3SStefan Hajnoczi         .is_write = is_write,
10811c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
10821c9805a3SStefan Hajnoczi     };
1083e7a8a783SKevin Wolf 
1084e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
10851c9805a3SStefan Hajnoczi 
10861c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
10871c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
10881c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
10891c9805a3SStefan Hajnoczi     } else {
10901c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
10911c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
10921c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
10931c9805a3SStefan Hajnoczi             qemu_aio_wait();
10941c9805a3SStefan Hajnoczi         }
10951c9805a3SStefan Hajnoczi     }
10961c9805a3SStefan Hajnoczi     return rwco.ret;
1097e7a8a783SKevin Wolf }
1098e7a8a783SKevin Wolf 
10991c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
11001c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
11011c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
11021c9805a3SStefan Hajnoczi {
11031c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
110483f64091Sbellard }
1105fc01f7e7Sbellard 
11067cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
11077cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
11087cd1e32aSlirans@il.ibm.com {
11097cd1e32aSlirans@il.ibm.com     int64_t start, end;
1110c6d22830SJan Kiszka     unsigned long val, idx, bit;
1111a55eb92cSJan Kiszka 
11126ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1113c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
11147cd1e32aSlirans@il.ibm.com 
11157cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1116c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1117c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1118c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1119c6d22830SJan Kiszka         if (dirty) {
11206d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1121aaa0eb75SLiran Schour                 bs->dirty_count++;
11226d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1123aaa0eb75SLiran Schour             }
1124c6d22830SJan Kiszka         } else {
11256d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1126aaa0eb75SLiran Schour                 bs->dirty_count--;
11276d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1128c6d22830SJan Kiszka             }
1129aaa0eb75SLiran Schour         }
1130c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11317cd1e32aSlirans@il.ibm.com     }
11327cd1e32aSlirans@il.ibm.com }
11337cd1e32aSlirans@il.ibm.com 
113419cb3738Sbellard /* Return < 0 if error. Important errors are:
113519cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
113619cb3738Sbellard   -ENOMEDIUM   No media inserted.
113719cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
113819cb3738Sbellard   -EACCES      Trying to write a read-only device
113919cb3738Sbellard */
1140fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1141fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1142fc01f7e7Sbellard {
11431c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
114483f64091Sbellard }
114583f64091Sbellard 
1146eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1147eda578e5Saliguori                void *buf, int count1)
114883f64091Sbellard {
11496ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
115083f64091Sbellard     int len, nb_sectors, count;
115183f64091Sbellard     int64_t sector_num;
11529a8c4cceSKevin Wolf     int ret;
115383f64091Sbellard 
115483f64091Sbellard     count = count1;
115583f64091Sbellard     /* first read to align to sector start */
11566ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
115783f64091Sbellard     if (len > count)
115883f64091Sbellard         len = count;
11596ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
116083f64091Sbellard     if (len > 0) {
11619a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11629a8c4cceSKevin Wolf             return ret;
11636ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
116483f64091Sbellard         count -= len;
116583f64091Sbellard         if (count == 0)
116683f64091Sbellard             return count1;
116783f64091Sbellard         sector_num++;
116883f64091Sbellard         buf += len;
116983f64091Sbellard     }
117083f64091Sbellard 
117183f64091Sbellard     /* read the sectors "in place" */
11726ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
117383f64091Sbellard     if (nb_sectors > 0) {
11749a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11759a8c4cceSKevin Wolf             return ret;
117683f64091Sbellard         sector_num += nb_sectors;
11776ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
117883f64091Sbellard         buf += len;
117983f64091Sbellard         count -= len;
118083f64091Sbellard     }
118183f64091Sbellard 
118283f64091Sbellard     /* add data from the last sector */
118383f64091Sbellard     if (count > 0) {
11849a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11859a8c4cceSKevin Wolf             return ret;
118683f64091Sbellard         memcpy(buf, tmp_buf, count);
118783f64091Sbellard     }
118883f64091Sbellard     return count1;
118983f64091Sbellard }
119083f64091Sbellard 
1191eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1192eda578e5Saliguori                 const void *buf, int count1)
119383f64091Sbellard {
11946ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
119583f64091Sbellard     int len, nb_sectors, count;
119683f64091Sbellard     int64_t sector_num;
11979a8c4cceSKevin Wolf     int ret;
119883f64091Sbellard 
119983f64091Sbellard     count = count1;
120083f64091Sbellard     /* first write to align to sector start */
12016ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
120283f64091Sbellard     if (len > count)
120383f64091Sbellard         len = count;
12046ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
120583f64091Sbellard     if (len > 0) {
12069a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12079a8c4cceSKevin Wolf             return ret;
12086ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
12099a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12109a8c4cceSKevin Wolf             return ret;
121183f64091Sbellard         count -= len;
121283f64091Sbellard         if (count == 0)
121383f64091Sbellard             return count1;
121483f64091Sbellard         sector_num++;
121583f64091Sbellard         buf += len;
121683f64091Sbellard     }
121783f64091Sbellard 
121883f64091Sbellard     /* write the sectors "in place" */
12196ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
122083f64091Sbellard     if (nb_sectors > 0) {
12219a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12229a8c4cceSKevin Wolf             return ret;
122383f64091Sbellard         sector_num += nb_sectors;
12246ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
122583f64091Sbellard         buf += len;
122683f64091Sbellard         count -= len;
122783f64091Sbellard     }
122883f64091Sbellard 
122983f64091Sbellard     /* add data from the last sector */
123083f64091Sbellard     if (count > 0) {
12319a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12329a8c4cceSKevin Wolf             return ret;
123383f64091Sbellard         memcpy(tmp_buf, buf, count);
12349a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12359a8c4cceSKevin Wolf             return ret;
123683f64091Sbellard     }
123783f64091Sbellard     return count1;
123883f64091Sbellard }
123983f64091Sbellard 
1240f08145feSKevin Wolf /*
1241f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1242f08145feSKevin Wolf  * request (acts as a barrier)
1243f08145feSKevin Wolf  *
1244f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1245f08145feSKevin Wolf  */
1246f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1247f08145feSKevin Wolf     const void *buf, int count)
1248f08145feSKevin Wolf {
1249f08145feSKevin Wolf     int ret;
1250f08145feSKevin Wolf 
1251f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1252f08145feSKevin Wolf     if (ret < 0) {
1253f08145feSKevin Wolf         return ret;
1254f08145feSKevin Wolf     }
1255f08145feSKevin Wolf 
125692196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
125792196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1258f08145feSKevin Wolf         bdrv_flush(bs);
1259f08145feSKevin Wolf     }
1260f08145feSKevin Wolf 
1261f08145feSKevin Wolf     return 0;
1262f08145feSKevin Wolf }
1263f08145feSKevin Wolf 
1264c5fbe571SStefan Hajnoczi /*
1265c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1266c5fbe571SStefan Hajnoczi  */
1267c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1268c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1269da1fa91dSKevin Wolf {
1270da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1271da1fa91dSKevin Wolf 
1272da1fa91dSKevin Wolf     if (!drv) {
1273da1fa91dSKevin Wolf         return -ENOMEDIUM;
1274da1fa91dSKevin Wolf     }
1275da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1276da1fa91dSKevin Wolf         return -EIO;
1277da1fa91dSKevin Wolf     }
1278da1fa91dSKevin Wolf 
1279da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1280da1fa91dSKevin Wolf }
1281da1fa91dSKevin Wolf 
1282c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1283da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1284da1fa91dSKevin Wolf {
1285c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1286da1fa91dSKevin Wolf 
1287c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1288c5fbe571SStefan Hajnoczi }
1289c5fbe571SStefan Hajnoczi 
1290c5fbe571SStefan Hajnoczi /*
1291c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1292c5fbe571SStefan Hajnoczi  */
1293c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1294c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1295c5fbe571SStefan Hajnoczi {
1296c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
12976b7cb247SStefan Hajnoczi     int ret;
1298da1fa91dSKevin Wolf 
1299da1fa91dSKevin Wolf     if (!bs->drv) {
1300da1fa91dSKevin Wolf         return -ENOMEDIUM;
1301da1fa91dSKevin Wolf     }
1302da1fa91dSKevin Wolf     if (bs->read_only) {
1303da1fa91dSKevin Wolf         return -EACCES;
1304da1fa91dSKevin Wolf     }
1305da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1306da1fa91dSKevin Wolf         return -EIO;
1307da1fa91dSKevin Wolf     }
1308da1fa91dSKevin Wolf 
13096b7cb247SStefan Hajnoczi     ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
13106b7cb247SStefan Hajnoczi 
1311da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1312da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1313da1fa91dSKevin Wolf     }
1314da1fa91dSKevin Wolf 
1315da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1316da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1317da1fa91dSKevin Wolf     }
1318da1fa91dSKevin Wolf 
13196b7cb247SStefan Hajnoczi     return ret;
1320da1fa91dSKevin Wolf }
1321da1fa91dSKevin Wolf 
1322c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1323c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1324c5fbe571SStefan Hajnoczi {
1325c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1326c5fbe571SStefan Hajnoczi 
1327c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1328c5fbe571SStefan Hajnoczi }
1329c5fbe571SStefan Hajnoczi 
133083f64091Sbellard /**
133183f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
133283f64091Sbellard  */
133383f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
133483f64091Sbellard {
133583f64091Sbellard     BlockDriver *drv = bs->drv;
133651762288SStefan Hajnoczi     int ret;
133783f64091Sbellard     if (!drv)
133819cb3738Sbellard         return -ENOMEDIUM;
133983f64091Sbellard     if (!drv->bdrv_truncate)
134083f64091Sbellard         return -ENOTSUP;
134159f2689dSNaphtali Sprei     if (bs->read_only)
134259f2689dSNaphtali Sprei         return -EACCES;
13438591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13448591675fSMarcelo Tosatti         return -EBUSY;
134551762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
134651762288SStefan Hajnoczi     if (ret == 0) {
134751762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1348145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
134951762288SStefan Hajnoczi     }
135051762288SStefan Hajnoczi     return ret;
135183f64091Sbellard }
135283f64091Sbellard 
135383f64091Sbellard /**
13544a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13554a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13564a1d5e1fSFam Zheng  */
13574a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13584a1d5e1fSFam Zheng {
13594a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13604a1d5e1fSFam Zheng     if (!drv) {
13614a1d5e1fSFam Zheng         return -ENOMEDIUM;
13624a1d5e1fSFam Zheng     }
13634a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13644a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13654a1d5e1fSFam Zheng     }
13664a1d5e1fSFam Zheng     if (bs->file) {
13674a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13684a1d5e1fSFam Zheng     }
13694a1d5e1fSFam Zheng     return -ENOTSUP;
13704a1d5e1fSFam Zheng }
13714a1d5e1fSFam Zheng 
13724a1d5e1fSFam Zheng /**
137383f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
137483f64091Sbellard  */
137583f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
137683f64091Sbellard {
137783f64091Sbellard     BlockDriver *drv = bs->drv;
137883f64091Sbellard     if (!drv)
137919cb3738Sbellard         return -ENOMEDIUM;
138051762288SStefan Hajnoczi 
13812c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
138246a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
138383f64091Sbellard             return drv->bdrv_getlength(bs);
1384fc01f7e7Sbellard         }
138546a4e4e6SStefan Hajnoczi     }
138646a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
138746a4e4e6SStefan Hajnoczi }
1388fc01f7e7Sbellard 
138919cb3738Sbellard /* return 0 as number of sectors if no device present or error */
139096b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1391fc01f7e7Sbellard {
139219cb3738Sbellard     int64_t length;
139319cb3738Sbellard     length = bdrv_getlength(bs);
139419cb3738Sbellard     if (length < 0)
139519cb3738Sbellard         length = 0;
139619cb3738Sbellard     else
13976ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
139819cb3738Sbellard     *nb_sectors_ptr = length;
1399fc01f7e7Sbellard }
1400cf98951bSbellard 
1401f3d54fc4Saliguori struct partition {
1402f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1403f3d54fc4Saliguori         uint8_t head;               /* starting head */
1404f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1405f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1406f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1407f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1408f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1409f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1410f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1411f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1412541dc0d4SStefan Weil } QEMU_PACKED;
1413f3d54fc4Saliguori 
1414f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1415f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1416f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1417f3d54fc4Saliguori {
1418eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1419f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1420f3d54fc4Saliguori     struct partition *p;
1421f3d54fc4Saliguori     uint32_t nr_sects;
1422a38131b6Sblueswir1     uint64_t nb_sectors;
1423f3d54fc4Saliguori 
1424f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1425f3d54fc4Saliguori 
1426f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1427f3d54fc4Saliguori     if (ret < 0)
1428f3d54fc4Saliguori         return -1;
1429f3d54fc4Saliguori     /* test msdos magic */
1430f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1431f3d54fc4Saliguori         return -1;
1432f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1433f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1434f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1435f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1436f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1437f3d54fc4Saliguori                a cylinder boundary */
1438f3d54fc4Saliguori             heads = p->end_head + 1;
1439f3d54fc4Saliguori             sectors = p->end_sector & 63;
1440f3d54fc4Saliguori             if (sectors == 0)
1441f3d54fc4Saliguori                 continue;
1442f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1443f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1444f3d54fc4Saliguori                 continue;
1445f3d54fc4Saliguori             *pheads = heads;
1446f3d54fc4Saliguori             *psectors = sectors;
1447f3d54fc4Saliguori             *pcylinders = cylinders;
1448f3d54fc4Saliguori #if 0
1449f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1450f3d54fc4Saliguori                    cylinders, heads, sectors);
1451f3d54fc4Saliguori #endif
1452f3d54fc4Saliguori             return 0;
1453f3d54fc4Saliguori         }
1454f3d54fc4Saliguori     }
1455f3d54fc4Saliguori     return -1;
1456f3d54fc4Saliguori }
1457f3d54fc4Saliguori 
1458f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1459f3d54fc4Saliguori {
1460f3d54fc4Saliguori     int translation, lba_detected = 0;
1461f3d54fc4Saliguori     int cylinders, heads, secs;
1462a38131b6Sblueswir1     uint64_t nb_sectors;
1463f3d54fc4Saliguori 
1464f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1465f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1466f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1467f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1468f3d54fc4Saliguori     if (cylinders != 0) {
1469f3d54fc4Saliguori         *pcyls = cylinders;
1470f3d54fc4Saliguori         *pheads = heads;
1471f3d54fc4Saliguori         *psecs = secs;
1472f3d54fc4Saliguori     } else {
1473f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1474f3d54fc4Saliguori             if (heads > 16) {
1475f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1476f3d54fc4Saliguori                    translation was active, so the default
1477f3d54fc4Saliguori                    hardware geometry is OK */
1478f3d54fc4Saliguori                 lba_detected = 1;
1479f3d54fc4Saliguori                 goto default_geometry;
1480f3d54fc4Saliguori             } else {
1481f3d54fc4Saliguori                 *pcyls = cylinders;
1482f3d54fc4Saliguori                 *pheads = heads;
1483f3d54fc4Saliguori                 *psecs = secs;
1484f3d54fc4Saliguori                 /* disable any translation to be in sync with
1485f3d54fc4Saliguori                    the logical geometry */
1486f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1487f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1488f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1489f3d54fc4Saliguori                 }
1490f3d54fc4Saliguori             }
1491f3d54fc4Saliguori         } else {
1492f3d54fc4Saliguori         default_geometry:
1493f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1494f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1495f3d54fc4Saliguori 
1496f3d54fc4Saliguori             if (cylinders > 16383)
1497f3d54fc4Saliguori                 cylinders = 16383;
1498f3d54fc4Saliguori             else if (cylinders < 2)
1499f3d54fc4Saliguori                 cylinders = 2;
1500f3d54fc4Saliguori             *pcyls = cylinders;
1501f3d54fc4Saliguori             *pheads = 16;
1502f3d54fc4Saliguori             *psecs = 63;
1503f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1504f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1505f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1506f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1507f3d54fc4Saliguori                 } else {
1508f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1509f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1510f3d54fc4Saliguori                 }
1511f3d54fc4Saliguori             }
1512f3d54fc4Saliguori         }
1513f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1514f3d54fc4Saliguori     }
1515f3d54fc4Saliguori }
1516f3d54fc4Saliguori 
1517b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1518b338082bSbellard                             int cyls, int heads, int secs)
1519b338082bSbellard {
1520b338082bSbellard     bs->cyls = cyls;
1521b338082bSbellard     bs->heads = heads;
1522b338082bSbellard     bs->secs = secs;
1523b338082bSbellard }
1524b338082bSbellard 
152546d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
152646d4767dSbellard {
152746d4767dSbellard     bs->translation = translation;
152846d4767dSbellard }
152946d4767dSbellard 
1530b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1531b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1532b338082bSbellard {
1533b338082bSbellard     *pcyls = bs->cyls;
1534b338082bSbellard     *pheads = bs->heads;
1535b338082bSbellard     *psecs = bs->secs;
1536b338082bSbellard }
1537b338082bSbellard 
15385bbdbb46SBlue Swirl /* Recognize floppy formats */
15395bbdbb46SBlue Swirl typedef struct FDFormat {
15405bbdbb46SBlue Swirl     FDriveType drive;
15415bbdbb46SBlue Swirl     uint8_t last_sect;
15425bbdbb46SBlue Swirl     uint8_t max_track;
15435bbdbb46SBlue Swirl     uint8_t max_head;
15445bbdbb46SBlue Swirl } FDFormat;
15455bbdbb46SBlue Swirl 
15465bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15475bbdbb46SBlue Swirl     /* First entry is default format */
15485bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15495bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15505bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15515bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15525bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15535bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15545bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15555bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15565bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15575bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15585bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15595bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15605bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15615bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15625bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15635bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15645bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15655bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15665bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15675bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15685bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15695bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15705bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15715bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15725bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15735bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15745bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15755bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15765bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15775bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15785bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15795bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15805bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15815bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15825bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15835bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15845bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15855bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
15865bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
15875bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
15885bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
15895bbdbb46SBlue Swirl     /* end */
15905bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
15915bbdbb46SBlue Swirl };
15925bbdbb46SBlue Swirl 
15935bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
15945bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
15955bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
15965bbdbb46SBlue Swirl {
15975bbdbb46SBlue Swirl     const FDFormat *parse;
15985bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
15995bbdbb46SBlue Swirl     int i, first_match, match;
16005bbdbb46SBlue Swirl 
16015bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
16025bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
16035bbdbb46SBlue Swirl         /* User defined disk */
16045bbdbb46SBlue Swirl     } else {
16055bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
16065bbdbb46SBlue Swirl         match = -1;
16075bbdbb46SBlue Swirl         first_match = -1;
16085bbdbb46SBlue Swirl         for (i = 0; ; i++) {
16095bbdbb46SBlue Swirl             parse = &fd_formats[i];
16105bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
16115bbdbb46SBlue Swirl                 break;
16125bbdbb46SBlue Swirl             }
16135bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
16145bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
16155bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
16165bbdbb46SBlue Swirl                     parse->last_sect;
16175bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16185bbdbb46SBlue Swirl                     match = i;
16195bbdbb46SBlue Swirl                     break;
16205bbdbb46SBlue Swirl                 }
16215bbdbb46SBlue Swirl                 if (first_match == -1) {
16225bbdbb46SBlue Swirl                     first_match = i;
16235bbdbb46SBlue Swirl                 }
16245bbdbb46SBlue Swirl             }
16255bbdbb46SBlue Swirl         }
16265bbdbb46SBlue Swirl         if (match == -1) {
16275bbdbb46SBlue Swirl             if (first_match == -1) {
16285bbdbb46SBlue Swirl                 match = 1;
16295bbdbb46SBlue Swirl             } else {
16305bbdbb46SBlue Swirl                 match = first_match;
16315bbdbb46SBlue Swirl             }
16325bbdbb46SBlue Swirl             parse = &fd_formats[match];
16335bbdbb46SBlue Swirl         }
16345bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16355bbdbb46SBlue Swirl         *max_track = parse->max_track;
16365bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16375bbdbb46SBlue Swirl         *drive = parse->drive;
16385bbdbb46SBlue Swirl     }
16395bbdbb46SBlue Swirl }
16405bbdbb46SBlue Swirl 
164146d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
164246d4767dSbellard {
164346d4767dSbellard     return bs->translation;
164446d4767dSbellard }
164546d4767dSbellard 
1646abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1647abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1648abd7f68dSMarkus Armbruster {
1649abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1650abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1651abd7f68dSMarkus Armbruster }
1652abd7f68dSMarkus Armbruster 
1653abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1654abd7f68dSMarkus Armbruster {
1655abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1656abd7f68dSMarkus Armbruster }
1657abd7f68dSMarkus Armbruster 
1658b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1659b338082bSbellard {
1660b338082bSbellard     return bs->read_only;
1661b338082bSbellard }
1662b338082bSbellard 
1663985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1664985a03b0Sths {
1665985a03b0Sths     return bs->sg;
1666985a03b0Sths }
1667985a03b0Sths 
1668e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1669e900a7b7SChristoph Hellwig {
1670e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1671e900a7b7SChristoph Hellwig }
1672e900a7b7SChristoph Hellwig 
1673ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1674ea2384d3Sbellard {
1675ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1676ea2384d3Sbellard         return 1;
1677ea2384d3Sbellard     return bs->encrypted;
1678ea2384d3Sbellard }
1679ea2384d3Sbellard 
1680c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1681c0f4ce77Saliguori {
1682c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1683c0f4ce77Saliguori 
1684c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1685c0f4ce77Saliguori         return 1;
1686c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1687c0f4ce77Saliguori }
1688c0f4ce77Saliguori 
1689ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1690ea2384d3Sbellard {
1691ea2384d3Sbellard     int ret;
1692ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1693ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1694ea2384d3Sbellard         if (ret < 0)
1695ea2384d3Sbellard             return ret;
1696ea2384d3Sbellard         if (!bs->encrypted)
1697ea2384d3Sbellard             return 0;
1698ea2384d3Sbellard     }
1699fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1700fd04a2aeSShahar Havivi         return -EINVAL;
1701fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1702fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1703fd04a2aeSShahar Havivi     }
1704c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1705bb5fc20fSaliguori     if (ret < 0) {
1706bb5fc20fSaliguori         bs->valid_key = 0;
1707bb5fc20fSaliguori     } else if (!bs->valid_key) {
1708bb5fc20fSaliguori         bs->valid_key = 1;
1709bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
17107d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1711bb5fc20fSaliguori     }
1712c0f4ce77Saliguori     return ret;
1713ea2384d3Sbellard }
1714ea2384d3Sbellard 
1715ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1716ea2384d3Sbellard {
171719cb3738Sbellard     if (!bs->drv) {
1718ea2384d3Sbellard         buf[0] = '\0';
1719ea2384d3Sbellard     } else {
1720ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1721ea2384d3Sbellard     }
1722ea2384d3Sbellard }
1723ea2384d3Sbellard 
1724ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1725ea2384d3Sbellard                          void *opaque)
1726ea2384d3Sbellard {
1727ea2384d3Sbellard     BlockDriver *drv;
1728ea2384d3Sbellard 
17298a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1730ea2384d3Sbellard         it(opaque, drv->format_name);
1731ea2384d3Sbellard     }
1732ea2384d3Sbellard }
1733ea2384d3Sbellard 
1734b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1735b338082bSbellard {
1736b338082bSbellard     BlockDriverState *bs;
1737b338082bSbellard 
17381b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17391b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1740b338082bSbellard             return bs;
1741b338082bSbellard         }
17421b7bdbc1SStefan Hajnoczi     }
1743b338082bSbellard     return NULL;
1744b338082bSbellard }
1745b338082bSbellard 
17462f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17472f399b0aSMarkus Armbruster {
17482f399b0aSMarkus Armbruster     if (!bs) {
17492f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17502f399b0aSMarkus Armbruster     }
17512f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17522f399b0aSMarkus Armbruster }
17532f399b0aSMarkus Armbruster 
175451de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
175581d0912dSbellard {
175681d0912dSbellard     BlockDriverState *bs;
175781d0912dSbellard 
17581b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
175951de9760Saliguori         it(opaque, bs);
176081d0912dSbellard     }
176181d0912dSbellard }
176281d0912dSbellard 
1763ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1764ea2384d3Sbellard {
1765ea2384d3Sbellard     return bs->device_name;
1766ea2384d3Sbellard }
1767ea2384d3Sbellard 
1768205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs)
17697a6cba61Spbrook {
1770016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
1771205ef796SKevin Wolf         return 0;
1772016f5cf6SAlexander Graf     }
1773016f5cf6SAlexander Graf 
1774e7a8a783SKevin Wolf     if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) {
1775e7a8a783SKevin Wolf         return bdrv_co_flush_em(bs);
1776e7a8a783SKevin Wolf     }
1777e7a8a783SKevin Wolf 
1778205ef796SKevin Wolf     if (bs->drv && bs->drv->bdrv_flush) {
1779205ef796SKevin Wolf         return bs->drv->bdrv_flush(bs);
1780205ef796SKevin Wolf     }
1781205ef796SKevin Wolf 
1782205ef796SKevin Wolf     /*
1783205ef796SKevin Wolf      * Some block drivers always operate in either writethrough or unsafe mode
1784205ef796SKevin Wolf      * and don't support bdrv_flush therefore. Usually qemu doesn't know how
1785205ef796SKevin Wolf      * the server works (because the behaviour is hardcoded or depends on
1786205ef796SKevin Wolf      * server-side configuration), so we can't ensure that everything is safe
1787205ef796SKevin Wolf      * on disk. Returning an error doesn't work because that would break guests
1788205ef796SKevin Wolf      * even if the server operates in writethrough mode.
1789205ef796SKevin Wolf      *
1790205ef796SKevin Wolf      * Let's hope the user knows what he's doing.
1791205ef796SKevin Wolf      */
1792205ef796SKevin Wolf     return 0;
17937a6cba61Spbrook }
17947a6cba61Spbrook 
1795c6ca28d6Saliguori void bdrv_flush_all(void)
1796c6ca28d6Saliguori {
1797c6ca28d6Saliguori     BlockDriverState *bs;
1798c6ca28d6Saliguori 
17991b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1800c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1801c6ca28d6Saliguori             bdrv_flush(bs);
1802c6ca28d6Saliguori         }
18031b7bdbc1SStefan Hajnoczi     }
18041b7bdbc1SStefan Hajnoczi }
1805c6ca28d6Saliguori 
1806f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1807f2feebbdSKevin Wolf {
1808f2feebbdSKevin Wolf     assert(bs->drv);
1809f2feebbdSKevin Wolf 
1810336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1811336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1812f2feebbdSKevin Wolf     }
1813f2feebbdSKevin Wolf 
1814f2feebbdSKevin Wolf     return 1;
1815f2feebbdSKevin Wolf }
1816f2feebbdSKevin Wolf 
1817bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
1818bb8bf76fSChristoph Hellwig {
1819bb8bf76fSChristoph Hellwig     if (!bs->drv) {
1820bb8bf76fSChristoph Hellwig         return -ENOMEDIUM;
1821bb8bf76fSChristoph Hellwig     }
1822bb8bf76fSChristoph Hellwig     if (!bs->drv->bdrv_discard) {
1823bb8bf76fSChristoph Hellwig         return 0;
1824bb8bf76fSChristoph Hellwig     }
1825bb8bf76fSChristoph Hellwig     return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
1826bb8bf76fSChristoph Hellwig }
1827bb8bf76fSChristoph Hellwig 
1828f58c7b35Sths /*
1829f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1830f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1831f58c7b35Sths  * hence all their sectors are reported as allocated.
1832f58c7b35Sths  *
1833f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1834f58c7b35Sths  * the specified sector) that are known to be in the same
1835f58c7b35Sths  * allocated/unallocated state.
1836f58c7b35Sths  *
1837f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1838f58c7b35Sths  */
1839f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1840f58c7b35Sths 	int *pnum)
1841f58c7b35Sths {
1842f58c7b35Sths     int64_t n;
1843f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1844f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1845f58c7b35Sths             *pnum = 0;
1846f58c7b35Sths             return 0;
1847f58c7b35Sths         }
1848f58c7b35Sths         n = bs->total_sectors - sector_num;
1849f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1850f58c7b35Sths         return 1;
1851f58c7b35Sths     }
1852f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1853f58c7b35Sths }
1854f58c7b35Sths 
18552582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18562582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18572582bfedSLuiz Capitulino {
18582582bfedSLuiz Capitulino     QObject *data;
18592582bfedSLuiz Capitulino     const char *action_str;
18602582bfedSLuiz Capitulino 
18612582bfedSLuiz Capitulino     switch (action) {
18622582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18632582bfedSLuiz Capitulino         action_str = "report";
18642582bfedSLuiz Capitulino         break;
18652582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18662582bfedSLuiz Capitulino         action_str = "ignore";
18672582bfedSLuiz Capitulino         break;
18682582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18692582bfedSLuiz Capitulino         action_str = "stop";
18702582bfedSLuiz Capitulino         break;
18712582bfedSLuiz Capitulino     default:
18722582bfedSLuiz Capitulino         abort();
18732582bfedSLuiz Capitulino     }
18742582bfedSLuiz Capitulino 
18752582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18762582bfedSLuiz Capitulino                               bdrv->device_name,
18772582bfedSLuiz Capitulino                               action_str,
18782582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18792582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18802582bfedSLuiz Capitulino 
18812582bfedSLuiz Capitulino     qobject_decref(data);
18822582bfedSLuiz Capitulino }
18832582bfedSLuiz Capitulino 
1884d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque)
1885b338082bSbellard {
1886d15e5465SLuiz Capitulino     QDict *bs_dict;
1887d15e5465SLuiz Capitulino     Monitor *mon = opaque;
1888b338082bSbellard 
1889d15e5465SLuiz Capitulino     bs_dict = qobject_to_qdict(obj);
1890d15e5465SLuiz Capitulino 
1891d8aeeb31SMarkus Armbruster     monitor_printf(mon, "%s: removable=%d",
1892d15e5465SLuiz Capitulino                         qdict_get_str(bs_dict, "device"),
1893d15e5465SLuiz Capitulino                         qdict_get_bool(bs_dict, "removable"));
1894d15e5465SLuiz Capitulino 
1895d15e5465SLuiz Capitulino     if (qdict_get_bool(bs_dict, "removable")) {
1896d15e5465SLuiz Capitulino         monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
1897e4def80bSMarkus Armbruster         monitor_printf(mon, " tray-open=%d",
1898e4def80bSMarkus Armbruster                        qdict_get_bool(bs_dict, "tray-open"));
1899b338082bSbellard     }
1900d2078cc2SLuiz Capitulino 
1901d2078cc2SLuiz Capitulino     if (qdict_haskey(bs_dict, "io-status")) {
1902d2078cc2SLuiz Capitulino         monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
1903d2078cc2SLuiz Capitulino     }
1904d2078cc2SLuiz Capitulino 
1905d15e5465SLuiz Capitulino     if (qdict_haskey(bs_dict, "inserted")) {
1906d15e5465SLuiz Capitulino         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
1907d15e5465SLuiz Capitulino 
1908376253ecSaliguori         monitor_printf(mon, " file=");
1909d15e5465SLuiz Capitulino         monitor_print_filename(mon, qdict_get_str(qdict, "file"));
1910d15e5465SLuiz Capitulino         if (qdict_haskey(qdict, "backing_file")) {
1911376253ecSaliguori             monitor_printf(mon, " backing_file=");
1912d15e5465SLuiz Capitulino             monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
1913fef30743Sths         }
1914d15e5465SLuiz Capitulino         monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
1915d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "ro"),
1916d15e5465SLuiz Capitulino                             qdict_get_str(qdict, "drv"),
1917d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "encrypted"));
1918b338082bSbellard     } else {
1919376253ecSaliguori         monitor_printf(mon, " [not inserted]");
1920b338082bSbellard     }
1921d15e5465SLuiz Capitulino 
1922376253ecSaliguori     monitor_printf(mon, "\n");
1923b338082bSbellard }
1924d15e5465SLuiz Capitulino 
1925d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data)
1926d15e5465SLuiz Capitulino {
1927d15e5465SLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
1928d15e5465SLuiz Capitulino }
1929d15e5465SLuiz Capitulino 
1930f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = {
1931f04ef601SLuiz Capitulino     [BDRV_IOS_OK] = "ok",
1932f04ef601SLuiz Capitulino     [BDRV_IOS_FAILED] = "failed",
1933f04ef601SLuiz Capitulino     [BDRV_IOS_ENOSPC] = "nospace",
1934f04ef601SLuiz Capitulino };
1935f04ef601SLuiz Capitulino 
1936d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data)
1937d15e5465SLuiz Capitulino {
1938d15e5465SLuiz Capitulino     QList *bs_list;
1939d15e5465SLuiz Capitulino     BlockDriverState *bs;
1940d15e5465SLuiz Capitulino 
1941d15e5465SLuiz Capitulino     bs_list = qlist_new();
1942d15e5465SLuiz Capitulino 
19431b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1944d15e5465SLuiz Capitulino         QObject *bs_obj;
1945e4def80bSMarkus Armbruster         QDict *bs_dict;
1946d15e5465SLuiz Capitulino 
1947d8aeeb31SMarkus Armbruster         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
1948d15e5465SLuiz Capitulino                                     "'removable': %i, 'locked': %i }",
19492c6942faSMarkus Armbruster                                     bs->device_name,
19502c6942faSMarkus Armbruster                                     bdrv_dev_has_removable_media(bs),
1951f107639aSMarkus Armbruster                                     bdrv_dev_is_medium_locked(bs));
1952e4def80bSMarkus Armbruster         bs_dict = qobject_to_qdict(bs_obj);
1953d15e5465SLuiz Capitulino 
1954e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1955e4def80bSMarkus Armbruster             qdict_put(bs_dict, "tray-open",
1956e4def80bSMarkus Armbruster                       qbool_from_int(bdrv_dev_is_tray_open(bs)));
1957e4def80bSMarkus Armbruster         }
1958f04ef601SLuiz Capitulino 
1959f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1960f04ef601SLuiz Capitulino             qdict_put(bs_dict, "io-status",
1961f04ef601SLuiz Capitulino                       qstring_from_str(io_status_name[bs->iostatus]));
1962f04ef601SLuiz Capitulino         }
1963f04ef601SLuiz Capitulino 
1964d15e5465SLuiz Capitulino         if (bs->drv) {
1965d15e5465SLuiz Capitulino             QObject *obj;
1966d15e5465SLuiz Capitulino 
1967d15e5465SLuiz Capitulino             obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
1968d15e5465SLuiz Capitulino                                      "'encrypted': %i }",
1969d15e5465SLuiz Capitulino                                      bs->filename, bs->read_only,
1970d15e5465SLuiz Capitulino                                      bs->drv->format_name,
1971d15e5465SLuiz Capitulino                                      bdrv_is_encrypted(bs));
1972d15e5465SLuiz Capitulino             if (bs->backing_file[0] != '\0') {
1973d15e5465SLuiz Capitulino                 QDict *qdict = qobject_to_qdict(obj);
1974d15e5465SLuiz Capitulino                 qdict_put(qdict, "backing_file",
1975d15e5465SLuiz Capitulino                           qstring_from_str(bs->backing_file));
1976d15e5465SLuiz Capitulino             }
1977d15e5465SLuiz Capitulino 
1978d15e5465SLuiz Capitulino             qdict_put_obj(bs_dict, "inserted", obj);
1979d15e5465SLuiz Capitulino         }
1980d15e5465SLuiz Capitulino         qlist_append_obj(bs_list, bs_obj);
1981d15e5465SLuiz Capitulino     }
1982d15e5465SLuiz Capitulino 
1983d15e5465SLuiz Capitulino     *ret_data = QOBJECT(bs_list);
1984b338082bSbellard }
1985a36e69ddSths 
1986218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque)
1987a36e69ddSths {
1988218a536aSLuiz Capitulino     QDict *qdict;
1989218a536aSLuiz Capitulino     Monitor *mon = opaque;
1990218a536aSLuiz Capitulino 
1991218a536aSLuiz Capitulino     qdict = qobject_to_qdict(data);
1992218a536aSLuiz Capitulino     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
1993218a536aSLuiz Capitulino 
1994218a536aSLuiz Capitulino     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
1995218a536aSLuiz Capitulino     monitor_printf(mon, " rd_bytes=%" PRId64
1996218a536aSLuiz Capitulino                         " wr_bytes=%" PRId64
1997218a536aSLuiz Capitulino                         " rd_operations=%" PRId64
1998218a536aSLuiz Capitulino                         " wr_operations=%" PRId64
1999e8045d67SChristoph Hellwig                         " flush_operations=%" PRId64
2000c488c7f6SChristoph Hellwig                         " wr_total_time_ns=%" PRId64
2001c488c7f6SChristoph Hellwig                         " rd_total_time_ns=%" PRId64
2002c488c7f6SChristoph Hellwig                         " flush_total_time_ns=%" PRId64
2003218a536aSLuiz Capitulino                         "\n",
2004218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_bytes"),
2005218a536aSLuiz Capitulino                         qdict_get_int(qdict, "wr_bytes"),
2006218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_operations"),
2007e8045d67SChristoph Hellwig                         qdict_get_int(qdict, "wr_operations"),
2008c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_operations"),
2009c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "wr_total_time_ns"),
2010c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "rd_total_time_ns"),
2011c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_total_time_ns"));
2012218a536aSLuiz Capitulino }
2013218a536aSLuiz Capitulino 
2014218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data)
2015218a536aSLuiz Capitulino {
2016218a536aSLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
2017218a536aSLuiz Capitulino }
2018218a536aSLuiz Capitulino 
2019294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
2020294cc35fSKevin Wolf {
2021294cc35fSKevin Wolf     QObject *res;
2022294cc35fSKevin Wolf     QDict *dict;
2023294cc35fSKevin Wolf 
2024294cc35fSKevin Wolf     res = qobject_from_jsonf("{ 'stats': {"
2025294cc35fSKevin Wolf                              "'rd_bytes': %" PRId64 ","
2026294cc35fSKevin Wolf                              "'wr_bytes': %" PRId64 ","
2027294cc35fSKevin Wolf                              "'rd_operations': %" PRId64 ","
2028294cc35fSKevin Wolf                              "'wr_operations': %" PRId64 ","
2029e8045d67SChristoph Hellwig                              "'wr_highest_offset': %" PRId64 ","
2030c488c7f6SChristoph Hellwig                              "'flush_operations': %" PRId64 ","
2031c488c7f6SChristoph Hellwig                              "'wr_total_time_ns': %" PRId64 ","
2032c488c7f6SChristoph Hellwig                              "'rd_total_time_ns': %" PRId64 ","
2033c488c7f6SChristoph Hellwig                              "'flush_total_time_ns': %" PRId64
2034294cc35fSKevin Wolf                              "} }",
2035a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_READ],
2036a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_WRITE],
2037a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_READ],
2038a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_WRITE],
20395ffbbc67SBlue Swirl                              bs->wr_highest_sector *
2040e8045d67SChristoph Hellwig                              (uint64_t)BDRV_SECTOR_SIZE,
2041c488c7f6SChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_FLUSH],
2042c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_WRITE],
2043c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_READ],
2044c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_FLUSH]);
2045294cc35fSKevin Wolf     dict  = qobject_to_qdict(res);
2046294cc35fSKevin Wolf 
2047294cc35fSKevin Wolf     if (*bs->device_name) {
2048294cc35fSKevin Wolf         qdict_put(dict, "device", qstring_from_str(bs->device_name));
2049294cc35fSKevin Wolf     }
2050294cc35fSKevin Wolf 
2051294cc35fSKevin Wolf     if (bs->file) {
2052294cc35fSKevin Wolf         QObject *parent = bdrv_info_stats_bs(bs->file);
2053294cc35fSKevin Wolf         qdict_put_obj(dict, "parent", parent);
2054294cc35fSKevin Wolf     }
2055294cc35fSKevin Wolf 
2056294cc35fSKevin Wolf     return res;
2057294cc35fSKevin Wolf }
2058294cc35fSKevin Wolf 
2059218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data)
2060218a536aSLuiz Capitulino {
2061218a536aSLuiz Capitulino     QObject *obj;
2062218a536aSLuiz Capitulino     QList *devices;
2063a36e69ddSths     BlockDriverState *bs;
2064a36e69ddSths 
2065218a536aSLuiz Capitulino     devices = qlist_new();
2066218a536aSLuiz Capitulino 
20671b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
2068294cc35fSKevin Wolf         obj = bdrv_info_stats_bs(bs);
2069218a536aSLuiz Capitulino         qlist_append_obj(devices, obj);
2070a36e69ddSths     }
2071218a536aSLuiz Capitulino 
2072218a536aSLuiz Capitulino     *ret_data = QOBJECT(devices);
2073a36e69ddSths }
2074ea2384d3Sbellard 
2075045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
2076045df330Saliguori {
2077045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
2078045df330Saliguori         return bs->backing_file;
2079045df330Saliguori     else if (bs->encrypted)
2080045df330Saliguori         return bs->filename;
2081045df330Saliguori     else
2082045df330Saliguori         return NULL;
2083045df330Saliguori }
2084045df330Saliguori 
208583f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
208683f64091Sbellard                                char *filename, int filename_size)
208783f64091Sbellard {
2088b783e409SKevin Wolf     if (!bs->backing_file) {
208983f64091Sbellard         pstrcpy(filename, filename_size, "");
209083f64091Sbellard     } else {
209183f64091Sbellard         pstrcpy(filename, filename_size, bs->backing_file);
209283f64091Sbellard     }
209383f64091Sbellard }
209483f64091Sbellard 
2095faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
2096faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
2097faea38e7Sbellard {
2098faea38e7Sbellard     BlockDriver *drv = bs->drv;
2099faea38e7Sbellard     if (!drv)
210019cb3738Sbellard         return -ENOMEDIUM;
2101faea38e7Sbellard     if (!drv->bdrv_write_compressed)
2102faea38e7Sbellard         return -ENOTSUP;
2103fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
2104fbb7b4e0SKevin Wolf         return -EIO;
21057cd1e32aSlirans@il.ibm.com 
2106c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
21077cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
21087cd1e32aSlirans@il.ibm.com     }
21097cd1e32aSlirans@il.ibm.com 
2110faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2111faea38e7Sbellard }
2112faea38e7Sbellard 
2113faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2114faea38e7Sbellard {
2115faea38e7Sbellard     BlockDriver *drv = bs->drv;
2116faea38e7Sbellard     if (!drv)
211719cb3738Sbellard         return -ENOMEDIUM;
2118faea38e7Sbellard     if (!drv->bdrv_get_info)
2119faea38e7Sbellard         return -ENOTSUP;
2120faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2121faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2122faea38e7Sbellard }
2123faea38e7Sbellard 
212445566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
212545566e9cSChristoph Hellwig                       int64_t pos, int size)
2126178e08a5Saliguori {
2127178e08a5Saliguori     BlockDriver *drv = bs->drv;
2128178e08a5Saliguori     if (!drv)
2129178e08a5Saliguori         return -ENOMEDIUM;
21307cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
213145566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
21327cdb1f6dSMORITA Kazutaka     if (bs->file)
21337cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
21347cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2135178e08a5Saliguori }
2136178e08a5Saliguori 
213745566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
213845566e9cSChristoph Hellwig                       int64_t pos, int size)
2139178e08a5Saliguori {
2140178e08a5Saliguori     BlockDriver *drv = bs->drv;
2141178e08a5Saliguori     if (!drv)
2142178e08a5Saliguori         return -ENOMEDIUM;
21437cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
214445566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
21457cdb1f6dSMORITA Kazutaka     if (bs->file)
21467cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
21477cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2148178e08a5Saliguori }
2149178e08a5Saliguori 
21508b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
21518b9b0cc2SKevin Wolf {
21528b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
21538b9b0cc2SKevin Wolf 
21548b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
21558b9b0cc2SKevin Wolf         return;
21568b9b0cc2SKevin Wolf     }
21578b9b0cc2SKevin Wolf 
21588b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
21598b9b0cc2SKevin Wolf 
21608b9b0cc2SKevin Wolf }
21618b9b0cc2SKevin Wolf 
2162faea38e7Sbellard /**************************************************************/
2163faea38e7Sbellard /* handling of snapshots */
2164faea38e7Sbellard 
2165feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2166feeee5acSMiguel Di Ciurcio Filho {
2167feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
216807b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2169feeee5acSMiguel Di Ciurcio Filho         return 0;
2170feeee5acSMiguel Di Ciurcio Filho     }
2171feeee5acSMiguel Di Ciurcio Filho 
2172feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2173feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2174feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2175feeee5acSMiguel Di Ciurcio Filho         }
2176feeee5acSMiguel Di Ciurcio Filho         return 0;
2177feeee5acSMiguel Di Ciurcio Filho     }
2178feeee5acSMiguel Di Ciurcio Filho 
2179feeee5acSMiguel Di Ciurcio Filho     return 1;
2180feeee5acSMiguel Di Ciurcio Filho }
2181feeee5acSMiguel Di Ciurcio Filho 
2182199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2183199630b6SBlue Swirl {
2184199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2185199630b6SBlue Swirl }
2186199630b6SBlue Swirl 
2187f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2188f9092b10SMarkus Armbruster {
2189f9092b10SMarkus Armbruster     BlockDriverState *bs;
2190f9092b10SMarkus Armbruster 
21913ac906f7SMarkus Armbruster     if (bs_snapshots) {
2192f9092b10SMarkus Armbruster         return bs_snapshots;
21933ac906f7SMarkus Armbruster     }
2194f9092b10SMarkus Armbruster 
2195f9092b10SMarkus Armbruster     bs = NULL;
2196f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2197f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
21983ac906f7SMarkus Armbruster             bs_snapshots = bs;
21993ac906f7SMarkus Armbruster             return bs;
2200f9092b10SMarkus Armbruster         }
2201f9092b10SMarkus Armbruster     }
2202f9092b10SMarkus Armbruster     return NULL;
2203f9092b10SMarkus Armbruster }
2204f9092b10SMarkus Armbruster 
2205faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2206faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2207faea38e7Sbellard {
2208faea38e7Sbellard     BlockDriver *drv = bs->drv;
2209faea38e7Sbellard     if (!drv)
221019cb3738Sbellard         return -ENOMEDIUM;
22117cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2212faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
22137cdb1f6dSMORITA Kazutaka     if (bs->file)
22147cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
22157cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2216faea38e7Sbellard }
2217faea38e7Sbellard 
2218faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2219faea38e7Sbellard                        const char *snapshot_id)
2220faea38e7Sbellard {
2221faea38e7Sbellard     BlockDriver *drv = bs->drv;
22227cdb1f6dSMORITA Kazutaka     int ret, open_ret;
22237cdb1f6dSMORITA Kazutaka 
2224faea38e7Sbellard     if (!drv)
222519cb3738Sbellard         return -ENOMEDIUM;
22267cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2227faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
22287cdb1f6dSMORITA Kazutaka 
22297cdb1f6dSMORITA Kazutaka     if (bs->file) {
22307cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
22317cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
22327cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
22337cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
22347cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
22357cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
22367cdb1f6dSMORITA Kazutaka             return open_ret;
22377cdb1f6dSMORITA Kazutaka         }
22387cdb1f6dSMORITA Kazutaka         return ret;
22397cdb1f6dSMORITA Kazutaka     }
22407cdb1f6dSMORITA Kazutaka 
22417cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2242faea38e7Sbellard }
2243faea38e7Sbellard 
2244faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2245faea38e7Sbellard {
2246faea38e7Sbellard     BlockDriver *drv = bs->drv;
2247faea38e7Sbellard     if (!drv)
224819cb3738Sbellard         return -ENOMEDIUM;
22497cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2250faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
22517cdb1f6dSMORITA Kazutaka     if (bs->file)
22527cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
22537cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2254faea38e7Sbellard }
2255faea38e7Sbellard 
2256faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2257faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2258faea38e7Sbellard {
2259faea38e7Sbellard     BlockDriver *drv = bs->drv;
2260faea38e7Sbellard     if (!drv)
226119cb3738Sbellard         return -ENOMEDIUM;
22627cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2263faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
22647cdb1f6dSMORITA Kazutaka     if (bs->file)
22657cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
22667cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2267faea38e7Sbellard }
2268faea38e7Sbellard 
226951ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
227051ef6727Sedison         const char *snapshot_name)
227151ef6727Sedison {
227251ef6727Sedison     BlockDriver *drv = bs->drv;
227351ef6727Sedison     if (!drv) {
227451ef6727Sedison         return -ENOMEDIUM;
227551ef6727Sedison     }
227651ef6727Sedison     if (!bs->read_only) {
227751ef6727Sedison         return -EINVAL;
227851ef6727Sedison     }
227951ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
228051ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
228151ef6727Sedison     }
228251ef6727Sedison     return -ENOTSUP;
228351ef6727Sedison }
228451ef6727Sedison 
2285faea38e7Sbellard #define NB_SUFFIXES 4
2286faea38e7Sbellard 
2287faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2288faea38e7Sbellard {
2289faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2290faea38e7Sbellard     int64_t base;
2291faea38e7Sbellard     int i;
2292faea38e7Sbellard 
2293faea38e7Sbellard     if (size <= 999) {
2294faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2295faea38e7Sbellard     } else {
2296faea38e7Sbellard         base = 1024;
2297faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2298faea38e7Sbellard             if (size < (10 * base)) {
2299faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2300faea38e7Sbellard                          (double)size / base,
2301faea38e7Sbellard                          suffixes[i]);
2302faea38e7Sbellard                 break;
2303faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2304faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2305faea38e7Sbellard                          ((size + (base >> 1)) / base),
2306faea38e7Sbellard                          suffixes[i]);
2307faea38e7Sbellard                 break;
2308faea38e7Sbellard             }
2309faea38e7Sbellard             base = base * 1024;
2310faea38e7Sbellard         }
2311faea38e7Sbellard     }
2312faea38e7Sbellard     return buf;
2313faea38e7Sbellard }
2314faea38e7Sbellard 
2315faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2316faea38e7Sbellard {
2317faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
23183b9f94e1Sbellard #ifdef _WIN32
23193b9f94e1Sbellard     struct tm *ptm;
23203b9f94e1Sbellard #else
2321faea38e7Sbellard     struct tm tm;
23223b9f94e1Sbellard #endif
2323faea38e7Sbellard     time_t ti;
2324faea38e7Sbellard     int64_t secs;
2325faea38e7Sbellard 
2326faea38e7Sbellard     if (!sn) {
2327faea38e7Sbellard         snprintf(buf, buf_size,
2328faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2329faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2330faea38e7Sbellard     } else {
2331faea38e7Sbellard         ti = sn->date_sec;
23323b9f94e1Sbellard #ifdef _WIN32
23333b9f94e1Sbellard         ptm = localtime(&ti);
23343b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
23353b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
23363b9f94e1Sbellard #else
2337faea38e7Sbellard         localtime_r(&ti, &tm);
2338faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2339faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
23403b9f94e1Sbellard #endif
2341faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2342faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2343faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2344faea38e7Sbellard                  (int)(secs / 3600),
2345faea38e7Sbellard                  (int)((secs / 60) % 60),
2346faea38e7Sbellard                  (int)(secs % 60),
2347faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2348faea38e7Sbellard         snprintf(buf, buf_size,
2349faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2350faea38e7Sbellard                  sn->id_str, sn->name,
2351faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2352faea38e7Sbellard                  date_buf,
2353faea38e7Sbellard                  clock_buf);
2354faea38e7Sbellard     }
2355faea38e7Sbellard     return buf;
2356faea38e7Sbellard }
2357faea38e7Sbellard 
2358ea2384d3Sbellard /**************************************************************/
235983f64091Sbellard /* async I/Os */
2360ea2384d3Sbellard 
23613b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2362f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
236383f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2364ea2384d3Sbellard {
2365bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2366bbf0a440SStefan Hajnoczi 
2367b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
23688c5873d6SStefan Hajnoczi                                  cb, opaque, false);
236983f64091Sbellard }
237083f64091Sbellard 
2371f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2372f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
237383f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
23747674e7bfSbellard {
2375bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2376bbf0a440SStefan Hajnoczi 
23771a6e115bSStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
23788c5873d6SStefan Hajnoczi                                  cb, opaque, true);
237983f64091Sbellard }
238083f64091Sbellard 
238140b4f539SKevin Wolf 
238240b4f539SKevin Wolf typedef struct MultiwriteCB {
238340b4f539SKevin Wolf     int error;
238440b4f539SKevin Wolf     int num_requests;
238540b4f539SKevin Wolf     int num_callbacks;
238640b4f539SKevin Wolf     struct {
238740b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
238840b4f539SKevin Wolf         void *opaque;
238940b4f539SKevin Wolf         QEMUIOVector *free_qiov;
239040b4f539SKevin Wolf         void *free_buf;
239140b4f539SKevin Wolf     } callbacks[];
239240b4f539SKevin Wolf } MultiwriteCB;
239340b4f539SKevin Wolf 
239440b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
239540b4f539SKevin Wolf {
239640b4f539SKevin Wolf     int i;
239740b4f539SKevin Wolf 
239840b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
239940b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
24001e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
24011e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
24021e1ea48dSStefan Hajnoczi         }
24037267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2404f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
240540b4f539SKevin Wolf     }
240640b4f539SKevin Wolf }
240740b4f539SKevin Wolf 
240840b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
240940b4f539SKevin Wolf {
241040b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
241140b4f539SKevin Wolf 
24126d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
24136d519a5fSStefan Hajnoczi 
2414cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
241540b4f539SKevin Wolf         mcb->error = ret;
241640b4f539SKevin Wolf     }
241740b4f539SKevin Wolf 
241840b4f539SKevin Wolf     mcb->num_requests--;
241940b4f539SKevin Wolf     if (mcb->num_requests == 0) {
242040b4f539SKevin Wolf         multiwrite_user_cb(mcb);
24217267c094SAnthony Liguori         g_free(mcb);
242240b4f539SKevin Wolf     }
242340b4f539SKevin Wolf }
242440b4f539SKevin Wolf 
242540b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
242640b4f539SKevin Wolf {
242777be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
242877be4366SChristoph Hellwig 
242977be4366SChristoph Hellwig     /*
243077be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
243177be4366SChristoph Hellwig      * here as that could overflow the return value.
243277be4366SChristoph Hellwig      */
243377be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
243477be4366SChristoph Hellwig         return 1;
243577be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
243677be4366SChristoph Hellwig         return -1;
243777be4366SChristoph Hellwig     } else {
243877be4366SChristoph Hellwig         return 0;
243977be4366SChristoph Hellwig     }
244040b4f539SKevin Wolf }
244140b4f539SKevin Wolf 
244240b4f539SKevin Wolf /*
244340b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
244440b4f539SKevin Wolf  * requests that remain after merging.
244540b4f539SKevin Wolf  */
244640b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
244740b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
244840b4f539SKevin Wolf {
244940b4f539SKevin Wolf     int i, outidx;
245040b4f539SKevin Wolf 
245140b4f539SKevin Wolf     // Sort requests by start sector
245240b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
245340b4f539SKevin Wolf 
245440b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
245540b4f539SKevin Wolf     // filling up gaps with zero sectors.
245640b4f539SKevin Wolf     outidx = 0;
245740b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
245840b4f539SKevin Wolf         int merge = 0;
245940b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
246040b4f539SKevin Wolf 
246140b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
246240b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
246340b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
246440b4f539SKevin Wolf             merge = 1;
246540b4f539SKevin Wolf         }
246640b4f539SKevin Wolf 
246740b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
246840b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
246940b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
247040b4f539SKevin Wolf         // unused space in format like qcow2).
247140b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
247240b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
247340b4f539SKevin Wolf         }
247440b4f539SKevin Wolf 
2475e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2476e2a305fbSChristoph Hellwig             merge = 0;
2477e2a305fbSChristoph Hellwig         }
2478e2a305fbSChristoph Hellwig 
247940b4f539SKevin Wolf         if (merge) {
248040b4f539SKevin Wolf             size_t size;
24817267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
248240b4f539SKevin Wolf             qemu_iovec_init(qiov,
248340b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
248440b4f539SKevin Wolf 
248540b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
248640b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
248740b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
248840b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
248940b4f539SKevin Wolf 
249040b4f539SKevin Wolf             // We might need to add some zeros between the two requests
249140b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
249240b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
249340b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
249440b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
249540b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
249640b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
249740b4f539SKevin Wolf             }
249840b4f539SKevin Wolf 
249940b4f539SKevin Wolf             // Add the second request
250040b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
250140b4f539SKevin Wolf 
2502cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
250340b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
250440b4f539SKevin Wolf 
250540b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
250640b4f539SKevin Wolf         } else {
250740b4f539SKevin Wolf             outidx++;
250840b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
250940b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
251040b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
251140b4f539SKevin Wolf         }
251240b4f539SKevin Wolf     }
251340b4f539SKevin Wolf 
251440b4f539SKevin Wolf     return outidx + 1;
251540b4f539SKevin Wolf }
251640b4f539SKevin Wolf 
251740b4f539SKevin Wolf /*
251840b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
251940b4f539SKevin Wolf  *
252040b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
252140b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
252240b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
252340b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
252440b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
252540b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
252640b4f539SKevin Wolf  *
252740b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
252840b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
252940b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
253040b4f539SKevin Wolf  */
253140b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
253240b4f539SKevin Wolf {
253340b4f539SKevin Wolf     BlockDriverAIOCB *acb;
253440b4f539SKevin Wolf     MultiwriteCB *mcb;
253540b4f539SKevin Wolf     int i;
253640b4f539SKevin Wolf 
2537301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2538301db7c2SRyan Harper     if (bs->drv == NULL) {
2539301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2540301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2541301db7c2SRyan Harper         }
2542301db7c2SRyan Harper         return -1;
2543301db7c2SRyan Harper     }
2544301db7c2SRyan Harper 
254540b4f539SKevin Wolf     if (num_reqs == 0) {
254640b4f539SKevin Wolf         return 0;
254740b4f539SKevin Wolf     }
254840b4f539SKevin Wolf 
254940b4f539SKevin Wolf     // Create MultiwriteCB structure
25507267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
255140b4f539SKevin Wolf     mcb->num_requests = 0;
255240b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
255340b4f539SKevin Wolf 
255440b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
255540b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
255640b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
255740b4f539SKevin Wolf     }
255840b4f539SKevin Wolf 
255940b4f539SKevin Wolf     // Check for mergable requests
256040b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
256140b4f539SKevin Wolf 
25626d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
25636d519a5fSStefan Hajnoczi 
2564453f9a16SKevin Wolf     /*
2565453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2566453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2567453f9a16SKevin Wolf      * return failure for all requests anyway)
2568453f9a16SKevin Wolf      *
2569453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2570453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2571453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2572453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2573453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2574453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2575453f9a16SKevin Wolf      * incremented for each request that is submitted.
2576453f9a16SKevin Wolf      *
2577453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2578453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2579453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2580453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2581453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2582453f9a16SKevin Wolf      */
2583453f9a16SKevin Wolf     mcb->num_requests = 1;
2584453f9a16SKevin Wolf 
25856d519a5fSStefan Hajnoczi     // Run the aio requests
258640b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2587453f9a16SKevin Wolf         mcb->num_requests++;
258840b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
258940b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
259040b4f539SKevin Wolf 
259140b4f539SKevin Wolf         if (acb == NULL) {
259240b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
259340b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
259440b4f539SKevin Wolf             // complete and report the error in the callback.
2595453f9a16SKevin Wolf             if (i == 0) {
25966d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
259740b4f539SKevin Wolf                 goto fail;
259840b4f539SKevin Wolf             } else {
25996d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
26007eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
260140b4f539SKevin Wolf                 break;
260240b4f539SKevin Wolf             }
260340b4f539SKevin Wolf         }
260440b4f539SKevin Wolf     }
260540b4f539SKevin Wolf 
2606453f9a16SKevin Wolf     /* Complete the dummy request */
2607453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2608453f9a16SKevin Wolf 
260940b4f539SKevin Wolf     return 0;
261040b4f539SKevin Wolf 
261140b4f539SKevin Wolf fail:
2612453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2613453f9a16SKevin Wolf         reqs[i].error = -EIO;
2614453f9a16SKevin Wolf     }
26157267c094SAnthony Liguori     g_free(mcb);
261640b4f539SKevin Wolf     return -1;
261740b4f539SKevin Wolf }
261840b4f539SKevin Wolf 
2619b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2620b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2621b2e12bc6SChristoph Hellwig {
2622b2e12bc6SChristoph Hellwig     BlockDriver *drv = bs->drv;
2623b2e12bc6SChristoph Hellwig 
2624a13aac04SStefan Hajnoczi     trace_bdrv_aio_flush(bs, opaque);
2625a13aac04SStefan Hajnoczi 
2626016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
2627016f5cf6SAlexander Graf         return bdrv_aio_noop_em(bs, cb, opaque);
2628016f5cf6SAlexander Graf     }
2629016f5cf6SAlexander Graf 
2630b2e12bc6SChristoph Hellwig     if (!drv)
2631b2e12bc6SChristoph Hellwig         return NULL;
2632b2e12bc6SChristoph Hellwig     return drv->bdrv_aio_flush(bs, cb, opaque);
2633b2e12bc6SChristoph Hellwig }
2634b2e12bc6SChristoph Hellwig 
263583f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
263683f64091Sbellard {
26376bbff9a0Saliguori     acb->pool->cancel(acb);
263883f64091Sbellard }
263983f64091Sbellard 
264083f64091Sbellard 
264183f64091Sbellard /**************************************************************/
264283f64091Sbellard /* async block device emulation */
264383f64091Sbellard 
2644c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2645c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2646c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2647c16b5a2cSChristoph Hellwig     int ret;
2648c16b5a2cSChristoph Hellwig     /* vector translation state */
2649c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2650c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2651c16b5a2cSChristoph Hellwig     int is_write;
2652c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2653c16b5a2cSChristoph Hellwig 
2654c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2655c16b5a2cSChristoph Hellwig {
2656b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2657b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
26586a7ad299SDor Laor     qemu_bh_delete(acb->bh);
265936afc451SAvi Kivity     acb->bh = NULL;
2660c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2661c16b5a2cSChristoph Hellwig }
2662c16b5a2cSChristoph Hellwig 
2663c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2664c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2665c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2666c16b5a2cSChristoph Hellwig };
2667c16b5a2cSChristoph Hellwig 
266883f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2669beac80cdSbellard {
2670ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2671f141eafeSaliguori 
2672f141eafeSaliguori     if (!acb->is_write)
2673f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2674ceb42de8Saliguori     qemu_vfree(acb->bounce);
2675ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
26766a7ad299SDor Laor     qemu_bh_delete(acb->bh);
267736afc451SAvi Kivity     acb->bh = NULL;
2678ce1a14dcSpbrook     qemu_aio_release(acb);
2679beac80cdSbellard }
2680beac80cdSbellard 
2681f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2682f141eafeSaliguori                                             int64_t sector_num,
2683f141eafeSaliguori                                             QEMUIOVector *qiov,
2684f141eafeSaliguori                                             int nb_sectors,
2685f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2686f141eafeSaliguori                                             void *opaque,
2687f141eafeSaliguori                                             int is_write)
2688f141eafeSaliguori 
2689ea2384d3Sbellard {
2690ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
269183f64091Sbellard 
2692c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2693f141eafeSaliguori     acb->is_write = is_write;
2694f141eafeSaliguori     acb->qiov = qiov;
2695e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2696f141eafeSaliguori 
2697ce1a14dcSpbrook     if (!acb->bh)
2698ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2699f141eafeSaliguori 
2700f141eafeSaliguori     if (is_write) {
2701f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
27021ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2703f141eafeSaliguori     } else {
27041ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2705f141eafeSaliguori     }
2706f141eafeSaliguori 
2707ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2708f141eafeSaliguori 
2709ce1a14dcSpbrook     return &acb->common;
27107a6cba61Spbrook }
27117a6cba61Spbrook 
2712f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2713f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2714ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
271583f64091Sbellard {
2716f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
271783f64091Sbellard }
271883f64091Sbellard 
2719f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2720f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2721f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2722f141eafeSaliguori {
2723f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2724f141eafeSaliguori }
2725f141eafeSaliguori 
272668485420SKevin Wolf 
272768485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
272868485420SKevin Wolf     BlockDriverAIOCB common;
272968485420SKevin Wolf     BlockRequest req;
273068485420SKevin Wolf     bool is_write;
273168485420SKevin Wolf     QEMUBH* bh;
273268485420SKevin Wolf } BlockDriverAIOCBCoroutine;
273368485420SKevin Wolf 
273468485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
273568485420SKevin Wolf {
273668485420SKevin Wolf     qemu_aio_flush();
273768485420SKevin Wolf }
273868485420SKevin Wolf 
273968485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
274068485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
274168485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
274268485420SKevin Wolf };
274368485420SKevin Wolf 
274468485420SKevin Wolf static void bdrv_co_rw_bh(void *opaque)
274568485420SKevin Wolf {
274668485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
274768485420SKevin Wolf 
274868485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
274968485420SKevin Wolf     qemu_bh_delete(acb->bh);
275068485420SKevin Wolf     qemu_aio_release(acb);
275168485420SKevin Wolf }
275268485420SKevin Wolf 
2753b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2754b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2755b2a61371SStefan Hajnoczi {
2756b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2757b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2758b2a61371SStefan Hajnoczi 
2759b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2760b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2761b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2762b2a61371SStefan Hajnoczi     } else {
2763b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2764b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2765b2a61371SStefan Hajnoczi     }
2766b2a61371SStefan Hajnoczi 
2767b2a61371SStefan Hajnoczi     acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
2768b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2769b2a61371SStefan Hajnoczi }
2770b2a61371SStefan Hajnoczi 
277168485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
277268485420SKevin Wolf                                                int64_t sector_num,
277368485420SKevin Wolf                                                QEMUIOVector *qiov,
277468485420SKevin Wolf                                                int nb_sectors,
277568485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
277668485420SKevin Wolf                                                void *opaque,
27778c5873d6SStefan Hajnoczi                                                bool is_write)
277868485420SKevin Wolf {
277968485420SKevin Wolf     Coroutine *co;
278068485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
278168485420SKevin Wolf 
278268485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
278368485420SKevin Wolf     acb->req.sector = sector_num;
278468485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
278568485420SKevin Wolf     acb->req.qiov = qiov;
278668485420SKevin Wolf     acb->is_write = is_write;
278768485420SKevin Wolf 
27888c5873d6SStefan Hajnoczi     co = qemu_coroutine_create(bdrv_co_do_rw);
278968485420SKevin Wolf     qemu_coroutine_enter(co, acb);
279068485420SKevin Wolf 
279168485420SKevin Wolf     return &acb->common;
279268485420SKevin Wolf }
279368485420SKevin Wolf 
2794b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
2795b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2796b2e12bc6SChristoph Hellwig {
2797b2e12bc6SChristoph Hellwig     BlockDriverAIOCBSync *acb;
2798b2e12bc6SChristoph Hellwig 
2799b2e12bc6SChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2800b2e12bc6SChristoph Hellwig     acb->is_write = 1; /* don't bounce in the completion hadler */
2801b2e12bc6SChristoph Hellwig     acb->qiov = NULL;
2802b2e12bc6SChristoph Hellwig     acb->bounce = NULL;
2803b2e12bc6SChristoph Hellwig     acb->ret = 0;
2804b2e12bc6SChristoph Hellwig 
2805b2e12bc6SChristoph Hellwig     if (!acb->bh)
2806b2e12bc6SChristoph Hellwig         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2807b2e12bc6SChristoph Hellwig 
2808b2e12bc6SChristoph Hellwig     bdrv_flush(bs);
2809b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2810b2e12bc6SChristoph Hellwig     return &acb->common;
2811b2e12bc6SChristoph Hellwig }
2812b2e12bc6SChristoph Hellwig 
2813016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
2814016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2815016f5cf6SAlexander Graf {
2816016f5cf6SAlexander Graf     BlockDriverAIOCBSync *acb;
2817016f5cf6SAlexander Graf 
2818016f5cf6SAlexander Graf     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2819016f5cf6SAlexander Graf     acb->is_write = 1; /* don't bounce in the completion handler */
2820016f5cf6SAlexander Graf     acb->qiov = NULL;
2821016f5cf6SAlexander Graf     acb->bounce = NULL;
2822016f5cf6SAlexander Graf     acb->ret = 0;
2823016f5cf6SAlexander Graf 
2824016f5cf6SAlexander Graf     if (!acb->bh) {
2825016f5cf6SAlexander Graf         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2826016f5cf6SAlexander Graf     }
2827016f5cf6SAlexander Graf 
2828016f5cf6SAlexander Graf     qemu_bh_schedule(acb->bh);
2829016f5cf6SAlexander Graf     return &acb->common;
2830016f5cf6SAlexander Graf }
2831016f5cf6SAlexander Graf 
2832ea2384d3Sbellard void bdrv_init(void)
2833ea2384d3Sbellard {
28345efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2835ea2384d3Sbellard }
2836ce1a14dcSpbrook 
2837eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2838eb852011SMarkus Armbruster {
2839eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2840eb852011SMarkus Armbruster     bdrv_init();
2841eb852011SMarkus Armbruster }
2842eb852011SMarkus Armbruster 
2843c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
28446bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
28456bbff9a0Saliguori {
2846ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2847ce1a14dcSpbrook 
28486bbff9a0Saliguori     if (pool->free_aiocb) {
28496bbff9a0Saliguori         acb = pool->free_aiocb;
28506bbff9a0Saliguori         pool->free_aiocb = acb->next;
2851ce1a14dcSpbrook     } else {
28527267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
28536bbff9a0Saliguori         acb->pool = pool;
2854ce1a14dcSpbrook     }
2855ce1a14dcSpbrook     acb->bs = bs;
2856ce1a14dcSpbrook     acb->cb = cb;
2857ce1a14dcSpbrook     acb->opaque = opaque;
2858ce1a14dcSpbrook     return acb;
2859ce1a14dcSpbrook }
2860ce1a14dcSpbrook 
2861ce1a14dcSpbrook void qemu_aio_release(void *p)
2862ce1a14dcSpbrook {
28636bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
28646bbff9a0Saliguori     AIOPool *pool = acb->pool;
28656bbff9a0Saliguori     acb->next = pool->free_aiocb;
28666bbff9a0Saliguori     pool->free_aiocb = acb;
2867ce1a14dcSpbrook }
286819cb3738Sbellard 
286919cb3738Sbellard /**************************************************************/
2870f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2871f9f05dc5SKevin Wolf 
2872f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2873f9f05dc5SKevin Wolf     Coroutine *coroutine;
2874f9f05dc5SKevin Wolf     int ret;
2875f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2876f9f05dc5SKevin Wolf 
2877f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2878f9f05dc5SKevin Wolf {
2879f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2880f9f05dc5SKevin Wolf 
2881f9f05dc5SKevin Wolf     co->ret = ret;
2882f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
2883f9f05dc5SKevin Wolf }
2884f9f05dc5SKevin Wolf 
2885f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
2886f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
2887f9f05dc5SKevin Wolf                                       bool is_write)
2888f9f05dc5SKevin Wolf {
2889f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
2890f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
2891f9f05dc5SKevin Wolf     };
2892f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
2893f9f05dc5SKevin Wolf 
2894f9f05dc5SKevin Wolf     if (is_write) {
2895a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
2896f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
2897f9f05dc5SKevin Wolf     } else {
2898a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
2899f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
2900f9f05dc5SKevin Wolf     }
2901f9f05dc5SKevin Wolf 
290259370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
2903f9f05dc5SKevin Wolf     if (!acb) {
2904f9f05dc5SKevin Wolf         return -EIO;
2905f9f05dc5SKevin Wolf     }
2906f9f05dc5SKevin Wolf     qemu_coroutine_yield();
2907f9f05dc5SKevin Wolf 
2908f9f05dc5SKevin Wolf     return co.ret;
2909f9f05dc5SKevin Wolf }
2910f9f05dc5SKevin Wolf 
2911f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
2912f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2913f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2914f9f05dc5SKevin Wolf {
2915f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
2916f9f05dc5SKevin Wolf }
2917f9f05dc5SKevin Wolf 
2918f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
2919f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2920f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2921f9f05dc5SKevin Wolf {
2922f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
2923f9f05dc5SKevin Wolf }
2924f9f05dc5SKevin Wolf 
2925e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
2926e7a8a783SKevin Wolf {
2927e7a8a783SKevin Wolf     CoroutineIOCompletion co = {
2928e7a8a783SKevin Wolf         .coroutine = qemu_coroutine_self(),
2929e7a8a783SKevin Wolf     };
2930e7a8a783SKevin Wolf     BlockDriverAIOCB *acb;
2931e7a8a783SKevin Wolf 
2932e7a8a783SKevin Wolf     acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
2933e7a8a783SKevin Wolf     if (!acb) {
2934e7a8a783SKevin Wolf         return -EIO;
2935e7a8a783SKevin Wolf     }
2936e7a8a783SKevin Wolf     qemu_coroutine_yield();
2937e7a8a783SKevin Wolf     return co.ret;
2938e7a8a783SKevin Wolf }
2939e7a8a783SKevin Wolf 
2940f9f05dc5SKevin Wolf /**************************************************************/
294119cb3738Sbellard /* removable device support */
294219cb3738Sbellard 
294319cb3738Sbellard /**
294419cb3738Sbellard  * Return TRUE if the media is present
294519cb3738Sbellard  */
294619cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
294719cb3738Sbellard {
294819cb3738Sbellard     BlockDriver *drv = bs->drv;
2949a1aff5bfSMarkus Armbruster 
295019cb3738Sbellard     if (!drv)
295119cb3738Sbellard         return 0;
295219cb3738Sbellard     if (!drv->bdrv_is_inserted)
2953a1aff5bfSMarkus Armbruster         return 1;
2954a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
295519cb3738Sbellard }
295619cb3738Sbellard 
295719cb3738Sbellard /**
29588e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
29598e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
296019cb3738Sbellard  */
296119cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
296219cb3738Sbellard {
296319cb3738Sbellard     BlockDriver *drv = bs->drv;
296419cb3738Sbellard 
29658e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
29668e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
29678e49ca46SMarkus Armbruster     }
29688e49ca46SMarkus Armbruster     return -ENOTSUP;
296919cb3738Sbellard }
297019cb3738Sbellard 
297119cb3738Sbellard /**
297219cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
297319cb3738Sbellard  */
2974fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
297519cb3738Sbellard {
297619cb3738Sbellard     BlockDriver *drv = bs->drv;
297719cb3738Sbellard 
2978822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
2979822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
298019cb3738Sbellard     }
298119cb3738Sbellard }
298219cb3738Sbellard 
298319cb3738Sbellard /**
298419cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
298519cb3738Sbellard  * to eject it manually).
298619cb3738Sbellard  */
2987025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
298819cb3738Sbellard {
298919cb3738Sbellard     BlockDriver *drv = bs->drv;
299019cb3738Sbellard 
2991025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
2992b8c6d095SStefan Hajnoczi 
2993025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
2994025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
299519cb3738Sbellard     }
299619cb3738Sbellard }
2997985a03b0Sths 
2998985a03b0Sths /* needed for generic scsi interface */
2999985a03b0Sths 
3000985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3001985a03b0Sths {
3002985a03b0Sths     BlockDriver *drv = bs->drv;
3003985a03b0Sths 
3004985a03b0Sths     if (drv && drv->bdrv_ioctl)
3005985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3006985a03b0Sths     return -ENOTSUP;
3007985a03b0Sths }
30087d780669Saliguori 
3009221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3010221f715dSaliguori         unsigned long int req, void *buf,
30117d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
30127d780669Saliguori {
3013221f715dSaliguori     BlockDriver *drv = bs->drv;
30147d780669Saliguori 
3015221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3016221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3017221f715dSaliguori     return NULL;
30187d780669Saliguori }
3019e268ca52Saliguori 
30207b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
30217b6f9300SMarkus Armbruster {
30227b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
30237b6f9300SMarkus Armbruster }
30247cd1e32aSlirans@il.ibm.com 
3025e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3026e268ca52Saliguori {
3027e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3028e268ca52Saliguori }
30297cd1e32aSlirans@il.ibm.com 
30307cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
30317cd1e32aSlirans@il.ibm.com {
30327cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3033a55eb92cSJan Kiszka 
3034aaa0eb75SLiran Schour     bs->dirty_count = 0;
30357cd1e32aSlirans@il.ibm.com     if (enable) {
3036c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3037c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3038c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3039c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
30407cd1e32aSlirans@il.ibm.com 
30417267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
30427cd1e32aSlirans@il.ibm.com         }
30437cd1e32aSlirans@il.ibm.com     } else {
3044c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
30457267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3046c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
30477cd1e32aSlirans@il.ibm.com         }
30487cd1e32aSlirans@il.ibm.com     }
30497cd1e32aSlirans@il.ibm.com }
30507cd1e32aSlirans@il.ibm.com 
30517cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
30527cd1e32aSlirans@il.ibm.com {
30536ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
30547cd1e32aSlirans@il.ibm.com 
3055c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3056c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
30576d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
30586d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
30597cd1e32aSlirans@il.ibm.com     } else {
30607cd1e32aSlirans@il.ibm.com         return 0;
30617cd1e32aSlirans@il.ibm.com     }
30627cd1e32aSlirans@il.ibm.com }
30637cd1e32aSlirans@il.ibm.com 
30647cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
30657cd1e32aSlirans@il.ibm.com                       int nr_sectors)
30667cd1e32aSlirans@il.ibm.com {
30677cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
30687cd1e32aSlirans@il.ibm.com }
3069aaa0eb75SLiran Schour 
3070aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3071aaa0eb75SLiran Schour {
3072aaa0eb75SLiran Schour     return bs->dirty_count;
3073aaa0eb75SLiran Schour }
3074f88e1a42SJes Sorensen 
3075db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3076db593f25SMarcelo Tosatti {
3077db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3078db593f25SMarcelo Tosatti     bs->in_use = in_use;
3079db593f25SMarcelo Tosatti }
3080db593f25SMarcelo Tosatti 
3081db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3082db593f25SMarcelo Tosatti {
3083db593f25SMarcelo Tosatti     return bs->in_use;
3084db593f25SMarcelo Tosatti }
3085db593f25SMarcelo Tosatti 
308628a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
308728a7282aSLuiz Capitulino {
308828a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_OK;
308928a7282aSLuiz Capitulino }
309028a7282aSLuiz Capitulino 
309128a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
309228a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
309328a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
309428a7282aSLuiz Capitulino {
309528a7282aSLuiz Capitulino     return (bs->iostatus != BDRV_IOS_INVAL &&
309628a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
309728a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
309828a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
309928a7282aSLuiz Capitulino }
310028a7282aSLuiz Capitulino 
310128a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
310228a7282aSLuiz Capitulino {
310328a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_INVAL;
310428a7282aSLuiz Capitulino }
310528a7282aSLuiz Capitulino 
310628a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
310728a7282aSLuiz Capitulino {
310828a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
310928a7282aSLuiz Capitulino         bs->iostatus = BDRV_IOS_OK;
311028a7282aSLuiz Capitulino     }
311128a7282aSLuiz Capitulino }
311228a7282aSLuiz Capitulino 
311328a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
311428a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
311528a7282aSLuiz Capitulino    possible to implement this without device models being involved */
311628a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
311728a7282aSLuiz Capitulino {
311828a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
311928a7282aSLuiz Capitulino         assert(error >= 0);
312028a7282aSLuiz Capitulino         bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
312128a7282aSLuiz Capitulino     }
312228a7282aSLuiz Capitulino }
312328a7282aSLuiz Capitulino 
3124a597e79cSChristoph Hellwig void
3125a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3126a597e79cSChristoph Hellwig         enum BlockAcctType type)
3127a597e79cSChristoph Hellwig {
3128a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3129a597e79cSChristoph Hellwig 
3130a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3131c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3132a597e79cSChristoph Hellwig     cookie->type = type;
3133a597e79cSChristoph Hellwig }
3134a597e79cSChristoph Hellwig 
3135a597e79cSChristoph Hellwig void
3136a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3137a597e79cSChristoph Hellwig {
3138a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3139a597e79cSChristoph Hellwig 
3140a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3141a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3142c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3143a597e79cSChristoph Hellwig }
3144a597e79cSChristoph Hellwig 
3145f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3146f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3147f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3148f88e1a42SJes Sorensen {
3149f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3150d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3151f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3152f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
315396df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3154f88e1a42SJes Sorensen     int ret = 0;
3155f88e1a42SJes Sorensen 
3156f88e1a42SJes Sorensen     /* Find driver and parse its options */
3157f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3158f88e1a42SJes Sorensen     if (!drv) {
3159f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
31604f70f249SJes Sorensen         ret = -EINVAL;
3161f88e1a42SJes Sorensen         goto out;
3162f88e1a42SJes Sorensen     }
3163f88e1a42SJes Sorensen 
3164f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3165f88e1a42SJes Sorensen     if (!proto_drv) {
3166f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
31674f70f249SJes Sorensen         ret = -EINVAL;
3168f88e1a42SJes Sorensen         goto out;
3169f88e1a42SJes Sorensen     }
3170f88e1a42SJes Sorensen 
3171f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3172f88e1a42SJes Sorensen                                               drv->create_options);
3173f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3174f88e1a42SJes Sorensen                                               proto_drv->create_options);
3175f88e1a42SJes Sorensen 
3176f88e1a42SJes Sorensen     /* Create parameter list with default values */
3177f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3178f88e1a42SJes Sorensen 
3179f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3180f88e1a42SJes Sorensen 
3181f88e1a42SJes Sorensen     /* Parse -o options */
3182f88e1a42SJes Sorensen     if (options) {
3183f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3184f88e1a42SJes Sorensen         if (param == NULL) {
3185f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
31864f70f249SJes Sorensen             ret = -EINVAL;
3187f88e1a42SJes Sorensen             goto out;
3188f88e1a42SJes Sorensen         }
3189f88e1a42SJes Sorensen     }
3190f88e1a42SJes Sorensen 
3191f88e1a42SJes Sorensen     if (base_filename) {
3192f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3193f88e1a42SJes Sorensen                                  base_filename)) {
3194f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3195f88e1a42SJes Sorensen                          fmt);
31964f70f249SJes Sorensen             ret = -EINVAL;
3197f88e1a42SJes Sorensen             goto out;
3198f88e1a42SJes Sorensen         }
3199f88e1a42SJes Sorensen     }
3200f88e1a42SJes Sorensen 
3201f88e1a42SJes Sorensen     if (base_fmt) {
3202f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3203f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3204f88e1a42SJes Sorensen                          "format '%s'", fmt);
32054f70f249SJes Sorensen             ret = -EINVAL;
3206f88e1a42SJes Sorensen             goto out;
3207f88e1a42SJes Sorensen         }
3208f88e1a42SJes Sorensen     }
3209f88e1a42SJes Sorensen 
3210792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3211792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3212792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3213792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3214792da93aSJes Sorensen                          "same filename as the backing file");
32154f70f249SJes Sorensen             ret = -EINVAL;
3216792da93aSJes Sorensen             goto out;
3217792da93aSJes Sorensen         }
3218792da93aSJes Sorensen     }
3219792da93aSJes Sorensen 
3220f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3221f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
322296df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
322396df67d1SStefan Hajnoczi         if (!backing_drv) {
3224f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3225f88e1a42SJes Sorensen                          backing_fmt->value.s);
32264f70f249SJes Sorensen             ret = -EINVAL;
3227f88e1a42SJes Sorensen             goto out;
3228f88e1a42SJes Sorensen         }
3229f88e1a42SJes Sorensen     }
3230f88e1a42SJes Sorensen 
3231f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3232f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3233d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3234d220894eSKevin Wolf     if (size && size->value.n == -1) {
3235f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3236f88e1a42SJes Sorensen             uint64_t size;
3237f88e1a42SJes Sorensen             char buf[32];
3238f88e1a42SJes Sorensen 
3239f88e1a42SJes Sorensen             bs = bdrv_new("");
3240f88e1a42SJes Sorensen 
324196df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3242f88e1a42SJes Sorensen             if (ret < 0) {
324396df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3244f88e1a42SJes Sorensen                 goto out;
3245f88e1a42SJes Sorensen             }
3246f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3247f88e1a42SJes Sorensen             size *= 512;
3248f88e1a42SJes Sorensen 
3249f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3250f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3251f88e1a42SJes Sorensen         } else {
3252f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
32534f70f249SJes Sorensen             ret = -EINVAL;
3254f88e1a42SJes Sorensen             goto out;
3255f88e1a42SJes Sorensen         }
3256f88e1a42SJes Sorensen     }
3257f88e1a42SJes Sorensen 
3258f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3259f88e1a42SJes Sorensen     print_option_parameters(param);
3260f88e1a42SJes Sorensen     puts("");
3261f88e1a42SJes Sorensen 
3262f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3263f88e1a42SJes Sorensen 
3264f88e1a42SJes Sorensen     if (ret < 0) {
3265f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3266f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3267f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3268f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3269f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3270f88e1a42SJes Sorensen                          fmt);
3271f88e1a42SJes Sorensen         } else {
3272f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3273f88e1a42SJes Sorensen                          strerror(-ret));
3274f88e1a42SJes Sorensen         }
3275f88e1a42SJes Sorensen     }
3276f88e1a42SJes Sorensen 
3277f88e1a42SJes Sorensen out:
3278f88e1a42SJes Sorensen     free_option_parameters(create_options);
3279f88e1a42SJes Sorensen     free_option_parameters(param);
3280f88e1a42SJes Sorensen 
3281f88e1a42SJes Sorensen     if (bs) {
3282f88e1a42SJes Sorensen         bdrv_delete(bs);
3283f88e1a42SJes Sorensen     }
32844f70f249SJes Sorensen 
32854f70f249SJes Sorensen     return ret;
3286f88e1a42SJes Sorensen }
3287