xref: /openbmc/qemu/block.c (revision 0f15423c3234335ca0dbeeae6d19db4699faca07)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
243990d09aSblueswir1 #include "config-host.h"
25faf07963Spbrook #include "qemu-common.h"
266d519a5fSStefan Hajnoczi #include "trace.h"
27376253ecSaliguori #include "monitor.h"
28ea2384d3Sbellard #include "block_int.h"
295efa9d5aSAnthony Liguori #include "module.h"
30f795e743SLuiz Capitulino #include "qjson.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32b2023818SLuiz Capitulino #include "qmp-commands.h"
33fc01f7e7Sbellard 
3471e72a19SJuan Quintela #ifdef CONFIG_BSD
357674e7bfSbellard #include <sys/types.h>
367674e7bfSbellard #include <sys/stat.h>
377674e7bfSbellard #include <sys/ioctl.h>
3872cf2d4fSBlue Swirl #include <sys/queue.h>
39c5e97233Sblueswir1 #ifndef __DragonFly__
407674e7bfSbellard #include <sys/disk.h>
417674e7bfSbellard #endif
42c5e97233Sblueswir1 #endif
437674e7bfSbellard 
4449dc768dSaliguori #ifdef _WIN32
4549dc768dSaliguori #include <windows.h>
4649dc768dSaliguori #endif
4749dc768dSaliguori 
481c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
491c9805a3SStefan Hajnoczi 
507d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
51f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
52f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
53c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
54f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
55f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
56ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
57f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
58f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
59f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
60f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
61f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
62f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
63c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
64c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
651c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
661c9805a3SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
67b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
68b2a61371SStefan Hajnoczi                                                int64_t sector_num,
69b2a61371SStefan Hajnoczi                                                QEMUIOVector *qiov,
70b2a61371SStefan Hajnoczi                                                int nb_sectors,
71b2a61371SStefan Hajnoczi                                                BlockDriverCompletionFunc *cb,
72b2a61371SStefan Hajnoczi                                                void *opaque,
738c5873d6SStefan Hajnoczi                                                bool is_write);
74b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque);
75ec530c81Sbellard 
761b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
771b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
787ee930d0Sblueswir1 
798a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
808a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
81ea2384d3Sbellard 
82f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
83f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
84f9092b10SMarkus Armbruster 
85eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
86eb852011SMarkus Armbruster static int use_bdrv_whitelist;
87eb852011SMarkus Armbruster 
889e0b22f4SStefan Hajnoczi #ifdef _WIN32
899e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
909e0b22f4SStefan Hajnoczi {
919e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
929e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
939e0b22f4SStefan Hajnoczi             filename[1] == ':');
949e0b22f4SStefan Hajnoczi }
959e0b22f4SStefan Hajnoczi 
969e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
979e0b22f4SStefan Hajnoczi {
989e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
999e0b22f4SStefan Hajnoczi         filename[2] == '\0')
1009e0b22f4SStefan Hajnoczi         return 1;
1019e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1029e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1039e0b22f4SStefan Hajnoczi         return 1;
1049e0b22f4SStefan Hajnoczi     return 0;
1059e0b22f4SStefan Hajnoczi }
1069e0b22f4SStefan Hajnoczi #endif
1079e0b22f4SStefan Hajnoczi 
1089e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1099e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1109e0b22f4SStefan Hajnoczi {
1119e0b22f4SStefan Hajnoczi #ifdef _WIN32
1129e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1139e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1149e0b22f4SStefan Hajnoczi         return 0;
1159e0b22f4SStefan Hajnoczi     }
1169e0b22f4SStefan Hajnoczi #endif
1179e0b22f4SStefan Hajnoczi 
1189e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1199e0b22f4SStefan Hajnoczi }
1209e0b22f4SStefan Hajnoczi 
12183f64091Sbellard int path_is_absolute(const char *path)
12283f64091Sbellard {
12383f64091Sbellard     const char *p;
12421664424Sbellard #ifdef _WIN32
12521664424Sbellard     /* specific case for names like: "\\.\d:" */
12621664424Sbellard     if (*path == '/' || *path == '\\')
12721664424Sbellard         return 1;
12821664424Sbellard #endif
12983f64091Sbellard     p = strchr(path, ':');
13083f64091Sbellard     if (p)
13183f64091Sbellard         p++;
13283f64091Sbellard     else
13383f64091Sbellard         p = path;
1343b9f94e1Sbellard #ifdef _WIN32
1353b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1363b9f94e1Sbellard #else
1373b9f94e1Sbellard     return (*p == '/');
1383b9f94e1Sbellard #endif
13983f64091Sbellard }
14083f64091Sbellard 
14183f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
14283f64091Sbellard    path to it by considering it is relative to base_path. URL are
14383f64091Sbellard    supported. */
14483f64091Sbellard void path_combine(char *dest, int dest_size,
14583f64091Sbellard                   const char *base_path,
14683f64091Sbellard                   const char *filename)
14783f64091Sbellard {
14883f64091Sbellard     const char *p, *p1;
14983f64091Sbellard     int len;
15083f64091Sbellard 
15183f64091Sbellard     if (dest_size <= 0)
15283f64091Sbellard         return;
15383f64091Sbellard     if (path_is_absolute(filename)) {
15483f64091Sbellard         pstrcpy(dest, dest_size, filename);
15583f64091Sbellard     } else {
15683f64091Sbellard         p = strchr(base_path, ':');
15783f64091Sbellard         if (p)
15883f64091Sbellard             p++;
15983f64091Sbellard         else
16083f64091Sbellard             p = base_path;
1613b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1623b9f94e1Sbellard #ifdef _WIN32
1633b9f94e1Sbellard         {
1643b9f94e1Sbellard             const char *p2;
1653b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1663b9f94e1Sbellard             if (!p1 || p2 > p1)
1673b9f94e1Sbellard                 p1 = p2;
1683b9f94e1Sbellard         }
1693b9f94e1Sbellard #endif
17083f64091Sbellard         if (p1)
17183f64091Sbellard             p1++;
17283f64091Sbellard         else
17383f64091Sbellard             p1 = base_path;
17483f64091Sbellard         if (p1 > p)
17583f64091Sbellard             p = p1;
17683f64091Sbellard         len = p - base_path;
17783f64091Sbellard         if (len > dest_size - 1)
17883f64091Sbellard             len = dest_size - 1;
17983f64091Sbellard         memcpy(dest, base_path, len);
18083f64091Sbellard         dest[len] = '\0';
18183f64091Sbellard         pstrcat(dest, dest_size, filename);
18283f64091Sbellard     }
18383f64091Sbellard }
18483f64091Sbellard 
1855efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
186ea2384d3Sbellard {
1878c5873d6SStefan Hajnoczi     /* Block drivers without coroutine functions need emulation */
1888c5873d6SStefan Hajnoczi     if (!bdrv->bdrv_co_readv) {
189f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
190f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
191f9f05dc5SKevin Wolf 
192f8c35c1dSStefan Hajnoczi         /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
193f8c35c1dSStefan Hajnoczi          * the block driver lacks aio we need to emulate that too.
194f8c35c1dSStefan Hajnoczi          */
195f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
19683f64091Sbellard             /* add AIO emulation layer */
197f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
198f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
19983f64091Sbellard         }
200f9f05dc5SKevin Wolf     }
201b2e12bc6SChristoph Hellwig 
2028a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
203ea2384d3Sbellard }
204b338082bSbellard 
205b338082bSbellard /* create a new block device (by default it is empty) */
206b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
207fc01f7e7Sbellard {
2081b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
209b338082bSbellard 
2107267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
211b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
212ea2384d3Sbellard     if (device_name[0] != '\0') {
2131b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
214ea2384d3Sbellard     }
21528a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
216b338082bSbellard     return bs;
217b338082bSbellard }
218b338082bSbellard 
219ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
220ea2384d3Sbellard {
221ea2384d3Sbellard     BlockDriver *drv1;
2228a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2238a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
224ea2384d3Sbellard             return drv1;
225ea2384d3Sbellard         }
2268a22f02aSStefan Hajnoczi     }
227ea2384d3Sbellard     return NULL;
228ea2384d3Sbellard }
229ea2384d3Sbellard 
230eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
231eb852011SMarkus Armbruster {
232eb852011SMarkus Armbruster     static const char *whitelist[] = {
233eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
234eb852011SMarkus Armbruster     };
235eb852011SMarkus Armbruster     const char **p;
236eb852011SMarkus Armbruster 
237eb852011SMarkus Armbruster     if (!whitelist[0])
238eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
239eb852011SMarkus Armbruster 
240eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
241eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
242eb852011SMarkus Armbruster             return 1;
243eb852011SMarkus Armbruster         }
244eb852011SMarkus Armbruster     }
245eb852011SMarkus Armbruster     return 0;
246eb852011SMarkus Armbruster }
247eb852011SMarkus Armbruster 
248eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
249eb852011SMarkus Armbruster {
250eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
251eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
252eb852011SMarkus Armbruster }
253eb852011SMarkus Armbruster 
2540e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2550e7e1989SKevin Wolf     QEMUOptionParameter *options)
256ea2384d3Sbellard {
257ea2384d3Sbellard     if (!drv->bdrv_create)
258ea2384d3Sbellard         return -ENOTSUP;
2590e7e1989SKevin Wolf 
2600e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
261ea2384d3Sbellard }
262ea2384d3Sbellard 
26384a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
26484a12e66SChristoph Hellwig {
26584a12e66SChristoph Hellwig     BlockDriver *drv;
26684a12e66SChristoph Hellwig 
267b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
26884a12e66SChristoph Hellwig     if (drv == NULL) {
26916905d71SStefan Hajnoczi         return -ENOENT;
27084a12e66SChristoph Hellwig     }
27184a12e66SChristoph Hellwig 
27284a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
27384a12e66SChristoph Hellwig }
27484a12e66SChristoph Hellwig 
275d5249393Sbellard #ifdef _WIN32
27695389c86Sbellard void get_tmp_filename(char *filename, int size)
277d5249393Sbellard {
2783b9f94e1Sbellard     char temp_dir[MAX_PATH];
2793b9f94e1Sbellard 
2803b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
2813b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
282d5249393Sbellard }
283d5249393Sbellard #else
28495389c86Sbellard void get_tmp_filename(char *filename, int size)
285ea2384d3Sbellard {
286ea2384d3Sbellard     int fd;
2877ccfb2ebSblueswir1     const char *tmpdir;
288d5249393Sbellard     /* XXX: race condition possible */
2890badc1eeSaurel32     tmpdir = getenv("TMPDIR");
2900badc1eeSaurel32     if (!tmpdir)
2910badc1eeSaurel32         tmpdir = "/tmp";
2920badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
293ea2384d3Sbellard     fd = mkstemp(filename);
294ea2384d3Sbellard     close(fd);
295ea2384d3Sbellard }
296d5249393Sbellard #endif
297ea2384d3Sbellard 
298f3a5d3f8SChristoph Hellwig /*
299f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
300f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
301f3a5d3f8SChristoph Hellwig  */
302f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
303f3a5d3f8SChristoph Hellwig {
304508c7cb3SChristoph Hellwig     int score_max = 0, score;
305508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
306f3a5d3f8SChristoph Hellwig 
3078a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
308508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
309508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
310508c7cb3SChristoph Hellwig             if (score > score_max) {
311508c7cb3SChristoph Hellwig                 score_max = score;
312508c7cb3SChristoph Hellwig                 drv = d;
313f3a5d3f8SChristoph Hellwig             }
314508c7cb3SChristoph Hellwig         }
315f3a5d3f8SChristoph Hellwig     }
316f3a5d3f8SChristoph Hellwig 
317508c7cb3SChristoph Hellwig     return drv;
318f3a5d3f8SChristoph Hellwig }
319f3a5d3f8SChristoph Hellwig 
320b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
32184a12e66SChristoph Hellwig {
32284a12e66SChristoph Hellwig     BlockDriver *drv1;
32384a12e66SChristoph Hellwig     char protocol[128];
32484a12e66SChristoph Hellwig     int len;
32584a12e66SChristoph Hellwig     const char *p;
32684a12e66SChristoph Hellwig 
32766f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
32866f82ceeSKevin Wolf 
32939508e7aSChristoph Hellwig     /*
33039508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
33139508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
33239508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
33339508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
33439508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
33539508e7aSChristoph Hellwig      */
33684a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
33739508e7aSChristoph Hellwig     if (drv1) {
33884a12e66SChristoph Hellwig         return drv1;
33984a12e66SChristoph Hellwig     }
34039508e7aSChristoph Hellwig 
3419e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
34239508e7aSChristoph Hellwig         return bdrv_find_format("file");
34339508e7aSChristoph Hellwig     }
3449e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3459e0b22f4SStefan Hajnoczi     assert(p != NULL);
34684a12e66SChristoph Hellwig     len = p - filename;
34784a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
34884a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
34984a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
35084a12e66SChristoph Hellwig     protocol[len] = '\0';
35184a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
35284a12e66SChristoph Hellwig         if (drv1->protocol_name &&
35384a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
35484a12e66SChristoph Hellwig             return drv1;
35584a12e66SChristoph Hellwig         }
35684a12e66SChristoph Hellwig     }
35784a12e66SChristoph Hellwig     return NULL;
35884a12e66SChristoph Hellwig }
35984a12e66SChristoph Hellwig 
360c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
361ea2384d3Sbellard {
36283f64091Sbellard     int ret, score, score_max;
363ea2384d3Sbellard     BlockDriver *drv1, *drv;
36483f64091Sbellard     uint8_t buf[2048];
36583f64091Sbellard     BlockDriverState *bs;
366ea2384d3Sbellard 
367f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
368c98ac35dSStefan Weil     if (ret < 0) {
369c98ac35dSStefan Weil         *pdrv = NULL;
370c98ac35dSStefan Weil         return ret;
371c98ac35dSStefan Weil     }
372f8ea0b00SNicholas Bellinger 
37308a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
37408a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
3751a396859SNicholas A. Bellinger         bdrv_delete(bs);
376c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
377c98ac35dSStefan Weil         if (!drv) {
378c98ac35dSStefan Weil             ret = -ENOENT;
379c98ac35dSStefan Weil         }
380c98ac35dSStefan Weil         *pdrv = drv;
381c98ac35dSStefan Weil         return ret;
3821a396859SNicholas A. Bellinger     }
383f8ea0b00SNicholas Bellinger 
38483f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
38583f64091Sbellard     bdrv_delete(bs);
386ea2384d3Sbellard     if (ret < 0) {
387c98ac35dSStefan Weil         *pdrv = NULL;
388c98ac35dSStefan Weil         return ret;
389ea2384d3Sbellard     }
390ea2384d3Sbellard 
391ea2384d3Sbellard     score_max = 0;
39284a12e66SChristoph Hellwig     drv = NULL;
3938a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
39483f64091Sbellard         if (drv1->bdrv_probe) {
395ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
396ea2384d3Sbellard             if (score > score_max) {
397ea2384d3Sbellard                 score_max = score;
398ea2384d3Sbellard                 drv = drv1;
399ea2384d3Sbellard             }
400ea2384d3Sbellard         }
40183f64091Sbellard     }
402c98ac35dSStefan Weil     if (!drv) {
403c98ac35dSStefan Weil         ret = -ENOENT;
404c98ac35dSStefan Weil     }
405c98ac35dSStefan Weil     *pdrv = drv;
406c98ac35dSStefan Weil     return ret;
407ea2384d3Sbellard }
408ea2384d3Sbellard 
40951762288SStefan Hajnoczi /**
41051762288SStefan Hajnoczi  * Set the current 'total_sectors' value
41151762288SStefan Hajnoczi  */
41251762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
41351762288SStefan Hajnoczi {
41451762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
41551762288SStefan Hajnoczi 
416396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
417396759adSNicholas Bellinger     if (bs->sg)
418396759adSNicholas Bellinger         return 0;
419396759adSNicholas Bellinger 
42051762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
42151762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
42251762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
42351762288SStefan Hajnoczi         if (length < 0) {
42451762288SStefan Hajnoczi             return length;
42551762288SStefan Hajnoczi         }
42651762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
42751762288SStefan Hajnoczi     }
42851762288SStefan Hajnoczi 
42951762288SStefan Hajnoczi     bs->total_sectors = hint;
43051762288SStefan Hajnoczi     return 0;
43151762288SStefan Hajnoczi }
43251762288SStefan Hajnoczi 
433c3993cdcSStefan Hajnoczi /**
434c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
435c3993cdcSStefan Hajnoczi  *
436c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
437c3993cdcSStefan Hajnoczi  */
438c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
439c3993cdcSStefan Hajnoczi {
440c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
441c3993cdcSStefan Hajnoczi 
442c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
443c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
44492196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
44592196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
446c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
447c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
448c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
449c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
450c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
451c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
452c3993cdcSStefan Hajnoczi         /* this is the default */
453c3993cdcSStefan Hajnoczi     } else {
454c3993cdcSStefan Hajnoczi         return -1;
455c3993cdcSStefan Hajnoczi     }
456c3993cdcSStefan Hajnoczi 
457c3993cdcSStefan Hajnoczi     return 0;
458c3993cdcSStefan Hajnoczi }
459c3993cdcSStefan Hajnoczi 
460b6ce07aaSKevin Wolf /*
46157915332SKevin Wolf  * Common part for opening disk images and files
46257915332SKevin Wolf  */
46357915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
46457915332SKevin Wolf     int flags, BlockDriver *drv)
46557915332SKevin Wolf {
46657915332SKevin Wolf     int ret, open_flags;
46757915332SKevin Wolf 
46857915332SKevin Wolf     assert(drv != NULL);
46957915332SKevin Wolf 
47028dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
47128dcee10SStefan Hajnoczi 
47266f82ceeSKevin Wolf     bs->file = NULL;
47351762288SStefan Hajnoczi     bs->total_sectors = 0;
47457915332SKevin Wolf     bs->encrypted = 0;
47557915332SKevin Wolf     bs->valid_key = 0;
47603f541bdSStefan Hajnoczi     bs->sg = 0;
47757915332SKevin Wolf     bs->open_flags = flags;
47803f541bdSStefan Hajnoczi     bs->growable = 0;
47957915332SKevin Wolf     bs->buffer_alignment = 512;
48057915332SKevin Wolf 
48157915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
48203f541bdSStefan Hajnoczi     bs->backing_file[0] = '\0';
48357915332SKevin Wolf 
48457915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
48557915332SKevin Wolf         return -ENOTSUP;
48657915332SKevin Wolf     }
48757915332SKevin Wolf 
48857915332SKevin Wolf     bs->drv = drv;
4897267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
49057915332SKevin Wolf 
49103f541bdSStefan Hajnoczi     bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
49257915332SKevin Wolf 
49357915332SKevin Wolf     /*
49457915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
49557915332SKevin Wolf      * image.
49657915332SKevin Wolf      */
49757915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
49857915332SKevin Wolf 
49957915332SKevin Wolf     /*
500ebabb67aSStefan Weil      * Snapshots should be writable.
50157915332SKevin Wolf      */
50257915332SKevin Wolf     if (bs->is_temporary) {
50357915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
50457915332SKevin Wolf     }
50557915332SKevin Wolf 
506e7c63796SStefan Hajnoczi     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
507e7c63796SStefan Hajnoczi 
50866f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
50966f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
51066f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
51166f82ceeSKevin Wolf     } else {
51266f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
51366f82ceeSKevin Wolf         if (ret >= 0) {
51466f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
51566f82ceeSKevin Wolf         }
51666f82ceeSKevin Wolf     }
51766f82ceeSKevin Wolf 
51857915332SKevin Wolf     if (ret < 0) {
51957915332SKevin Wolf         goto free_and_fail;
52057915332SKevin Wolf     }
52157915332SKevin Wolf 
52251762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
52351762288SStefan Hajnoczi     if (ret < 0) {
52451762288SStefan Hajnoczi         goto free_and_fail;
52557915332SKevin Wolf     }
52651762288SStefan Hajnoczi 
52757915332SKevin Wolf #ifndef _WIN32
52857915332SKevin Wolf     if (bs->is_temporary) {
52957915332SKevin Wolf         unlink(filename);
53057915332SKevin Wolf     }
53157915332SKevin Wolf #endif
53257915332SKevin Wolf     return 0;
53357915332SKevin Wolf 
53457915332SKevin Wolf free_and_fail:
53566f82ceeSKevin Wolf     if (bs->file) {
53666f82ceeSKevin Wolf         bdrv_delete(bs->file);
53766f82ceeSKevin Wolf         bs->file = NULL;
53866f82ceeSKevin Wolf     }
5397267c094SAnthony Liguori     g_free(bs->opaque);
54057915332SKevin Wolf     bs->opaque = NULL;
54157915332SKevin Wolf     bs->drv = NULL;
54257915332SKevin Wolf     return ret;
54357915332SKevin Wolf }
54457915332SKevin Wolf 
54557915332SKevin Wolf /*
546b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
547b6ce07aaSKevin Wolf  */
54883f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
549b338082bSbellard {
55083f64091Sbellard     BlockDriverState *bs;
5516db95603SChristoph Hellwig     BlockDriver *drv;
55283f64091Sbellard     int ret;
5533b0d4f61Sbellard 
554b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5556db95603SChristoph Hellwig     if (!drv) {
5566db95603SChristoph Hellwig         return -ENOENT;
5576db95603SChristoph Hellwig     }
5586db95603SChristoph Hellwig 
55983f64091Sbellard     bs = bdrv_new("");
560b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
56183f64091Sbellard     if (ret < 0) {
56283f64091Sbellard         bdrv_delete(bs);
56383f64091Sbellard         return ret;
5643b0d4f61Sbellard     }
56571d0770cSaliguori     bs->growable = 1;
56683f64091Sbellard     *pbs = bs;
56783f64091Sbellard     return 0;
5683b0d4f61Sbellard }
5693b0d4f61Sbellard 
570b6ce07aaSKevin Wolf /*
571b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
572b6ce07aaSKevin Wolf  */
573d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
574ea2384d3Sbellard               BlockDriver *drv)
575ea2384d3Sbellard {
576b6ce07aaSKevin Wolf     int ret;
5772b572816SKevin Wolf     char tmp_filename[PATH_MAX];
57833e3963eSbellard 
57983f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
580ea2384d3Sbellard         BlockDriverState *bs1;
581ea2384d3Sbellard         int64_t total_size;
5827c96d46eSaliguori         int is_protocol = 0;
58391a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
58491a073a9SKevin Wolf         QEMUOptionParameter *options;
585b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
58633e3963eSbellard 
587ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
588ea2384d3Sbellard            instead of opening 'filename' directly */
589ea2384d3Sbellard 
590ea2384d3Sbellard         /* if there is a backing file, use it */
591ea2384d3Sbellard         bs1 = bdrv_new("");
592d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
59351d7c00cSaliguori         if (ret < 0) {
594ea2384d3Sbellard             bdrv_delete(bs1);
59551d7c00cSaliguori             return ret;
596ea2384d3Sbellard         }
5973e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
5987c96d46eSaliguori 
5997c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
6007c96d46eSaliguori             is_protocol = 1;
6017c96d46eSaliguori 
602ea2384d3Sbellard         bdrv_delete(bs1);
603ea2384d3Sbellard 
604ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6057c96d46eSaliguori 
6067c96d46eSaliguori         /* Real path is meaningless for protocols */
6077c96d46eSaliguori         if (is_protocol)
6087c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6097c96d46eSaliguori                      "%s", filename);
610114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
611114cdfa9SKirill A. Shutemov             return -errno;
6127c96d46eSaliguori 
61391a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
61491a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
61591a073a9SKevin Wolf 
6163e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
61791a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
61891a073a9SKevin Wolf         if (drv) {
61991a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
62091a073a9SKevin Wolf                 drv->format_name);
62191a073a9SKevin Wolf         }
62291a073a9SKevin Wolf 
62391a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
624d748768cSJan Kiszka         free_option_parameters(options);
62551d7c00cSaliguori         if (ret < 0) {
62651d7c00cSaliguori             return ret;
627ea2384d3Sbellard         }
62891a073a9SKevin Wolf 
629ea2384d3Sbellard         filename = tmp_filename;
63091a073a9SKevin Wolf         drv = bdrv_qcow2;
631ea2384d3Sbellard         bs->is_temporary = 1;
632ea2384d3Sbellard     }
633ea2384d3Sbellard 
634b6ce07aaSKevin Wolf     /* Find the right image format driver */
6356db95603SChristoph Hellwig     if (!drv) {
636c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
637ea2384d3Sbellard     }
6386987307cSChristoph Hellwig 
63951d7c00cSaliguori     if (!drv) {
64051d7c00cSaliguori         goto unlink_and_fail;
64183f64091Sbellard     }
642b6ce07aaSKevin Wolf 
643b6ce07aaSKevin Wolf     /* Open the image */
644b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
645b6ce07aaSKevin Wolf     if (ret < 0) {
6466987307cSChristoph Hellwig         goto unlink_and_fail;
6476987307cSChristoph Hellwig     }
6486987307cSChristoph Hellwig 
649b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
650b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
651b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
652b6ce07aaSKevin Wolf         int back_flags;
653b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
654b6ce07aaSKevin Wolf 
655b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
656df2dbb4aSStefan Hajnoczi 
657df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
658df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
659df2dbb4aSStefan Hajnoczi                     bs->backing_file);
660df2dbb4aSStefan Hajnoczi         } else {
661b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
662b6ce07aaSKevin Wolf                          filename, bs->backing_file);
663df2dbb4aSStefan Hajnoczi         }
664df2dbb4aSStefan Hajnoczi 
665df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
666b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
667df2dbb4aSStefan Hajnoczi         }
668b6ce07aaSKevin Wolf 
669b6ce07aaSKevin Wolf         /* backing files always opened read-only */
670b6ce07aaSKevin Wolf         back_flags =
671b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
672b6ce07aaSKevin Wolf 
673b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
674b6ce07aaSKevin Wolf         if (ret < 0) {
675b6ce07aaSKevin Wolf             bdrv_close(bs);
676b6ce07aaSKevin Wolf             return ret;
677b6ce07aaSKevin Wolf         }
678b6ce07aaSKevin Wolf         if (bs->is_temporary) {
679b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
680b6ce07aaSKevin Wolf         } else {
681b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
682b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
683b6ce07aaSKevin Wolf         }
684b6ce07aaSKevin Wolf     }
685b6ce07aaSKevin Wolf 
686b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
6877d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
688b6ce07aaSKevin Wolf     }
689b6ce07aaSKevin Wolf 
690b6ce07aaSKevin Wolf     return 0;
691b6ce07aaSKevin Wolf 
692b6ce07aaSKevin Wolf unlink_and_fail:
693b6ce07aaSKevin Wolf     if (bs->is_temporary) {
694b6ce07aaSKevin Wolf         unlink(filename);
695b6ce07aaSKevin Wolf     }
696b6ce07aaSKevin Wolf     return ret;
697b6ce07aaSKevin Wolf }
698b6ce07aaSKevin Wolf 
699fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
700fc01f7e7Sbellard {
70119cb3738Sbellard     if (bs->drv) {
702f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
703f9092b10SMarkus Armbruster             bs_snapshots = NULL;
704f9092b10SMarkus Armbruster         }
705557df6acSStefan Hajnoczi         if (bs->backing_hd) {
706ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
707557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
708557df6acSStefan Hajnoczi         }
709ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7107267c094SAnthony Liguori         g_free(bs->opaque);
711ea2384d3Sbellard #ifdef _WIN32
712ea2384d3Sbellard         if (bs->is_temporary) {
713ea2384d3Sbellard             unlink(bs->filename);
714ea2384d3Sbellard         }
71567b915a5Sbellard #endif
716ea2384d3Sbellard         bs->opaque = NULL;
717ea2384d3Sbellard         bs->drv = NULL;
718b338082bSbellard 
71966f82ceeSKevin Wolf         if (bs->file != NULL) {
72066f82ceeSKevin Wolf             bdrv_close(bs->file);
72166f82ceeSKevin Wolf         }
72266f82ceeSKevin Wolf 
7237d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
724b338082bSbellard     }
725b338082bSbellard }
726b338082bSbellard 
7272bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7282bc93fedSMORITA Kazutaka {
7292bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7302bc93fedSMORITA Kazutaka 
7312bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7322bc93fedSMORITA Kazutaka         bdrv_close(bs);
7332bc93fedSMORITA Kazutaka     }
7342bc93fedSMORITA Kazutaka }
7352bc93fedSMORITA Kazutaka 
736d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
737d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
738d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
739d22b2f41SRyan Harper {
740d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
741d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
742d22b2f41SRyan Harper     }
743d22b2f41SRyan Harper     bs->device_name[0] = '\0';
744d22b2f41SRyan Harper }
745d22b2f41SRyan Harper 
746b338082bSbellard void bdrv_delete(BlockDriverState *bs)
747b338082bSbellard {
748fa879d62SMarkus Armbruster     assert(!bs->dev);
74918846deeSMarkus Armbruster 
7501b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
751d22b2f41SRyan Harper     bdrv_make_anon(bs);
75234c6f050Saurel32 
753b338082bSbellard     bdrv_close(bs);
75466f82ceeSKevin Wolf     if (bs->file != NULL) {
75566f82ceeSKevin Wolf         bdrv_delete(bs->file);
75666f82ceeSKevin Wolf     }
75766f82ceeSKevin Wolf 
758f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7597267c094SAnthony Liguori     g_free(bs);
760fc01f7e7Sbellard }
761fc01f7e7Sbellard 
762fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
763fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
76418846deeSMarkus Armbruster {
765fa879d62SMarkus Armbruster     if (bs->dev) {
76618846deeSMarkus Armbruster         return -EBUSY;
76718846deeSMarkus Armbruster     }
768fa879d62SMarkus Armbruster     bs->dev = dev;
76928a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
77018846deeSMarkus Armbruster     return 0;
77118846deeSMarkus Armbruster }
77218846deeSMarkus Armbruster 
773fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
774fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
77518846deeSMarkus Armbruster {
776fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
777fa879d62SMarkus Armbruster         abort();
778fa879d62SMarkus Armbruster     }
779fa879d62SMarkus Armbruster }
780fa879d62SMarkus Armbruster 
781fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
782fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
783fa879d62SMarkus Armbruster {
784fa879d62SMarkus Armbruster     assert(bs->dev == dev);
785fa879d62SMarkus Armbruster     bs->dev = NULL;
7860e49de52SMarkus Armbruster     bs->dev_ops = NULL;
7870e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
78829e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
78918846deeSMarkus Armbruster }
79018846deeSMarkus Armbruster 
791fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
792fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
79318846deeSMarkus Armbruster {
794fa879d62SMarkus Armbruster     return bs->dev;
79518846deeSMarkus Armbruster }
79618846deeSMarkus Armbruster 
7970e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
7980e49de52SMarkus Armbruster                       void *opaque)
7990e49de52SMarkus Armbruster {
8000e49de52SMarkus Armbruster     bs->dev_ops = ops;
8010e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8022c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8032c6942faSMarkus Armbruster         bs_snapshots = NULL;
8042c6942faSMarkus Armbruster     }
8050e49de52SMarkus Armbruster }
8060e49de52SMarkus Armbruster 
8077d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8080e49de52SMarkus Armbruster {
809145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8107d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
811145feb17SMarkus Armbruster     }
812145feb17SMarkus Armbruster }
813145feb17SMarkus Armbruster 
8142c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8152c6942faSMarkus Armbruster {
8162c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8172c6942faSMarkus Armbruster }
8182c6942faSMarkus Armbruster 
819025ccaa7SPaolo Bonzini void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
820025ccaa7SPaolo Bonzini {
821025ccaa7SPaolo Bonzini     if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
822025ccaa7SPaolo Bonzini         bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
823025ccaa7SPaolo Bonzini     }
824025ccaa7SPaolo Bonzini }
825025ccaa7SPaolo Bonzini 
826e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
827e4def80bSMarkus Armbruster {
828e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
829e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
830e4def80bSMarkus Armbruster     }
831e4def80bSMarkus Armbruster     return false;
832e4def80bSMarkus Armbruster }
833e4def80bSMarkus Armbruster 
834145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
835145feb17SMarkus Armbruster {
836145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
837145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8380e49de52SMarkus Armbruster     }
8390e49de52SMarkus Armbruster }
8400e49de52SMarkus Armbruster 
841f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
842f107639aSMarkus Armbruster {
843f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
844f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
845f107639aSMarkus Armbruster     }
846f107639aSMarkus Armbruster     return false;
847f107639aSMarkus Armbruster }
848f107639aSMarkus Armbruster 
849e97fc193Saliguori /*
850e97fc193Saliguori  * Run consistency checks on an image
851e97fc193Saliguori  *
852e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
853a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
854e076f338SKevin Wolf  * check are stored in res.
855e97fc193Saliguori  */
856e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
857e97fc193Saliguori {
858e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
859e97fc193Saliguori         return -ENOTSUP;
860e97fc193Saliguori     }
861e97fc193Saliguori 
862e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8639ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
864e97fc193Saliguori }
865e97fc193Saliguori 
8668a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8678a426614SKevin Wolf 
86833e3963eSbellard /* commit COW file into the raw image */
86933e3963eSbellard int bdrv_commit(BlockDriverState *bs)
87033e3963eSbellard {
87119cb3738Sbellard     BlockDriver *drv = bs->drv;
872ee181196SKevin Wolf     BlockDriver *backing_drv;
8738a426614SKevin Wolf     int64_t sector, total_sectors;
8748a426614SKevin Wolf     int n, ro, open_flags;
8754dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8768a426614SKevin Wolf     uint8_t *buf;
8774dca4b63SNaphtali Sprei     char filename[1024];
8784dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
87933e3963eSbellard 
88019cb3738Sbellard     if (!drv)
88119cb3738Sbellard         return -ENOMEDIUM;
88233e3963eSbellard 
8834dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8844dca4b63SNaphtali Sprei         return -ENOTSUP;
8854dca4b63SNaphtali Sprei     }
8864dca4b63SNaphtali Sprei 
8874dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
888ea2384d3Sbellard         return -EACCES;
88933e3963eSbellard     }
89033e3963eSbellard 
891ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
8924dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
8934dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
8944dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
8954dca4b63SNaphtali Sprei 
8964dca4b63SNaphtali Sprei     if (ro) {
8974dca4b63SNaphtali Sprei         /* re-open as RW */
8984dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
8994dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9004dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
901ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
902ee181196SKevin Wolf             backing_drv);
9034dca4b63SNaphtali Sprei         if (rw_ret < 0) {
9044dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
9054dca4b63SNaphtali Sprei             /* try to re-open read-only */
9064dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
907ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
908ee181196SKevin Wolf                 backing_drv);
9094dca4b63SNaphtali Sprei             if (ret < 0) {
9104dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9114dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9124dca4b63SNaphtali Sprei                 bs->drv = NULL;
9134dca4b63SNaphtali Sprei                 return ret;
9144dca4b63SNaphtali Sprei             }
9154dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9164dca4b63SNaphtali Sprei             return rw_ret;
9174dca4b63SNaphtali Sprei         }
9184dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
919ea2384d3Sbellard     }
920ea2384d3Sbellard 
9216ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9227267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9238a426614SKevin Wolf 
9248a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9258a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9268a426614SKevin Wolf 
9278a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9284dca4b63SNaphtali Sprei                 ret = -EIO;
9294dca4b63SNaphtali Sprei                 goto ro_cleanup;
93033e3963eSbellard             }
93133e3963eSbellard 
9328a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9334dca4b63SNaphtali Sprei                 ret = -EIO;
9344dca4b63SNaphtali Sprei                 goto ro_cleanup;
93533e3963eSbellard             }
93633e3963eSbellard         }
93733e3963eSbellard     }
93895389c86Sbellard 
9391d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9401d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9411d44952fSChristoph Hellwig         bdrv_flush(bs);
9421d44952fSChristoph Hellwig     }
94395389c86Sbellard 
9443f5075aeSChristoph Hellwig     /*
9453f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9463f5075aeSChristoph Hellwig      * stable on disk.
9473f5075aeSChristoph Hellwig      */
9483f5075aeSChristoph Hellwig     if (bs->backing_hd)
9493f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9504dca4b63SNaphtali Sprei 
9514dca4b63SNaphtali Sprei ro_cleanup:
9527267c094SAnthony Liguori     g_free(buf);
9534dca4b63SNaphtali Sprei 
9544dca4b63SNaphtali Sprei     if (ro) {
9554dca4b63SNaphtali Sprei         /* re-open as RO */
9564dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9574dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9584dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
959ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
960ee181196SKevin Wolf             backing_drv);
9614dca4b63SNaphtali Sprei         if (ret < 0) {
9624dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9634dca4b63SNaphtali Sprei             /* drive not functional anymore */
9644dca4b63SNaphtali Sprei             bs->drv = NULL;
9654dca4b63SNaphtali Sprei             return ret;
9664dca4b63SNaphtali Sprei         }
9674dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9684dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9694dca4b63SNaphtali Sprei     }
9704dca4b63SNaphtali Sprei 
9711d44952fSChristoph Hellwig     return ret;
97233e3963eSbellard }
97333e3963eSbellard 
9746ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9756ab4b5abSMarkus Armbruster {
9766ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9776ab4b5abSMarkus Armbruster 
9786ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9796ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9806ab4b5abSMarkus Armbruster     }
9816ab4b5abSMarkus Armbruster }
9826ab4b5abSMarkus Armbruster 
983756e6736SKevin Wolf /*
984756e6736SKevin Wolf  * Return values:
985756e6736SKevin Wolf  * 0        - success
986756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
987756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
988756e6736SKevin Wolf  *            image file header
989756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
990756e6736SKevin Wolf  */
991756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
992756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
993756e6736SKevin Wolf {
994756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
995756e6736SKevin Wolf 
996756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
997756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
998756e6736SKevin Wolf     } else {
999756e6736SKevin Wolf         return -ENOTSUP;
1000756e6736SKevin Wolf     }
1001756e6736SKevin Wolf }
1002756e6736SKevin Wolf 
100371d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
100471d0770cSaliguori                                    size_t size)
100571d0770cSaliguori {
100671d0770cSaliguori     int64_t len;
100771d0770cSaliguori 
100871d0770cSaliguori     if (!bdrv_is_inserted(bs))
100971d0770cSaliguori         return -ENOMEDIUM;
101071d0770cSaliguori 
101171d0770cSaliguori     if (bs->growable)
101271d0770cSaliguori         return 0;
101371d0770cSaliguori 
101471d0770cSaliguori     len = bdrv_getlength(bs);
101571d0770cSaliguori 
1016fbb7b4e0SKevin Wolf     if (offset < 0)
1017fbb7b4e0SKevin Wolf         return -EIO;
1018fbb7b4e0SKevin Wolf 
1019fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
102071d0770cSaliguori         return -EIO;
102171d0770cSaliguori 
102271d0770cSaliguori     return 0;
102371d0770cSaliguori }
102471d0770cSaliguori 
102571d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
102671d0770cSaliguori                               int nb_sectors)
102771d0770cSaliguori {
1028eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1029eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
103071d0770cSaliguori }
103171d0770cSaliguori 
10321c9805a3SStefan Hajnoczi typedef struct RwCo {
10331c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10341c9805a3SStefan Hajnoczi     int64_t sector_num;
10351c9805a3SStefan Hajnoczi     int nb_sectors;
10361c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10371c9805a3SStefan Hajnoczi     bool is_write;
10381c9805a3SStefan Hajnoczi     int ret;
10391c9805a3SStefan Hajnoczi } RwCo;
10401c9805a3SStefan Hajnoczi 
10411c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1042fc01f7e7Sbellard {
10431c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1044fc01f7e7Sbellard 
10451c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10461c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10471c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10481c9805a3SStefan Hajnoczi     } else {
10491c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10501c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10511c9805a3SStefan Hajnoczi     }
10521c9805a3SStefan Hajnoczi }
1053e7a8a783SKevin Wolf 
10541c9805a3SStefan Hajnoczi /*
10551c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10561c9805a3SStefan Hajnoczi  */
10571c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10581c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10591c9805a3SStefan Hajnoczi {
1060e7a8a783SKevin Wolf     QEMUIOVector qiov;
1061e7a8a783SKevin Wolf     struct iovec iov = {
1062e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1063e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1064e7a8a783SKevin Wolf     };
10651c9805a3SStefan Hajnoczi     Coroutine *co;
10661c9805a3SStefan Hajnoczi     RwCo rwco = {
10671c9805a3SStefan Hajnoczi         .bs = bs,
10681c9805a3SStefan Hajnoczi         .sector_num = sector_num,
10691c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
10701c9805a3SStefan Hajnoczi         .qiov = &qiov,
10711c9805a3SStefan Hajnoczi         .is_write = is_write,
10721c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
10731c9805a3SStefan Hajnoczi     };
1074e7a8a783SKevin Wolf 
1075e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
10761c9805a3SStefan Hajnoczi 
10771c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
10781c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
10791c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
10801c9805a3SStefan Hajnoczi     } else {
10811c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
10821c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
10831c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
10841c9805a3SStefan Hajnoczi             qemu_aio_wait();
10851c9805a3SStefan Hajnoczi         }
10861c9805a3SStefan Hajnoczi     }
10871c9805a3SStefan Hajnoczi     return rwco.ret;
1088e7a8a783SKevin Wolf }
1089e7a8a783SKevin Wolf 
10901c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
10911c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
10921c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
10931c9805a3SStefan Hajnoczi {
10941c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
109583f64091Sbellard }
1096fc01f7e7Sbellard 
10977cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
10987cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
10997cd1e32aSlirans@il.ibm.com {
11007cd1e32aSlirans@il.ibm.com     int64_t start, end;
1101c6d22830SJan Kiszka     unsigned long val, idx, bit;
1102a55eb92cSJan Kiszka 
11036ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1104c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
11057cd1e32aSlirans@il.ibm.com 
11067cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1107c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1108c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1109c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1110c6d22830SJan Kiszka         if (dirty) {
11116d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1112aaa0eb75SLiran Schour                 bs->dirty_count++;
11136d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1114aaa0eb75SLiran Schour             }
1115c6d22830SJan Kiszka         } else {
11166d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1117aaa0eb75SLiran Schour                 bs->dirty_count--;
11186d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1119c6d22830SJan Kiszka             }
1120aaa0eb75SLiran Schour         }
1121c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11227cd1e32aSlirans@il.ibm.com     }
11237cd1e32aSlirans@il.ibm.com }
11247cd1e32aSlirans@il.ibm.com 
112519cb3738Sbellard /* Return < 0 if error. Important errors are:
112619cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
112719cb3738Sbellard   -ENOMEDIUM   No media inserted.
112819cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
112919cb3738Sbellard   -EACCES      Trying to write a read-only device
113019cb3738Sbellard */
1131fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1132fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1133fc01f7e7Sbellard {
11341c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
113583f64091Sbellard }
113683f64091Sbellard 
1137eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1138eda578e5Saliguori                void *buf, int count1)
113983f64091Sbellard {
11406ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
114183f64091Sbellard     int len, nb_sectors, count;
114283f64091Sbellard     int64_t sector_num;
11439a8c4cceSKevin Wolf     int ret;
114483f64091Sbellard 
114583f64091Sbellard     count = count1;
114683f64091Sbellard     /* first read to align to sector start */
11476ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
114883f64091Sbellard     if (len > count)
114983f64091Sbellard         len = count;
11506ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
115183f64091Sbellard     if (len > 0) {
11529a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11539a8c4cceSKevin Wolf             return ret;
11546ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
115583f64091Sbellard         count -= len;
115683f64091Sbellard         if (count == 0)
115783f64091Sbellard             return count1;
115883f64091Sbellard         sector_num++;
115983f64091Sbellard         buf += len;
116083f64091Sbellard     }
116183f64091Sbellard 
116283f64091Sbellard     /* read the sectors "in place" */
11636ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
116483f64091Sbellard     if (nb_sectors > 0) {
11659a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11669a8c4cceSKevin Wolf             return ret;
116783f64091Sbellard         sector_num += nb_sectors;
11686ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
116983f64091Sbellard         buf += len;
117083f64091Sbellard         count -= len;
117183f64091Sbellard     }
117283f64091Sbellard 
117383f64091Sbellard     /* add data from the last sector */
117483f64091Sbellard     if (count > 0) {
11759a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11769a8c4cceSKevin Wolf             return ret;
117783f64091Sbellard         memcpy(buf, tmp_buf, count);
117883f64091Sbellard     }
117983f64091Sbellard     return count1;
118083f64091Sbellard }
118183f64091Sbellard 
1182eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1183eda578e5Saliguori                 const void *buf, int count1)
118483f64091Sbellard {
11856ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
118683f64091Sbellard     int len, nb_sectors, count;
118783f64091Sbellard     int64_t sector_num;
11889a8c4cceSKevin Wolf     int ret;
118983f64091Sbellard 
119083f64091Sbellard     count = count1;
119183f64091Sbellard     /* first write to align to sector start */
11926ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
119383f64091Sbellard     if (len > count)
119483f64091Sbellard         len = count;
11956ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
119683f64091Sbellard     if (len > 0) {
11979a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11989a8c4cceSKevin Wolf             return ret;
11996ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
12009a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12019a8c4cceSKevin Wolf             return ret;
120283f64091Sbellard         count -= len;
120383f64091Sbellard         if (count == 0)
120483f64091Sbellard             return count1;
120583f64091Sbellard         sector_num++;
120683f64091Sbellard         buf += len;
120783f64091Sbellard     }
120883f64091Sbellard 
120983f64091Sbellard     /* write the sectors "in place" */
12106ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
121183f64091Sbellard     if (nb_sectors > 0) {
12129a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12139a8c4cceSKevin Wolf             return ret;
121483f64091Sbellard         sector_num += nb_sectors;
12156ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
121683f64091Sbellard         buf += len;
121783f64091Sbellard         count -= len;
121883f64091Sbellard     }
121983f64091Sbellard 
122083f64091Sbellard     /* add data from the last sector */
122183f64091Sbellard     if (count > 0) {
12229a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12239a8c4cceSKevin Wolf             return ret;
122483f64091Sbellard         memcpy(tmp_buf, buf, count);
12259a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12269a8c4cceSKevin Wolf             return ret;
122783f64091Sbellard     }
122883f64091Sbellard     return count1;
122983f64091Sbellard }
123083f64091Sbellard 
1231f08145feSKevin Wolf /*
1232f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1233f08145feSKevin Wolf  * request (acts as a barrier)
1234f08145feSKevin Wolf  *
1235f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1236f08145feSKevin Wolf  */
1237f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1238f08145feSKevin Wolf     const void *buf, int count)
1239f08145feSKevin Wolf {
1240f08145feSKevin Wolf     int ret;
1241f08145feSKevin Wolf 
1242f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1243f08145feSKevin Wolf     if (ret < 0) {
1244f08145feSKevin Wolf         return ret;
1245f08145feSKevin Wolf     }
1246f08145feSKevin Wolf 
124792196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
124892196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1249f08145feSKevin Wolf         bdrv_flush(bs);
1250f08145feSKevin Wolf     }
1251f08145feSKevin Wolf 
1252f08145feSKevin Wolf     return 0;
1253f08145feSKevin Wolf }
1254f08145feSKevin Wolf 
1255c5fbe571SStefan Hajnoczi /*
1256c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1257c5fbe571SStefan Hajnoczi  */
1258c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1259c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1260da1fa91dSKevin Wolf {
1261da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1262da1fa91dSKevin Wolf 
1263da1fa91dSKevin Wolf     if (!drv) {
1264da1fa91dSKevin Wolf         return -ENOMEDIUM;
1265da1fa91dSKevin Wolf     }
1266da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1267da1fa91dSKevin Wolf         return -EIO;
1268da1fa91dSKevin Wolf     }
1269da1fa91dSKevin Wolf 
1270da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1271da1fa91dSKevin Wolf }
1272da1fa91dSKevin Wolf 
1273c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1274da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1275da1fa91dSKevin Wolf {
1276c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1277da1fa91dSKevin Wolf 
1278c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1279c5fbe571SStefan Hajnoczi }
1280c5fbe571SStefan Hajnoczi 
1281c5fbe571SStefan Hajnoczi /*
1282c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1283c5fbe571SStefan Hajnoczi  */
1284c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1285c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1286c5fbe571SStefan Hajnoczi {
1287c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
12886b7cb247SStefan Hajnoczi     int ret;
1289da1fa91dSKevin Wolf 
1290da1fa91dSKevin Wolf     if (!bs->drv) {
1291da1fa91dSKevin Wolf         return -ENOMEDIUM;
1292da1fa91dSKevin Wolf     }
1293da1fa91dSKevin Wolf     if (bs->read_only) {
1294da1fa91dSKevin Wolf         return -EACCES;
1295da1fa91dSKevin Wolf     }
1296da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1297da1fa91dSKevin Wolf         return -EIO;
1298da1fa91dSKevin Wolf     }
1299da1fa91dSKevin Wolf 
13006b7cb247SStefan Hajnoczi     ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
13016b7cb247SStefan Hajnoczi 
1302da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1303da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1304da1fa91dSKevin Wolf     }
1305da1fa91dSKevin Wolf 
1306da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1307da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1308da1fa91dSKevin Wolf     }
1309da1fa91dSKevin Wolf 
13106b7cb247SStefan Hajnoczi     return ret;
1311da1fa91dSKevin Wolf }
1312da1fa91dSKevin Wolf 
1313c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1314c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1315c5fbe571SStefan Hajnoczi {
1316c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1317c5fbe571SStefan Hajnoczi 
1318c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1319c5fbe571SStefan Hajnoczi }
1320c5fbe571SStefan Hajnoczi 
132183f64091Sbellard /**
132283f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
132383f64091Sbellard  */
132483f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
132583f64091Sbellard {
132683f64091Sbellard     BlockDriver *drv = bs->drv;
132751762288SStefan Hajnoczi     int ret;
132883f64091Sbellard     if (!drv)
132919cb3738Sbellard         return -ENOMEDIUM;
133083f64091Sbellard     if (!drv->bdrv_truncate)
133183f64091Sbellard         return -ENOTSUP;
133259f2689dSNaphtali Sprei     if (bs->read_only)
133359f2689dSNaphtali Sprei         return -EACCES;
13348591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13358591675fSMarcelo Tosatti         return -EBUSY;
133651762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
133751762288SStefan Hajnoczi     if (ret == 0) {
133851762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1339145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
134051762288SStefan Hajnoczi     }
134151762288SStefan Hajnoczi     return ret;
134283f64091Sbellard }
134383f64091Sbellard 
134483f64091Sbellard /**
13454a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13464a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13474a1d5e1fSFam Zheng  */
13484a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13494a1d5e1fSFam Zheng {
13504a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13514a1d5e1fSFam Zheng     if (!drv) {
13524a1d5e1fSFam Zheng         return -ENOMEDIUM;
13534a1d5e1fSFam Zheng     }
13544a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13554a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13564a1d5e1fSFam Zheng     }
13574a1d5e1fSFam Zheng     if (bs->file) {
13584a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13594a1d5e1fSFam Zheng     }
13604a1d5e1fSFam Zheng     return -ENOTSUP;
13614a1d5e1fSFam Zheng }
13624a1d5e1fSFam Zheng 
13634a1d5e1fSFam Zheng /**
136483f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
136583f64091Sbellard  */
136683f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
136783f64091Sbellard {
136883f64091Sbellard     BlockDriver *drv = bs->drv;
136983f64091Sbellard     if (!drv)
137019cb3738Sbellard         return -ENOMEDIUM;
137151762288SStefan Hajnoczi 
13722c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
137346a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
137483f64091Sbellard             return drv->bdrv_getlength(bs);
1375fc01f7e7Sbellard         }
137646a4e4e6SStefan Hajnoczi     }
137746a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
137846a4e4e6SStefan Hajnoczi }
1379fc01f7e7Sbellard 
138019cb3738Sbellard /* return 0 as number of sectors if no device present or error */
138196b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1382fc01f7e7Sbellard {
138319cb3738Sbellard     int64_t length;
138419cb3738Sbellard     length = bdrv_getlength(bs);
138519cb3738Sbellard     if (length < 0)
138619cb3738Sbellard         length = 0;
138719cb3738Sbellard     else
13886ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
138919cb3738Sbellard     *nb_sectors_ptr = length;
1390fc01f7e7Sbellard }
1391cf98951bSbellard 
1392f3d54fc4Saliguori struct partition {
1393f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1394f3d54fc4Saliguori         uint8_t head;               /* starting head */
1395f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1396f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1397f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1398f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1399f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1400f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1401f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1402f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1403541dc0d4SStefan Weil } QEMU_PACKED;
1404f3d54fc4Saliguori 
1405f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1406f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1407f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1408f3d54fc4Saliguori {
1409eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1410f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1411f3d54fc4Saliguori     struct partition *p;
1412f3d54fc4Saliguori     uint32_t nr_sects;
1413a38131b6Sblueswir1     uint64_t nb_sectors;
1414f3d54fc4Saliguori 
1415f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1416f3d54fc4Saliguori 
1417f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1418f3d54fc4Saliguori     if (ret < 0)
1419f3d54fc4Saliguori         return -1;
1420f3d54fc4Saliguori     /* test msdos magic */
1421f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1422f3d54fc4Saliguori         return -1;
1423f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1424f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1425f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1426f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1427f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1428f3d54fc4Saliguori                a cylinder boundary */
1429f3d54fc4Saliguori             heads = p->end_head + 1;
1430f3d54fc4Saliguori             sectors = p->end_sector & 63;
1431f3d54fc4Saliguori             if (sectors == 0)
1432f3d54fc4Saliguori                 continue;
1433f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1434f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1435f3d54fc4Saliguori                 continue;
1436f3d54fc4Saliguori             *pheads = heads;
1437f3d54fc4Saliguori             *psectors = sectors;
1438f3d54fc4Saliguori             *pcylinders = cylinders;
1439f3d54fc4Saliguori #if 0
1440f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1441f3d54fc4Saliguori                    cylinders, heads, sectors);
1442f3d54fc4Saliguori #endif
1443f3d54fc4Saliguori             return 0;
1444f3d54fc4Saliguori         }
1445f3d54fc4Saliguori     }
1446f3d54fc4Saliguori     return -1;
1447f3d54fc4Saliguori }
1448f3d54fc4Saliguori 
1449f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1450f3d54fc4Saliguori {
1451f3d54fc4Saliguori     int translation, lba_detected = 0;
1452f3d54fc4Saliguori     int cylinders, heads, secs;
1453a38131b6Sblueswir1     uint64_t nb_sectors;
1454f3d54fc4Saliguori 
1455f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1456f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1457f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1458f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1459f3d54fc4Saliguori     if (cylinders != 0) {
1460f3d54fc4Saliguori         *pcyls = cylinders;
1461f3d54fc4Saliguori         *pheads = heads;
1462f3d54fc4Saliguori         *psecs = secs;
1463f3d54fc4Saliguori     } else {
1464f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1465f3d54fc4Saliguori             if (heads > 16) {
1466f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1467f3d54fc4Saliguori                    translation was active, so the default
1468f3d54fc4Saliguori                    hardware geometry is OK */
1469f3d54fc4Saliguori                 lba_detected = 1;
1470f3d54fc4Saliguori                 goto default_geometry;
1471f3d54fc4Saliguori             } else {
1472f3d54fc4Saliguori                 *pcyls = cylinders;
1473f3d54fc4Saliguori                 *pheads = heads;
1474f3d54fc4Saliguori                 *psecs = secs;
1475f3d54fc4Saliguori                 /* disable any translation to be in sync with
1476f3d54fc4Saliguori                    the logical geometry */
1477f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1478f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1479f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1480f3d54fc4Saliguori                 }
1481f3d54fc4Saliguori             }
1482f3d54fc4Saliguori         } else {
1483f3d54fc4Saliguori         default_geometry:
1484f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1485f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1486f3d54fc4Saliguori 
1487f3d54fc4Saliguori             if (cylinders > 16383)
1488f3d54fc4Saliguori                 cylinders = 16383;
1489f3d54fc4Saliguori             else if (cylinders < 2)
1490f3d54fc4Saliguori                 cylinders = 2;
1491f3d54fc4Saliguori             *pcyls = cylinders;
1492f3d54fc4Saliguori             *pheads = 16;
1493f3d54fc4Saliguori             *psecs = 63;
1494f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1495f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1496f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1497f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1498f3d54fc4Saliguori                 } else {
1499f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1500f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1501f3d54fc4Saliguori                 }
1502f3d54fc4Saliguori             }
1503f3d54fc4Saliguori         }
1504f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1505f3d54fc4Saliguori     }
1506f3d54fc4Saliguori }
1507f3d54fc4Saliguori 
1508b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1509b338082bSbellard                             int cyls, int heads, int secs)
1510b338082bSbellard {
1511b338082bSbellard     bs->cyls = cyls;
1512b338082bSbellard     bs->heads = heads;
1513b338082bSbellard     bs->secs = secs;
1514b338082bSbellard }
1515b338082bSbellard 
151646d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
151746d4767dSbellard {
151846d4767dSbellard     bs->translation = translation;
151946d4767dSbellard }
152046d4767dSbellard 
1521b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1522b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1523b338082bSbellard {
1524b338082bSbellard     *pcyls = bs->cyls;
1525b338082bSbellard     *pheads = bs->heads;
1526b338082bSbellard     *psecs = bs->secs;
1527b338082bSbellard }
1528b338082bSbellard 
15295bbdbb46SBlue Swirl /* Recognize floppy formats */
15305bbdbb46SBlue Swirl typedef struct FDFormat {
15315bbdbb46SBlue Swirl     FDriveType drive;
15325bbdbb46SBlue Swirl     uint8_t last_sect;
15335bbdbb46SBlue Swirl     uint8_t max_track;
15345bbdbb46SBlue Swirl     uint8_t max_head;
15355bbdbb46SBlue Swirl } FDFormat;
15365bbdbb46SBlue Swirl 
15375bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15385bbdbb46SBlue Swirl     /* First entry is default format */
15395bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15405bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15415bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15425bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15435bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15445bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15455bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15465bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15475bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15485bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15495bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15505bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15515bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15525bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15535bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15545bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15555bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15565bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15575bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15585bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15595bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15605bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15615bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15625bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15635bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15645bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15655bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15665bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15675bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15685bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15695bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15705bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15715bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15725bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15735bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15745bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15755bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15765bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
15775bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
15785bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
15795bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
15805bbdbb46SBlue Swirl     /* end */
15815bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
15825bbdbb46SBlue Swirl };
15835bbdbb46SBlue Swirl 
15845bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
15855bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
15865bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
15875bbdbb46SBlue Swirl {
15885bbdbb46SBlue Swirl     const FDFormat *parse;
15895bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
15905bbdbb46SBlue Swirl     int i, first_match, match;
15915bbdbb46SBlue Swirl 
15925bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
15935bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
15945bbdbb46SBlue Swirl         /* User defined disk */
15955bbdbb46SBlue Swirl     } else {
15965bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
15975bbdbb46SBlue Swirl         match = -1;
15985bbdbb46SBlue Swirl         first_match = -1;
15995bbdbb46SBlue Swirl         for (i = 0; ; i++) {
16005bbdbb46SBlue Swirl             parse = &fd_formats[i];
16015bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
16025bbdbb46SBlue Swirl                 break;
16035bbdbb46SBlue Swirl             }
16045bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
16055bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
16065bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
16075bbdbb46SBlue Swirl                     parse->last_sect;
16085bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16095bbdbb46SBlue Swirl                     match = i;
16105bbdbb46SBlue Swirl                     break;
16115bbdbb46SBlue Swirl                 }
16125bbdbb46SBlue Swirl                 if (first_match == -1) {
16135bbdbb46SBlue Swirl                     first_match = i;
16145bbdbb46SBlue Swirl                 }
16155bbdbb46SBlue Swirl             }
16165bbdbb46SBlue Swirl         }
16175bbdbb46SBlue Swirl         if (match == -1) {
16185bbdbb46SBlue Swirl             if (first_match == -1) {
16195bbdbb46SBlue Swirl                 match = 1;
16205bbdbb46SBlue Swirl             } else {
16215bbdbb46SBlue Swirl                 match = first_match;
16225bbdbb46SBlue Swirl             }
16235bbdbb46SBlue Swirl             parse = &fd_formats[match];
16245bbdbb46SBlue Swirl         }
16255bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16265bbdbb46SBlue Swirl         *max_track = parse->max_track;
16275bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16285bbdbb46SBlue Swirl         *drive = parse->drive;
16295bbdbb46SBlue Swirl     }
16305bbdbb46SBlue Swirl }
16315bbdbb46SBlue Swirl 
163246d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
163346d4767dSbellard {
163446d4767dSbellard     return bs->translation;
163546d4767dSbellard }
163646d4767dSbellard 
1637abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1638abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1639abd7f68dSMarkus Armbruster {
1640abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1641abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1642abd7f68dSMarkus Armbruster }
1643abd7f68dSMarkus Armbruster 
1644abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1645abd7f68dSMarkus Armbruster {
1646abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1647abd7f68dSMarkus Armbruster }
1648abd7f68dSMarkus Armbruster 
1649b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1650b338082bSbellard {
1651b338082bSbellard     return bs->read_only;
1652b338082bSbellard }
1653b338082bSbellard 
1654985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1655985a03b0Sths {
1656985a03b0Sths     return bs->sg;
1657985a03b0Sths }
1658985a03b0Sths 
1659e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1660e900a7b7SChristoph Hellwig {
1661e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1662e900a7b7SChristoph Hellwig }
1663e900a7b7SChristoph Hellwig 
1664ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1665ea2384d3Sbellard {
1666ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1667ea2384d3Sbellard         return 1;
1668ea2384d3Sbellard     return bs->encrypted;
1669ea2384d3Sbellard }
1670ea2384d3Sbellard 
1671c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1672c0f4ce77Saliguori {
1673c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1674c0f4ce77Saliguori 
1675c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1676c0f4ce77Saliguori         return 1;
1677c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1678c0f4ce77Saliguori }
1679c0f4ce77Saliguori 
1680ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1681ea2384d3Sbellard {
1682ea2384d3Sbellard     int ret;
1683ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1684ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1685ea2384d3Sbellard         if (ret < 0)
1686ea2384d3Sbellard             return ret;
1687ea2384d3Sbellard         if (!bs->encrypted)
1688ea2384d3Sbellard             return 0;
1689ea2384d3Sbellard     }
1690fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1691fd04a2aeSShahar Havivi         return -EINVAL;
1692fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1693fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1694fd04a2aeSShahar Havivi     }
1695c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1696bb5fc20fSaliguori     if (ret < 0) {
1697bb5fc20fSaliguori         bs->valid_key = 0;
1698bb5fc20fSaliguori     } else if (!bs->valid_key) {
1699bb5fc20fSaliguori         bs->valid_key = 1;
1700bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
17017d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1702bb5fc20fSaliguori     }
1703c0f4ce77Saliguori     return ret;
1704ea2384d3Sbellard }
1705ea2384d3Sbellard 
1706ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1707ea2384d3Sbellard {
170819cb3738Sbellard     if (!bs->drv) {
1709ea2384d3Sbellard         buf[0] = '\0';
1710ea2384d3Sbellard     } else {
1711ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1712ea2384d3Sbellard     }
1713ea2384d3Sbellard }
1714ea2384d3Sbellard 
1715ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1716ea2384d3Sbellard                          void *opaque)
1717ea2384d3Sbellard {
1718ea2384d3Sbellard     BlockDriver *drv;
1719ea2384d3Sbellard 
17208a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1721ea2384d3Sbellard         it(opaque, drv->format_name);
1722ea2384d3Sbellard     }
1723ea2384d3Sbellard }
1724ea2384d3Sbellard 
1725b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1726b338082bSbellard {
1727b338082bSbellard     BlockDriverState *bs;
1728b338082bSbellard 
17291b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17301b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1731b338082bSbellard             return bs;
1732b338082bSbellard         }
17331b7bdbc1SStefan Hajnoczi     }
1734b338082bSbellard     return NULL;
1735b338082bSbellard }
1736b338082bSbellard 
17372f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17382f399b0aSMarkus Armbruster {
17392f399b0aSMarkus Armbruster     if (!bs) {
17402f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17412f399b0aSMarkus Armbruster     }
17422f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17432f399b0aSMarkus Armbruster }
17442f399b0aSMarkus Armbruster 
174551de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
174681d0912dSbellard {
174781d0912dSbellard     BlockDriverState *bs;
174881d0912dSbellard 
17491b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
175051de9760Saliguori         it(opaque, bs);
175181d0912dSbellard     }
175281d0912dSbellard }
175381d0912dSbellard 
1754ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1755ea2384d3Sbellard {
1756ea2384d3Sbellard     return bs->device_name;
1757ea2384d3Sbellard }
1758ea2384d3Sbellard 
1759c6ca28d6Saliguori void bdrv_flush_all(void)
1760c6ca28d6Saliguori {
1761c6ca28d6Saliguori     BlockDriverState *bs;
1762c6ca28d6Saliguori 
17631b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1764c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1765c6ca28d6Saliguori             bdrv_flush(bs);
1766c6ca28d6Saliguori         }
17671b7bdbc1SStefan Hajnoczi     }
17681b7bdbc1SStefan Hajnoczi }
1769c6ca28d6Saliguori 
1770f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1771f2feebbdSKevin Wolf {
1772f2feebbdSKevin Wolf     assert(bs->drv);
1773f2feebbdSKevin Wolf 
1774336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1775336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1776f2feebbdSKevin Wolf     }
1777f2feebbdSKevin Wolf 
1778f2feebbdSKevin Wolf     return 1;
1779f2feebbdSKevin Wolf }
1780f2feebbdSKevin Wolf 
1781f58c7b35Sths /*
1782f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1783f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1784f58c7b35Sths  * hence all their sectors are reported as allocated.
1785f58c7b35Sths  *
1786f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1787f58c7b35Sths  * the specified sector) that are known to be in the same
1788f58c7b35Sths  * allocated/unallocated state.
1789f58c7b35Sths  *
1790f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1791f58c7b35Sths  */
1792f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1793f58c7b35Sths 	int *pnum)
1794f58c7b35Sths {
1795f58c7b35Sths     int64_t n;
1796f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1797f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1798f58c7b35Sths             *pnum = 0;
1799f58c7b35Sths             return 0;
1800f58c7b35Sths         }
1801f58c7b35Sths         n = bs->total_sectors - sector_num;
1802f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1803f58c7b35Sths         return 1;
1804f58c7b35Sths     }
1805f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1806f58c7b35Sths }
1807f58c7b35Sths 
18082582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18092582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18102582bfedSLuiz Capitulino {
18112582bfedSLuiz Capitulino     QObject *data;
18122582bfedSLuiz Capitulino     const char *action_str;
18132582bfedSLuiz Capitulino 
18142582bfedSLuiz Capitulino     switch (action) {
18152582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18162582bfedSLuiz Capitulino         action_str = "report";
18172582bfedSLuiz Capitulino         break;
18182582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18192582bfedSLuiz Capitulino         action_str = "ignore";
18202582bfedSLuiz Capitulino         break;
18212582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18222582bfedSLuiz Capitulino         action_str = "stop";
18232582bfedSLuiz Capitulino         break;
18242582bfedSLuiz Capitulino     default:
18252582bfedSLuiz Capitulino         abort();
18262582bfedSLuiz Capitulino     }
18272582bfedSLuiz Capitulino 
18282582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18292582bfedSLuiz Capitulino                               bdrv->device_name,
18302582bfedSLuiz Capitulino                               action_str,
18312582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18322582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18332582bfedSLuiz Capitulino 
18342582bfedSLuiz Capitulino     qobject_decref(data);
18352582bfedSLuiz Capitulino }
18362582bfedSLuiz Capitulino 
1837b2023818SLuiz Capitulino BlockInfoList *qmp_query_block(Error **errp)
1838b338082bSbellard {
1839b2023818SLuiz Capitulino     BlockInfoList *head = NULL, *cur_item = NULL;
1840d15e5465SLuiz Capitulino     BlockDriverState *bs;
1841d15e5465SLuiz Capitulino 
18421b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1843b2023818SLuiz Capitulino         BlockInfoList *info = g_malloc0(sizeof(*info));
1844d15e5465SLuiz Capitulino 
1845b2023818SLuiz Capitulino         info->value = g_malloc0(sizeof(*info->value));
1846b2023818SLuiz Capitulino         info->value->device = g_strdup(bs->device_name);
1847b2023818SLuiz Capitulino         info->value->type = g_strdup("unknown");
1848b2023818SLuiz Capitulino         info->value->locked = bdrv_dev_is_medium_locked(bs);
1849b2023818SLuiz Capitulino         info->value->removable = bdrv_dev_has_removable_media(bs);
1850d15e5465SLuiz Capitulino 
1851e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1852b2023818SLuiz Capitulino             info->value->has_tray_open = true;
1853b2023818SLuiz Capitulino             info->value->tray_open = bdrv_dev_is_tray_open(bs);
1854e4def80bSMarkus Armbruster         }
1855f04ef601SLuiz Capitulino 
1856f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1857b2023818SLuiz Capitulino             info->value->has_io_status = true;
1858b2023818SLuiz Capitulino             info->value->io_status = bs->iostatus;
1859f04ef601SLuiz Capitulino         }
1860f04ef601SLuiz Capitulino 
1861d15e5465SLuiz Capitulino         if (bs->drv) {
1862b2023818SLuiz Capitulino             info->value->has_inserted = true;
1863b2023818SLuiz Capitulino             info->value->inserted = g_malloc0(sizeof(*info->value->inserted));
1864b2023818SLuiz Capitulino             info->value->inserted->file = g_strdup(bs->filename);
1865b2023818SLuiz Capitulino             info->value->inserted->ro = bs->read_only;
1866b2023818SLuiz Capitulino             info->value->inserted->drv = g_strdup(bs->drv->format_name);
1867b2023818SLuiz Capitulino             info->value->inserted->encrypted = bs->encrypted;
1868b2023818SLuiz Capitulino             if (bs->backing_file[0]) {
1869b2023818SLuiz Capitulino                 info->value->inserted->has_backing_file = true;
1870b2023818SLuiz Capitulino                 info->value->inserted->backing_file = g_strdup(bs->backing_file);
1871b2023818SLuiz Capitulino             }
1872d15e5465SLuiz Capitulino         }
1873d15e5465SLuiz Capitulino 
1874b2023818SLuiz Capitulino         /* XXX: waiting for the qapi to support GSList */
1875b2023818SLuiz Capitulino         if (!cur_item) {
1876b2023818SLuiz Capitulino             head = cur_item = info;
1877b2023818SLuiz Capitulino         } else {
1878b2023818SLuiz Capitulino             cur_item->next = info;
1879b2023818SLuiz Capitulino             cur_item = info;
1880d15e5465SLuiz Capitulino         }
1881d15e5465SLuiz Capitulino     }
1882d15e5465SLuiz Capitulino 
1883b2023818SLuiz Capitulino     return head;
1884b338082bSbellard }
1885a36e69ddSths 
1886f11f57e4SLuiz Capitulino /* Consider exposing this as a full fledged QMP command */
1887f11f57e4SLuiz Capitulino static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp)
1888a36e69ddSths {
1889f11f57e4SLuiz Capitulino     BlockStats *s;
1890218a536aSLuiz Capitulino 
1891f11f57e4SLuiz Capitulino     s = g_malloc0(sizeof(*s));
1892218a536aSLuiz Capitulino 
1893f11f57e4SLuiz Capitulino     if (bs->device_name[0]) {
1894f11f57e4SLuiz Capitulino         s->has_device = true;
1895f11f57e4SLuiz Capitulino         s->device = g_strdup(bs->device_name);
1896218a536aSLuiz Capitulino     }
1897218a536aSLuiz Capitulino 
1898f11f57e4SLuiz Capitulino     s->stats = g_malloc0(sizeof(*s->stats));
1899f11f57e4SLuiz Capitulino     s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
1900f11f57e4SLuiz Capitulino     s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
1901f11f57e4SLuiz Capitulino     s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
1902f11f57e4SLuiz Capitulino     s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
1903f11f57e4SLuiz Capitulino     s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
1904f11f57e4SLuiz Capitulino     s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
1905f11f57e4SLuiz Capitulino     s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
1906f11f57e4SLuiz Capitulino     s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
1907f11f57e4SLuiz Capitulino     s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
1908294cc35fSKevin Wolf 
1909294cc35fSKevin Wolf     if (bs->file) {
1910f11f57e4SLuiz Capitulino         s->has_parent = true;
1911f11f57e4SLuiz Capitulino         s->parent = qmp_query_blockstat(bs->file, NULL);
1912294cc35fSKevin Wolf     }
1913294cc35fSKevin Wolf 
1914f11f57e4SLuiz Capitulino     return s;
1915294cc35fSKevin Wolf }
1916294cc35fSKevin Wolf 
1917f11f57e4SLuiz Capitulino BlockStatsList *qmp_query_blockstats(Error **errp)
1918218a536aSLuiz Capitulino {
1919f11f57e4SLuiz Capitulino     BlockStatsList *head = NULL, *cur_item = NULL;
1920a36e69ddSths     BlockDriverState *bs;
1921a36e69ddSths 
19221b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1923f11f57e4SLuiz Capitulino         BlockStatsList *info = g_malloc0(sizeof(*info));
1924f11f57e4SLuiz Capitulino         info->value = qmp_query_blockstat(bs, NULL);
1925f11f57e4SLuiz Capitulino 
1926f11f57e4SLuiz Capitulino         /* XXX: waiting for the qapi to support GSList */
1927f11f57e4SLuiz Capitulino         if (!cur_item) {
1928f11f57e4SLuiz Capitulino             head = cur_item = info;
1929f11f57e4SLuiz Capitulino         } else {
1930f11f57e4SLuiz Capitulino             cur_item->next = info;
1931f11f57e4SLuiz Capitulino             cur_item = info;
1932f11f57e4SLuiz Capitulino         }
1933a36e69ddSths     }
1934218a536aSLuiz Capitulino 
1935f11f57e4SLuiz Capitulino     return head;
1936a36e69ddSths }
1937ea2384d3Sbellard 
1938045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1939045df330Saliguori {
1940045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
1941045df330Saliguori         return bs->backing_file;
1942045df330Saliguori     else if (bs->encrypted)
1943045df330Saliguori         return bs->filename;
1944045df330Saliguori     else
1945045df330Saliguori         return NULL;
1946045df330Saliguori }
1947045df330Saliguori 
194883f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
194983f64091Sbellard                                char *filename, int filename_size)
195083f64091Sbellard {
195183f64091Sbellard     pstrcpy(filename, filename_size, bs->backing_file);
195283f64091Sbellard }
195383f64091Sbellard 
1954faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1955faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
1956faea38e7Sbellard {
1957faea38e7Sbellard     BlockDriver *drv = bs->drv;
1958faea38e7Sbellard     if (!drv)
195919cb3738Sbellard         return -ENOMEDIUM;
1960faea38e7Sbellard     if (!drv->bdrv_write_compressed)
1961faea38e7Sbellard         return -ENOTSUP;
1962fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
1963fbb7b4e0SKevin Wolf         return -EIO;
19647cd1e32aSlirans@il.ibm.com 
1965c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
19667cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
19677cd1e32aSlirans@il.ibm.com     }
19687cd1e32aSlirans@il.ibm.com 
1969faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
1970faea38e7Sbellard }
1971faea38e7Sbellard 
1972faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1973faea38e7Sbellard {
1974faea38e7Sbellard     BlockDriver *drv = bs->drv;
1975faea38e7Sbellard     if (!drv)
197619cb3738Sbellard         return -ENOMEDIUM;
1977faea38e7Sbellard     if (!drv->bdrv_get_info)
1978faea38e7Sbellard         return -ENOTSUP;
1979faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
1980faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
1981faea38e7Sbellard }
1982faea38e7Sbellard 
198345566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
198445566e9cSChristoph Hellwig                       int64_t pos, int size)
1985178e08a5Saliguori {
1986178e08a5Saliguori     BlockDriver *drv = bs->drv;
1987178e08a5Saliguori     if (!drv)
1988178e08a5Saliguori         return -ENOMEDIUM;
19897cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
199045566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
19917cdb1f6dSMORITA Kazutaka     if (bs->file)
19927cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
19937cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
1994178e08a5Saliguori }
1995178e08a5Saliguori 
199645566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
199745566e9cSChristoph Hellwig                       int64_t pos, int size)
1998178e08a5Saliguori {
1999178e08a5Saliguori     BlockDriver *drv = bs->drv;
2000178e08a5Saliguori     if (!drv)
2001178e08a5Saliguori         return -ENOMEDIUM;
20027cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
200345566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
20047cdb1f6dSMORITA Kazutaka     if (bs->file)
20057cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
20067cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2007178e08a5Saliguori }
2008178e08a5Saliguori 
20098b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
20108b9b0cc2SKevin Wolf {
20118b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
20128b9b0cc2SKevin Wolf 
20138b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
20148b9b0cc2SKevin Wolf         return;
20158b9b0cc2SKevin Wolf     }
20168b9b0cc2SKevin Wolf 
20178b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
20188b9b0cc2SKevin Wolf 
20198b9b0cc2SKevin Wolf }
20208b9b0cc2SKevin Wolf 
2021faea38e7Sbellard /**************************************************************/
2022faea38e7Sbellard /* handling of snapshots */
2023faea38e7Sbellard 
2024feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2025feeee5acSMiguel Di Ciurcio Filho {
2026feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
202707b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2028feeee5acSMiguel Di Ciurcio Filho         return 0;
2029feeee5acSMiguel Di Ciurcio Filho     }
2030feeee5acSMiguel Di Ciurcio Filho 
2031feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2032feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2033feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2034feeee5acSMiguel Di Ciurcio Filho         }
2035feeee5acSMiguel Di Ciurcio Filho         return 0;
2036feeee5acSMiguel Di Ciurcio Filho     }
2037feeee5acSMiguel Di Ciurcio Filho 
2038feeee5acSMiguel Di Ciurcio Filho     return 1;
2039feeee5acSMiguel Di Ciurcio Filho }
2040feeee5acSMiguel Di Ciurcio Filho 
2041199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2042199630b6SBlue Swirl {
2043199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2044199630b6SBlue Swirl }
2045199630b6SBlue Swirl 
2046f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2047f9092b10SMarkus Armbruster {
2048f9092b10SMarkus Armbruster     BlockDriverState *bs;
2049f9092b10SMarkus Armbruster 
20503ac906f7SMarkus Armbruster     if (bs_snapshots) {
2051f9092b10SMarkus Armbruster         return bs_snapshots;
20523ac906f7SMarkus Armbruster     }
2053f9092b10SMarkus Armbruster 
2054f9092b10SMarkus Armbruster     bs = NULL;
2055f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2056f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
20573ac906f7SMarkus Armbruster             bs_snapshots = bs;
20583ac906f7SMarkus Armbruster             return bs;
2059f9092b10SMarkus Armbruster         }
2060f9092b10SMarkus Armbruster     }
2061f9092b10SMarkus Armbruster     return NULL;
2062f9092b10SMarkus Armbruster }
2063f9092b10SMarkus Armbruster 
2064faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2065faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2066faea38e7Sbellard {
2067faea38e7Sbellard     BlockDriver *drv = bs->drv;
2068faea38e7Sbellard     if (!drv)
206919cb3738Sbellard         return -ENOMEDIUM;
20707cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2071faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
20727cdb1f6dSMORITA Kazutaka     if (bs->file)
20737cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
20747cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2075faea38e7Sbellard }
2076faea38e7Sbellard 
2077faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2078faea38e7Sbellard                        const char *snapshot_id)
2079faea38e7Sbellard {
2080faea38e7Sbellard     BlockDriver *drv = bs->drv;
20817cdb1f6dSMORITA Kazutaka     int ret, open_ret;
20827cdb1f6dSMORITA Kazutaka 
2083faea38e7Sbellard     if (!drv)
208419cb3738Sbellard         return -ENOMEDIUM;
20857cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2086faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
20877cdb1f6dSMORITA Kazutaka 
20887cdb1f6dSMORITA Kazutaka     if (bs->file) {
20897cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
20907cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
20917cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
20927cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
20937cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
20947cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
20957cdb1f6dSMORITA Kazutaka             return open_ret;
20967cdb1f6dSMORITA Kazutaka         }
20977cdb1f6dSMORITA Kazutaka         return ret;
20987cdb1f6dSMORITA Kazutaka     }
20997cdb1f6dSMORITA Kazutaka 
21007cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2101faea38e7Sbellard }
2102faea38e7Sbellard 
2103faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2104faea38e7Sbellard {
2105faea38e7Sbellard     BlockDriver *drv = bs->drv;
2106faea38e7Sbellard     if (!drv)
210719cb3738Sbellard         return -ENOMEDIUM;
21087cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2109faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
21107cdb1f6dSMORITA Kazutaka     if (bs->file)
21117cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
21127cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2113faea38e7Sbellard }
2114faea38e7Sbellard 
2115faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2116faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2117faea38e7Sbellard {
2118faea38e7Sbellard     BlockDriver *drv = bs->drv;
2119faea38e7Sbellard     if (!drv)
212019cb3738Sbellard         return -ENOMEDIUM;
21217cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2122faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
21237cdb1f6dSMORITA Kazutaka     if (bs->file)
21247cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
21257cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2126faea38e7Sbellard }
2127faea38e7Sbellard 
212851ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
212951ef6727Sedison         const char *snapshot_name)
213051ef6727Sedison {
213151ef6727Sedison     BlockDriver *drv = bs->drv;
213251ef6727Sedison     if (!drv) {
213351ef6727Sedison         return -ENOMEDIUM;
213451ef6727Sedison     }
213551ef6727Sedison     if (!bs->read_only) {
213651ef6727Sedison         return -EINVAL;
213751ef6727Sedison     }
213851ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
213951ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
214051ef6727Sedison     }
214151ef6727Sedison     return -ENOTSUP;
214251ef6727Sedison }
214351ef6727Sedison 
2144faea38e7Sbellard #define NB_SUFFIXES 4
2145faea38e7Sbellard 
2146faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2147faea38e7Sbellard {
2148faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2149faea38e7Sbellard     int64_t base;
2150faea38e7Sbellard     int i;
2151faea38e7Sbellard 
2152faea38e7Sbellard     if (size <= 999) {
2153faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2154faea38e7Sbellard     } else {
2155faea38e7Sbellard         base = 1024;
2156faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2157faea38e7Sbellard             if (size < (10 * base)) {
2158faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2159faea38e7Sbellard                          (double)size / base,
2160faea38e7Sbellard                          suffixes[i]);
2161faea38e7Sbellard                 break;
2162faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2163faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2164faea38e7Sbellard                          ((size + (base >> 1)) / base),
2165faea38e7Sbellard                          suffixes[i]);
2166faea38e7Sbellard                 break;
2167faea38e7Sbellard             }
2168faea38e7Sbellard             base = base * 1024;
2169faea38e7Sbellard         }
2170faea38e7Sbellard     }
2171faea38e7Sbellard     return buf;
2172faea38e7Sbellard }
2173faea38e7Sbellard 
2174faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2175faea38e7Sbellard {
2176faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
21773b9f94e1Sbellard #ifdef _WIN32
21783b9f94e1Sbellard     struct tm *ptm;
21793b9f94e1Sbellard #else
2180faea38e7Sbellard     struct tm tm;
21813b9f94e1Sbellard #endif
2182faea38e7Sbellard     time_t ti;
2183faea38e7Sbellard     int64_t secs;
2184faea38e7Sbellard 
2185faea38e7Sbellard     if (!sn) {
2186faea38e7Sbellard         snprintf(buf, buf_size,
2187faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2188faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2189faea38e7Sbellard     } else {
2190faea38e7Sbellard         ti = sn->date_sec;
21913b9f94e1Sbellard #ifdef _WIN32
21923b9f94e1Sbellard         ptm = localtime(&ti);
21933b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
21943b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
21953b9f94e1Sbellard #else
2196faea38e7Sbellard         localtime_r(&ti, &tm);
2197faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2198faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
21993b9f94e1Sbellard #endif
2200faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2201faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2202faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2203faea38e7Sbellard                  (int)(secs / 3600),
2204faea38e7Sbellard                  (int)((secs / 60) % 60),
2205faea38e7Sbellard                  (int)(secs % 60),
2206faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2207faea38e7Sbellard         snprintf(buf, buf_size,
2208faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2209faea38e7Sbellard                  sn->id_str, sn->name,
2210faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2211faea38e7Sbellard                  date_buf,
2212faea38e7Sbellard                  clock_buf);
2213faea38e7Sbellard     }
2214faea38e7Sbellard     return buf;
2215faea38e7Sbellard }
2216faea38e7Sbellard 
2217ea2384d3Sbellard /**************************************************************/
221883f64091Sbellard /* async I/Os */
2219ea2384d3Sbellard 
22203b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2221f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
222283f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2223ea2384d3Sbellard {
2224bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2225bbf0a440SStefan Hajnoczi 
2226b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22278c5873d6SStefan Hajnoczi                                  cb, opaque, false);
222883f64091Sbellard }
222983f64091Sbellard 
2230f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2231f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
223283f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
22337674e7bfSbellard {
2234bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2235bbf0a440SStefan Hajnoczi 
22361a6e115bSStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22378c5873d6SStefan Hajnoczi                                  cb, opaque, true);
223883f64091Sbellard }
223983f64091Sbellard 
224040b4f539SKevin Wolf 
224140b4f539SKevin Wolf typedef struct MultiwriteCB {
224240b4f539SKevin Wolf     int error;
224340b4f539SKevin Wolf     int num_requests;
224440b4f539SKevin Wolf     int num_callbacks;
224540b4f539SKevin Wolf     struct {
224640b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
224740b4f539SKevin Wolf         void *opaque;
224840b4f539SKevin Wolf         QEMUIOVector *free_qiov;
224940b4f539SKevin Wolf         void *free_buf;
225040b4f539SKevin Wolf     } callbacks[];
225140b4f539SKevin Wolf } MultiwriteCB;
225240b4f539SKevin Wolf 
225340b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
225440b4f539SKevin Wolf {
225540b4f539SKevin Wolf     int i;
225640b4f539SKevin Wolf 
225740b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
225840b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
22591e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
22601e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
22611e1ea48dSStefan Hajnoczi         }
22627267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2263f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
226440b4f539SKevin Wolf     }
226540b4f539SKevin Wolf }
226640b4f539SKevin Wolf 
226740b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
226840b4f539SKevin Wolf {
226940b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
227040b4f539SKevin Wolf 
22716d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
22726d519a5fSStefan Hajnoczi 
2273cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
227440b4f539SKevin Wolf         mcb->error = ret;
227540b4f539SKevin Wolf     }
227640b4f539SKevin Wolf 
227740b4f539SKevin Wolf     mcb->num_requests--;
227840b4f539SKevin Wolf     if (mcb->num_requests == 0) {
227940b4f539SKevin Wolf         multiwrite_user_cb(mcb);
22807267c094SAnthony Liguori         g_free(mcb);
228140b4f539SKevin Wolf     }
228240b4f539SKevin Wolf }
228340b4f539SKevin Wolf 
228440b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
228540b4f539SKevin Wolf {
228677be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
228777be4366SChristoph Hellwig 
228877be4366SChristoph Hellwig     /*
228977be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
229077be4366SChristoph Hellwig      * here as that could overflow the return value.
229177be4366SChristoph Hellwig      */
229277be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
229377be4366SChristoph Hellwig         return 1;
229477be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
229577be4366SChristoph Hellwig         return -1;
229677be4366SChristoph Hellwig     } else {
229777be4366SChristoph Hellwig         return 0;
229877be4366SChristoph Hellwig     }
229940b4f539SKevin Wolf }
230040b4f539SKevin Wolf 
230140b4f539SKevin Wolf /*
230240b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
230340b4f539SKevin Wolf  * requests that remain after merging.
230440b4f539SKevin Wolf  */
230540b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
230640b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
230740b4f539SKevin Wolf {
230840b4f539SKevin Wolf     int i, outidx;
230940b4f539SKevin Wolf 
231040b4f539SKevin Wolf     // Sort requests by start sector
231140b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
231240b4f539SKevin Wolf 
231340b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
231440b4f539SKevin Wolf     // filling up gaps with zero sectors.
231540b4f539SKevin Wolf     outidx = 0;
231640b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
231740b4f539SKevin Wolf         int merge = 0;
231840b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
231940b4f539SKevin Wolf 
232040b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
232140b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
232240b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
232340b4f539SKevin Wolf             merge = 1;
232440b4f539SKevin Wolf         }
232540b4f539SKevin Wolf 
232640b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
232740b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
232840b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
232940b4f539SKevin Wolf         // unused space in format like qcow2).
233040b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
233140b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
233240b4f539SKevin Wolf         }
233340b4f539SKevin Wolf 
2334e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2335e2a305fbSChristoph Hellwig             merge = 0;
2336e2a305fbSChristoph Hellwig         }
2337e2a305fbSChristoph Hellwig 
233840b4f539SKevin Wolf         if (merge) {
233940b4f539SKevin Wolf             size_t size;
23407267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
234140b4f539SKevin Wolf             qemu_iovec_init(qiov,
234240b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
234340b4f539SKevin Wolf 
234440b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
234540b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
234640b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
234740b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
234840b4f539SKevin Wolf 
234940b4f539SKevin Wolf             // We might need to add some zeros between the two requests
235040b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
235140b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
235240b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
235340b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
235440b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
235540b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
235640b4f539SKevin Wolf             }
235740b4f539SKevin Wolf 
235840b4f539SKevin Wolf             // Add the second request
235940b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
236040b4f539SKevin Wolf 
2361cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
236240b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
236340b4f539SKevin Wolf 
236440b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
236540b4f539SKevin Wolf         } else {
236640b4f539SKevin Wolf             outidx++;
236740b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
236840b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
236940b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
237040b4f539SKevin Wolf         }
237140b4f539SKevin Wolf     }
237240b4f539SKevin Wolf 
237340b4f539SKevin Wolf     return outidx + 1;
237440b4f539SKevin Wolf }
237540b4f539SKevin Wolf 
237640b4f539SKevin Wolf /*
237740b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
237840b4f539SKevin Wolf  *
237940b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
238040b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
238140b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
238240b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
238340b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
238440b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
238540b4f539SKevin Wolf  *
238640b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
238740b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
238840b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
238940b4f539SKevin Wolf  */
239040b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
239140b4f539SKevin Wolf {
239240b4f539SKevin Wolf     BlockDriverAIOCB *acb;
239340b4f539SKevin Wolf     MultiwriteCB *mcb;
239440b4f539SKevin Wolf     int i;
239540b4f539SKevin Wolf 
2396301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2397301db7c2SRyan Harper     if (bs->drv == NULL) {
2398301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2399301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2400301db7c2SRyan Harper         }
2401301db7c2SRyan Harper         return -1;
2402301db7c2SRyan Harper     }
2403301db7c2SRyan Harper 
240440b4f539SKevin Wolf     if (num_reqs == 0) {
240540b4f539SKevin Wolf         return 0;
240640b4f539SKevin Wolf     }
240740b4f539SKevin Wolf 
240840b4f539SKevin Wolf     // Create MultiwriteCB structure
24097267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
241040b4f539SKevin Wolf     mcb->num_requests = 0;
241140b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
241240b4f539SKevin Wolf 
241340b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
241440b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
241540b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
241640b4f539SKevin Wolf     }
241740b4f539SKevin Wolf 
241840b4f539SKevin Wolf     // Check for mergable requests
241940b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
242040b4f539SKevin Wolf 
24216d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
24226d519a5fSStefan Hajnoczi 
2423453f9a16SKevin Wolf     /*
2424453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2425453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2426453f9a16SKevin Wolf      * return failure for all requests anyway)
2427453f9a16SKevin Wolf      *
2428453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2429453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2430453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2431453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2432453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2433453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2434453f9a16SKevin Wolf      * incremented for each request that is submitted.
2435453f9a16SKevin Wolf      *
2436453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2437453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2438453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2439453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2440453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2441453f9a16SKevin Wolf      */
2442453f9a16SKevin Wolf     mcb->num_requests = 1;
2443453f9a16SKevin Wolf 
24446d519a5fSStefan Hajnoczi     // Run the aio requests
244540b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2446453f9a16SKevin Wolf         mcb->num_requests++;
244740b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
244840b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
244940b4f539SKevin Wolf 
245040b4f539SKevin Wolf         if (acb == NULL) {
245140b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
245240b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
245340b4f539SKevin Wolf             // complete and report the error in the callback.
2454453f9a16SKevin Wolf             if (i == 0) {
24556d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
245640b4f539SKevin Wolf                 goto fail;
245740b4f539SKevin Wolf             } else {
24586d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
24597eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
246040b4f539SKevin Wolf                 break;
246140b4f539SKevin Wolf             }
246240b4f539SKevin Wolf         }
246340b4f539SKevin Wolf     }
246440b4f539SKevin Wolf 
2465453f9a16SKevin Wolf     /* Complete the dummy request */
2466453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2467453f9a16SKevin Wolf 
246840b4f539SKevin Wolf     return 0;
246940b4f539SKevin Wolf 
247040b4f539SKevin Wolf fail:
2471453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2472453f9a16SKevin Wolf         reqs[i].error = -EIO;
2473453f9a16SKevin Wolf     }
24747267c094SAnthony Liguori     g_free(mcb);
247540b4f539SKevin Wolf     return -1;
247640b4f539SKevin Wolf }
247740b4f539SKevin Wolf 
247883f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
247983f64091Sbellard {
24806bbff9a0Saliguori     acb->pool->cancel(acb);
248183f64091Sbellard }
248283f64091Sbellard 
248383f64091Sbellard 
248483f64091Sbellard /**************************************************************/
248583f64091Sbellard /* async block device emulation */
248683f64091Sbellard 
2487c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2488c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2489c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2490c16b5a2cSChristoph Hellwig     int ret;
2491c16b5a2cSChristoph Hellwig     /* vector translation state */
2492c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2493c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2494c16b5a2cSChristoph Hellwig     int is_write;
2495c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2496c16b5a2cSChristoph Hellwig 
2497c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2498c16b5a2cSChristoph Hellwig {
2499b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2500b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
25016a7ad299SDor Laor     qemu_bh_delete(acb->bh);
250236afc451SAvi Kivity     acb->bh = NULL;
2503c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2504c16b5a2cSChristoph Hellwig }
2505c16b5a2cSChristoph Hellwig 
2506c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2507c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2508c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2509c16b5a2cSChristoph Hellwig };
2510c16b5a2cSChristoph Hellwig 
251183f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2512beac80cdSbellard {
2513ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2514f141eafeSaliguori 
2515f141eafeSaliguori     if (!acb->is_write)
2516f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2517ceb42de8Saliguori     qemu_vfree(acb->bounce);
2518ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
25196a7ad299SDor Laor     qemu_bh_delete(acb->bh);
252036afc451SAvi Kivity     acb->bh = NULL;
2521ce1a14dcSpbrook     qemu_aio_release(acb);
2522beac80cdSbellard }
2523beac80cdSbellard 
2524f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2525f141eafeSaliguori                                             int64_t sector_num,
2526f141eafeSaliguori                                             QEMUIOVector *qiov,
2527f141eafeSaliguori                                             int nb_sectors,
2528f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2529f141eafeSaliguori                                             void *opaque,
2530f141eafeSaliguori                                             int is_write)
2531f141eafeSaliguori 
2532ea2384d3Sbellard {
2533ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
253483f64091Sbellard 
2535c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2536f141eafeSaliguori     acb->is_write = is_write;
2537f141eafeSaliguori     acb->qiov = qiov;
2538e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2539f141eafeSaliguori 
2540ce1a14dcSpbrook     if (!acb->bh)
2541ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2542f141eafeSaliguori 
2543f141eafeSaliguori     if (is_write) {
2544f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
25451ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2546f141eafeSaliguori     } else {
25471ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2548f141eafeSaliguori     }
2549f141eafeSaliguori 
2550ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2551f141eafeSaliguori 
2552ce1a14dcSpbrook     return &acb->common;
25537a6cba61Spbrook }
25547a6cba61Spbrook 
2555f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2556f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2557ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
255883f64091Sbellard {
2559f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
256083f64091Sbellard }
256183f64091Sbellard 
2562f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2563f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2564f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2565f141eafeSaliguori {
2566f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2567f141eafeSaliguori }
2568f141eafeSaliguori 
256968485420SKevin Wolf 
257068485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
257168485420SKevin Wolf     BlockDriverAIOCB common;
257268485420SKevin Wolf     BlockRequest req;
257368485420SKevin Wolf     bool is_write;
257468485420SKevin Wolf     QEMUBH* bh;
257568485420SKevin Wolf } BlockDriverAIOCBCoroutine;
257668485420SKevin Wolf 
257768485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
257868485420SKevin Wolf {
257968485420SKevin Wolf     qemu_aio_flush();
258068485420SKevin Wolf }
258168485420SKevin Wolf 
258268485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
258368485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
258468485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
258568485420SKevin Wolf };
258668485420SKevin Wolf 
258735246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque)
258868485420SKevin Wolf {
258968485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
259068485420SKevin Wolf 
259168485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
259268485420SKevin Wolf     qemu_bh_delete(acb->bh);
259368485420SKevin Wolf     qemu_aio_release(acb);
259468485420SKevin Wolf }
259568485420SKevin Wolf 
2596b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2597b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2598b2a61371SStefan Hajnoczi {
2599b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2600b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2601b2a61371SStefan Hajnoczi 
2602b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2603b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2604b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2605b2a61371SStefan Hajnoczi     } else {
2606b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2607b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2608b2a61371SStefan Hajnoczi     }
2609b2a61371SStefan Hajnoczi 
261035246a68SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2611b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2612b2a61371SStefan Hajnoczi }
2613b2a61371SStefan Hajnoczi 
261468485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
261568485420SKevin Wolf                                                int64_t sector_num,
261668485420SKevin Wolf                                                QEMUIOVector *qiov,
261768485420SKevin Wolf                                                int nb_sectors,
261868485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
261968485420SKevin Wolf                                                void *opaque,
26208c5873d6SStefan Hajnoczi                                                bool is_write)
262168485420SKevin Wolf {
262268485420SKevin Wolf     Coroutine *co;
262368485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
262468485420SKevin Wolf 
262568485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
262668485420SKevin Wolf     acb->req.sector = sector_num;
262768485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
262868485420SKevin Wolf     acb->req.qiov = qiov;
262968485420SKevin Wolf     acb->is_write = is_write;
263068485420SKevin Wolf 
26318c5873d6SStefan Hajnoczi     co = qemu_coroutine_create(bdrv_co_do_rw);
263268485420SKevin Wolf     qemu_coroutine_enter(co, acb);
263368485420SKevin Wolf 
263468485420SKevin Wolf     return &acb->common;
263568485420SKevin Wolf }
263668485420SKevin Wolf 
263707f07615SPaolo Bonzini static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
2638b2e12bc6SChristoph Hellwig {
263907f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
264007f07615SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
2641b2e12bc6SChristoph Hellwig 
264207f07615SPaolo Bonzini     acb->req.error = bdrv_co_flush(bs);
264307f07615SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2644b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2645b2e12bc6SChristoph Hellwig }
2646b2e12bc6SChristoph Hellwig 
264707f07615SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2648016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2649016f5cf6SAlexander Graf {
265007f07615SPaolo Bonzini     trace_bdrv_aio_flush(bs, opaque);
2651016f5cf6SAlexander Graf 
265207f07615SPaolo Bonzini     Coroutine *co;
265307f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
2654016f5cf6SAlexander Graf 
265507f07615SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
265607f07615SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
265707f07615SPaolo Bonzini     qemu_coroutine_enter(co, acb);
2658016f5cf6SAlexander Graf 
2659016f5cf6SAlexander Graf     return &acb->common;
2660016f5cf6SAlexander Graf }
2661016f5cf6SAlexander Graf 
26624265d620SPaolo Bonzini static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
26634265d620SPaolo Bonzini {
26644265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
26654265d620SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
26664265d620SPaolo Bonzini 
26674265d620SPaolo Bonzini     acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
26684265d620SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
26694265d620SPaolo Bonzini     qemu_bh_schedule(acb->bh);
26704265d620SPaolo Bonzini }
26714265d620SPaolo Bonzini 
26724265d620SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
26734265d620SPaolo Bonzini         int64_t sector_num, int nb_sectors,
26744265d620SPaolo Bonzini         BlockDriverCompletionFunc *cb, void *opaque)
26754265d620SPaolo Bonzini {
26764265d620SPaolo Bonzini     Coroutine *co;
26774265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
26784265d620SPaolo Bonzini 
26794265d620SPaolo Bonzini     trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
26804265d620SPaolo Bonzini 
26814265d620SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
26824265d620SPaolo Bonzini     acb->req.sector = sector_num;
26834265d620SPaolo Bonzini     acb->req.nb_sectors = nb_sectors;
26844265d620SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
26854265d620SPaolo Bonzini     qemu_coroutine_enter(co, acb);
26864265d620SPaolo Bonzini 
26874265d620SPaolo Bonzini     return &acb->common;
26884265d620SPaolo Bonzini }
26894265d620SPaolo Bonzini 
2690ea2384d3Sbellard void bdrv_init(void)
2691ea2384d3Sbellard {
26925efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2693ea2384d3Sbellard }
2694ce1a14dcSpbrook 
2695eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2696eb852011SMarkus Armbruster {
2697eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2698eb852011SMarkus Armbruster     bdrv_init();
2699eb852011SMarkus Armbruster }
2700eb852011SMarkus Armbruster 
2701c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
27026bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
27036bbff9a0Saliguori {
2704ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2705ce1a14dcSpbrook 
27066bbff9a0Saliguori     if (pool->free_aiocb) {
27076bbff9a0Saliguori         acb = pool->free_aiocb;
27086bbff9a0Saliguori         pool->free_aiocb = acb->next;
2709ce1a14dcSpbrook     } else {
27107267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
27116bbff9a0Saliguori         acb->pool = pool;
2712ce1a14dcSpbrook     }
2713ce1a14dcSpbrook     acb->bs = bs;
2714ce1a14dcSpbrook     acb->cb = cb;
2715ce1a14dcSpbrook     acb->opaque = opaque;
2716ce1a14dcSpbrook     return acb;
2717ce1a14dcSpbrook }
2718ce1a14dcSpbrook 
2719ce1a14dcSpbrook void qemu_aio_release(void *p)
2720ce1a14dcSpbrook {
27216bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
27226bbff9a0Saliguori     AIOPool *pool = acb->pool;
27236bbff9a0Saliguori     acb->next = pool->free_aiocb;
27246bbff9a0Saliguori     pool->free_aiocb = acb;
2725ce1a14dcSpbrook }
272619cb3738Sbellard 
272719cb3738Sbellard /**************************************************************/
2728f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2729f9f05dc5SKevin Wolf 
2730f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2731f9f05dc5SKevin Wolf     Coroutine *coroutine;
2732f9f05dc5SKevin Wolf     int ret;
2733f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2734f9f05dc5SKevin Wolf 
2735f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2736f9f05dc5SKevin Wolf {
2737f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2738f9f05dc5SKevin Wolf 
2739f9f05dc5SKevin Wolf     co->ret = ret;
2740f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
2741f9f05dc5SKevin Wolf }
2742f9f05dc5SKevin Wolf 
2743f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
2744f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
2745f9f05dc5SKevin Wolf                                       bool is_write)
2746f9f05dc5SKevin Wolf {
2747f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
2748f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
2749f9f05dc5SKevin Wolf     };
2750f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
2751f9f05dc5SKevin Wolf 
2752f9f05dc5SKevin Wolf     if (is_write) {
2753a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
2754f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
2755f9f05dc5SKevin Wolf     } else {
2756a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
2757f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
2758f9f05dc5SKevin Wolf     }
2759f9f05dc5SKevin Wolf 
276059370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
2761f9f05dc5SKevin Wolf     if (!acb) {
2762f9f05dc5SKevin Wolf         return -EIO;
2763f9f05dc5SKevin Wolf     }
2764f9f05dc5SKevin Wolf     qemu_coroutine_yield();
2765f9f05dc5SKevin Wolf 
2766f9f05dc5SKevin Wolf     return co.ret;
2767f9f05dc5SKevin Wolf }
2768f9f05dc5SKevin Wolf 
2769f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
2770f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2771f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2772f9f05dc5SKevin Wolf {
2773f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
2774f9f05dc5SKevin Wolf }
2775f9f05dc5SKevin Wolf 
2776f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
2777f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2778f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2779f9f05dc5SKevin Wolf {
2780f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
2781f9f05dc5SKevin Wolf }
2782f9f05dc5SKevin Wolf 
278307f07615SPaolo Bonzini static void coroutine_fn bdrv_flush_co_entry(void *opaque)
2784e7a8a783SKevin Wolf {
278507f07615SPaolo Bonzini     RwCo *rwco = opaque;
278607f07615SPaolo Bonzini 
278707f07615SPaolo Bonzini     rwco->ret = bdrv_co_flush(rwco->bs);
278807f07615SPaolo Bonzini }
278907f07615SPaolo Bonzini 
279007f07615SPaolo Bonzini int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
279107f07615SPaolo Bonzini {
2792eb489bb1SKevin Wolf     int ret;
2793eb489bb1SKevin Wolf 
2794ca716364SKevin Wolf     if (!bs->drv) {
279507f07615SPaolo Bonzini         return 0;
2796eb489bb1SKevin Wolf     }
2797eb489bb1SKevin Wolf 
2798ca716364SKevin Wolf     /* Write back cached data to the OS even with cache=unsafe */
2799eb489bb1SKevin Wolf     if (bs->drv->bdrv_co_flush_to_os) {
2800eb489bb1SKevin Wolf         ret = bs->drv->bdrv_co_flush_to_os(bs);
2801eb489bb1SKevin Wolf         if (ret < 0) {
2802eb489bb1SKevin Wolf             return ret;
2803eb489bb1SKevin Wolf         }
2804eb489bb1SKevin Wolf     }
2805eb489bb1SKevin Wolf 
2806ca716364SKevin Wolf     /* But don't actually force it to the disk with cache=unsafe */
2807ca716364SKevin Wolf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
2808ca716364SKevin Wolf         return 0;
2809ca716364SKevin Wolf     }
2810ca716364SKevin Wolf 
2811eb489bb1SKevin Wolf     if (bs->drv->bdrv_co_flush_to_disk) {
2812c68b89acSKevin Wolf         return bs->drv->bdrv_co_flush_to_disk(bs);
281307f07615SPaolo Bonzini     } else if (bs->drv->bdrv_aio_flush) {
281407f07615SPaolo Bonzini         BlockDriverAIOCB *acb;
2815e7a8a783SKevin Wolf         CoroutineIOCompletion co = {
2816e7a8a783SKevin Wolf             .coroutine = qemu_coroutine_self(),
2817e7a8a783SKevin Wolf         };
2818e7a8a783SKevin Wolf 
281907f07615SPaolo Bonzini         acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
282007f07615SPaolo Bonzini         if (acb == NULL) {
2821e7a8a783SKevin Wolf             return -EIO;
282207f07615SPaolo Bonzini         } else {
2823e7a8a783SKevin Wolf             qemu_coroutine_yield();
2824e7a8a783SKevin Wolf             return co.ret;
2825e7a8a783SKevin Wolf         }
282607f07615SPaolo Bonzini     } else {
282707f07615SPaolo Bonzini         /*
282807f07615SPaolo Bonzini          * Some block drivers always operate in either writethrough or unsafe
282907f07615SPaolo Bonzini          * mode and don't support bdrv_flush therefore. Usually qemu doesn't
283007f07615SPaolo Bonzini          * know how the server works (because the behaviour is hardcoded or
283107f07615SPaolo Bonzini          * depends on server-side configuration), so we can't ensure that
283207f07615SPaolo Bonzini          * everything is safe on disk. Returning an error doesn't work because
283307f07615SPaolo Bonzini          * that would break guests even if the server operates in writethrough
283407f07615SPaolo Bonzini          * mode.
283507f07615SPaolo Bonzini          *
283607f07615SPaolo Bonzini          * Let's hope the user knows what he's doing.
283707f07615SPaolo Bonzini          */
283807f07615SPaolo Bonzini         return 0;
283907f07615SPaolo Bonzini     }
284007f07615SPaolo Bonzini }
284107f07615SPaolo Bonzini 
2842*0f15423cSAnthony Liguori void bdrv_invalidate_cache(BlockDriverState *bs)
2843*0f15423cSAnthony Liguori {
2844*0f15423cSAnthony Liguori     if (bs->drv && bs->drv->bdrv_invalidate_cache) {
2845*0f15423cSAnthony Liguori         bs->drv->bdrv_invalidate_cache(bs);
2846*0f15423cSAnthony Liguori     }
2847*0f15423cSAnthony Liguori }
2848*0f15423cSAnthony Liguori 
2849*0f15423cSAnthony Liguori void bdrv_invalidate_cache_all(void)
2850*0f15423cSAnthony Liguori {
2851*0f15423cSAnthony Liguori     BlockDriverState *bs;
2852*0f15423cSAnthony Liguori 
2853*0f15423cSAnthony Liguori     QTAILQ_FOREACH(bs, &bdrv_states, list) {
2854*0f15423cSAnthony Liguori         bdrv_invalidate_cache(bs);
2855*0f15423cSAnthony Liguori     }
2856*0f15423cSAnthony Liguori }
2857*0f15423cSAnthony Liguori 
285807f07615SPaolo Bonzini int bdrv_flush(BlockDriverState *bs)
285907f07615SPaolo Bonzini {
286007f07615SPaolo Bonzini     Coroutine *co;
286107f07615SPaolo Bonzini     RwCo rwco = {
286207f07615SPaolo Bonzini         .bs = bs,
286307f07615SPaolo Bonzini         .ret = NOT_DONE,
286407f07615SPaolo Bonzini     };
286507f07615SPaolo Bonzini 
286607f07615SPaolo Bonzini     if (qemu_in_coroutine()) {
286707f07615SPaolo Bonzini         /* Fast-path if already in coroutine context */
286807f07615SPaolo Bonzini         bdrv_flush_co_entry(&rwco);
286907f07615SPaolo Bonzini     } else {
287007f07615SPaolo Bonzini         co = qemu_coroutine_create(bdrv_flush_co_entry);
287107f07615SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
287207f07615SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
287307f07615SPaolo Bonzini             qemu_aio_wait();
287407f07615SPaolo Bonzini         }
287507f07615SPaolo Bonzini     }
287607f07615SPaolo Bonzini 
287707f07615SPaolo Bonzini     return rwco.ret;
287807f07615SPaolo Bonzini }
2879e7a8a783SKevin Wolf 
28804265d620SPaolo Bonzini static void coroutine_fn bdrv_discard_co_entry(void *opaque)
28814265d620SPaolo Bonzini {
28824265d620SPaolo Bonzini     RwCo *rwco = opaque;
28834265d620SPaolo Bonzini 
28844265d620SPaolo Bonzini     rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
28854265d620SPaolo Bonzini }
28864265d620SPaolo Bonzini 
28874265d620SPaolo Bonzini int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
28884265d620SPaolo Bonzini                                  int nb_sectors)
28894265d620SPaolo Bonzini {
28904265d620SPaolo Bonzini     if (!bs->drv) {
28914265d620SPaolo Bonzini         return -ENOMEDIUM;
28924265d620SPaolo Bonzini     } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
28934265d620SPaolo Bonzini         return -EIO;
28944265d620SPaolo Bonzini     } else if (bs->read_only) {
28954265d620SPaolo Bonzini         return -EROFS;
28964265d620SPaolo Bonzini     } else if (bs->drv->bdrv_co_discard) {
28974265d620SPaolo Bonzini         return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
28984265d620SPaolo Bonzini     } else if (bs->drv->bdrv_aio_discard) {
28994265d620SPaolo Bonzini         BlockDriverAIOCB *acb;
29004265d620SPaolo Bonzini         CoroutineIOCompletion co = {
29014265d620SPaolo Bonzini             .coroutine = qemu_coroutine_self(),
29024265d620SPaolo Bonzini         };
29034265d620SPaolo Bonzini 
29044265d620SPaolo Bonzini         acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
29054265d620SPaolo Bonzini                                         bdrv_co_io_em_complete, &co);
29064265d620SPaolo Bonzini         if (acb == NULL) {
29074265d620SPaolo Bonzini             return -EIO;
29084265d620SPaolo Bonzini         } else {
29094265d620SPaolo Bonzini             qemu_coroutine_yield();
29104265d620SPaolo Bonzini             return co.ret;
29114265d620SPaolo Bonzini         }
29124265d620SPaolo Bonzini     } else {
29134265d620SPaolo Bonzini         return 0;
29144265d620SPaolo Bonzini     }
29154265d620SPaolo Bonzini }
29164265d620SPaolo Bonzini 
29174265d620SPaolo Bonzini int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
29184265d620SPaolo Bonzini {
29194265d620SPaolo Bonzini     Coroutine *co;
29204265d620SPaolo Bonzini     RwCo rwco = {
29214265d620SPaolo Bonzini         .bs = bs,
29224265d620SPaolo Bonzini         .sector_num = sector_num,
29234265d620SPaolo Bonzini         .nb_sectors = nb_sectors,
29244265d620SPaolo Bonzini         .ret = NOT_DONE,
29254265d620SPaolo Bonzini     };
29264265d620SPaolo Bonzini 
29274265d620SPaolo Bonzini     if (qemu_in_coroutine()) {
29284265d620SPaolo Bonzini         /* Fast-path if already in coroutine context */
29294265d620SPaolo Bonzini         bdrv_discard_co_entry(&rwco);
29304265d620SPaolo Bonzini     } else {
29314265d620SPaolo Bonzini         co = qemu_coroutine_create(bdrv_discard_co_entry);
29324265d620SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
29334265d620SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
29344265d620SPaolo Bonzini             qemu_aio_wait();
29354265d620SPaolo Bonzini         }
29364265d620SPaolo Bonzini     }
29374265d620SPaolo Bonzini 
29384265d620SPaolo Bonzini     return rwco.ret;
29394265d620SPaolo Bonzini }
29404265d620SPaolo Bonzini 
2941f9f05dc5SKevin Wolf /**************************************************************/
294219cb3738Sbellard /* removable device support */
294319cb3738Sbellard 
294419cb3738Sbellard /**
294519cb3738Sbellard  * Return TRUE if the media is present
294619cb3738Sbellard  */
294719cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
294819cb3738Sbellard {
294919cb3738Sbellard     BlockDriver *drv = bs->drv;
2950a1aff5bfSMarkus Armbruster 
295119cb3738Sbellard     if (!drv)
295219cb3738Sbellard         return 0;
295319cb3738Sbellard     if (!drv->bdrv_is_inserted)
2954a1aff5bfSMarkus Armbruster         return 1;
2955a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
295619cb3738Sbellard }
295719cb3738Sbellard 
295819cb3738Sbellard /**
29598e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
29608e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
296119cb3738Sbellard  */
296219cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
296319cb3738Sbellard {
296419cb3738Sbellard     BlockDriver *drv = bs->drv;
296519cb3738Sbellard 
29668e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
29678e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
29688e49ca46SMarkus Armbruster     }
29698e49ca46SMarkus Armbruster     return -ENOTSUP;
297019cb3738Sbellard }
297119cb3738Sbellard 
297219cb3738Sbellard /**
297319cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
297419cb3738Sbellard  */
2975fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
297619cb3738Sbellard {
297719cb3738Sbellard     BlockDriver *drv = bs->drv;
297819cb3738Sbellard 
2979822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
2980822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
298119cb3738Sbellard     }
298219cb3738Sbellard }
298319cb3738Sbellard 
298419cb3738Sbellard /**
298519cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
298619cb3738Sbellard  * to eject it manually).
298719cb3738Sbellard  */
2988025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
298919cb3738Sbellard {
299019cb3738Sbellard     BlockDriver *drv = bs->drv;
299119cb3738Sbellard 
2992025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
2993b8c6d095SStefan Hajnoczi 
2994025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
2995025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
299619cb3738Sbellard     }
299719cb3738Sbellard }
2998985a03b0Sths 
2999985a03b0Sths /* needed for generic scsi interface */
3000985a03b0Sths 
3001985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3002985a03b0Sths {
3003985a03b0Sths     BlockDriver *drv = bs->drv;
3004985a03b0Sths 
3005985a03b0Sths     if (drv && drv->bdrv_ioctl)
3006985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3007985a03b0Sths     return -ENOTSUP;
3008985a03b0Sths }
30097d780669Saliguori 
3010221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3011221f715dSaliguori         unsigned long int req, void *buf,
30127d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
30137d780669Saliguori {
3014221f715dSaliguori     BlockDriver *drv = bs->drv;
30157d780669Saliguori 
3016221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3017221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3018221f715dSaliguori     return NULL;
30197d780669Saliguori }
3020e268ca52Saliguori 
30217b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
30227b6f9300SMarkus Armbruster {
30237b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
30247b6f9300SMarkus Armbruster }
30257cd1e32aSlirans@il.ibm.com 
3026e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3027e268ca52Saliguori {
3028e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3029e268ca52Saliguori }
30307cd1e32aSlirans@il.ibm.com 
30317cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
30327cd1e32aSlirans@il.ibm.com {
30337cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3034a55eb92cSJan Kiszka 
3035aaa0eb75SLiran Schour     bs->dirty_count = 0;
30367cd1e32aSlirans@il.ibm.com     if (enable) {
3037c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3038c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3039c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3040c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
30417cd1e32aSlirans@il.ibm.com 
30427267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
30437cd1e32aSlirans@il.ibm.com         }
30447cd1e32aSlirans@il.ibm.com     } else {
3045c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
30467267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3047c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
30487cd1e32aSlirans@il.ibm.com         }
30497cd1e32aSlirans@il.ibm.com     }
30507cd1e32aSlirans@il.ibm.com }
30517cd1e32aSlirans@il.ibm.com 
30527cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
30537cd1e32aSlirans@il.ibm.com {
30546ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
30557cd1e32aSlirans@il.ibm.com 
3056c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3057c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
30586d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
30596d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
30607cd1e32aSlirans@il.ibm.com     } else {
30617cd1e32aSlirans@il.ibm.com         return 0;
30627cd1e32aSlirans@il.ibm.com     }
30637cd1e32aSlirans@il.ibm.com }
30647cd1e32aSlirans@il.ibm.com 
30657cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
30667cd1e32aSlirans@il.ibm.com                       int nr_sectors)
30677cd1e32aSlirans@il.ibm.com {
30687cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
30697cd1e32aSlirans@il.ibm.com }
3070aaa0eb75SLiran Schour 
3071aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3072aaa0eb75SLiran Schour {
3073aaa0eb75SLiran Schour     return bs->dirty_count;
3074aaa0eb75SLiran Schour }
3075f88e1a42SJes Sorensen 
3076db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3077db593f25SMarcelo Tosatti {
3078db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3079db593f25SMarcelo Tosatti     bs->in_use = in_use;
3080db593f25SMarcelo Tosatti }
3081db593f25SMarcelo Tosatti 
3082db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3083db593f25SMarcelo Tosatti {
3084db593f25SMarcelo Tosatti     return bs->in_use;
3085db593f25SMarcelo Tosatti }
3086db593f25SMarcelo Tosatti 
308728a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
308828a7282aSLuiz Capitulino {
3089d6bf279eSLuiz Capitulino     bs->iostatus_enabled = true;
309058e21ef5SLuiz Capitulino     bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
309128a7282aSLuiz Capitulino }
309228a7282aSLuiz Capitulino 
309328a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
309428a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
309528a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
309628a7282aSLuiz Capitulino {
3097d6bf279eSLuiz Capitulino     return (bs->iostatus_enabled &&
309828a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
309928a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
310028a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
310128a7282aSLuiz Capitulino }
310228a7282aSLuiz Capitulino 
310328a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
310428a7282aSLuiz Capitulino {
3105d6bf279eSLuiz Capitulino     bs->iostatus_enabled = false;
310628a7282aSLuiz Capitulino }
310728a7282aSLuiz Capitulino 
310828a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
310928a7282aSLuiz Capitulino {
311028a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
311158e21ef5SLuiz Capitulino         bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
311228a7282aSLuiz Capitulino     }
311328a7282aSLuiz Capitulino }
311428a7282aSLuiz Capitulino 
311528a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
311628a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
311728a7282aSLuiz Capitulino    possible to implement this without device models being involved */
311828a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
311928a7282aSLuiz Capitulino {
312058e21ef5SLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) &&
312158e21ef5SLuiz Capitulino         bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
312228a7282aSLuiz Capitulino         assert(error >= 0);
312358e21ef5SLuiz Capitulino         bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
312458e21ef5SLuiz Capitulino                                          BLOCK_DEVICE_IO_STATUS_FAILED;
312528a7282aSLuiz Capitulino     }
312628a7282aSLuiz Capitulino }
312728a7282aSLuiz Capitulino 
3128a597e79cSChristoph Hellwig void
3129a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3130a597e79cSChristoph Hellwig         enum BlockAcctType type)
3131a597e79cSChristoph Hellwig {
3132a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3133a597e79cSChristoph Hellwig 
3134a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3135c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3136a597e79cSChristoph Hellwig     cookie->type = type;
3137a597e79cSChristoph Hellwig }
3138a597e79cSChristoph Hellwig 
3139a597e79cSChristoph Hellwig void
3140a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3141a597e79cSChristoph Hellwig {
3142a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3143a597e79cSChristoph Hellwig 
3144a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3145a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3146c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3147a597e79cSChristoph Hellwig }
3148a597e79cSChristoph Hellwig 
3149f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3150f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3151f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3152f88e1a42SJes Sorensen {
3153f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3154d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3155f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3156f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
315796df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3158f88e1a42SJes Sorensen     int ret = 0;
3159f88e1a42SJes Sorensen 
3160f88e1a42SJes Sorensen     /* Find driver and parse its options */
3161f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3162f88e1a42SJes Sorensen     if (!drv) {
3163f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
31644f70f249SJes Sorensen         ret = -EINVAL;
3165f88e1a42SJes Sorensen         goto out;
3166f88e1a42SJes Sorensen     }
3167f88e1a42SJes Sorensen 
3168f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3169f88e1a42SJes Sorensen     if (!proto_drv) {
3170f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
31714f70f249SJes Sorensen         ret = -EINVAL;
3172f88e1a42SJes Sorensen         goto out;
3173f88e1a42SJes Sorensen     }
3174f88e1a42SJes Sorensen 
3175f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3176f88e1a42SJes Sorensen                                               drv->create_options);
3177f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3178f88e1a42SJes Sorensen                                               proto_drv->create_options);
3179f88e1a42SJes Sorensen 
3180f88e1a42SJes Sorensen     /* Create parameter list with default values */
3181f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3182f88e1a42SJes Sorensen 
3183f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3184f88e1a42SJes Sorensen 
3185f88e1a42SJes Sorensen     /* Parse -o options */
3186f88e1a42SJes Sorensen     if (options) {
3187f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3188f88e1a42SJes Sorensen         if (param == NULL) {
3189f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
31904f70f249SJes Sorensen             ret = -EINVAL;
3191f88e1a42SJes Sorensen             goto out;
3192f88e1a42SJes Sorensen         }
3193f88e1a42SJes Sorensen     }
3194f88e1a42SJes Sorensen 
3195f88e1a42SJes Sorensen     if (base_filename) {
3196f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3197f88e1a42SJes Sorensen                                  base_filename)) {
3198f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3199f88e1a42SJes Sorensen                          fmt);
32004f70f249SJes Sorensen             ret = -EINVAL;
3201f88e1a42SJes Sorensen             goto out;
3202f88e1a42SJes Sorensen         }
3203f88e1a42SJes Sorensen     }
3204f88e1a42SJes Sorensen 
3205f88e1a42SJes Sorensen     if (base_fmt) {
3206f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3207f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3208f88e1a42SJes Sorensen                          "format '%s'", fmt);
32094f70f249SJes Sorensen             ret = -EINVAL;
3210f88e1a42SJes Sorensen             goto out;
3211f88e1a42SJes Sorensen         }
3212f88e1a42SJes Sorensen     }
3213f88e1a42SJes Sorensen 
3214792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3215792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3216792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3217792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3218792da93aSJes Sorensen                          "same filename as the backing file");
32194f70f249SJes Sorensen             ret = -EINVAL;
3220792da93aSJes Sorensen             goto out;
3221792da93aSJes Sorensen         }
3222792da93aSJes Sorensen     }
3223792da93aSJes Sorensen 
3224f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3225f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
322696df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
322796df67d1SStefan Hajnoczi         if (!backing_drv) {
3228f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3229f88e1a42SJes Sorensen                          backing_fmt->value.s);
32304f70f249SJes Sorensen             ret = -EINVAL;
3231f88e1a42SJes Sorensen             goto out;
3232f88e1a42SJes Sorensen         }
3233f88e1a42SJes Sorensen     }
3234f88e1a42SJes Sorensen 
3235f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3236f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3237d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3238d220894eSKevin Wolf     if (size && size->value.n == -1) {
3239f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3240f88e1a42SJes Sorensen             uint64_t size;
3241f88e1a42SJes Sorensen             char buf[32];
3242f88e1a42SJes Sorensen 
3243f88e1a42SJes Sorensen             bs = bdrv_new("");
3244f88e1a42SJes Sorensen 
324596df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3246f88e1a42SJes Sorensen             if (ret < 0) {
324796df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3248f88e1a42SJes Sorensen                 goto out;
3249f88e1a42SJes Sorensen             }
3250f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3251f88e1a42SJes Sorensen             size *= 512;
3252f88e1a42SJes Sorensen 
3253f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3254f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3255f88e1a42SJes Sorensen         } else {
3256f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
32574f70f249SJes Sorensen             ret = -EINVAL;
3258f88e1a42SJes Sorensen             goto out;
3259f88e1a42SJes Sorensen         }
3260f88e1a42SJes Sorensen     }
3261f88e1a42SJes Sorensen 
3262f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3263f88e1a42SJes Sorensen     print_option_parameters(param);
3264f88e1a42SJes Sorensen     puts("");
3265f88e1a42SJes Sorensen 
3266f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3267f88e1a42SJes Sorensen 
3268f88e1a42SJes Sorensen     if (ret < 0) {
3269f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3270f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3271f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3272f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3273f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3274f88e1a42SJes Sorensen                          fmt);
3275f88e1a42SJes Sorensen         } else {
3276f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3277f88e1a42SJes Sorensen                          strerror(-ret));
3278f88e1a42SJes Sorensen         }
3279f88e1a42SJes Sorensen     }
3280f88e1a42SJes Sorensen 
3281f88e1a42SJes Sorensen out:
3282f88e1a42SJes Sorensen     free_option_parameters(create_options);
3283f88e1a42SJes Sorensen     free_option_parameters(param);
3284f88e1a42SJes Sorensen 
3285f88e1a42SJes Sorensen     if (bs) {
3286f88e1a42SJes Sorensen         bdrv_delete(bs);
3287f88e1a42SJes Sorensen     }
32884f70f249SJes Sorensen 
32894f70f249SJes Sorensen     return ret;
3290f88e1a42SJes Sorensen }
3291