xref: /openbmc/qemu/block.c (revision b202381800d81fbff9978abbdea95760dd363bb6)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
243990d09aSblueswir1 #include "config-host.h"
25faf07963Spbrook #include "qemu-common.h"
266d519a5fSStefan Hajnoczi #include "trace.h"
27376253ecSaliguori #include "monitor.h"
28ea2384d3Sbellard #include "block_int.h"
295efa9d5aSAnthony Liguori #include "module.h"
30d15e5465SLuiz Capitulino #include "qemu-objects.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32*b2023818SLuiz 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;
47657915332SKevin Wolf     bs->open_flags = flags;
47757915332SKevin Wolf     bs->buffer_alignment = 512;
47857915332SKevin Wolf 
47957915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
48057915332SKevin Wolf 
48157915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
48257915332SKevin Wolf         return -ENOTSUP;
48357915332SKevin Wolf     }
48457915332SKevin Wolf 
48557915332SKevin Wolf     bs->drv = drv;
4867267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
48757915332SKevin Wolf 
488a6599793SChristoph Hellwig     if (flags & BDRV_O_CACHE_WB)
48957915332SKevin Wolf         bs->enable_write_cache = 1;
49057915332SKevin Wolf 
49157915332SKevin Wolf     /*
49257915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
49357915332SKevin Wolf      * image.
49457915332SKevin Wolf      */
49557915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
49657915332SKevin Wolf 
49757915332SKevin Wolf     /*
498ebabb67aSStefan Weil      * Snapshots should be writable.
49957915332SKevin Wolf      */
50057915332SKevin Wolf     if (bs->is_temporary) {
50157915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
50257915332SKevin Wolf     }
50357915332SKevin Wolf 
50466f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
50566f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
50666f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
50766f82ceeSKevin Wolf     } else {
50866f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
50966f82ceeSKevin Wolf         if (ret >= 0) {
51066f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
51166f82ceeSKevin Wolf         }
51266f82ceeSKevin Wolf     }
51366f82ceeSKevin Wolf 
51457915332SKevin Wolf     if (ret < 0) {
51557915332SKevin Wolf         goto free_and_fail;
51657915332SKevin Wolf     }
51757915332SKevin Wolf 
51857915332SKevin Wolf     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
51951762288SStefan Hajnoczi 
52051762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
52151762288SStefan Hajnoczi     if (ret < 0) {
52251762288SStefan Hajnoczi         goto free_and_fail;
52357915332SKevin Wolf     }
52451762288SStefan Hajnoczi 
52557915332SKevin Wolf #ifndef _WIN32
52657915332SKevin Wolf     if (bs->is_temporary) {
52757915332SKevin Wolf         unlink(filename);
52857915332SKevin Wolf     }
52957915332SKevin Wolf #endif
53057915332SKevin Wolf     return 0;
53157915332SKevin Wolf 
53257915332SKevin Wolf free_and_fail:
53366f82ceeSKevin Wolf     if (bs->file) {
53466f82ceeSKevin Wolf         bdrv_delete(bs->file);
53566f82ceeSKevin Wolf         bs->file = NULL;
53666f82ceeSKevin Wolf     }
5377267c094SAnthony Liguori     g_free(bs->opaque);
53857915332SKevin Wolf     bs->opaque = NULL;
53957915332SKevin Wolf     bs->drv = NULL;
54057915332SKevin Wolf     return ret;
54157915332SKevin Wolf }
54257915332SKevin Wolf 
54357915332SKevin Wolf /*
544b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
545b6ce07aaSKevin Wolf  */
54683f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
547b338082bSbellard {
54883f64091Sbellard     BlockDriverState *bs;
5496db95603SChristoph Hellwig     BlockDriver *drv;
55083f64091Sbellard     int ret;
5513b0d4f61Sbellard 
552b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5536db95603SChristoph Hellwig     if (!drv) {
5546db95603SChristoph Hellwig         return -ENOENT;
5556db95603SChristoph Hellwig     }
5566db95603SChristoph Hellwig 
55783f64091Sbellard     bs = bdrv_new("");
558b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
55983f64091Sbellard     if (ret < 0) {
56083f64091Sbellard         bdrv_delete(bs);
56183f64091Sbellard         return ret;
5623b0d4f61Sbellard     }
56371d0770cSaliguori     bs->growable = 1;
56483f64091Sbellard     *pbs = bs;
56583f64091Sbellard     return 0;
5663b0d4f61Sbellard }
5673b0d4f61Sbellard 
568b6ce07aaSKevin Wolf /*
569b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
570b6ce07aaSKevin Wolf  */
571d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
572ea2384d3Sbellard               BlockDriver *drv)
573ea2384d3Sbellard {
574b6ce07aaSKevin Wolf     int ret;
57533e3963eSbellard 
57683f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
577ea2384d3Sbellard         BlockDriverState *bs1;
578ea2384d3Sbellard         int64_t total_size;
5797c96d46eSaliguori         int is_protocol = 0;
58091a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
58191a073a9SKevin Wolf         QEMUOptionParameter *options;
582b6ce07aaSKevin Wolf         char tmp_filename[PATH_MAX];
583b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
58433e3963eSbellard 
585ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
586ea2384d3Sbellard            instead of opening 'filename' directly */
587ea2384d3Sbellard 
588ea2384d3Sbellard         /* if there is a backing file, use it */
589ea2384d3Sbellard         bs1 = bdrv_new("");
590d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
59151d7c00cSaliguori         if (ret < 0) {
592ea2384d3Sbellard             bdrv_delete(bs1);
59351d7c00cSaliguori             return ret;
594ea2384d3Sbellard         }
5953e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
5967c96d46eSaliguori 
5977c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
5987c96d46eSaliguori             is_protocol = 1;
5997c96d46eSaliguori 
600ea2384d3Sbellard         bdrv_delete(bs1);
601ea2384d3Sbellard 
602ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6037c96d46eSaliguori 
6047c96d46eSaliguori         /* Real path is meaningless for protocols */
6057c96d46eSaliguori         if (is_protocol)
6067c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6077c96d46eSaliguori                      "%s", filename);
608114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
609114cdfa9SKirill A. Shutemov             return -errno;
6107c96d46eSaliguori 
61191a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
61291a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
61391a073a9SKevin Wolf 
6143e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
61591a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
61691a073a9SKevin Wolf         if (drv) {
61791a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
61891a073a9SKevin Wolf                 drv->format_name);
61991a073a9SKevin Wolf         }
62091a073a9SKevin Wolf 
62191a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
622d748768cSJan Kiszka         free_option_parameters(options);
62351d7c00cSaliguori         if (ret < 0) {
62451d7c00cSaliguori             return ret;
625ea2384d3Sbellard         }
62691a073a9SKevin Wolf 
627ea2384d3Sbellard         filename = tmp_filename;
62891a073a9SKevin Wolf         drv = bdrv_qcow2;
629ea2384d3Sbellard         bs->is_temporary = 1;
630ea2384d3Sbellard     }
631ea2384d3Sbellard 
632b6ce07aaSKevin Wolf     /* Find the right image format driver */
6336db95603SChristoph Hellwig     if (!drv) {
634c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
635ea2384d3Sbellard     }
6366987307cSChristoph Hellwig 
63751d7c00cSaliguori     if (!drv) {
63851d7c00cSaliguori         goto unlink_and_fail;
63983f64091Sbellard     }
640b6ce07aaSKevin Wolf 
641b6ce07aaSKevin Wolf     /* Open the image */
642b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
643b6ce07aaSKevin Wolf     if (ret < 0) {
6446987307cSChristoph Hellwig         goto unlink_and_fail;
6456987307cSChristoph Hellwig     }
6466987307cSChristoph Hellwig 
647b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
648b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
649b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
650b6ce07aaSKevin Wolf         int back_flags;
651b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
652b6ce07aaSKevin Wolf 
653b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
654df2dbb4aSStefan Hajnoczi 
655df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
656df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
657df2dbb4aSStefan Hajnoczi                     bs->backing_file);
658df2dbb4aSStefan Hajnoczi         } else {
659b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
660b6ce07aaSKevin Wolf                          filename, bs->backing_file);
661df2dbb4aSStefan Hajnoczi         }
662df2dbb4aSStefan Hajnoczi 
663df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
664b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
665df2dbb4aSStefan Hajnoczi         }
666b6ce07aaSKevin Wolf 
667b6ce07aaSKevin Wolf         /* backing files always opened read-only */
668b6ce07aaSKevin Wolf         back_flags =
669b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
670b6ce07aaSKevin Wolf 
671b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
672b6ce07aaSKevin Wolf         if (ret < 0) {
673b6ce07aaSKevin Wolf             bdrv_close(bs);
674b6ce07aaSKevin Wolf             return ret;
675b6ce07aaSKevin Wolf         }
676b6ce07aaSKevin Wolf         if (bs->is_temporary) {
677b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
678b6ce07aaSKevin Wolf         } else {
679b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
680b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
681b6ce07aaSKevin Wolf         }
682b6ce07aaSKevin Wolf     }
683b6ce07aaSKevin Wolf 
684b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
6857d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
686b6ce07aaSKevin Wolf     }
687b6ce07aaSKevin Wolf 
688b6ce07aaSKevin Wolf     return 0;
689b6ce07aaSKevin Wolf 
690b6ce07aaSKevin Wolf unlink_and_fail:
691b6ce07aaSKevin Wolf     if (bs->is_temporary) {
692b6ce07aaSKevin Wolf         unlink(filename);
693b6ce07aaSKevin Wolf     }
694b6ce07aaSKevin Wolf     return ret;
695b6ce07aaSKevin Wolf }
696b6ce07aaSKevin Wolf 
697fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
698fc01f7e7Sbellard {
69919cb3738Sbellard     if (bs->drv) {
700f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
701f9092b10SMarkus Armbruster             bs_snapshots = NULL;
702f9092b10SMarkus Armbruster         }
703557df6acSStefan Hajnoczi         if (bs->backing_hd) {
704ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
705557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
706557df6acSStefan Hajnoczi         }
707ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7087267c094SAnthony Liguori         g_free(bs->opaque);
709ea2384d3Sbellard #ifdef _WIN32
710ea2384d3Sbellard         if (bs->is_temporary) {
711ea2384d3Sbellard             unlink(bs->filename);
712ea2384d3Sbellard         }
71367b915a5Sbellard #endif
714ea2384d3Sbellard         bs->opaque = NULL;
715ea2384d3Sbellard         bs->drv = NULL;
716b338082bSbellard 
71766f82ceeSKevin Wolf         if (bs->file != NULL) {
71866f82ceeSKevin Wolf             bdrv_close(bs->file);
71966f82ceeSKevin Wolf         }
72066f82ceeSKevin Wolf 
7217d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
722b338082bSbellard     }
723b338082bSbellard }
724b338082bSbellard 
7252bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7262bc93fedSMORITA Kazutaka {
7272bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7282bc93fedSMORITA Kazutaka 
7292bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7302bc93fedSMORITA Kazutaka         bdrv_close(bs);
7312bc93fedSMORITA Kazutaka     }
7322bc93fedSMORITA Kazutaka }
7332bc93fedSMORITA Kazutaka 
734d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
735d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
736d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
737d22b2f41SRyan Harper {
738d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
739d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
740d22b2f41SRyan Harper     }
741d22b2f41SRyan Harper     bs->device_name[0] = '\0';
742d22b2f41SRyan Harper }
743d22b2f41SRyan Harper 
744b338082bSbellard void bdrv_delete(BlockDriverState *bs)
745b338082bSbellard {
746fa879d62SMarkus Armbruster     assert(!bs->dev);
74718846deeSMarkus Armbruster 
7481b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
749d22b2f41SRyan Harper     bdrv_make_anon(bs);
75034c6f050Saurel32 
751b338082bSbellard     bdrv_close(bs);
75266f82ceeSKevin Wolf     if (bs->file != NULL) {
75366f82ceeSKevin Wolf         bdrv_delete(bs->file);
75466f82ceeSKevin Wolf     }
75566f82ceeSKevin Wolf 
756f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7577267c094SAnthony Liguori     g_free(bs);
758fc01f7e7Sbellard }
759fc01f7e7Sbellard 
760fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
761fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
76218846deeSMarkus Armbruster {
763fa879d62SMarkus Armbruster     if (bs->dev) {
76418846deeSMarkus Armbruster         return -EBUSY;
76518846deeSMarkus Armbruster     }
766fa879d62SMarkus Armbruster     bs->dev = dev;
76728a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
76818846deeSMarkus Armbruster     return 0;
76918846deeSMarkus Armbruster }
77018846deeSMarkus Armbruster 
771fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
772fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
77318846deeSMarkus Armbruster {
774fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
775fa879d62SMarkus Armbruster         abort();
776fa879d62SMarkus Armbruster     }
777fa879d62SMarkus Armbruster }
778fa879d62SMarkus Armbruster 
779fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
780fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
781fa879d62SMarkus Armbruster {
782fa879d62SMarkus Armbruster     assert(bs->dev == dev);
783fa879d62SMarkus Armbruster     bs->dev = NULL;
7840e49de52SMarkus Armbruster     bs->dev_ops = NULL;
7850e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
78629e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
78718846deeSMarkus Armbruster }
78818846deeSMarkus Armbruster 
789fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
790fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
79118846deeSMarkus Armbruster {
792fa879d62SMarkus Armbruster     return bs->dev;
79318846deeSMarkus Armbruster }
79418846deeSMarkus Armbruster 
7950e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
7960e49de52SMarkus Armbruster                       void *opaque)
7970e49de52SMarkus Armbruster {
7980e49de52SMarkus Armbruster     bs->dev_ops = ops;
7990e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8002c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8012c6942faSMarkus Armbruster         bs_snapshots = NULL;
8022c6942faSMarkus Armbruster     }
8030e49de52SMarkus Armbruster }
8040e49de52SMarkus Armbruster 
8057d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8060e49de52SMarkus Armbruster {
807145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8087d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
809145feb17SMarkus Armbruster     }
810145feb17SMarkus Armbruster }
811145feb17SMarkus Armbruster 
8122c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8132c6942faSMarkus Armbruster {
8142c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8152c6942faSMarkus Armbruster }
8162c6942faSMarkus Armbruster 
817e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
818e4def80bSMarkus Armbruster {
819e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
820e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
821e4def80bSMarkus Armbruster     }
822e4def80bSMarkus Armbruster     return false;
823e4def80bSMarkus Armbruster }
824e4def80bSMarkus Armbruster 
825145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
826145feb17SMarkus Armbruster {
827145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
828145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8290e49de52SMarkus Armbruster     }
8300e49de52SMarkus Armbruster }
8310e49de52SMarkus Armbruster 
832f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
833f107639aSMarkus Armbruster {
834f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
835f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
836f107639aSMarkus Armbruster     }
837f107639aSMarkus Armbruster     return false;
838f107639aSMarkus Armbruster }
839f107639aSMarkus Armbruster 
840e97fc193Saliguori /*
841e97fc193Saliguori  * Run consistency checks on an image
842e97fc193Saliguori  *
843e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
844a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
845e076f338SKevin Wolf  * check are stored in res.
846e97fc193Saliguori  */
847e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
848e97fc193Saliguori {
849e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
850e97fc193Saliguori         return -ENOTSUP;
851e97fc193Saliguori     }
852e97fc193Saliguori 
853e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8549ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
855e97fc193Saliguori }
856e97fc193Saliguori 
8578a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8588a426614SKevin Wolf 
85933e3963eSbellard /* commit COW file into the raw image */
86033e3963eSbellard int bdrv_commit(BlockDriverState *bs)
86133e3963eSbellard {
86219cb3738Sbellard     BlockDriver *drv = bs->drv;
863ee181196SKevin Wolf     BlockDriver *backing_drv;
8648a426614SKevin Wolf     int64_t sector, total_sectors;
8658a426614SKevin Wolf     int n, ro, open_flags;
8664dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8678a426614SKevin Wolf     uint8_t *buf;
8684dca4b63SNaphtali Sprei     char filename[1024];
8694dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
87033e3963eSbellard 
87119cb3738Sbellard     if (!drv)
87219cb3738Sbellard         return -ENOMEDIUM;
87333e3963eSbellard 
8744dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8754dca4b63SNaphtali Sprei         return -ENOTSUP;
8764dca4b63SNaphtali Sprei     }
8774dca4b63SNaphtali Sprei 
8784dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
879ea2384d3Sbellard         return -EACCES;
88033e3963eSbellard     }
88133e3963eSbellard 
882ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
8834dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
8844dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
8854dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
8864dca4b63SNaphtali Sprei 
8874dca4b63SNaphtali Sprei     if (ro) {
8884dca4b63SNaphtali Sprei         /* re-open as RW */
8894dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
8904dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
8914dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
892ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
893ee181196SKevin Wolf             backing_drv);
8944dca4b63SNaphtali Sprei         if (rw_ret < 0) {
8954dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
8964dca4b63SNaphtali Sprei             /* try to re-open read-only */
8974dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
898ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
899ee181196SKevin Wolf                 backing_drv);
9004dca4b63SNaphtali Sprei             if (ret < 0) {
9014dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9024dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9034dca4b63SNaphtali Sprei                 bs->drv = NULL;
9044dca4b63SNaphtali Sprei                 return ret;
9054dca4b63SNaphtali Sprei             }
9064dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9074dca4b63SNaphtali Sprei             return rw_ret;
9084dca4b63SNaphtali Sprei         }
9094dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
910ea2384d3Sbellard     }
911ea2384d3Sbellard 
9126ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9137267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9148a426614SKevin Wolf 
9158a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9168a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9178a426614SKevin Wolf 
9188a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9194dca4b63SNaphtali Sprei                 ret = -EIO;
9204dca4b63SNaphtali Sprei                 goto ro_cleanup;
92133e3963eSbellard             }
92233e3963eSbellard 
9238a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9244dca4b63SNaphtali Sprei                 ret = -EIO;
9254dca4b63SNaphtali Sprei                 goto ro_cleanup;
92633e3963eSbellard             }
92733e3963eSbellard         }
92833e3963eSbellard     }
92995389c86Sbellard 
9301d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9311d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9321d44952fSChristoph Hellwig         bdrv_flush(bs);
9331d44952fSChristoph Hellwig     }
93495389c86Sbellard 
9353f5075aeSChristoph Hellwig     /*
9363f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9373f5075aeSChristoph Hellwig      * stable on disk.
9383f5075aeSChristoph Hellwig      */
9393f5075aeSChristoph Hellwig     if (bs->backing_hd)
9403f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9414dca4b63SNaphtali Sprei 
9424dca4b63SNaphtali Sprei ro_cleanup:
9437267c094SAnthony Liguori     g_free(buf);
9444dca4b63SNaphtali Sprei 
9454dca4b63SNaphtali Sprei     if (ro) {
9464dca4b63SNaphtali Sprei         /* re-open as RO */
9474dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9484dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9494dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
950ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
951ee181196SKevin Wolf             backing_drv);
9524dca4b63SNaphtali Sprei         if (ret < 0) {
9534dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9544dca4b63SNaphtali Sprei             /* drive not functional anymore */
9554dca4b63SNaphtali Sprei             bs->drv = NULL;
9564dca4b63SNaphtali Sprei             return ret;
9574dca4b63SNaphtali Sprei         }
9584dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9594dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9604dca4b63SNaphtali Sprei     }
9614dca4b63SNaphtali Sprei 
9621d44952fSChristoph Hellwig     return ret;
96333e3963eSbellard }
96433e3963eSbellard 
9656ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9666ab4b5abSMarkus Armbruster {
9676ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9686ab4b5abSMarkus Armbruster 
9696ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9706ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9716ab4b5abSMarkus Armbruster     }
9726ab4b5abSMarkus Armbruster }
9736ab4b5abSMarkus Armbruster 
974756e6736SKevin Wolf /*
975756e6736SKevin Wolf  * Return values:
976756e6736SKevin Wolf  * 0        - success
977756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
978756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
979756e6736SKevin Wolf  *            image file header
980756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
981756e6736SKevin Wolf  */
982756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
983756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
984756e6736SKevin Wolf {
985756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
986756e6736SKevin Wolf 
987756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
988756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
989756e6736SKevin Wolf     } else {
990756e6736SKevin Wolf         return -ENOTSUP;
991756e6736SKevin Wolf     }
992756e6736SKevin Wolf }
993756e6736SKevin Wolf 
99471d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
99571d0770cSaliguori                                    size_t size)
99671d0770cSaliguori {
99771d0770cSaliguori     int64_t len;
99871d0770cSaliguori 
99971d0770cSaliguori     if (!bdrv_is_inserted(bs))
100071d0770cSaliguori         return -ENOMEDIUM;
100171d0770cSaliguori 
100271d0770cSaliguori     if (bs->growable)
100371d0770cSaliguori         return 0;
100471d0770cSaliguori 
100571d0770cSaliguori     len = bdrv_getlength(bs);
100671d0770cSaliguori 
1007fbb7b4e0SKevin Wolf     if (offset < 0)
1008fbb7b4e0SKevin Wolf         return -EIO;
1009fbb7b4e0SKevin Wolf 
1010fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
101171d0770cSaliguori         return -EIO;
101271d0770cSaliguori 
101371d0770cSaliguori     return 0;
101471d0770cSaliguori }
101571d0770cSaliguori 
101671d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
101771d0770cSaliguori                               int nb_sectors)
101871d0770cSaliguori {
1019eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1020eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
102171d0770cSaliguori }
102271d0770cSaliguori 
10231c9805a3SStefan Hajnoczi typedef struct RwCo {
10241c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10251c9805a3SStefan Hajnoczi     int64_t sector_num;
10261c9805a3SStefan Hajnoczi     int nb_sectors;
10271c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10281c9805a3SStefan Hajnoczi     bool is_write;
10291c9805a3SStefan Hajnoczi     int ret;
10301c9805a3SStefan Hajnoczi } RwCo;
10311c9805a3SStefan Hajnoczi 
10321c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1033fc01f7e7Sbellard {
10341c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1035fc01f7e7Sbellard 
10361c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10371c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10381c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10391c9805a3SStefan Hajnoczi     } else {
10401c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10411c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10421c9805a3SStefan Hajnoczi     }
10431c9805a3SStefan Hajnoczi }
1044e7a8a783SKevin Wolf 
10451c9805a3SStefan Hajnoczi /*
10461c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10471c9805a3SStefan Hajnoczi  */
10481c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10491c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10501c9805a3SStefan Hajnoczi {
1051e7a8a783SKevin Wolf     QEMUIOVector qiov;
1052e7a8a783SKevin Wolf     struct iovec iov = {
1053e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1054e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1055e7a8a783SKevin Wolf     };
10561c9805a3SStefan Hajnoczi     Coroutine *co;
10571c9805a3SStefan Hajnoczi     RwCo rwco = {
10581c9805a3SStefan Hajnoczi         .bs = bs,
10591c9805a3SStefan Hajnoczi         .sector_num = sector_num,
10601c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
10611c9805a3SStefan Hajnoczi         .qiov = &qiov,
10621c9805a3SStefan Hajnoczi         .is_write = is_write,
10631c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
10641c9805a3SStefan Hajnoczi     };
1065e7a8a783SKevin Wolf 
1066e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
10671c9805a3SStefan Hajnoczi 
10681c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
10691c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
10701c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
10711c9805a3SStefan Hajnoczi     } else {
10721c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
10731c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
10741c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
10751c9805a3SStefan Hajnoczi             qemu_aio_wait();
10761c9805a3SStefan Hajnoczi         }
10771c9805a3SStefan Hajnoczi     }
10781c9805a3SStefan Hajnoczi     return rwco.ret;
1079e7a8a783SKevin Wolf }
1080e7a8a783SKevin Wolf 
10811c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
10821c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
10831c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
10841c9805a3SStefan Hajnoczi {
10851c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
108683f64091Sbellard }
1087fc01f7e7Sbellard 
10887cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
10897cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
10907cd1e32aSlirans@il.ibm.com {
10917cd1e32aSlirans@il.ibm.com     int64_t start, end;
1092c6d22830SJan Kiszka     unsigned long val, idx, bit;
1093a55eb92cSJan Kiszka 
10946ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1095c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
10967cd1e32aSlirans@il.ibm.com 
10977cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1098c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1099c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1100c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1101c6d22830SJan Kiszka         if (dirty) {
11026d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1103aaa0eb75SLiran Schour                 bs->dirty_count++;
11046d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1105aaa0eb75SLiran Schour             }
1106c6d22830SJan Kiszka         } else {
11076d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1108aaa0eb75SLiran Schour                 bs->dirty_count--;
11096d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1110c6d22830SJan Kiszka             }
1111aaa0eb75SLiran Schour         }
1112c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11137cd1e32aSlirans@il.ibm.com     }
11147cd1e32aSlirans@il.ibm.com }
11157cd1e32aSlirans@il.ibm.com 
111619cb3738Sbellard /* Return < 0 if error. Important errors are:
111719cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
111819cb3738Sbellard   -ENOMEDIUM   No media inserted.
111919cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
112019cb3738Sbellard   -EACCES      Trying to write a read-only device
112119cb3738Sbellard */
1122fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1123fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1124fc01f7e7Sbellard {
11251c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
112683f64091Sbellard }
112783f64091Sbellard 
1128eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1129eda578e5Saliguori                void *buf, int count1)
113083f64091Sbellard {
11316ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
113283f64091Sbellard     int len, nb_sectors, count;
113383f64091Sbellard     int64_t sector_num;
11349a8c4cceSKevin Wolf     int ret;
113583f64091Sbellard 
113683f64091Sbellard     count = count1;
113783f64091Sbellard     /* first read to align to sector start */
11386ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
113983f64091Sbellard     if (len > count)
114083f64091Sbellard         len = count;
11416ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
114283f64091Sbellard     if (len > 0) {
11439a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11449a8c4cceSKevin Wolf             return ret;
11456ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
114683f64091Sbellard         count -= len;
114783f64091Sbellard         if (count == 0)
114883f64091Sbellard             return count1;
114983f64091Sbellard         sector_num++;
115083f64091Sbellard         buf += len;
115183f64091Sbellard     }
115283f64091Sbellard 
115383f64091Sbellard     /* read the sectors "in place" */
11546ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
115583f64091Sbellard     if (nb_sectors > 0) {
11569a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11579a8c4cceSKevin Wolf             return ret;
115883f64091Sbellard         sector_num += nb_sectors;
11596ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
116083f64091Sbellard         buf += len;
116183f64091Sbellard         count -= len;
116283f64091Sbellard     }
116383f64091Sbellard 
116483f64091Sbellard     /* add data from the last sector */
116583f64091Sbellard     if (count > 0) {
11669a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11679a8c4cceSKevin Wolf             return ret;
116883f64091Sbellard         memcpy(buf, tmp_buf, count);
116983f64091Sbellard     }
117083f64091Sbellard     return count1;
117183f64091Sbellard }
117283f64091Sbellard 
1173eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1174eda578e5Saliguori                 const void *buf, int count1)
117583f64091Sbellard {
11766ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
117783f64091Sbellard     int len, nb_sectors, count;
117883f64091Sbellard     int64_t sector_num;
11799a8c4cceSKevin Wolf     int ret;
118083f64091Sbellard 
118183f64091Sbellard     count = count1;
118283f64091Sbellard     /* first write to align to sector start */
11836ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
118483f64091Sbellard     if (len > count)
118583f64091Sbellard         len = count;
11866ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
118783f64091Sbellard     if (len > 0) {
11889a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11899a8c4cceSKevin Wolf             return ret;
11906ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
11919a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
11929a8c4cceSKevin Wolf             return ret;
119383f64091Sbellard         count -= len;
119483f64091Sbellard         if (count == 0)
119583f64091Sbellard             return count1;
119683f64091Sbellard         sector_num++;
119783f64091Sbellard         buf += len;
119883f64091Sbellard     }
119983f64091Sbellard 
120083f64091Sbellard     /* write the sectors "in place" */
12016ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
120283f64091Sbellard     if (nb_sectors > 0) {
12039a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12049a8c4cceSKevin Wolf             return ret;
120583f64091Sbellard         sector_num += nb_sectors;
12066ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
120783f64091Sbellard         buf += len;
120883f64091Sbellard         count -= len;
120983f64091Sbellard     }
121083f64091Sbellard 
121183f64091Sbellard     /* add data from the last sector */
121283f64091Sbellard     if (count > 0) {
12139a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12149a8c4cceSKevin Wolf             return ret;
121583f64091Sbellard         memcpy(tmp_buf, buf, count);
12169a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12179a8c4cceSKevin Wolf             return ret;
121883f64091Sbellard     }
121983f64091Sbellard     return count1;
122083f64091Sbellard }
122183f64091Sbellard 
1222f08145feSKevin Wolf /*
1223f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1224f08145feSKevin Wolf  * request (acts as a barrier)
1225f08145feSKevin Wolf  *
1226f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1227f08145feSKevin Wolf  */
1228f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1229f08145feSKevin Wolf     const void *buf, int count)
1230f08145feSKevin Wolf {
1231f08145feSKevin Wolf     int ret;
1232f08145feSKevin Wolf 
1233f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1234f08145feSKevin Wolf     if (ret < 0) {
1235f08145feSKevin Wolf         return ret;
1236f08145feSKevin Wolf     }
1237f08145feSKevin Wolf 
123892196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
123992196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1240f08145feSKevin Wolf         bdrv_flush(bs);
1241f08145feSKevin Wolf     }
1242f08145feSKevin Wolf 
1243f08145feSKevin Wolf     return 0;
1244f08145feSKevin Wolf }
1245f08145feSKevin Wolf 
1246c5fbe571SStefan Hajnoczi /*
1247c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1248c5fbe571SStefan Hajnoczi  */
1249c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1250c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1251da1fa91dSKevin Wolf {
1252da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1253da1fa91dSKevin Wolf 
1254da1fa91dSKevin Wolf     if (!drv) {
1255da1fa91dSKevin Wolf         return -ENOMEDIUM;
1256da1fa91dSKevin Wolf     }
1257da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1258da1fa91dSKevin Wolf         return -EIO;
1259da1fa91dSKevin Wolf     }
1260da1fa91dSKevin Wolf 
1261da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1262da1fa91dSKevin Wolf }
1263da1fa91dSKevin Wolf 
1264c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1265da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1266da1fa91dSKevin Wolf {
1267c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1268da1fa91dSKevin Wolf 
1269c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1270c5fbe571SStefan Hajnoczi }
1271c5fbe571SStefan Hajnoczi 
1272c5fbe571SStefan Hajnoczi /*
1273c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1274c5fbe571SStefan Hajnoczi  */
1275c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1276c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1277c5fbe571SStefan Hajnoczi {
1278c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
12796b7cb247SStefan Hajnoczi     int ret;
1280da1fa91dSKevin Wolf 
1281da1fa91dSKevin Wolf     if (!bs->drv) {
1282da1fa91dSKevin Wolf         return -ENOMEDIUM;
1283da1fa91dSKevin Wolf     }
1284da1fa91dSKevin Wolf     if (bs->read_only) {
1285da1fa91dSKevin Wolf         return -EACCES;
1286da1fa91dSKevin Wolf     }
1287da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1288da1fa91dSKevin Wolf         return -EIO;
1289da1fa91dSKevin Wolf     }
1290da1fa91dSKevin Wolf 
12916b7cb247SStefan Hajnoczi     ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
12926b7cb247SStefan Hajnoczi 
1293da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1294da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1295da1fa91dSKevin Wolf     }
1296da1fa91dSKevin Wolf 
1297da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1298da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1299da1fa91dSKevin Wolf     }
1300da1fa91dSKevin Wolf 
13016b7cb247SStefan Hajnoczi     return ret;
1302da1fa91dSKevin Wolf }
1303da1fa91dSKevin Wolf 
1304c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1305c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1306c5fbe571SStefan Hajnoczi {
1307c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1308c5fbe571SStefan Hajnoczi 
1309c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1310c5fbe571SStefan Hajnoczi }
1311c5fbe571SStefan Hajnoczi 
131283f64091Sbellard /**
131383f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
131483f64091Sbellard  */
131583f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
131683f64091Sbellard {
131783f64091Sbellard     BlockDriver *drv = bs->drv;
131851762288SStefan Hajnoczi     int ret;
131983f64091Sbellard     if (!drv)
132019cb3738Sbellard         return -ENOMEDIUM;
132183f64091Sbellard     if (!drv->bdrv_truncate)
132283f64091Sbellard         return -ENOTSUP;
132359f2689dSNaphtali Sprei     if (bs->read_only)
132459f2689dSNaphtali Sprei         return -EACCES;
13258591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13268591675fSMarcelo Tosatti         return -EBUSY;
132751762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
132851762288SStefan Hajnoczi     if (ret == 0) {
132951762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1330145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
133151762288SStefan Hajnoczi     }
133251762288SStefan Hajnoczi     return ret;
133383f64091Sbellard }
133483f64091Sbellard 
133583f64091Sbellard /**
13364a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13374a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13384a1d5e1fSFam Zheng  */
13394a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13404a1d5e1fSFam Zheng {
13414a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13424a1d5e1fSFam Zheng     if (!drv) {
13434a1d5e1fSFam Zheng         return -ENOMEDIUM;
13444a1d5e1fSFam Zheng     }
13454a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13464a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13474a1d5e1fSFam Zheng     }
13484a1d5e1fSFam Zheng     if (bs->file) {
13494a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13504a1d5e1fSFam Zheng     }
13514a1d5e1fSFam Zheng     return -ENOTSUP;
13524a1d5e1fSFam Zheng }
13534a1d5e1fSFam Zheng 
13544a1d5e1fSFam Zheng /**
135583f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
135683f64091Sbellard  */
135783f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
135883f64091Sbellard {
135983f64091Sbellard     BlockDriver *drv = bs->drv;
136083f64091Sbellard     if (!drv)
136119cb3738Sbellard         return -ENOMEDIUM;
136251762288SStefan Hajnoczi 
13632c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
136446a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
136583f64091Sbellard             return drv->bdrv_getlength(bs);
1366fc01f7e7Sbellard         }
136746a4e4e6SStefan Hajnoczi     }
136846a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
136946a4e4e6SStefan Hajnoczi }
1370fc01f7e7Sbellard 
137119cb3738Sbellard /* return 0 as number of sectors if no device present or error */
137296b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1373fc01f7e7Sbellard {
137419cb3738Sbellard     int64_t length;
137519cb3738Sbellard     length = bdrv_getlength(bs);
137619cb3738Sbellard     if (length < 0)
137719cb3738Sbellard         length = 0;
137819cb3738Sbellard     else
13796ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
138019cb3738Sbellard     *nb_sectors_ptr = length;
1381fc01f7e7Sbellard }
1382cf98951bSbellard 
1383f3d54fc4Saliguori struct partition {
1384f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1385f3d54fc4Saliguori         uint8_t head;               /* starting head */
1386f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1387f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1388f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1389f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1390f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1391f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1392f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1393f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1394541dc0d4SStefan Weil } QEMU_PACKED;
1395f3d54fc4Saliguori 
1396f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1397f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1398f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1399f3d54fc4Saliguori {
1400eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1401f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1402f3d54fc4Saliguori     struct partition *p;
1403f3d54fc4Saliguori     uint32_t nr_sects;
1404a38131b6Sblueswir1     uint64_t nb_sectors;
1405f3d54fc4Saliguori 
1406f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1407f3d54fc4Saliguori 
1408f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1409f3d54fc4Saliguori     if (ret < 0)
1410f3d54fc4Saliguori         return -1;
1411f3d54fc4Saliguori     /* test msdos magic */
1412f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1413f3d54fc4Saliguori         return -1;
1414f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1415f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1416f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1417f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1418f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1419f3d54fc4Saliguori                a cylinder boundary */
1420f3d54fc4Saliguori             heads = p->end_head + 1;
1421f3d54fc4Saliguori             sectors = p->end_sector & 63;
1422f3d54fc4Saliguori             if (sectors == 0)
1423f3d54fc4Saliguori                 continue;
1424f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1425f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1426f3d54fc4Saliguori                 continue;
1427f3d54fc4Saliguori             *pheads = heads;
1428f3d54fc4Saliguori             *psectors = sectors;
1429f3d54fc4Saliguori             *pcylinders = cylinders;
1430f3d54fc4Saliguori #if 0
1431f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1432f3d54fc4Saliguori                    cylinders, heads, sectors);
1433f3d54fc4Saliguori #endif
1434f3d54fc4Saliguori             return 0;
1435f3d54fc4Saliguori         }
1436f3d54fc4Saliguori     }
1437f3d54fc4Saliguori     return -1;
1438f3d54fc4Saliguori }
1439f3d54fc4Saliguori 
1440f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1441f3d54fc4Saliguori {
1442f3d54fc4Saliguori     int translation, lba_detected = 0;
1443f3d54fc4Saliguori     int cylinders, heads, secs;
1444a38131b6Sblueswir1     uint64_t nb_sectors;
1445f3d54fc4Saliguori 
1446f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1447f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1448f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1449f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1450f3d54fc4Saliguori     if (cylinders != 0) {
1451f3d54fc4Saliguori         *pcyls = cylinders;
1452f3d54fc4Saliguori         *pheads = heads;
1453f3d54fc4Saliguori         *psecs = secs;
1454f3d54fc4Saliguori     } else {
1455f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1456f3d54fc4Saliguori             if (heads > 16) {
1457f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1458f3d54fc4Saliguori                    translation was active, so the default
1459f3d54fc4Saliguori                    hardware geometry is OK */
1460f3d54fc4Saliguori                 lba_detected = 1;
1461f3d54fc4Saliguori                 goto default_geometry;
1462f3d54fc4Saliguori             } else {
1463f3d54fc4Saliguori                 *pcyls = cylinders;
1464f3d54fc4Saliguori                 *pheads = heads;
1465f3d54fc4Saliguori                 *psecs = secs;
1466f3d54fc4Saliguori                 /* disable any translation to be in sync with
1467f3d54fc4Saliguori                    the logical geometry */
1468f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1469f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1470f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1471f3d54fc4Saliguori                 }
1472f3d54fc4Saliguori             }
1473f3d54fc4Saliguori         } else {
1474f3d54fc4Saliguori         default_geometry:
1475f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1476f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1477f3d54fc4Saliguori 
1478f3d54fc4Saliguori             if (cylinders > 16383)
1479f3d54fc4Saliguori                 cylinders = 16383;
1480f3d54fc4Saliguori             else if (cylinders < 2)
1481f3d54fc4Saliguori                 cylinders = 2;
1482f3d54fc4Saliguori             *pcyls = cylinders;
1483f3d54fc4Saliguori             *pheads = 16;
1484f3d54fc4Saliguori             *psecs = 63;
1485f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1486f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1487f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1488f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1489f3d54fc4Saliguori                 } else {
1490f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1491f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1492f3d54fc4Saliguori                 }
1493f3d54fc4Saliguori             }
1494f3d54fc4Saliguori         }
1495f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1496f3d54fc4Saliguori     }
1497f3d54fc4Saliguori }
1498f3d54fc4Saliguori 
1499b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1500b338082bSbellard                             int cyls, int heads, int secs)
1501b338082bSbellard {
1502b338082bSbellard     bs->cyls = cyls;
1503b338082bSbellard     bs->heads = heads;
1504b338082bSbellard     bs->secs = secs;
1505b338082bSbellard }
1506b338082bSbellard 
150746d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
150846d4767dSbellard {
150946d4767dSbellard     bs->translation = translation;
151046d4767dSbellard }
151146d4767dSbellard 
1512b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1513b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1514b338082bSbellard {
1515b338082bSbellard     *pcyls = bs->cyls;
1516b338082bSbellard     *pheads = bs->heads;
1517b338082bSbellard     *psecs = bs->secs;
1518b338082bSbellard }
1519b338082bSbellard 
15205bbdbb46SBlue Swirl /* Recognize floppy formats */
15215bbdbb46SBlue Swirl typedef struct FDFormat {
15225bbdbb46SBlue Swirl     FDriveType drive;
15235bbdbb46SBlue Swirl     uint8_t last_sect;
15245bbdbb46SBlue Swirl     uint8_t max_track;
15255bbdbb46SBlue Swirl     uint8_t max_head;
15265bbdbb46SBlue Swirl } FDFormat;
15275bbdbb46SBlue Swirl 
15285bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15295bbdbb46SBlue Swirl     /* First entry is default format */
15305bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15315bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15325bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15335bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15345bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15355bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15365bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15375bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15385bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15395bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15405bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15415bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15425bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15435bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15445bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15455bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15465bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15475bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15485bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15495bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15505bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15515bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15525bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15535bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15545bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15555bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15565bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15575bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15585bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15595bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15605bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15615bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15625bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15635bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15645bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15655bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15665bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15675bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
15685bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
15695bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
15705bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
15715bbdbb46SBlue Swirl     /* end */
15725bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
15735bbdbb46SBlue Swirl };
15745bbdbb46SBlue Swirl 
15755bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
15765bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
15775bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
15785bbdbb46SBlue Swirl {
15795bbdbb46SBlue Swirl     const FDFormat *parse;
15805bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
15815bbdbb46SBlue Swirl     int i, first_match, match;
15825bbdbb46SBlue Swirl 
15835bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
15845bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
15855bbdbb46SBlue Swirl         /* User defined disk */
15865bbdbb46SBlue Swirl     } else {
15875bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
15885bbdbb46SBlue Swirl         match = -1;
15895bbdbb46SBlue Swirl         first_match = -1;
15905bbdbb46SBlue Swirl         for (i = 0; ; i++) {
15915bbdbb46SBlue Swirl             parse = &fd_formats[i];
15925bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
15935bbdbb46SBlue Swirl                 break;
15945bbdbb46SBlue Swirl             }
15955bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
15965bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
15975bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
15985bbdbb46SBlue Swirl                     parse->last_sect;
15995bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16005bbdbb46SBlue Swirl                     match = i;
16015bbdbb46SBlue Swirl                     break;
16025bbdbb46SBlue Swirl                 }
16035bbdbb46SBlue Swirl                 if (first_match == -1) {
16045bbdbb46SBlue Swirl                     first_match = i;
16055bbdbb46SBlue Swirl                 }
16065bbdbb46SBlue Swirl             }
16075bbdbb46SBlue Swirl         }
16085bbdbb46SBlue Swirl         if (match == -1) {
16095bbdbb46SBlue Swirl             if (first_match == -1) {
16105bbdbb46SBlue Swirl                 match = 1;
16115bbdbb46SBlue Swirl             } else {
16125bbdbb46SBlue Swirl                 match = first_match;
16135bbdbb46SBlue Swirl             }
16145bbdbb46SBlue Swirl             parse = &fd_formats[match];
16155bbdbb46SBlue Swirl         }
16165bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16175bbdbb46SBlue Swirl         *max_track = parse->max_track;
16185bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16195bbdbb46SBlue Swirl         *drive = parse->drive;
16205bbdbb46SBlue Swirl     }
16215bbdbb46SBlue Swirl }
16225bbdbb46SBlue Swirl 
162346d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
162446d4767dSbellard {
162546d4767dSbellard     return bs->translation;
162646d4767dSbellard }
162746d4767dSbellard 
1628abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1629abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1630abd7f68dSMarkus Armbruster {
1631abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1632abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1633abd7f68dSMarkus Armbruster }
1634abd7f68dSMarkus Armbruster 
1635abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1636abd7f68dSMarkus Armbruster {
1637abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1638abd7f68dSMarkus Armbruster }
1639abd7f68dSMarkus Armbruster 
1640b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1641b338082bSbellard {
1642b338082bSbellard     return bs->read_only;
1643b338082bSbellard }
1644b338082bSbellard 
1645985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1646985a03b0Sths {
1647985a03b0Sths     return bs->sg;
1648985a03b0Sths }
1649985a03b0Sths 
1650e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1651e900a7b7SChristoph Hellwig {
1652e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1653e900a7b7SChristoph Hellwig }
1654e900a7b7SChristoph Hellwig 
1655ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1656ea2384d3Sbellard {
1657ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1658ea2384d3Sbellard         return 1;
1659ea2384d3Sbellard     return bs->encrypted;
1660ea2384d3Sbellard }
1661ea2384d3Sbellard 
1662c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1663c0f4ce77Saliguori {
1664c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1665c0f4ce77Saliguori 
1666c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1667c0f4ce77Saliguori         return 1;
1668c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1669c0f4ce77Saliguori }
1670c0f4ce77Saliguori 
1671ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1672ea2384d3Sbellard {
1673ea2384d3Sbellard     int ret;
1674ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1675ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1676ea2384d3Sbellard         if (ret < 0)
1677ea2384d3Sbellard             return ret;
1678ea2384d3Sbellard         if (!bs->encrypted)
1679ea2384d3Sbellard             return 0;
1680ea2384d3Sbellard     }
1681fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1682fd04a2aeSShahar Havivi         return -EINVAL;
1683fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1684fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1685fd04a2aeSShahar Havivi     }
1686c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1687bb5fc20fSaliguori     if (ret < 0) {
1688bb5fc20fSaliguori         bs->valid_key = 0;
1689bb5fc20fSaliguori     } else if (!bs->valid_key) {
1690bb5fc20fSaliguori         bs->valid_key = 1;
1691bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
16927d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1693bb5fc20fSaliguori     }
1694c0f4ce77Saliguori     return ret;
1695ea2384d3Sbellard }
1696ea2384d3Sbellard 
1697ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1698ea2384d3Sbellard {
169919cb3738Sbellard     if (!bs->drv) {
1700ea2384d3Sbellard         buf[0] = '\0';
1701ea2384d3Sbellard     } else {
1702ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1703ea2384d3Sbellard     }
1704ea2384d3Sbellard }
1705ea2384d3Sbellard 
1706ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1707ea2384d3Sbellard                          void *opaque)
1708ea2384d3Sbellard {
1709ea2384d3Sbellard     BlockDriver *drv;
1710ea2384d3Sbellard 
17118a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1712ea2384d3Sbellard         it(opaque, drv->format_name);
1713ea2384d3Sbellard     }
1714ea2384d3Sbellard }
1715ea2384d3Sbellard 
1716b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1717b338082bSbellard {
1718b338082bSbellard     BlockDriverState *bs;
1719b338082bSbellard 
17201b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17211b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1722b338082bSbellard             return bs;
1723b338082bSbellard         }
17241b7bdbc1SStefan Hajnoczi     }
1725b338082bSbellard     return NULL;
1726b338082bSbellard }
1727b338082bSbellard 
17282f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17292f399b0aSMarkus Armbruster {
17302f399b0aSMarkus Armbruster     if (!bs) {
17312f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17322f399b0aSMarkus Armbruster     }
17332f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17342f399b0aSMarkus Armbruster }
17352f399b0aSMarkus Armbruster 
173651de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
173781d0912dSbellard {
173881d0912dSbellard     BlockDriverState *bs;
173981d0912dSbellard 
17401b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
174151de9760Saliguori         it(opaque, bs);
174281d0912dSbellard     }
174381d0912dSbellard }
174481d0912dSbellard 
1745ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1746ea2384d3Sbellard {
1747ea2384d3Sbellard     return bs->device_name;
1748ea2384d3Sbellard }
1749ea2384d3Sbellard 
1750c6ca28d6Saliguori void bdrv_flush_all(void)
1751c6ca28d6Saliguori {
1752c6ca28d6Saliguori     BlockDriverState *bs;
1753c6ca28d6Saliguori 
17541b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1755c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1756c6ca28d6Saliguori             bdrv_flush(bs);
1757c6ca28d6Saliguori         }
17581b7bdbc1SStefan Hajnoczi     }
17591b7bdbc1SStefan Hajnoczi }
1760c6ca28d6Saliguori 
1761f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1762f2feebbdSKevin Wolf {
1763f2feebbdSKevin Wolf     assert(bs->drv);
1764f2feebbdSKevin Wolf 
1765336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1766336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1767f2feebbdSKevin Wolf     }
1768f2feebbdSKevin Wolf 
1769f2feebbdSKevin Wolf     return 1;
1770f2feebbdSKevin Wolf }
1771f2feebbdSKevin Wolf 
1772f58c7b35Sths /*
1773f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1774f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1775f58c7b35Sths  * hence all their sectors are reported as allocated.
1776f58c7b35Sths  *
1777f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1778f58c7b35Sths  * the specified sector) that are known to be in the same
1779f58c7b35Sths  * allocated/unallocated state.
1780f58c7b35Sths  *
1781f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1782f58c7b35Sths  */
1783f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1784f58c7b35Sths 	int *pnum)
1785f58c7b35Sths {
1786f58c7b35Sths     int64_t n;
1787f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1788f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1789f58c7b35Sths             *pnum = 0;
1790f58c7b35Sths             return 0;
1791f58c7b35Sths         }
1792f58c7b35Sths         n = bs->total_sectors - sector_num;
1793f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1794f58c7b35Sths         return 1;
1795f58c7b35Sths     }
1796f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1797f58c7b35Sths }
1798f58c7b35Sths 
17992582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18002582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18012582bfedSLuiz Capitulino {
18022582bfedSLuiz Capitulino     QObject *data;
18032582bfedSLuiz Capitulino     const char *action_str;
18042582bfedSLuiz Capitulino 
18052582bfedSLuiz Capitulino     switch (action) {
18062582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18072582bfedSLuiz Capitulino         action_str = "report";
18082582bfedSLuiz Capitulino         break;
18092582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18102582bfedSLuiz Capitulino         action_str = "ignore";
18112582bfedSLuiz Capitulino         break;
18122582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18132582bfedSLuiz Capitulino         action_str = "stop";
18142582bfedSLuiz Capitulino         break;
18152582bfedSLuiz Capitulino     default:
18162582bfedSLuiz Capitulino         abort();
18172582bfedSLuiz Capitulino     }
18182582bfedSLuiz Capitulino 
18192582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18202582bfedSLuiz Capitulino                               bdrv->device_name,
18212582bfedSLuiz Capitulino                               action_str,
18222582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18232582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18242582bfedSLuiz Capitulino 
18252582bfedSLuiz Capitulino     qobject_decref(data);
18262582bfedSLuiz Capitulino }
18272582bfedSLuiz Capitulino 
1828*b2023818SLuiz Capitulino BlockInfoList *qmp_query_block(Error **errp)
1829b338082bSbellard {
1830*b2023818SLuiz Capitulino     BlockInfoList *head = NULL, *cur_item = NULL;
1831d15e5465SLuiz Capitulino     BlockDriverState *bs;
1832d15e5465SLuiz Capitulino 
18331b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1834*b2023818SLuiz Capitulino         BlockInfoList *info = g_malloc0(sizeof(*info));
1835d15e5465SLuiz Capitulino 
1836*b2023818SLuiz Capitulino         info->value = g_malloc0(sizeof(*info->value));
1837*b2023818SLuiz Capitulino         info->value->device = g_strdup(bs->device_name);
1838*b2023818SLuiz Capitulino         info->value->type = g_strdup("unknown");
1839*b2023818SLuiz Capitulino         info->value->locked = bdrv_dev_is_medium_locked(bs);
1840*b2023818SLuiz Capitulino         info->value->removable = bdrv_dev_has_removable_media(bs);
1841d15e5465SLuiz Capitulino 
1842e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1843*b2023818SLuiz Capitulino             info->value->has_tray_open = true;
1844*b2023818SLuiz Capitulino             info->value->tray_open = bdrv_dev_is_tray_open(bs);
1845e4def80bSMarkus Armbruster         }
1846f04ef601SLuiz Capitulino 
1847f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1848*b2023818SLuiz Capitulino             info->value->has_io_status = true;
1849*b2023818SLuiz Capitulino             info->value->io_status = bs->iostatus;
1850f04ef601SLuiz Capitulino         }
1851f04ef601SLuiz Capitulino 
1852d15e5465SLuiz Capitulino         if (bs->drv) {
1853*b2023818SLuiz Capitulino             info->value->has_inserted = true;
1854*b2023818SLuiz Capitulino             info->value->inserted = g_malloc0(sizeof(*info->value->inserted));
1855*b2023818SLuiz Capitulino             info->value->inserted->file = g_strdup(bs->filename);
1856*b2023818SLuiz Capitulino             info->value->inserted->ro = bs->read_only;
1857*b2023818SLuiz Capitulino             info->value->inserted->drv = g_strdup(bs->drv->format_name);
1858*b2023818SLuiz Capitulino             info->value->inserted->encrypted = bs->encrypted;
1859*b2023818SLuiz Capitulino             if (bs->backing_file[0]) {
1860*b2023818SLuiz Capitulino                 info->value->inserted->has_backing_file = true;
1861*b2023818SLuiz Capitulino                 info->value->inserted->backing_file = g_strdup(bs->backing_file);
1862*b2023818SLuiz Capitulino             }
1863d15e5465SLuiz Capitulino         }
1864d15e5465SLuiz Capitulino 
1865*b2023818SLuiz Capitulino         /* XXX: waiting for the qapi to support GSList */
1866*b2023818SLuiz Capitulino         if (!cur_item) {
1867*b2023818SLuiz Capitulino             head = cur_item = info;
1868*b2023818SLuiz Capitulino         } else {
1869*b2023818SLuiz Capitulino             cur_item->next = info;
1870*b2023818SLuiz Capitulino             cur_item = info;
1871d15e5465SLuiz Capitulino         }
1872d15e5465SLuiz Capitulino     }
1873d15e5465SLuiz Capitulino 
1874*b2023818SLuiz Capitulino     return head;
1875b338082bSbellard }
1876a36e69ddSths 
1877218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque)
1878a36e69ddSths {
1879218a536aSLuiz Capitulino     QDict *qdict;
1880218a536aSLuiz Capitulino     Monitor *mon = opaque;
1881218a536aSLuiz Capitulino 
1882218a536aSLuiz Capitulino     qdict = qobject_to_qdict(data);
1883218a536aSLuiz Capitulino     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
1884218a536aSLuiz Capitulino 
1885218a536aSLuiz Capitulino     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
1886218a536aSLuiz Capitulino     monitor_printf(mon, " rd_bytes=%" PRId64
1887218a536aSLuiz Capitulino                         " wr_bytes=%" PRId64
1888218a536aSLuiz Capitulino                         " rd_operations=%" PRId64
1889218a536aSLuiz Capitulino                         " wr_operations=%" PRId64
1890e8045d67SChristoph Hellwig                         " flush_operations=%" PRId64
1891c488c7f6SChristoph Hellwig                         " wr_total_time_ns=%" PRId64
1892c488c7f6SChristoph Hellwig                         " rd_total_time_ns=%" PRId64
1893c488c7f6SChristoph Hellwig                         " flush_total_time_ns=%" PRId64
1894218a536aSLuiz Capitulino                         "\n",
1895218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_bytes"),
1896218a536aSLuiz Capitulino                         qdict_get_int(qdict, "wr_bytes"),
1897218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_operations"),
1898e8045d67SChristoph Hellwig                         qdict_get_int(qdict, "wr_operations"),
1899c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_operations"),
1900c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "wr_total_time_ns"),
1901c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "rd_total_time_ns"),
1902c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_total_time_ns"));
1903218a536aSLuiz Capitulino }
1904218a536aSLuiz Capitulino 
1905218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data)
1906218a536aSLuiz Capitulino {
1907218a536aSLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
1908218a536aSLuiz Capitulino }
1909218a536aSLuiz Capitulino 
1910294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
1911294cc35fSKevin Wolf {
1912294cc35fSKevin Wolf     QObject *res;
1913294cc35fSKevin Wolf     QDict *dict;
1914294cc35fSKevin Wolf 
1915294cc35fSKevin Wolf     res = qobject_from_jsonf("{ 'stats': {"
1916294cc35fSKevin Wolf                              "'rd_bytes': %" PRId64 ","
1917294cc35fSKevin Wolf                              "'wr_bytes': %" PRId64 ","
1918294cc35fSKevin Wolf                              "'rd_operations': %" PRId64 ","
1919294cc35fSKevin Wolf                              "'wr_operations': %" PRId64 ","
1920e8045d67SChristoph Hellwig                              "'wr_highest_offset': %" PRId64 ","
1921c488c7f6SChristoph Hellwig                              "'flush_operations': %" PRId64 ","
1922c488c7f6SChristoph Hellwig                              "'wr_total_time_ns': %" PRId64 ","
1923c488c7f6SChristoph Hellwig                              "'rd_total_time_ns': %" PRId64 ","
1924c488c7f6SChristoph Hellwig                              "'flush_total_time_ns': %" PRId64
1925294cc35fSKevin Wolf                              "} }",
1926a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_READ],
1927a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_WRITE],
1928a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_READ],
1929a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_WRITE],
19305ffbbc67SBlue Swirl                              bs->wr_highest_sector *
1931e8045d67SChristoph Hellwig                              (uint64_t)BDRV_SECTOR_SIZE,
1932c488c7f6SChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_FLUSH],
1933c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_WRITE],
1934c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_READ],
1935c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_FLUSH]);
1936294cc35fSKevin Wolf     dict  = qobject_to_qdict(res);
1937294cc35fSKevin Wolf 
1938294cc35fSKevin Wolf     if (*bs->device_name) {
1939294cc35fSKevin Wolf         qdict_put(dict, "device", qstring_from_str(bs->device_name));
1940294cc35fSKevin Wolf     }
1941294cc35fSKevin Wolf 
1942294cc35fSKevin Wolf     if (bs->file) {
1943294cc35fSKevin Wolf         QObject *parent = bdrv_info_stats_bs(bs->file);
1944294cc35fSKevin Wolf         qdict_put_obj(dict, "parent", parent);
1945294cc35fSKevin Wolf     }
1946294cc35fSKevin Wolf 
1947294cc35fSKevin Wolf     return res;
1948294cc35fSKevin Wolf }
1949294cc35fSKevin Wolf 
1950218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data)
1951218a536aSLuiz Capitulino {
1952218a536aSLuiz Capitulino     QObject *obj;
1953218a536aSLuiz Capitulino     QList *devices;
1954a36e69ddSths     BlockDriverState *bs;
1955a36e69ddSths 
1956218a536aSLuiz Capitulino     devices = qlist_new();
1957218a536aSLuiz Capitulino 
19581b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1959294cc35fSKevin Wolf         obj = bdrv_info_stats_bs(bs);
1960218a536aSLuiz Capitulino         qlist_append_obj(devices, obj);
1961a36e69ddSths     }
1962218a536aSLuiz Capitulino 
1963218a536aSLuiz Capitulino     *ret_data = QOBJECT(devices);
1964a36e69ddSths }
1965ea2384d3Sbellard 
1966045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1967045df330Saliguori {
1968045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
1969045df330Saliguori         return bs->backing_file;
1970045df330Saliguori     else if (bs->encrypted)
1971045df330Saliguori         return bs->filename;
1972045df330Saliguori     else
1973045df330Saliguori         return NULL;
1974045df330Saliguori }
1975045df330Saliguori 
197683f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
197783f64091Sbellard                                char *filename, int filename_size)
197883f64091Sbellard {
1979b783e409SKevin Wolf     if (!bs->backing_file) {
198083f64091Sbellard         pstrcpy(filename, filename_size, "");
198183f64091Sbellard     } else {
198283f64091Sbellard         pstrcpy(filename, filename_size, bs->backing_file);
198383f64091Sbellard     }
198483f64091Sbellard }
198583f64091Sbellard 
1986faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1987faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
1988faea38e7Sbellard {
1989faea38e7Sbellard     BlockDriver *drv = bs->drv;
1990faea38e7Sbellard     if (!drv)
199119cb3738Sbellard         return -ENOMEDIUM;
1992faea38e7Sbellard     if (!drv->bdrv_write_compressed)
1993faea38e7Sbellard         return -ENOTSUP;
1994fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
1995fbb7b4e0SKevin Wolf         return -EIO;
19967cd1e32aSlirans@il.ibm.com 
1997c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
19987cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
19997cd1e32aSlirans@il.ibm.com     }
20007cd1e32aSlirans@il.ibm.com 
2001faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2002faea38e7Sbellard }
2003faea38e7Sbellard 
2004faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2005faea38e7Sbellard {
2006faea38e7Sbellard     BlockDriver *drv = bs->drv;
2007faea38e7Sbellard     if (!drv)
200819cb3738Sbellard         return -ENOMEDIUM;
2009faea38e7Sbellard     if (!drv->bdrv_get_info)
2010faea38e7Sbellard         return -ENOTSUP;
2011faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2012faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2013faea38e7Sbellard }
2014faea38e7Sbellard 
201545566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
201645566e9cSChristoph Hellwig                       int64_t pos, int size)
2017178e08a5Saliguori {
2018178e08a5Saliguori     BlockDriver *drv = bs->drv;
2019178e08a5Saliguori     if (!drv)
2020178e08a5Saliguori         return -ENOMEDIUM;
20217cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
202245566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
20237cdb1f6dSMORITA Kazutaka     if (bs->file)
20247cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
20257cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2026178e08a5Saliguori }
2027178e08a5Saliguori 
202845566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
202945566e9cSChristoph Hellwig                       int64_t pos, int size)
2030178e08a5Saliguori {
2031178e08a5Saliguori     BlockDriver *drv = bs->drv;
2032178e08a5Saliguori     if (!drv)
2033178e08a5Saliguori         return -ENOMEDIUM;
20347cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
203545566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
20367cdb1f6dSMORITA Kazutaka     if (bs->file)
20377cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
20387cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2039178e08a5Saliguori }
2040178e08a5Saliguori 
20418b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
20428b9b0cc2SKevin Wolf {
20438b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
20448b9b0cc2SKevin Wolf 
20458b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
20468b9b0cc2SKevin Wolf         return;
20478b9b0cc2SKevin Wolf     }
20488b9b0cc2SKevin Wolf 
20498b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
20508b9b0cc2SKevin Wolf 
20518b9b0cc2SKevin Wolf }
20528b9b0cc2SKevin Wolf 
2053faea38e7Sbellard /**************************************************************/
2054faea38e7Sbellard /* handling of snapshots */
2055faea38e7Sbellard 
2056feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2057feeee5acSMiguel Di Ciurcio Filho {
2058feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
205907b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2060feeee5acSMiguel Di Ciurcio Filho         return 0;
2061feeee5acSMiguel Di Ciurcio Filho     }
2062feeee5acSMiguel Di Ciurcio Filho 
2063feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2064feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2065feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2066feeee5acSMiguel Di Ciurcio Filho         }
2067feeee5acSMiguel Di Ciurcio Filho         return 0;
2068feeee5acSMiguel Di Ciurcio Filho     }
2069feeee5acSMiguel Di Ciurcio Filho 
2070feeee5acSMiguel Di Ciurcio Filho     return 1;
2071feeee5acSMiguel Di Ciurcio Filho }
2072feeee5acSMiguel Di Ciurcio Filho 
2073199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2074199630b6SBlue Swirl {
2075199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2076199630b6SBlue Swirl }
2077199630b6SBlue Swirl 
2078f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2079f9092b10SMarkus Armbruster {
2080f9092b10SMarkus Armbruster     BlockDriverState *bs;
2081f9092b10SMarkus Armbruster 
20823ac906f7SMarkus Armbruster     if (bs_snapshots) {
2083f9092b10SMarkus Armbruster         return bs_snapshots;
20843ac906f7SMarkus Armbruster     }
2085f9092b10SMarkus Armbruster 
2086f9092b10SMarkus Armbruster     bs = NULL;
2087f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2088f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
20893ac906f7SMarkus Armbruster             bs_snapshots = bs;
20903ac906f7SMarkus Armbruster             return bs;
2091f9092b10SMarkus Armbruster         }
2092f9092b10SMarkus Armbruster     }
2093f9092b10SMarkus Armbruster     return NULL;
2094f9092b10SMarkus Armbruster }
2095f9092b10SMarkus Armbruster 
2096faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2097faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2098faea38e7Sbellard {
2099faea38e7Sbellard     BlockDriver *drv = bs->drv;
2100faea38e7Sbellard     if (!drv)
210119cb3738Sbellard         return -ENOMEDIUM;
21027cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2103faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
21047cdb1f6dSMORITA Kazutaka     if (bs->file)
21057cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
21067cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2107faea38e7Sbellard }
2108faea38e7Sbellard 
2109faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2110faea38e7Sbellard                        const char *snapshot_id)
2111faea38e7Sbellard {
2112faea38e7Sbellard     BlockDriver *drv = bs->drv;
21137cdb1f6dSMORITA Kazutaka     int ret, open_ret;
21147cdb1f6dSMORITA Kazutaka 
2115faea38e7Sbellard     if (!drv)
211619cb3738Sbellard         return -ENOMEDIUM;
21177cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2118faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
21197cdb1f6dSMORITA Kazutaka 
21207cdb1f6dSMORITA Kazutaka     if (bs->file) {
21217cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
21227cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
21237cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
21247cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
21257cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
21267cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
21277cdb1f6dSMORITA Kazutaka             return open_ret;
21287cdb1f6dSMORITA Kazutaka         }
21297cdb1f6dSMORITA Kazutaka         return ret;
21307cdb1f6dSMORITA Kazutaka     }
21317cdb1f6dSMORITA Kazutaka 
21327cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2133faea38e7Sbellard }
2134faea38e7Sbellard 
2135faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2136faea38e7Sbellard {
2137faea38e7Sbellard     BlockDriver *drv = bs->drv;
2138faea38e7Sbellard     if (!drv)
213919cb3738Sbellard         return -ENOMEDIUM;
21407cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2141faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
21427cdb1f6dSMORITA Kazutaka     if (bs->file)
21437cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
21447cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2145faea38e7Sbellard }
2146faea38e7Sbellard 
2147faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2148faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2149faea38e7Sbellard {
2150faea38e7Sbellard     BlockDriver *drv = bs->drv;
2151faea38e7Sbellard     if (!drv)
215219cb3738Sbellard         return -ENOMEDIUM;
21537cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2154faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
21557cdb1f6dSMORITA Kazutaka     if (bs->file)
21567cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
21577cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2158faea38e7Sbellard }
2159faea38e7Sbellard 
216051ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
216151ef6727Sedison         const char *snapshot_name)
216251ef6727Sedison {
216351ef6727Sedison     BlockDriver *drv = bs->drv;
216451ef6727Sedison     if (!drv) {
216551ef6727Sedison         return -ENOMEDIUM;
216651ef6727Sedison     }
216751ef6727Sedison     if (!bs->read_only) {
216851ef6727Sedison         return -EINVAL;
216951ef6727Sedison     }
217051ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
217151ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
217251ef6727Sedison     }
217351ef6727Sedison     return -ENOTSUP;
217451ef6727Sedison }
217551ef6727Sedison 
2176faea38e7Sbellard #define NB_SUFFIXES 4
2177faea38e7Sbellard 
2178faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2179faea38e7Sbellard {
2180faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2181faea38e7Sbellard     int64_t base;
2182faea38e7Sbellard     int i;
2183faea38e7Sbellard 
2184faea38e7Sbellard     if (size <= 999) {
2185faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2186faea38e7Sbellard     } else {
2187faea38e7Sbellard         base = 1024;
2188faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2189faea38e7Sbellard             if (size < (10 * base)) {
2190faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2191faea38e7Sbellard                          (double)size / base,
2192faea38e7Sbellard                          suffixes[i]);
2193faea38e7Sbellard                 break;
2194faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2195faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2196faea38e7Sbellard                          ((size + (base >> 1)) / base),
2197faea38e7Sbellard                          suffixes[i]);
2198faea38e7Sbellard                 break;
2199faea38e7Sbellard             }
2200faea38e7Sbellard             base = base * 1024;
2201faea38e7Sbellard         }
2202faea38e7Sbellard     }
2203faea38e7Sbellard     return buf;
2204faea38e7Sbellard }
2205faea38e7Sbellard 
2206faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2207faea38e7Sbellard {
2208faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
22093b9f94e1Sbellard #ifdef _WIN32
22103b9f94e1Sbellard     struct tm *ptm;
22113b9f94e1Sbellard #else
2212faea38e7Sbellard     struct tm tm;
22133b9f94e1Sbellard #endif
2214faea38e7Sbellard     time_t ti;
2215faea38e7Sbellard     int64_t secs;
2216faea38e7Sbellard 
2217faea38e7Sbellard     if (!sn) {
2218faea38e7Sbellard         snprintf(buf, buf_size,
2219faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2220faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2221faea38e7Sbellard     } else {
2222faea38e7Sbellard         ti = sn->date_sec;
22233b9f94e1Sbellard #ifdef _WIN32
22243b9f94e1Sbellard         ptm = localtime(&ti);
22253b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
22263b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
22273b9f94e1Sbellard #else
2228faea38e7Sbellard         localtime_r(&ti, &tm);
2229faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2230faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
22313b9f94e1Sbellard #endif
2232faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2233faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2234faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2235faea38e7Sbellard                  (int)(secs / 3600),
2236faea38e7Sbellard                  (int)((secs / 60) % 60),
2237faea38e7Sbellard                  (int)(secs % 60),
2238faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2239faea38e7Sbellard         snprintf(buf, buf_size,
2240faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2241faea38e7Sbellard                  sn->id_str, sn->name,
2242faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2243faea38e7Sbellard                  date_buf,
2244faea38e7Sbellard                  clock_buf);
2245faea38e7Sbellard     }
2246faea38e7Sbellard     return buf;
2247faea38e7Sbellard }
2248faea38e7Sbellard 
2249ea2384d3Sbellard /**************************************************************/
225083f64091Sbellard /* async I/Os */
2251ea2384d3Sbellard 
22523b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2253f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
225483f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2255ea2384d3Sbellard {
2256bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2257bbf0a440SStefan Hajnoczi 
2258b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22598c5873d6SStefan Hajnoczi                                  cb, opaque, false);
226083f64091Sbellard }
226183f64091Sbellard 
2262f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2263f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
226483f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
22657674e7bfSbellard {
2266bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2267bbf0a440SStefan Hajnoczi 
22681a6e115bSStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
22698c5873d6SStefan Hajnoczi                                  cb, opaque, true);
227083f64091Sbellard }
227183f64091Sbellard 
227240b4f539SKevin Wolf 
227340b4f539SKevin Wolf typedef struct MultiwriteCB {
227440b4f539SKevin Wolf     int error;
227540b4f539SKevin Wolf     int num_requests;
227640b4f539SKevin Wolf     int num_callbacks;
227740b4f539SKevin Wolf     struct {
227840b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
227940b4f539SKevin Wolf         void *opaque;
228040b4f539SKevin Wolf         QEMUIOVector *free_qiov;
228140b4f539SKevin Wolf         void *free_buf;
228240b4f539SKevin Wolf     } callbacks[];
228340b4f539SKevin Wolf } MultiwriteCB;
228440b4f539SKevin Wolf 
228540b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
228640b4f539SKevin Wolf {
228740b4f539SKevin Wolf     int i;
228840b4f539SKevin Wolf 
228940b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
229040b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
22911e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
22921e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
22931e1ea48dSStefan Hajnoczi         }
22947267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2295f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
229640b4f539SKevin Wolf     }
229740b4f539SKevin Wolf }
229840b4f539SKevin Wolf 
229940b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
230040b4f539SKevin Wolf {
230140b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
230240b4f539SKevin Wolf 
23036d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
23046d519a5fSStefan Hajnoczi 
2305cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
230640b4f539SKevin Wolf         mcb->error = ret;
230740b4f539SKevin Wolf     }
230840b4f539SKevin Wolf 
230940b4f539SKevin Wolf     mcb->num_requests--;
231040b4f539SKevin Wolf     if (mcb->num_requests == 0) {
231140b4f539SKevin Wolf         multiwrite_user_cb(mcb);
23127267c094SAnthony Liguori         g_free(mcb);
231340b4f539SKevin Wolf     }
231440b4f539SKevin Wolf }
231540b4f539SKevin Wolf 
231640b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
231740b4f539SKevin Wolf {
231877be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
231977be4366SChristoph Hellwig 
232077be4366SChristoph Hellwig     /*
232177be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
232277be4366SChristoph Hellwig      * here as that could overflow the return value.
232377be4366SChristoph Hellwig      */
232477be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
232577be4366SChristoph Hellwig         return 1;
232677be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
232777be4366SChristoph Hellwig         return -1;
232877be4366SChristoph Hellwig     } else {
232977be4366SChristoph Hellwig         return 0;
233077be4366SChristoph Hellwig     }
233140b4f539SKevin Wolf }
233240b4f539SKevin Wolf 
233340b4f539SKevin Wolf /*
233440b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
233540b4f539SKevin Wolf  * requests that remain after merging.
233640b4f539SKevin Wolf  */
233740b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
233840b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
233940b4f539SKevin Wolf {
234040b4f539SKevin Wolf     int i, outidx;
234140b4f539SKevin Wolf 
234240b4f539SKevin Wolf     // Sort requests by start sector
234340b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
234440b4f539SKevin Wolf 
234540b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
234640b4f539SKevin Wolf     // filling up gaps with zero sectors.
234740b4f539SKevin Wolf     outidx = 0;
234840b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
234940b4f539SKevin Wolf         int merge = 0;
235040b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
235140b4f539SKevin Wolf 
235240b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
235340b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
235440b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
235540b4f539SKevin Wolf             merge = 1;
235640b4f539SKevin Wolf         }
235740b4f539SKevin Wolf 
235840b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
235940b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
236040b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
236140b4f539SKevin Wolf         // unused space in format like qcow2).
236240b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
236340b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
236440b4f539SKevin Wolf         }
236540b4f539SKevin Wolf 
2366e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2367e2a305fbSChristoph Hellwig             merge = 0;
2368e2a305fbSChristoph Hellwig         }
2369e2a305fbSChristoph Hellwig 
237040b4f539SKevin Wolf         if (merge) {
237140b4f539SKevin Wolf             size_t size;
23727267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
237340b4f539SKevin Wolf             qemu_iovec_init(qiov,
237440b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
237540b4f539SKevin Wolf 
237640b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
237740b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
237840b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
237940b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
238040b4f539SKevin Wolf 
238140b4f539SKevin Wolf             // We might need to add some zeros between the two requests
238240b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
238340b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
238440b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
238540b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
238640b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
238740b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
238840b4f539SKevin Wolf             }
238940b4f539SKevin Wolf 
239040b4f539SKevin Wolf             // Add the second request
239140b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
239240b4f539SKevin Wolf 
2393cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
239440b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
239540b4f539SKevin Wolf 
239640b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
239740b4f539SKevin Wolf         } else {
239840b4f539SKevin Wolf             outidx++;
239940b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
240040b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
240140b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
240240b4f539SKevin Wolf         }
240340b4f539SKevin Wolf     }
240440b4f539SKevin Wolf 
240540b4f539SKevin Wolf     return outidx + 1;
240640b4f539SKevin Wolf }
240740b4f539SKevin Wolf 
240840b4f539SKevin Wolf /*
240940b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
241040b4f539SKevin Wolf  *
241140b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
241240b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
241340b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
241440b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
241540b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
241640b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
241740b4f539SKevin Wolf  *
241840b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
241940b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
242040b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
242140b4f539SKevin Wolf  */
242240b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
242340b4f539SKevin Wolf {
242440b4f539SKevin Wolf     BlockDriverAIOCB *acb;
242540b4f539SKevin Wolf     MultiwriteCB *mcb;
242640b4f539SKevin Wolf     int i;
242740b4f539SKevin Wolf 
2428301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2429301db7c2SRyan Harper     if (bs->drv == NULL) {
2430301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2431301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2432301db7c2SRyan Harper         }
2433301db7c2SRyan Harper         return -1;
2434301db7c2SRyan Harper     }
2435301db7c2SRyan Harper 
243640b4f539SKevin Wolf     if (num_reqs == 0) {
243740b4f539SKevin Wolf         return 0;
243840b4f539SKevin Wolf     }
243940b4f539SKevin Wolf 
244040b4f539SKevin Wolf     // Create MultiwriteCB structure
24417267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
244240b4f539SKevin Wolf     mcb->num_requests = 0;
244340b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
244440b4f539SKevin Wolf 
244540b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
244640b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
244740b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
244840b4f539SKevin Wolf     }
244940b4f539SKevin Wolf 
245040b4f539SKevin Wolf     // Check for mergable requests
245140b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
245240b4f539SKevin Wolf 
24536d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
24546d519a5fSStefan Hajnoczi 
2455453f9a16SKevin Wolf     /*
2456453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2457453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2458453f9a16SKevin Wolf      * return failure for all requests anyway)
2459453f9a16SKevin Wolf      *
2460453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2461453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2462453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2463453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2464453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2465453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2466453f9a16SKevin Wolf      * incremented for each request that is submitted.
2467453f9a16SKevin Wolf      *
2468453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2469453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2470453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2471453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2472453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2473453f9a16SKevin Wolf      */
2474453f9a16SKevin Wolf     mcb->num_requests = 1;
2475453f9a16SKevin Wolf 
24766d519a5fSStefan Hajnoczi     // Run the aio requests
247740b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2478453f9a16SKevin Wolf         mcb->num_requests++;
247940b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
248040b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
248140b4f539SKevin Wolf 
248240b4f539SKevin Wolf         if (acb == NULL) {
248340b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
248440b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
248540b4f539SKevin Wolf             // complete and report the error in the callback.
2486453f9a16SKevin Wolf             if (i == 0) {
24876d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
248840b4f539SKevin Wolf                 goto fail;
248940b4f539SKevin Wolf             } else {
24906d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
24917eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
249240b4f539SKevin Wolf                 break;
249340b4f539SKevin Wolf             }
249440b4f539SKevin Wolf         }
249540b4f539SKevin Wolf     }
249640b4f539SKevin Wolf 
2497453f9a16SKevin Wolf     /* Complete the dummy request */
2498453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2499453f9a16SKevin Wolf 
250040b4f539SKevin Wolf     return 0;
250140b4f539SKevin Wolf 
250240b4f539SKevin Wolf fail:
2503453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2504453f9a16SKevin Wolf         reqs[i].error = -EIO;
2505453f9a16SKevin Wolf     }
25067267c094SAnthony Liguori     g_free(mcb);
250740b4f539SKevin Wolf     return -1;
250840b4f539SKevin Wolf }
250940b4f539SKevin Wolf 
251083f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
251183f64091Sbellard {
25126bbff9a0Saliguori     acb->pool->cancel(acb);
251383f64091Sbellard }
251483f64091Sbellard 
251583f64091Sbellard 
251683f64091Sbellard /**************************************************************/
251783f64091Sbellard /* async block device emulation */
251883f64091Sbellard 
2519c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2520c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2521c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2522c16b5a2cSChristoph Hellwig     int ret;
2523c16b5a2cSChristoph Hellwig     /* vector translation state */
2524c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2525c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2526c16b5a2cSChristoph Hellwig     int is_write;
2527c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2528c16b5a2cSChristoph Hellwig 
2529c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2530c16b5a2cSChristoph Hellwig {
2531b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2532b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
25336a7ad299SDor Laor     qemu_bh_delete(acb->bh);
253436afc451SAvi Kivity     acb->bh = NULL;
2535c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2536c16b5a2cSChristoph Hellwig }
2537c16b5a2cSChristoph Hellwig 
2538c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2539c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2540c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2541c16b5a2cSChristoph Hellwig };
2542c16b5a2cSChristoph Hellwig 
254383f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2544beac80cdSbellard {
2545ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2546f141eafeSaliguori 
2547f141eafeSaliguori     if (!acb->is_write)
2548f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2549ceb42de8Saliguori     qemu_vfree(acb->bounce);
2550ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
25516a7ad299SDor Laor     qemu_bh_delete(acb->bh);
255236afc451SAvi Kivity     acb->bh = NULL;
2553ce1a14dcSpbrook     qemu_aio_release(acb);
2554beac80cdSbellard }
2555beac80cdSbellard 
2556f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2557f141eafeSaliguori                                             int64_t sector_num,
2558f141eafeSaliguori                                             QEMUIOVector *qiov,
2559f141eafeSaliguori                                             int nb_sectors,
2560f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2561f141eafeSaliguori                                             void *opaque,
2562f141eafeSaliguori                                             int is_write)
2563f141eafeSaliguori 
2564ea2384d3Sbellard {
2565ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
256683f64091Sbellard 
2567c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2568f141eafeSaliguori     acb->is_write = is_write;
2569f141eafeSaliguori     acb->qiov = qiov;
2570e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2571f141eafeSaliguori 
2572ce1a14dcSpbrook     if (!acb->bh)
2573ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2574f141eafeSaliguori 
2575f141eafeSaliguori     if (is_write) {
2576f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
25771ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2578f141eafeSaliguori     } else {
25791ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2580f141eafeSaliguori     }
2581f141eafeSaliguori 
2582ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2583f141eafeSaliguori 
2584ce1a14dcSpbrook     return &acb->common;
25857a6cba61Spbrook }
25867a6cba61Spbrook 
2587f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2588f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2589ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
259083f64091Sbellard {
2591f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
259283f64091Sbellard }
259383f64091Sbellard 
2594f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2595f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2596f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2597f141eafeSaliguori {
2598f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2599f141eafeSaliguori }
2600f141eafeSaliguori 
260168485420SKevin Wolf 
260268485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
260368485420SKevin Wolf     BlockDriverAIOCB common;
260468485420SKevin Wolf     BlockRequest req;
260568485420SKevin Wolf     bool is_write;
260668485420SKevin Wolf     QEMUBH* bh;
260768485420SKevin Wolf } BlockDriverAIOCBCoroutine;
260868485420SKevin Wolf 
260968485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
261068485420SKevin Wolf {
261168485420SKevin Wolf     qemu_aio_flush();
261268485420SKevin Wolf }
261368485420SKevin Wolf 
261468485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
261568485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
261668485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
261768485420SKevin Wolf };
261868485420SKevin Wolf 
261935246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque)
262068485420SKevin Wolf {
262168485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
262268485420SKevin Wolf 
262368485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
262468485420SKevin Wolf     qemu_bh_delete(acb->bh);
262568485420SKevin Wolf     qemu_aio_release(acb);
262668485420SKevin Wolf }
262768485420SKevin Wolf 
2628b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2629b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2630b2a61371SStefan Hajnoczi {
2631b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2632b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2633b2a61371SStefan Hajnoczi 
2634b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2635b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2636b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2637b2a61371SStefan Hajnoczi     } else {
2638b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2639b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2640b2a61371SStefan Hajnoczi     }
2641b2a61371SStefan Hajnoczi 
264235246a68SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2643b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2644b2a61371SStefan Hajnoczi }
2645b2a61371SStefan Hajnoczi 
264668485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
264768485420SKevin Wolf                                                int64_t sector_num,
264868485420SKevin Wolf                                                QEMUIOVector *qiov,
264968485420SKevin Wolf                                                int nb_sectors,
265068485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
265168485420SKevin Wolf                                                void *opaque,
26528c5873d6SStefan Hajnoczi                                                bool is_write)
265368485420SKevin Wolf {
265468485420SKevin Wolf     Coroutine *co;
265568485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
265668485420SKevin Wolf 
265768485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
265868485420SKevin Wolf     acb->req.sector = sector_num;
265968485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
266068485420SKevin Wolf     acb->req.qiov = qiov;
266168485420SKevin Wolf     acb->is_write = is_write;
266268485420SKevin Wolf 
26638c5873d6SStefan Hajnoczi     co = qemu_coroutine_create(bdrv_co_do_rw);
266468485420SKevin Wolf     qemu_coroutine_enter(co, acb);
266568485420SKevin Wolf 
266668485420SKevin Wolf     return &acb->common;
266768485420SKevin Wolf }
266868485420SKevin Wolf 
266907f07615SPaolo Bonzini static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
2670b2e12bc6SChristoph Hellwig {
267107f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
267207f07615SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
2673b2e12bc6SChristoph Hellwig 
267407f07615SPaolo Bonzini     acb->req.error = bdrv_co_flush(bs);
267507f07615SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2676b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2677b2e12bc6SChristoph Hellwig }
2678b2e12bc6SChristoph Hellwig 
267907f07615SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2680016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2681016f5cf6SAlexander Graf {
268207f07615SPaolo Bonzini     trace_bdrv_aio_flush(bs, opaque);
2683016f5cf6SAlexander Graf 
268407f07615SPaolo Bonzini     Coroutine *co;
268507f07615SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
2686016f5cf6SAlexander Graf 
268707f07615SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
268807f07615SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
268907f07615SPaolo Bonzini     qemu_coroutine_enter(co, acb);
2690016f5cf6SAlexander Graf 
2691016f5cf6SAlexander Graf     return &acb->common;
2692016f5cf6SAlexander Graf }
2693016f5cf6SAlexander Graf 
26944265d620SPaolo Bonzini static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
26954265d620SPaolo Bonzini {
26964265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb = opaque;
26974265d620SPaolo Bonzini     BlockDriverState *bs = acb->common.bs;
26984265d620SPaolo Bonzini 
26994265d620SPaolo Bonzini     acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
27004265d620SPaolo Bonzini     acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
27014265d620SPaolo Bonzini     qemu_bh_schedule(acb->bh);
27024265d620SPaolo Bonzini }
27034265d620SPaolo Bonzini 
27044265d620SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
27054265d620SPaolo Bonzini         int64_t sector_num, int nb_sectors,
27064265d620SPaolo Bonzini         BlockDriverCompletionFunc *cb, void *opaque)
27074265d620SPaolo Bonzini {
27084265d620SPaolo Bonzini     Coroutine *co;
27094265d620SPaolo Bonzini     BlockDriverAIOCBCoroutine *acb;
27104265d620SPaolo Bonzini 
27114265d620SPaolo Bonzini     trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
27124265d620SPaolo Bonzini 
27134265d620SPaolo Bonzini     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
27144265d620SPaolo Bonzini     acb->req.sector = sector_num;
27154265d620SPaolo Bonzini     acb->req.nb_sectors = nb_sectors;
27164265d620SPaolo Bonzini     co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
27174265d620SPaolo Bonzini     qemu_coroutine_enter(co, acb);
27184265d620SPaolo Bonzini 
27194265d620SPaolo Bonzini     return &acb->common;
27204265d620SPaolo Bonzini }
27214265d620SPaolo Bonzini 
2722ea2384d3Sbellard void bdrv_init(void)
2723ea2384d3Sbellard {
27245efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
2725ea2384d3Sbellard }
2726ce1a14dcSpbrook 
2727eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
2728eb852011SMarkus Armbruster {
2729eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
2730eb852011SMarkus Armbruster     bdrv_init();
2731eb852011SMarkus Armbruster }
2732eb852011SMarkus Armbruster 
2733c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
27346bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
27356bbff9a0Saliguori {
2736ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2737ce1a14dcSpbrook 
27386bbff9a0Saliguori     if (pool->free_aiocb) {
27396bbff9a0Saliguori         acb = pool->free_aiocb;
27406bbff9a0Saliguori         pool->free_aiocb = acb->next;
2741ce1a14dcSpbrook     } else {
27427267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
27436bbff9a0Saliguori         acb->pool = pool;
2744ce1a14dcSpbrook     }
2745ce1a14dcSpbrook     acb->bs = bs;
2746ce1a14dcSpbrook     acb->cb = cb;
2747ce1a14dcSpbrook     acb->opaque = opaque;
2748ce1a14dcSpbrook     return acb;
2749ce1a14dcSpbrook }
2750ce1a14dcSpbrook 
2751ce1a14dcSpbrook void qemu_aio_release(void *p)
2752ce1a14dcSpbrook {
27536bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
27546bbff9a0Saliguori     AIOPool *pool = acb->pool;
27556bbff9a0Saliguori     acb->next = pool->free_aiocb;
27566bbff9a0Saliguori     pool->free_aiocb = acb;
2757ce1a14dcSpbrook }
275819cb3738Sbellard 
275919cb3738Sbellard /**************************************************************/
2760f9f05dc5SKevin Wolf /* Coroutine block device emulation */
2761f9f05dc5SKevin Wolf 
2762f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
2763f9f05dc5SKevin Wolf     Coroutine *coroutine;
2764f9f05dc5SKevin Wolf     int ret;
2765f9f05dc5SKevin Wolf } CoroutineIOCompletion;
2766f9f05dc5SKevin Wolf 
2767f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
2768f9f05dc5SKevin Wolf {
2769f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
2770f9f05dc5SKevin Wolf 
2771f9f05dc5SKevin Wolf     co->ret = ret;
2772f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
2773f9f05dc5SKevin Wolf }
2774f9f05dc5SKevin Wolf 
2775f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
2776f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
2777f9f05dc5SKevin Wolf                                       bool is_write)
2778f9f05dc5SKevin Wolf {
2779f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
2780f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
2781f9f05dc5SKevin Wolf     };
2782f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
2783f9f05dc5SKevin Wolf 
2784f9f05dc5SKevin Wolf     if (is_write) {
2785a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
2786f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
2787f9f05dc5SKevin Wolf     } else {
2788a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
2789f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
2790f9f05dc5SKevin Wolf     }
2791f9f05dc5SKevin Wolf 
279259370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
2793f9f05dc5SKevin Wolf     if (!acb) {
2794f9f05dc5SKevin Wolf         return -EIO;
2795f9f05dc5SKevin Wolf     }
2796f9f05dc5SKevin Wolf     qemu_coroutine_yield();
2797f9f05dc5SKevin Wolf 
2798f9f05dc5SKevin Wolf     return co.ret;
2799f9f05dc5SKevin Wolf }
2800f9f05dc5SKevin Wolf 
2801f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
2802f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2803f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2804f9f05dc5SKevin Wolf {
2805f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
2806f9f05dc5SKevin Wolf }
2807f9f05dc5SKevin Wolf 
2808f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
2809f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
2810f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
2811f9f05dc5SKevin Wolf {
2812f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
2813f9f05dc5SKevin Wolf }
2814f9f05dc5SKevin Wolf 
281507f07615SPaolo Bonzini static void coroutine_fn bdrv_flush_co_entry(void *opaque)
2816e7a8a783SKevin Wolf {
281707f07615SPaolo Bonzini     RwCo *rwco = opaque;
281807f07615SPaolo Bonzini 
281907f07615SPaolo Bonzini     rwco->ret = bdrv_co_flush(rwco->bs);
282007f07615SPaolo Bonzini }
282107f07615SPaolo Bonzini 
282207f07615SPaolo Bonzini int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
282307f07615SPaolo Bonzini {
282407f07615SPaolo Bonzini     if (bs->open_flags & BDRV_O_NO_FLUSH) {
282507f07615SPaolo Bonzini         return 0;
282607f07615SPaolo Bonzini     } else if (!bs->drv) {
282707f07615SPaolo Bonzini         return 0;
282807f07615SPaolo Bonzini     } else if (bs->drv->bdrv_co_flush) {
282907f07615SPaolo Bonzini         return bs->drv->bdrv_co_flush(bs);
283007f07615SPaolo Bonzini     } else if (bs->drv->bdrv_aio_flush) {
283107f07615SPaolo Bonzini         BlockDriverAIOCB *acb;
2832e7a8a783SKevin Wolf         CoroutineIOCompletion co = {
2833e7a8a783SKevin Wolf             .coroutine = qemu_coroutine_self(),
2834e7a8a783SKevin Wolf         };
2835e7a8a783SKevin Wolf 
283607f07615SPaolo Bonzini         acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
283707f07615SPaolo Bonzini         if (acb == NULL) {
2838e7a8a783SKevin Wolf             return -EIO;
283907f07615SPaolo Bonzini         } else {
2840e7a8a783SKevin Wolf             qemu_coroutine_yield();
2841e7a8a783SKevin Wolf             return co.ret;
2842e7a8a783SKevin Wolf         }
284307f07615SPaolo Bonzini     } else {
284407f07615SPaolo Bonzini         /*
284507f07615SPaolo Bonzini          * Some block drivers always operate in either writethrough or unsafe
284607f07615SPaolo Bonzini          * mode and don't support bdrv_flush therefore. Usually qemu doesn't
284707f07615SPaolo Bonzini          * know how the server works (because the behaviour is hardcoded or
284807f07615SPaolo Bonzini          * depends on server-side configuration), so we can't ensure that
284907f07615SPaolo Bonzini          * everything is safe on disk. Returning an error doesn't work because
285007f07615SPaolo Bonzini          * that would break guests even if the server operates in writethrough
285107f07615SPaolo Bonzini          * mode.
285207f07615SPaolo Bonzini          *
285307f07615SPaolo Bonzini          * Let's hope the user knows what he's doing.
285407f07615SPaolo Bonzini          */
285507f07615SPaolo Bonzini         return 0;
285607f07615SPaolo Bonzini     }
285707f07615SPaolo Bonzini }
285807f07615SPaolo Bonzini 
285907f07615SPaolo Bonzini int bdrv_flush(BlockDriverState *bs)
286007f07615SPaolo Bonzini {
286107f07615SPaolo Bonzini     Coroutine *co;
286207f07615SPaolo Bonzini     RwCo rwco = {
286307f07615SPaolo Bonzini         .bs = bs,
286407f07615SPaolo Bonzini         .ret = NOT_DONE,
286507f07615SPaolo Bonzini     };
286607f07615SPaolo Bonzini 
286707f07615SPaolo Bonzini     if (qemu_in_coroutine()) {
286807f07615SPaolo Bonzini         /* Fast-path if already in coroutine context */
286907f07615SPaolo Bonzini         bdrv_flush_co_entry(&rwco);
287007f07615SPaolo Bonzini     } else {
287107f07615SPaolo Bonzini         co = qemu_coroutine_create(bdrv_flush_co_entry);
287207f07615SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
287307f07615SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
287407f07615SPaolo Bonzini             qemu_aio_wait();
287507f07615SPaolo Bonzini         }
287607f07615SPaolo Bonzini     }
287707f07615SPaolo Bonzini 
287807f07615SPaolo Bonzini     return rwco.ret;
287907f07615SPaolo Bonzini }
2880e7a8a783SKevin Wolf 
28814265d620SPaolo Bonzini static void coroutine_fn bdrv_discard_co_entry(void *opaque)
28824265d620SPaolo Bonzini {
28834265d620SPaolo Bonzini     RwCo *rwco = opaque;
28844265d620SPaolo Bonzini 
28854265d620SPaolo Bonzini     rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
28864265d620SPaolo Bonzini }
28874265d620SPaolo Bonzini 
28884265d620SPaolo Bonzini int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
28894265d620SPaolo Bonzini                                  int nb_sectors)
28904265d620SPaolo Bonzini {
28914265d620SPaolo Bonzini     if (!bs->drv) {
28924265d620SPaolo Bonzini         return -ENOMEDIUM;
28934265d620SPaolo Bonzini     } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
28944265d620SPaolo Bonzini         return -EIO;
28954265d620SPaolo Bonzini     } else if (bs->read_only) {
28964265d620SPaolo Bonzini         return -EROFS;
28974265d620SPaolo Bonzini     } else if (bs->drv->bdrv_co_discard) {
28984265d620SPaolo Bonzini         return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
28994265d620SPaolo Bonzini     } else if (bs->drv->bdrv_aio_discard) {
29004265d620SPaolo Bonzini         BlockDriverAIOCB *acb;
29014265d620SPaolo Bonzini         CoroutineIOCompletion co = {
29024265d620SPaolo Bonzini             .coroutine = qemu_coroutine_self(),
29034265d620SPaolo Bonzini         };
29044265d620SPaolo Bonzini 
29054265d620SPaolo Bonzini         acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
29064265d620SPaolo Bonzini                                         bdrv_co_io_em_complete, &co);
29074265d620SPaolo Bonzini         if (acb == NULL) {
29084265d620SPaolo Bonzini             return -EIO;
29094265d620SPaolo Bonzini         } else {
29104265d620SPaolo Bonzini             qemu_coroutine_yield();
29114265d620SPaolo Bonzini             return co.ret;
29124265d620SPaolo Bonzini         }
29134265d620SPaolo Bonzini     } else {
29144265d620SPaolo Bonzini         return 0;
29154265d620SPaolo Bonzini     }
29164265d620SPaolo Bonzini }
29174265d620SPaolo Bonzini 
29184265d620SPaolo Bonzini int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
29194265d620SPaolo Bonzini {
29204265d620SPaolo Bonzini     Coroutine *co;
29214265d620SPaolo Bonzini     RwCo rwco = {
29224265d620SPaolo Bonzini         .bs = bs,
29234265d620SPaolo Bonzini         .sector_num = sector_num,
29244265d620SPaolo Bonzini         .nb_sectors = nb_sectors,
29254265d620SPaolo Bonzini         .ret = NOT_DONE,
29264265d620SPaolo Bonzini     };
29274265d620SPaolo Bonzini 
29284265d620SPaolo Bonzini     if (qemu_in_coroutine()) {
29294265d620SPaolo Bonzini         /* Fast-path if already in coroutine context */
29304265d620SPaolo Bonzini         bdrv_discard_co_entry(&rwco);
29314265d620SPaolo Bonzini     } else {
29324265d620SPaolo Bonzini         co = qemu_coroutine_create(bdrv_discard_co_entry);
29334265d620SPaolo Bonzini         qemu_coroutine_enter(co, &rwco);
29344265d620SPaolo Bonzini         while (rwco.ret == NOT_DONE) {
29354265d620SPaolo Bonzini             qemu_aio_wait();
29364265d620SPaolo Bonzini         }
29374265d620SPaolo Bonzini     }
29384265d620SPaolo Bonzini 
29394265d620SPaolo Bonzini     return rwco.ret;
29404265d620SPaolo Bonzini }
29414265d620SPaolo Bonzini 
2942f9f05dc5SKevin Wolf /**************************************************************/
294319cb3738Sbellard /* removable device support */
294419cb3738Sbellard 
294519cb3738Sbellard /**
294619cb3738Sbellard  * Return TRUE if the media is present
294719cb3738Sbellard  */
294819cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
294919cb3738Sbellard {
295019cb3738Sbellard     BlockDriver *drv = bs->drv;
2951a1aff5bfSMarkus Armbruster 
295219cb3738Sbellard     if (!drv)
295319cb3738Sbellard         return 0;
295419cb3738Sbellard     if (!drv->bdrv_is_inserted)
2955a1aff5bfSMarkus Armbruster         return 1;
2956a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
295719cb3738Sbellard }
295819cb3738Sbellard 
295919cb3738Sbellard /**
29608e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
29618e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
296219cb3738Sbellard  */
296319cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
296419cb3738Sbellard {
296519cb3738Sbellard     BlockDriver *drv = bs->drv;
296619cb3738Sbellard 
29678e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
29688e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
29698e49ca46SMarkus Armbruster     }
29708e49ca46SMarkus Armbruster     return -ENOTSUP;
297119cb3738Sbellard }
297219cb3738Sbellard 
297319cb3738Sbellard /**
297419cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
297519cb3738Sbellard  */
2976fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
297719cb3738Sbellard {
297819cb3738Sbellard     BlockDriver *drv = bs->drv;
297919cb3738Sbellard 
2980822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
2981822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
298219cb3738Sbellard     }
298319cb3738Sbellard }
298419cb3738Sbellard 
298519cb3738Sbellard /**
298619cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
298719cb3738Sbellard  * to eject it manually).
298819cb3738Sbellard  */
2989025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
299019cb3738Sbellard {
299119cb3738Sbellard     BlockDriver *drv = bs->drv;
299219cb3738Sbellard 
2993025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
2994b8c6d095SStefan Hajnoczi 
2995025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
2996025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
299719cb3738Sbellard     }
299819cb3738Sbellard }
2999985a03b0Sths 
3000985a03b0Sths /* needed for generic scsi interface */
3001985a03b0Sths 
3002985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3003985a03b0Sths {
3004985a03b0Sths     BlockDriver *drv = bs->drv;
3005985a03b0Sths 
3006985a03b0Sths     if (drv && drv->bdrv_ioctl)
3007985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3008985a03b0Sths     return -ENOTSUP;
3009985a03b0Sths }
30107d780669Saliguori 
3011221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3012221f715dSaliguori         unsigned long int req, void *buf,
30137d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
30147d780669Saliguori {
3015221f715dSaliguori     BlockDriver *drv = bs->drv;
30167d780669Saliguori 
3017221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3018221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3019221f715dSaliguori     return NULL;
30207d780669Saliguori }
3021e268ca52Saliguori 
30227b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
30237b6f9300SMarkus Armbruster {
30247b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
30257b6f9300SMarkus Armbruster }
30267cd1e32aSlirans@il.ibm.com 
3027e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3028e268ca52Saliguori {
3029e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3030e268ca52Saliguori }
30317cd1e32aSlirans@il.ibm.com 
30327cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
30337cd1e32aSlirans@il.ibm.com {
30347cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3035a55eb92cSJan Kiszka 
3036aaa0eb75SLiran Schour     bs->dirty_count = 0;
30377cd1e32aSlirans@il.ibm.com     if (enable) {
3038c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3039c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3040c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3041c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
30427cd1e32aSlirans@il.ibm.com 
30437267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
30447cd1e32aSlirans@il.ibm.com         }
30457cd1e32aSlirans@il.ibm.com     } else {
3046c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
30477267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3048c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
30497cd1e32aSlirans@il.ibm.com         }
30507cd1e32aSlirans@il.ibm.com     }
30517cd1e32aSlirans@il.ibm.com }
30527cd1e32aSlirans@il.ibm.com 
30537cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
30547cd1e32aSlirans@il.ibm.com {
30556ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
30567cd1e32aSlirans@il.ibm.com 
3057c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3058c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
30596d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
30606d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
30617cd1e32aSlirans@il.ibm.com     } else {
30627cd1e32aSlirans@il.ibm.com         return 0;
30637cd1e32aSlirans@il.ibm.com     }
30647cd1e32aSlirans@il.ibm.com }
30657cd1e32aSlirans@il.ibm.com 
30667cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
30677cd1e32aSlirans@il.ibm.com                       int nr_sectors)
30687cd1e32aSlirans@il.ibm.com {
30697cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
30707cd1e32aSlirans@il.ibm.com }
3071aaa0eb75SLiran Schour 
3072aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3073aaa0eb75SLiran Schour {
3074aaa0eb75SLiran Schour     return bs->dirty_count;
3075aaa0eb75SLiran Schour }
3076f88e1a42SJes Sorensen 
3077db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3078db593f25SMarcelo Tosatti {
3079db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3080db593f25SMarcelo Tosatti     bs->in_use = in_use;
3081db593f25SMarcelo Tosatti }
3082db593f25SMarcelo Tosatti 
3083db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3084db593f25SMarcelo Tosatti {
3085db593f25SMarcelo Tosatti     return bs->in_use;
3086db593f25SMarcelo Tosatti }
3087db593f25SMarcelo Tosatti 
308828a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
308928a7282aSLuiz Capitulino {
3090d6bf279eSLuiz Capitulino     bs->iostatus_enabled = true;
309158e21ef5SLuiz Capitulino     bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
309228a7282aSLuiz Capitulino }
309328a7282aSLuiz Capitulino 
309428a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
309528a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
309628a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
309728a7282aSLuiz Capitulino {
3098d6bf279eSLuiz Capitulino     return (bs->iostatus_enabled &&
309928a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
310028a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
310128a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
310228a7282aSLuiz Capitulino }
310328a7282aSLuiz Capitulino 
310428a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
310528a7282aSLuiz Capitulino {
3106d6bf279eSLuiz Capitulino     bs->iostatus_enabled = false;
310728a7282aSLuiz Capitulino }
310828a7282aSLuiz Capitulino 
310928a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
311028a7282aSLuiz Capitulino {
311128a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
311258e21ef5SLuiz Capitulino         bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
311328a7282aSLuiz Capitulino     }
311428a7282aSLuiz Capitulino }
311528a7282aSLuiz Capitulino 
311628a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
311728a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
311828a7282aSLuiz Capitulino    possible to implement this without device models being involved */
311928a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
312028a7282aSLuiz Capitulino {
312158e21ef5SLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) &&
312258e21ef5SLuiz Capitulino         bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
312328a7282aSLuiz Capitulino         assert(error >= 0);
312458e21ef5SLuiz Capitulino         bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
312558e21ef5SLuiz Capitulino                                          BLOCK_DEVICE_IO_STATUS_FAILED;
312628a7282aSLuiz Capitulino     }
312728a7282aSLuiz Capitulino }
312828a7282aSLuiz Capitulino 
3129a597e79cSChristoph Hellwig void
3130a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3131a597e79cSChristoph Hellwig         enum BlockAcctType type)
3132a597e79cSChristoph Hellwig {
3133a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3134a597e79cSChristoph Hellwig 
3135a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3136c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3137a597e79cSChristoph Hellwig     cookie->type = type;
3138a597e79cSChristoph Hellwig }
3139a597e79cSChristoph Hellwig 
3140a597e79cSChristoph Hellwig void
3141a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3142a597e79cSChristoph Hellwig {
3143a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3144a597e79cSChristoph Hellwig 
3145a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3146a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3147c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3148a597e79cSChristoph Hellwig }
3149a597e79cSChristoph Hellwig 
3150f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3151f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3152f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3153f88e1a42SJes Sorensen {
3154f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3155d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3156f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3157f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
315896df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3159f88e1a42SJes Sorensen     int ret = 0;
3160f88e1a42SJes Sorensen 
3161f88e1a42SJes Sorensen     /* Find driver and parse its options */
3162f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3163f88e1a42SJes Sorensen     if (!drv) {
3164f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
31654f70f249SJes Sorensen         ret = -EINVAL;
3166f88e1a42SJes Sorensen         goto out;
3167f88e1a42SJes Sorensen     }
3168f88e1a42SJes Sorensen 
3169f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3170f88e1a42SJes Sorensen     if (!proto_drv) {
3171f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
31724f70f249SJes Sorensen         ret = -EINVAL;
3173f88e1a42SJes Sorensen         goto out;
3174f88e1a42SJes Sorensen     }
3175f88e1a42SJes Sorensen 
3176f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3177f88e1a42SJes Sorensen                                               drv->create_options);
3178f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3179f88e1a42SJes Sorensen                                               proto_drv->create_options);
3180f88e1a42SJes Sorensen 
3181f88e1a42SJes Sorensen     /* Create parameter list with default values */
3182f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3183f88e1a42SJes Sorensen 
3184f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3185f88e1a42SJes Sorensen 
3186f88e1a42SJes Sorensen     /* Parse -o options */
3187f88e1a42SJes Sorensen     if (options) {
3188f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3189f88e1a42SJes Sorensen         if (param == NULL) {
3190f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
31914f70f249SJes Sorensen             ret = -EINVAL;
3192f88e1a42SJes Sorensen             goto out;
3193f88e1a42SJes Sorensen         }
3194f88e1a42SJes Sorensen     }
3195f88e1a42SJes Sorensen 
3196f88e1a42SJes Sorensen     if (base_filename) {
3197f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3198f88e1a42SJes Sorensen                                  base_filename)) {
3199f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3200f88e1a42SJes Sorensen                          fmt);
32014f70f249SJes Sorensen             ret = -EINVAL;
3202f88e1a42SJes Sorensen             goto out;
3203f88e1a42SJes Sorensen         }
3204f88e1a42SJes Sorensen     }
3205f88e1a42SJes Sorensen 
3206f88e1a42SJes Sorensen     if (base_fmt) {
3207f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3208f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3209f88e1a42SJes Sorensen                          "format '%s'", fmt);
32104f70f249SJes Sorensen             ret = -EINVAL;
3211f88e1a42SJes Sorensen             goto out;
3212f88e1a42SJes Sorensen         }
3213f88e1a42SJes Sorensen     }
3214f88e1a42SJes Sorensen 
3215792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3216792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3217792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3218792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3219792da93aSJes Sorensen                          "same filename as the backing file");
32204f70f249SJes Sorensen             ret = -EINVAL;
3221792da93aSJes Sorensen             goto out;
3222792da93aSJes Sorensen         }
3223792da93aSJes Sorensen     }
3224792da93aSJes Sorensen 
3225f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3226f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
322796df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
322896df67d1SStefan Hajnoczi         if (!backing_drv) {
3229f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3230f88e1a42SJes Sorensen                          backing_fmt->value.s);
32314f70f249SJes Sorensen             ret = -EINVAL;
3232f88e1a42SJes Sorensen             goto out;
3233f88e1a42SJes Sorensen         }
3234f88e1a42SJes Sorensen     }
3235f88e1a42SJes Sorensen 
3236f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3237f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3238d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3239d220894eSKevin Wolf     if (size && size->value.n == -1) {
3240f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3241f88e1a42SJes Sorensen             uint64_t size;
3242f88e1a42SJes Sorensen             char buf[32];
3243f88e1a42SJes Sorensen 
3244f88e1a42SJes Sorensen             bs = bdrv_new("");
3245f88e1a42SJes Sorensen 
324696df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3247f88e1a42SJes Sorensen             if (ret < 0) {
324896df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3249f88e1a42SJes Sorensen                 goto out;
3250f88e1a42SJes Sorensen             }
3251f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3252f88e1a42SJes Sorensen             size *= 512;
3253f88e1a42SJes Sorensen 
3254f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3255f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3256f88e1a42SJes Sorensen         } else {
3257f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
32584f70f249SJes Sorensen             ret = -EINVAL;
3259f88e1a42SJes Sorensen             goto out;
3260f88e1a42SJes Sorensen         }
3261f88e1a42SJes Sorensen     }
3262f88e1a42SJes Sorensen 
3263f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3264f88e1a42SJes Sorensen     print_option_parameters(param);
3265f88e1a42SJes Sorensen     puts("");
3266f88e1a42SJes Sorensen 
3267f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3268f88e1a42SJes Sorensen 
3269f88e1a42SJes Sorensen     if (ret < 0) {
3270f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3271f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3272f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3273f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3274f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3275f88e1a42SJes Sorensen                          fmt);
3276f88e1a42SJes Sorensen         } else {
3277f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3278f88e1a42SJes Sorensen                          strerror(-ret));
3279f88e1a42SJes Sorensen         }
3280f88e1a42SJes Sorensen     }
3281f88e1a42SJes Sorensen 
3282f88e1a42SJes Sorensen out:
3283f88e1a42SJes Sorensen     free_option_parameters(create_options);
3284f88e1a42SJes Sorensen     free_option_parameters(param);
3285f88e1a42SJes Sorensen 
3286f88e1a42SJes Sorensen     if (bs) {
3287f88e1a42SJes Sorensen         bdrv_delete(bs);
3288f88e1a42SJes Sorensen     }
32894f70f249SJes Sorensen 
32904f70f249SJes Sorensen     return ret;
3291f88e1a42SJes Sorensen }
3292