xref: /openbmc/qemu/block.c (revision b2a6137166c765f3a35265e6457cd7c2de9d992c)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
243990d09aSblueswir1 #include "config-host.h"
25faf07963Spbrook #include "qemu-common.h"
266d519a5fSStefan Hajnoczi #include "trace.h"
27376253ecSaliguori #include "monitor.h"
28ea2384d3Sbellard #include "block_int.h"
295efa9d5aSAnthony Liguori #include "module.h"
30d15e5465SLuiz Capitulino #include "qemu-objects.h"
3168485420SKevin Wolf #include "qemu-coroutine.h"
32fc01f7e7Sbellard 
3371e72a19SJuan Quintela #ifdef CONFIG_BSD
347674e7bfSbellard #include <sys/types.h>
357674e7bfSbellard #include <sys/stat.h>
367674e7bfSbellard #include <sys/ioctl.h>
3772cf2d4fSBlue Swirl #include <sys/queue.h>
38c5e97233Sblueswir1 #ifndef __DragonFly__
397674e7bfSbellard #include <sys/disk.h>
407674e7bfSbellard #endif
41c5e97233Sblueswir1 #endif
427674e7bfSbellard 
4349dc768dSaliguori #ifdef _WIN32
4449dc768dSaliguori #include <windows.h>
4549dc768dSaliguori #endif
4649dc768dSaliguori 
471c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
481c9805a3SStefan Hajnoczi 
497d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
50f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
51f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
52c87c0672Saliguori         BlockDriverCompletionFunc *cb, void *opaque);
53f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
54f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
55ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque);
56b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
57b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque);
58016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
59016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque);
6083f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
6183f64091Sbellard                         uint8_t *buf, int nb_sectors);
6283f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
6383f64091Sbellard                          const uint8_t *buf, int nb_sectors);
6468485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
6568485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
6668485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque);
6768485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
6868485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
6968485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque);
70f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
71f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
72f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
73f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
74f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
75f9f05dc5SKevin Wolf                                          QEMUIOVector *iov);
76e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
77c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
78c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
791c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
801c9805a3SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
81*b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
82*b2a61371SStefan Hajnoczi                                                int64_t sector_num,
83*b2a61371SStefan Hajnoczi                                                QEMUIOVector *qiov,
84*b2a61371SStefan Hajnoczi                                                int nb_sectors,
85*b2a61371SStefan Hajnoczi                                                BlockDriverCompletionFunc *cb,
86*b2a61371SStefan Hajnoczi                                                void *opaque,
87*b2a61371SStefan Hajnoczi                                                bool is_write,
88*b2a61371SStefan Hajnoczi                                                CoroutineEntry *entry);
89*b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque);
90ec530c81Sbellard 
911b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
921b7bdbc1SStefan Hajnoczi     QTAILQ_HEAD_INITIALIZER(bdrv_states);
937ee930d0Sblueswir1 
948a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers =
958a22f02aSStefan Hajnoczi     QLIST_HEAD_INITIALIZER(bdrv_drivers);
96ea2384d3Sbellard 
97f9092b10SMarkus Armbruster /* The device to use for VM snapshots */
98f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots;
99f9092b10SMarkus Armbruster 
100eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */
101eb852011SMarkus Armbruster static int use_bdrv_whitelist;
102eb852011SMarkus Armbruster 
1039e0b22f4SStefan Hajnoczi #ifdef _WIN32
1049e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename)
1059e0b22f4SStefan Hajnoczi {
1069e0b22f4SStefan Hajnoczi     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
1079e0b22f4SStefan Hajnoczi              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
1089e0b22f4SStefan Hajnoczi             filename[1] == ':');
1099e0b22f4SStefan Hajnoczi }
1109e0b22f4SStefan Hajnoczi 
1119e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename)
1129e0b22f4SStefan Hajnoczi {
1139e0b22f4SStefan Hajnoczi     if (is_windows_drive_prefix(filename) &&
1149e0b22f4SStefan Hajnoczi         filename[2] == '\0')
1159e0b22f4SStefan Hajnoczi         return 1;
1169e0b22f4SStefan Hajnoczi     if (strstart(filename, "\\\\.\\", NULL) ||
1179e0b22f4SStefan Hajnoczi         strstart(filename, "//./", NULL))
1189e0b22f4SStefan Hajnoczi         return 1;
1199e0b22f4SStefan Hajnoczi     return 0;
1209e0b22f4SStefan Hajnoczi }
1219e0b22f4SStefan Hajnoczi #endif
1229e0b22f4SStefan Hajnoczi 
1239e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */
1249e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path)
1259e0b22f4SStefan Hajnoczi {
1269e0b22f4SStefan Hajnoczi #ifdef _WIN32
1279e0b22f4SStefan Hajnoczi     if (is_windows_drive(path) ||
1289e0b22f4SStefan Hajnoczi         is_windows_drive_prefix(path)) {
1299e0b22f4SStefan Hajnoczi         return 0;
1309e0b22f4SStefan Hajnoczi     }
1319e0b22f4SStefan Hajnoczi #endif
1329e0b22f4SStefan Hajnoczi 
1339e0b22f4SStefan Hajnoczi     return strchr(path, ':') != NULL;
1349e0b22f4SStefan Hajnoczi }
1359e0b22f4SStefan Hajnoczi 
13683f64091Sbellard int path_is_absolute(const char *path)
13783f64091Sbellard {
13883f64091Sbellard     const char *p;
13921664424Sbellard #ifdef _WIN32
14021664424Sbellard     /* specific case for names like: "\\.\d:" */
14121664424Sbellard     if (*path == '/' || *path == '\\')
14221664424Sbellard         return 1;
14321664424Sbellard #endif
14483f64091Sbellard     p = strchr(path, ':');
14583f64091Sbellard     if (p)
14683f64091Sbellard         p++;
14783f64091Sbellard     else
14883f64091Sbellard         p = path;
1493b9f94e1Sbellard #ifdef _WIN32
1503b9f94e1Sbellard     return (*p == '/' || *p == '\\');
1513b9f94e1Sbellard #else
1523b9f94e1Sbellard     return (*p == '/');
1533b9f94e1Sbellard #endif
15483f64091Sbellard }
15583f64091Sbellard 
15683f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a
15783f64091Sbellard    path to it by considering it is relative to base_path. URL are
15883f64091Sbellard    supported. */
15983f64091Sbellard void path_combine(char *dest, int dest_size,
16083f64091Sbellard                   const char *base_path,
16183f64091Sbellard                   const char *filename)
16283f64091Sbellard {
16383f64091Sbellard     const char *p, *p1;
16483f64091Sbellard     int len;
16583f64091Sbellard 
16683f64091Sbellard     if (dest_size <= 0)
16783f64091Sbellard         return;
16883f64091Sbellard     if (path_is_absolute(filename)) {
16983f64091Sbellard         pstrcpy(dest, dest_size, filename);
17083f64091Sbellard     } else {
17183f64091Sbellard         p = strchr(base_path, ':');
17283f64091Sbellard         if (p)
17383f64091Sbellard             p++;
17483f64091Sbellard         else
17583f64091Sbellard             p = base_path;
1763b9f94e1Sbellard         p1 = strrchr(base_path, '/');
1773b9f94e1Sbellard #ifdef _WIN32
1783b9f94e1Sbellard         {
1793b9f94e1Sbellard             const char *p2;
1803b9f94e1Sbellard             p2 = strrchr(base_path, '\\');
1813b9f94e1Sbellard             if (!p1 || p2 > p1)
1823b9f94e1Sbellard                 p1 = p2;
1833b9f94e1Sbellard         }
1843b9f94e1Sbellard #endif
18583f64091Sbellard         if (p1)
18683f64091Sbellard             p1++;
18783f64091Sbellard         else
18883f64091Sbellard             p1 = base_path;
18983f64091Sbellard         if (p1 > p)
19083f64091Sbellard             p = p1;
19183f64091Sbellard         len = p - base_path;
19283f64091Sbellard         if (len > dest_size - 1)
19383f64091Sbellard             len = dest_size - 1;
19483f64091Sbellard         memcpy(dest, base_path, len);
19583f64091Sbellard         dest[len] = '\0';
19683f64091Sbellard         pstrcat(dest, dest_size, filename);
19783f64091Sbellard     }
19883f64091Sbellard }
19983f64091Sbellard 
2005efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv)
201ea2384d3Sbellard {
20268485420SKevin Wolf     if (bdrv->bdrv_co_readv) {
20368485420SKevin Wolf         /* Emulate AIO by coroutines, and sync by AIO */
20468485420SKevin Wolf         bdrv->bdrv_aio_readv = bdrv_co_aio_readv_em;
20568485420SKevin Wolf         bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em;
20668485420SKevin Wolf         bdrv->bdrv_read = bdrv_read_em;
20768485420SKevin Wolf         bdrv->bdrv_write = bdrv_write_em;
208f9f05dc5SKevin Wolf      } else {
209f9f05dc5SKevin Wolf         bdrv->bdrv_co_readv = bdrv_co_readv_em;
210f9f05dc5SKevin Wolf         bdrv->bdrv_co_writev = bdrv_co_writev_em;
211f9f05dc5SKevin Wolf 
212f9f05dc5SKevin Wolf         if (!bdrv->bdrv_aio_readv) {
21383f64091Sbellard             /* add AIO emulation layer */
214f141eafeSaliguori             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
215f141eafeSaliguori             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
216eda578e5Saliguori         } else if (!bdrv->bdrv_read) {
21783f64091Sbellard             /* add synchronous IO emulation layer */
21883f64091Sbellard             bdrv->bdrv_read = bdrv_read_em;
21983f64091Sbellard             bdrv->bdrv_write = bdrv_write_em;
22083f64091Sbellard         }
221f9f05dc5SKevin Wolf     }
222b2e12bc6SChristoph Hellwig 
223b2e12bc6SChristoph Hellwig     if (!bdrv->bdrv_aio_flush)
224b2e12bc6SChristoph Hellwig         bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
225b2e12bc6SChristoph Hellwig 
2268a22f02aSStefan Hajnoczi     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
227ea2384d3Sbellard }
228b338082bSbellard 
229b338082bSbellard /* create a new block device (by default it is empty) */
230b338082bSbellard BlockDriverState *bdrv_new(const char *device_name)
231fc01f7e7Sbellard {
2321b7bdbc1SStefan Hajnoczi     BlockDriverState *bs;
233b338082bSbellard 
2347267c094SAnthony Liguori     bs = g_malloc0(sizeof(BlockDriverState));
235b338082bSbellard     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
236ea2384d3Sbellard     if (device_name[0] != '\0') {
2371b7bdbc1SStefan Hajnoczi         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
238ea2384d3Sbellard     }
23928a7282aSLuiz Capitulino     bdrv_iostatus_disable(bs);
240b338082bSbellard     return bs;
241b338082bSbellard }
242b338082bSbellard 
243ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name)
244ea2384d3Sbellard {
245ea2384d3Sbellard     BlockDriver *drv1;
2468a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
2478a22f02aSStefan Hajnoczi         if (!strcmp(drv1->format_name, format_name)) {
248ea2384d3Sbellard             return drv1;
249ea2384d3Sbellard         }
2508a22f02aSStefan Hajnoczi     }
251ea2384d3Sbellard     return NULL;
252ea2384d3Sbellard }
253ea2384d3Sbellard 
254eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv)
255eb852011SMarkus Armbruster {
256eb852011SMarkus Armbruster     static const char *whitelist[] = {
257eb852011SMarkus Armbruster         CONFIG_BDRV_WHITELIST
258eb852011SMarkus Armbruster     };
259eb852011SMarkus Armbruster     const char **p;
260eb852011SMarkus Armbruster 
261eb852011SMarkus Armbruster     if (!whitelist[0])
262eb852011SMarkus Armbruster         return 1;               /* no whitelist, anything goes */
263eb852011SMarkus Armbruster 
264eb852011SMarkus Armbruster     for (p = whitelist; *p; p++) {
265eb852011SMarkus Armbruster         if (!strcmp(drv->format_name, *p)) {
266eb852011SMarkus Armbruster             return 1;
267eb852011SMarkus Armbruster         }
268eb852011SMarkus Armbruster     }
269eb852011SMarkus Armbruster     return 0;
270eb852011SMarkus Armbruster }
271eb852011SMarkus Armbruster 
272eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
273eb852011SMarkus Armbruster {
274eb852011SMarkus Armbruster     BlockDriver *drv = bdrv_find_format(format_name);
275eb852011SMarkus Armbruster     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
276eb852011SMarkus Armbruster }
277eb852011SMarkus Armbruster 
2780e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename,
2790e7e1989SKevin Wolf     QEMUOptionParameter *options)
280ea2384d3Sbellard {
281ea2384d3Sbellard     if (!drv->bdrv_create)
282ea2384d3Sbellard         return -ENOTSUP;
2830e7e1989SKevin Wolf 
2840e7e1989SKevin Wolf     return drv->bdrv_create(filename, options);
285ea2384d3Sbellard }
286ea2384d3Sbellard 
28784a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
28884a12e66SChristoph Hellwig {
28984a12e66SChristoph Hellwig     BlockDriver *drv;
29084a12e66SChristoph Hellwig 
291b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
29284a12e66SChristoph Hellwig     if (drv == NULL) {
29316905d71SStefan Hajnoczi         return -ENOENT;
29484a12e66SChristoph Hellwig     }
29584a12e66SChristoph Hellwig 
29684a12e66SChristoph Hellwig     return bdrv_create(drv, filename, options);
29784a12e66SChristoph Hellwig }
29884a12e66SChristoph Hellwig 
299d5249393Sbellard #ifdef _WIN32
30095389c86Sbellard void get_tmp_filename(char *filename, int size)
301d5249393Sbellard {
3023b9f94e1Sbellard     char temp_dir[MAX_PATH];
3033b9f94e1Sbellard 
3043b9f94e1Sbellard     GetTempPath(MAX_PATH, temp_dir);
3053b9f94e1Sbellard     GetTempFileName(temp_dir, "qem", 0, filename);
306d5249393Sbellard }
307d5249393Sbellard #else
30895389c86Sbellard void get_tmp_filename(char *filename, int size)
309ea2384d3Sbellard {
310ea2384d3Sbellard     int fd;
3117ccfb2ebSblueswir1     const char *tmpdir;
312d5249393Sbellard     /* XXX: race condition possible */
3130badc1eeSaurel32     tmpdir = getenv("TMPDIR");
3140badc1eeSaurel32     if (!tmpdir)
3150badc1eeSaurel32         tmpdir = "/tmp";
3160badc1eeSaurel32     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
317ea2384d3Sbellard     fd = mkstemp(filename);
318ea2384d3Sbellard     close(fd);
319ea2384d3Sbellard }
320d5249393Sbellard #endif
321ea2384d3Sbellard 
322f3a5d3f8SChristoph Hellwig /*
323f3a5d3f8SChristoph Hellwig  * Detect host devices. By convention, /dev/cdrom[N] is always
324f3a5d3f8SChristoph Hellwig  * recognized as a host CDROM.
325f3a5d3f8SChristoph Hellwig  */
326f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename)
327f3a5d3f8SChristoph Hellwig {
328508c7cb3SChristoph Hellwig     int score_max = 0, score;
329508c7cb3SChristoph Hellwig     BlockDriver *drv = NULL, *d;
330f3a5d3f8SChristoph Hellwig 
3318a22f02aSStefan Hajnoczi     QLIST_FOREACH(d, &bdrv_drivers, list) {
332508c7cb3SChristoph Hellwig         if (d->bdrv_probe_device) {
333508c7cb3SChristoph Hellwig             score = d->bdrv_probe_device(filename);
334508c7cb3SChristoph Hellwig             if (score > score_max) {
335508c7cb3SChristoph Hellwig                 score_max = score;
336508c7cb3SChristoph Hellwig                 drv = d;
337f3a5d3f8SChristoph Hellwig             }
338508c7cb3SChristoph Hellwig         }
339f3a5d3f8SChristoph Hellwig     }
340f3a5d3f8SChristoph Hellwig 
341508c7cb3SChristoph Hellwig     return drv;
342f3a5d3f8SChristoph Hellwig }
343f3a5d3f8SChristoph Hellwig 
344b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename)
34584a12e66SChristoph Hellwig {
34684a12e66SChristoph Hellwig     BlockDriver *drv1;
34784a12e66SChristoph Hellwig     char protocol[128];
34884a12e66SChristoph Hellwig     int len;
34984a12e66SChristoph Hellwig     const char *p;
35084a12e66SChristoph Hellwig 
35166f82ceeSKevin Wolf     /* TODO Drivers without bdrv_file_open must be specified explicitly */
35266f82ceeSKevin Wolf 
35339508e7aSChristoph Hellwig     /*
35439508e7aSChristoph Hellwig      * XXX(hch): we really should not let host device detection
35539508e7aSChristoph Hellwig      * override an explicit protocol specification, but moving this
35639508e7aSChristoph Hellwig      * later breaks access to device names with colons in them.
35739508e7aSChristoph Hellwig      * Thanks to the brain-dead persistent naming schemes on udev-
35839508e7aSChristoph Hellwig      * based Linux systems those actually are quite common.
35939508e7aSChristoph Hellwig      */
36084a12e66SChristoph Hellwig     drv1 = find_hdev_driver(filename);
36139508e7aSChristoph Hellwig     if (drv1) {
36284a12e66SChristoph Hellwig         return drv1;
36384a12e66SChristoph Hellwig     }
36439508e7aSChristoph Hellwig 
3659e0b22f4SStefan Hajnoczi     if (!path_has_protocol(filename)) {
36639508e7aSChristoph Hellwig         return bdrv_find_format("file");
36739508e7aSChristoph Hellwig     }
3689e0b22f4SStefan Hajnoczi     p = strchr(filename, ':');
3699e0b22f4SStefan Hajnoczi     assert(p != NULL);
37084a12e66SChristoph Hellwig     len = p - filename;
37184a12e66SChristoph Hellwig     if (len > sizeof(protocol) - 1)
37284a12e66SChristoph Hellwig         len = sizeof(protocol) - 1;
37384a12e66SChristoph Hellwig     memcpy(protocol, filename, len);
37484a12e66SChristoph Hellwig     protocol[len] = '\0';
37584a12e66SChristoph Hellwig     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
37684a12e66SChristoph Hellwig         if (drv1->protocol_name &&
37784a12e66SChristoph Hellwig             !strcmp(drv1->protocol_name, protocol)) {
37884a12e66SChristoph Hellwig             return drv1;
37984a12e66SChristoph Hellwig         }
38084a12e66SChristoph Hellwig     }
38184a12e66SChristoph Hellwig     return NULL;
38284a12e66SChristoph Hellwig }
38384a12e66SChristoph Hellwig 
384c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv)
385ea2384d3Sbellard {
38683f64091Sbellard     int ret, score, score_max;
387ea2384d3Sbellard     BlockDriver *drv1, *drv;
38883f64091Sbellard     uint8_t buf[2048];
38983f64091Sbellard     BlockDriverState *bs;
390ea2384d3Sbellard 
391f5edb014SNaphtali Sprei     ret = bdrv_file_open(&bs, filename, 0);
392c98ac35dSStefan Weil     if (ret < 0) {
393c98ac35dSStefan Weil         *pdrv = NULL;
394c98ac35dSStefan Weil         return ret;
395c98ac35dSStefan Weil     }
396f8ea0b00SNicholas Bellinger 
39708a00559SKevin Wolf     /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
39808a00559SKevin Wolf     if (bs->sg || !bdrv_is_inserted(bs)) {
3991a396859SNicholas A. Bellinger         bdrv_delete(bs);
400c98ac35dSStefan Weil         drv = bdrv_find_format("raw");
401c98ac35dSStefan Weil         if (!drv) {
402c98ac35dSStefan Weil             ret = -ENOENT;
403c98ac35dSStefan Weil         }
404c98ac35dSStefan Weil         *pdrv = drv;
405c98ac35dSStefan Weil         return ret;
4061a396859SNicholas A. Bellinger     }
407f8ea0b00SNicholas Bellinger 
40883f64091Sbellard     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
40983f64091Sbellard     bdrv_delete(bs);
410ea2384d3Sbellard     if (ret < 0) {
411c98ac35dSStefan Weil         *pdrv = NULL;
412c98ac35dSStefan Weil         return ret;
413ea2384d3Sbellard     }
414ea2384d3Sbellard 
415ea2384d3Sbellard     score_max = 0;
41684a12e66SChristoph Hellwig     drv = NULL;
4178a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv1, &bdrv_drivers, list) {
41883f64091Sbellard         if (drv1->bdrv_probe) {
419ea2384d3Sbellard             score = drv1->bdrv_probe(buf, ret, filename);
420ea2384d3Sbellard             if (score > score_max) {
421ea2384d3Sbellard                 score_max = score;
422ea2384d3Sbellard                 drv = drv1;
423ea2384d3Sbellard             }
424ea2384d3Sbellard         }
42583f64091Sbellard     }
426c98ac35dSStefan Weil     if (!drv) {
427c98ac35dSStefan Weil         ret = -ENOENT;
428c98ac35dSStefan Weil     }
429c98ac35dSStefan Weil     *pdrv = drv;
430c98ac35dSStefan Weil     return ret;
431ea2384d3Sbellard }
432ea2384d3Sbellard 
43351762288SStefan Hajnoczi /**
43451762288SStefan Hajnoczi  * Set the current 'total_sectors' value
43551762288SStefan Hajnoczi  */
43651762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
43751762288SStefan Hajnoczi {
43851762288SStefan Hajnoczi     BlockDriver *drv = bs->drv;
43951762288SStefan Hajnoczi 
440396759adSNicholas Bellinger     /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
441396759adSNicholas Bellinger     if (bs->sg)
442396759adSNicholas Bellinger         return 0;
443396759adSNicholas Bellinger 
44451762288SStefan Hajnoczi     /* query actual device if possible, otherwise just trust the hint */
44551762288SStefan Hajnoczi     if (drv->bdrv_getlength) {
44651762288SStefan Hajnoczi         int64_t length = drv->bdrv_getlength(bs);
44751762288SStefan Hajnoczi         if (length < 0) {
44851762288SStefan Hajnoczi             return length;
44951762288SStefan Hajnoczi         }
45051762288SStefan Hajnoczi         hint = length >> BDRV_SECTOR_BITS;
45151762288SStefan Hajnoczi     }
45251762288SStefan Hajnoczi 
45351762288SStefan Hajnoczi     bs->total_sectors = hint;
45451762288SStefan Hajnoczi     return 0;
45551762288SStefan Hajnoczi }
45651762288SStefan Hajnoczi 
457c3993cdcSStefan Hajnoczi /**
458c3993cdcSStefan Hajnoczi  * Set open flags for a given cache mode
459c3993cdcSStefan Hajnoczi  *
460c3993cdcSStefan Hajnoczi  * Return 0 on success, -1 if the cache mode was invalid.
461c3993cdcSStefan Hajnoczi  */
462c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags)
463c3993cdcSStefan Hajnoczi {
464c3993cdcSStefan Hajnoczi     *flags &= ~BDRV_O_CACHE_MASK;
465c3993cdcSStefan Hajnoczi 
466c3993cdcSStefan Hajnoczi     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
467c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
46892196b2fSStefan Hajnoczi     } else if (!strcmp(mode, "directsync")) {
46992196b2fSStefan Hajnoczi         *flags |= BDRV_O_NOCACHE;
470c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writeback")) {
471c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
472c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "unsafe")) {
473c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_CACHE_WB;
474c3993cdcSStefan Hajnoczi         *flags |= BDRV_O_NO_FLUSH;
475c3993cdcSStefan Hajnoczi     } else if (!strcmp(mode, "writethrough")) {
476c3993cdcSStefan Hajnoczi         /* this is the default */
477c3993cdcSStefan Hajnoczi     } else {
478c3993cdcSStefan Hajnoczi         return -1;
479c3993cdcSStefan Hajnoczi     }
480c3993cdcSStefan Hajnoczi 
481c3993cdcSStefan Hajnoczi     return 0;
482c3993cdcSStefan Hajnoczi }
483c3993cdcSStefan Hajnoczi 
484b6ce07aaSKevin Wolf /*
48557915332SKevin Wolf  * Common part for opening disk images and files
48657915332SKevin Wolf  */
48757915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename,
48857915332SKevin Wolf     int flags, BlockDriver *drv)
48957915332SKevin Wolf {
49057915332SKevin Wolf     int ret, open_flags;
49157915332SKevin Wolf 
49257915332SKevin Wolf     assert(drv != NULL);
49357915332SKevin Wolf 
49428dcee10SStefan Hajnoczi     trace_bdrv_open_common(bs, filename, flags, drv->format_name);
49528dcee10SStefan Hajnoczi 
49666f82ceeSKevin Wolf     bs->file = NULL;
49751762288SStefan Hajnoczi     bs->total_sectors = 0;
49857915332SKevin Wolf     bs->encrypted = 0;
49957915332SKevin Wolf     bs->valid_key = 0;
50057915332SKevin Wolf     bs->open_flags = flags;
50157915332SKevin Wolf     bs->buffer_alignment = 512;
50257915332SKevin Wolf 
50357915332SKevin Wolf     pstrcpy(bs->filename, sizeof(bs->filename), filename);
50457915332SKevin Wolf 
50557915332SKevin Wolf     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
50657915332SKevin Wolf         return -ENOTSUP;
50757915332SKevin Wolf     }
50857915332SKevin Wolf 
50957915332SKevin Wolf     bs->drv = drv;
5107267c094SAnthony Liguori     bs->opaque = g_malloc0(drv->instance_size);
51157915332SKevin Wolf 
512a6599793SChristoph Hellwig     if (flags & BDRV_O_CACHE_WB)
51357915332SKevin Wolf         bs->enable_write_cache = 1;
51457915332SKevin Wolf 
51557915332SKevin Wolf     /*
51657915332SKevin Wolf      * Clear flags that are internal to the block layer before opening the
51757915332SKevin Wolf      * image.
51857915332SKevin Wolf      */
51957915332SKevin Wolf     open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
52057915332SKevin Wolf 
52157915332SKevin Wolf     /*
522ebabb67aSStefan Weil      * Snapshots should be writable.
52357915332SKevin Wolf      */
52457915332SKevin Wolf     if (bs->is_temporary) {
52557915332SKevin Wolf         open_flags |= BDRV_O_RDWR;
52657915332SKevin Wolf     }
52757915332SKevin Wolf 
52866f82ceeSKevin Wolf     /* Open the image, either directly or using a protocol */
52966f82ceeSKevin Wolf     if (drv->bdrv_file_open) {
53066f82ceeSKevin Wolf         ret = drv->bdrv_file_open(bs, filename, open_flags);
53166f82ceeSKevin Wolf     } else {
53266f82ceeSKevin Wolf         ret = bdrv_file_open(&bs->file, filename, open_flags);
53366f82ceeSKevin Wolf         if (ret >= 0) {
53466f82ceeSKevin Wolf             ret = drv->bdrv_open(bs, open_flags);
53566f82ceeSKevin Wolf         }
53666f82ceeSKevin Wolf     }
53766f82ceeSKevin Wolf 
53857915332SKevin Wolf     if (ret < 0) {
53957915332SKevin Wolf         goto free_and_fail;
54057915332SKevin Wolf     }
54157915332SKevin Wolf 
54257915332SKevin Wolf     bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
54351762288SStefan Hajnoczi 
54451762288SStefan Hajnoczi     ret = refresh_total_sectors(bs, bs->total_sectors);
54551762288SStefan Hajnoczi     if (ret < 0) {
54651762288SStefan Hajnoczi         goto free_and_fail;
54757915332SKevin Wolf     }
54851762288SStefan Hajnoczi 
54957915332SKevin Wolf #ifndef _WIN32
55057915332SKevin Wolf     if (bs->is_temporary) {
55157915332SKevin Wolf         unlink(filename);
55257915332SKevin Wolf     }
55357915332SKevin Wolf #endif
55457915332SKevin Wolf     return 0;
55557915332SKevin Wolf 
55657915332SKevin Wolf free_and_fail:
55766f82ceeSKevin Wolf     if (bs->file) {
55866f82ceeSKevin Wolf         bdrv_delete(bs->file);
55966f82ceeSKevin Wolf         bs->file = NULL;
56066f82ceeSKevin Wolf     }
5617267c094SAnthony Liguori     g_free(bs->opaque);
56257915332SKevin Wolf     bs->opaque = NULL;
56357915332SKevin Wolf     bs->drv = NULL;
56457915332SKevin Wolf     return ret;
56557915332SKevin Wolf }
56657915332SKevin Wolf 
56757915332SKevin Wolf /*
568b6ce07aaSKevin Wolf  * Opens a file using a protocol (file, host_device, nbd, ...)
569b6ce07aaSKevin Wolf  */
57083f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
571b338082bSbellard {
57283f64091Sbellard     BlockDriverState *bs;
5736db95603SChristoph Hellwig     BlockDriver *drv;
57483f64091Sbellard     int ret;
5753b0d4f61Sbellard 
576b50cbabcSMORITA Kazutaka     drv = bdrv_find_protocol(filename);
5776db95603SChristoph Hellwig     if (!drv) {
5786db95603SChristoph Hellwig         return -ENOENT;
5796db95603SChristoph Hellwig     }
5806db95603SChristoph Hellwig 
58183f64091Sbellard     bs = bdrv_new("");
582b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
58383f64091Sbellard     if (ret < 0) {
58483f64091Sbellard         bdrv_delete(bs);
58583f64091Sbellard         return ret;
5863b0d4f61Sbellard     }
58771d0770cSaliguori     bs->growable = 1;
58883f64091Sbellard     *pbs = bs;
58983f64091Sbellard     return 0;
5903b0d4f61Sbellard }
5913b0d4f61Sbellard 
592b6ce07aaSKevin Wolf /*
593b6ce07aaSKevin Wolf  * Opens a disk image (raw, qcow2, vmdk, ...)
594b6ce07aaSKevin Wolf  */
595d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
596ea2384d3Sbellard               BlockDriver *drv)
597ea2384d3Sbellard {
598b6ce07aaSKevin Wolf     int ret;
59933e3963eSbellard 
60083f64091Sbellard     if (flags & BDRV_O_SNAPSHOT) {
601ea2384d3Sbellard         BlockDriverState *bs1;
602ea2384d3Sbellard         int64_t total_size;
6037c96d46eSaliguori         int is_protocol = 0;
60491a073a9SKevin Wolf         BlockDriver *bdrv_qcow2;
60591a073a9SKevin Wolf         QEMUOptionParameter *options;
606b6ce07aaSKevin Wolf         char tmp_filename[PATH_MAX];
607b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
60833e3963eSbellard 
609ea2384d3Sbellard         /* if snapshot, we create a temporary backing file and open it
610ea2384d3Sbellard            instead of opening 'filename' directly */
611ea2384d3Sbellard 
612ea2384d3Sbellard         /* if there is a backing file, use it */
613ea2384d3Sbellard         bs1 = bdrv_new("");
614d6e9098eSKevin Wolf         ret = bdrv_open(bs1, filename, 0, drv);
61551d7c00cSaliguori         if (ret < 0) {
616ea2384d3Sbellard             bdrv_delete(bs1);
61751d7c00cSaliguori             return ret;
618ea2384d3Sbellard         }
6193e82990bSJes Sorensen         total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
6207c96d46eSaliguori 
6217c96d46eSaliguori         if (bs1->drv && bs1->drv->protocol_name)
6227c96d46eSaliguori             is_protocol = 1;
6237c96d46eSaliguori 
624ea2384d3Sbellard         bdrv_delete(bs1);
625ea2384d3Sbellard 
626ea2384d3Sbellard         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
6277c96d46eSaliguori 
6287c96d46eSaliguori         /* Real path is meaningless for protocols */
6297c96d46eSaliguori         if (is_protocol)
6307c96d46eSaliguori             snprintf(backing_filename, sizeof(backing_filename),
6317c96d46eSaliguori                      "%s", filename);
632114cdfa9SKirill A. Shutemov         else if (!realpath(filename, backing_filename))
633114cdfa9SKirill A. Shutemov             return -errno;
6347c96d46eSaliguori 
63591a073a9SKevin Wolf         bdrv_qcow2 = bdrv_find_format("qcow2");
63691a073a9SKevin Wolf         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
63791a073a9SKevin Wolf 
6383e82990bSJes Sorensen         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
63991a073a9SKevin Wolf         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
64091a073a9SKevin Wolf         if (drv) {
64191a073a9SKevin Wolf             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
64291a073a9SKevin Wolf                 drv->format_name);
64391a073a9SKevin Wolf         }
64491a073a9SKevin Wolf 
64591a073a9SKevin Wolf         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
646d748768cSJan Kiszka         free_option_parameters(options);
64751d7c00cSaliguori         if (ret < 0) {
64851d7c00cSaliguori             return ret;
649ea2384d3Sbellard         }
65091a073a9SKevin Wolf 
651ea2384d3Sbellard         filename = tmp_filename;
65291a073a9SKevin Wolf         drv = bdrv_qcow2;
653ea2384d3Sbellard         bs->is_temporary = 1;
654ea2384d3Sbellard     }
655ea2384d3Sbellard 
656b6ce07aaSKevin Wolf     /* Find the right image format driver */
6576db95603SChristoph Hellwig     if (!drv) {
658c98ac35dSStefan Weil         ret = find_image_format(filename, &drv);
659ea2384d3Sbellard     }
6606987307cSChristoph Hellwig 
66151d7c00cSaliguori     if (!drv) {
66251d7c00cSaliguori         goto unlink_and_fail;
66383f64091Sbellard     }
664b6ce07aaSKevin Wolf 
665b6ce07aaSKevin Wolf     /* Open the image */
666b6ce07aaSKevin Wolf     ret = bdrv_open_common(bs, filename, flags, drv);
667b6ce07aaSKevin Wolf     if (ret < 0) {
6686987307cSChristoph Hellwig         goto unlink_and_fail;
6696987307cSChristoph Hellwig     }
6706987307cSChristoph Hellwig 
671b6ce07aaSKevin Wolf     /* If there is a backing file, use it */
672b6ce07aaSKevin Wolf     if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
673b6ce07aaSKevin Wolf         char backing_filename[PATH_MAX];
674b6ce07aaSKevin Wolf         int back_flags;
675b6ce07aaSKevin Wolf         BlockDriver *back_drv = NULL;
676b6ce07aaSKevin Wolf 
677b6ce07aaSKevin Wolf         bs->backing_hd = bdrv_new("");
678df2dbb4aSStefan Hajnoczi 
679df2dbb4aSStefan Hajnoczi         if (path_has_protocol(bs->backing_file)) {
680df2dbb4aSStefan Hajnoczi             pstrcpy(backing_filename, sizeof(backing_filename),
681df2dbb4aSStefan Hajnoczi                     bs->backing_file);
682df2dbb4aSStefan Hajnoczi         } else {
683b6ce07aaSKevin Wolf             path_combine(backing_filename, sizeof(backing_filename),
684b6ce07aaSKevin Wolf                          filename, bs->backing_file);
685df2dbb4aSStefan Hajnoczi         }
686df2dbb4aSStefan Hajnoczi 
687df2dbb4aSStefan Hajnoczi         if (bs->backing_format[0] != '\0') {
688b6ce07aaSKevin Wolf             back_drv = bdrv_find_format(bs->backing_format);
689df2dbb4aSStefan Hajnoczi         }
690b6ce07aaSKevin Wolf 
691b6ce07aaSKevin Wolf         /* backing files always opened read-only */
692b6ce07aaSKevin Wolf         back_flags =
693b6ce07aaSKevin Wolf             flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
694b6ce07aaSKevin Wolf 
695b6ce07aaSKevin Wolf         ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
696b6ce07aaSKevin Wolf         if (ret < 0) {
697b6ce07aaSKevin Wolf             bdrv_close(bs);
698b6ce07aaSKevin Wolf             return ret;
699b6ce07aaSKevin Wolf         }
700b6ce07aaSKevin Wolf         if (bs->is_temporary) {
701b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
702b6ce07aaSKevin Wolf         } else {
703b6ce07aaSKevin Wolf             /* base image inherits from "parent" */
704b6ce07aaSKevin Wolf             bs->backing_hd->keep_read_only = bs->keep_read_only;
705b6ce07aaSKevin Wolf         }
706b6ce07aaSKevin Wolf     }
707b6ce07aaSKevin Wolf 
708b6ce07aaSKevin Wolf     if (!bdrv_key_required(bs)) {
7097d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
710b6ce07aaSKevin Wolf     }
711b6ce07aaSKevin Wolf 
712b6ce07aaSKevin Wolf     return 0;
713b6ce07aaSKevin Wolf 
714b6ce07aaSKevin Wolf unlink_and_fail:
715b6ce07aaSKevin Wolf     if (bs->is_temporary) {
716b6ce07aaSKevin Wolf         unlink(filename);
717b6ce07aaSKevin Wolf     }
718b6ce07aaSKevin Wolf     return ret;
719b6ce07aaSKevin Wolf }
720b6ce07aaSKevin Wolf 
721fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
722fc01f7e7Sbellard {
72319cb3738Sbellard     if (bs->drv) {
724f9092b10SMarkus Armbruster         if (bs == bs_snapshots) {
725f9092b10SMarkus Armbruster             bs_snapshots = NULL;
726f9092b10SMarkus Armbruster         }
727557df6acSStefan Hajnoczi         if (bs->backing_hd) {
728ea2384d3Sbellard             bdrv_delete(bs->backing_hd);
729557df6acSStefan Hajnoczi             bs->backing_hd = NULL;
730557df6acSStefan Hajnoczi         }
731ea2384d3Sbellard         bs->drv->bdrv_close(bs);
7327267c094SAnthony Liguori         g_free(bs->opaque);
733ea2384d3Sbellard #ifdef _WIN32
734ea2384d3Sbellard         if (bs->is_temporary) {
735ea2384d3Sbellard             unlink(bs->filename);
736ea2384d3Sbellard         }
73767b915a5Sbellard #endif
738ea2384d3Sbellard         bs->opaque = NULL;
739ea2384d3Sbellard         bs->drv = NULL;
740b338082bSbellard 
74166f82ceeSKevin Wolf         if (bs->file != NULL) {
74266f82ceeSKevin Wolf             bdrv_close(bs->file);
74366f82ceeSKevin Wolf         }
74466f82ceeSKevin Wolf 
7457d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, false);
746b338082bSbellard     }
747b338082bSbellard }
748b338082bSbellard 
7492bc93fedSMORITA Kazutaka void bdrv_close_all(void)
7502bc93fedSMORITA Kazutaka {
7512bc93fedSMORITA Kazutaka     BlockDriverState *bs;
7522bc93fedSMORITA Kazutaka 
7532bc93fedSMORITA Kazutaka     QTAILQ_FOREACH(bs, &bdrv_states, list) {
7542bc93fedSMORITA Kazutaka         bdrv_close(bs);
7552bc93fedSMORITA Kazutaka     }
7562bc93fedSMORITA Kazutaka }
7572bc93fedSMORITA Kazutaka 
758d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list.
759d22b2f41SRyan Harper    Also, NULL terminate the device_name to prevent double remove */
760d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs)
761d22b2f41SRyan Harper {
762d22b2f41SRyan Harper     if (bs->device_name[0] != '\0') {
763d22b2f41SRyan Harper         QTAILQ_REMOVE(&bdrv_states, bs, list);
764d22b2f41SRyan Harper     }
765d22b2f41SRyan Harper     bs->device_name[0] = '\0';
766d22b2f41SRyan Harper }
767d22b2f41SRyan Harper 
768b338082bSbellard void bdrv_delete(BlockDriverState *bs)
769b338082bSbellard {
770fa879d62SMarkus Armbruster     assert(!bs->dev);
77118846deeSMarkus Armbruster 
7721b7bdbc1SStefan Hajnoczi     /* remove from list, if necessary */
773d22b2f41SRyan Harper     bdrv_make_anon(bs);
77434c6f050Saurel32 
775b338082bSbellard     bdrv_close(bs);
77666f82ceeSKevin Wolf     if (bs->file != NULL) {
77766f82ceeSKevin Wolf         bdrv_delete(bs->file);
77866f82ceeSKevin Wolf     }
77966f82ceeSKevin Wolf 
780f9092b10SMarkus Armbruster     assert(bs != bs_snapshots);
7817267c094SAnthony Liguori     g_free(bs);
782fc01f7e7Sbellard }
783fc01f7e7Sbellard 
784fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev)
785fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
78618846deeSMarkus Armbruster {
787fa879d62SMarkus Armbruster     if (bs->dev) {
78818846deeSMarkus Armbruster         return -EBUSY;
78918846deeSMarkus Armbruster     }
790fa879d62SMarkus Armbruster     bs->dev = dev;
79128a7282aSLuiz Capitulino     bdrv_iostatus_reset(bs);
79218846deeSMarkus Armbruster     return 0;
79318846deeSMarkus Armbruster }
79418846deeSMarkus Armbruster 
795fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */
796fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
79718846deeSMarkus Armbruster {
798fa879d62SMarkus Armbruster     if (bdrv_attach_dev(bs, dev) < 0) {
799fa879d62SMarkus Armbruster         abort();
800fa879d62SMarkus Armbruster     }
801fa879d62SMarkus Armbruster }
802fa879d62SMarkus Armbruster 
803fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev)
804fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
805fa879d62SMarkus Armbruster {
806fa879d62SMarkus Armbruster     assert(bs->dev == dev);
807fa879d62SMarkus Armbruster     bs->dev = NULL;
8080e49de52SMarkus Armbruster     bs->dev_ops = NULL;
8090e49de52SMarkus Armbruster     bs->dev_opaque = NULL;
81029e05f20SMarkus Armbruster     bs->buffer_alignment = 512;
81118846deeSMarkus Armbruster }
81218846deeSMarkus Armbruster 
813fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
814fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs)
81518846deeSMarkus Armbruster {
816fa879d62SMarkus Armbruster     return bs->dev;
81718846deeSMarkus Armbruster }
81818846deeSMarkus Armbruster 
8190e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
8200e49de52SMarkus Armbruster                       void *opaque)
8210e49de52SMarkus Armbruster {
8220e49de52SMarkus Armbruster     bs->dev_ops = ops;
8230e49de52SMarkus Armbruster     bs->dev_opaque = opaque;
8242c6942faSMarkus Armbruster     if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
8252c6942faSMarkus Armbruster         bs_snapshots = NULL;
8262c6942faSMarkus Armbruster     }
8270e49de52SMarkus Armbruster }
8280e49de52SMarkus Armbruster 
8297d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
8300e49de52SMarkus Armbruster {
831145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->change_media_cb) {
8327d4b4ba5SMarkus Armbruster         bs->dev_ops->change_media_cb(bs->dev_opaque, load);
833145feb17SMarkus Armbruster     }
834145feb17SMarkus Armbruster }
835145feb17SMarkus Armbruster 
8362c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs)
8372c6942faSMarkus Armbruster {
8382c6942faSMarkus Armbruster     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
8392c6942faSMarkus Armbruster }
8402c6942faSMarkus Armbruster 
841e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs)
842e4def80bSMarkus Armbruster {
843e4def80bSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
844e4def80bSMarkus Armbruster         return bs->dev_ops->is_tray_open(bs->dev_opaque);
845e4def80bSMarkus Armbruster     }
846e4def80bSMarkus Armbruster     return false;
847e4def80bSMarkus Armbruster }
848e4def80bSMarkus Armbruster 
849145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs)
850145feb17SMarkus Armbruster {
851145feb17SMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->resize_cb) {
852145feb17SMarkus Armbruster         bs->dev_ops->resize_cb(bs->dev_opaque);
8530e49de52SMarkus Armbruster     }
8540e49de52SMarkus Armbruster }
8550e49de52SMarkus Armbruster 
856f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
857f107639aSMarkus Armbruster {
858f107639aSMarkus Armbruster     if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
859f107639aSMarkus Armbruster         return bs->dev_ops->is_medium_locked(bs->dev_opaque);
860f107639aSMarkus Armbruster     }
861f107639aSMarkus Armbruster     return false;
862f107639aSMarkus Armbruster }
863f107639aSMarkus Armbruster 
864e97fc193Saliguori /*
865e97fc193Saliguori  * Run consistency checks on an image
866e97fc193Saliguori  *
867e076f338SKevin Wolf  * Returns 0 if the check could be completed (it doesn't mean that the image is
868a1c7273bSStefan Weil  * free of errors) or -errno when an internal error occurred. The results of the
869e076f338SKevin Wolf  * check are stored in res.
870e97fc193Saliguori  */
871e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
872e97fc193Saliguori {
873e97fc193Saliguori     if (bs->drv->bdrv_check == NULL) {
874e97fc193Saliguori         return -ENOTSUP;
875e97fc193Saliguori     }
876e97fc193Saliguori 
877e076f338SKevin Wolf     memset(res, 0, sizeof(*res));
8789ac228e0SKevin Wolf     return bs->drv->bdrv_check(bs, res);
879e97fc193Saliguori }
880e97fc193Saliguori 
8818a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048
8828a426614SKevin Wolf 
88333e3963eSbellard /* commit COW file into the raw image */
88433e3963eSbellard int bdrv_commit(BlockDriverState *bs)
88533e3963eSbellard {
88619cb3738Sbellard     BlockDriver *drv = bs->drv;
887ee181196SKevin Wolf     BlockDriver *backing_drv;
8888a426614SKevin Wolf     int64_t sector, total_sectors;
8898a426614SKevin Wolf     int n, ro, open_flags;
8904dca4b63SNaphtali Sprei     int ret = 0, rw_ret = 0;
8918a426614SKevin Wolf     uint8_t *buf;
8924dca4b63SNaphtali Sprei     char filename[1024];
8934dca4b63SNaphtali Sprei     BlockDriverState *bs_rw, *bs_ro;
89433e3963eSbellard 
89519cb3738Sbellard     if (!drv)
89619cb3738Sbellard         return -ENOMEDIUM;
89733e3963eSbellard 
8984dca4b63SNaphtali Sprei     if (!bs->backing_hd) {
8994dca4b63SNaphtali Sprei         return -ENOTSUP;
9004dca4b63SNaphtali Sprei     }
9014dca4b63SNaphtali Sprei 
9024dca4b63SNaphtali Sprei     if (bs->backing_hd->keep_read_only) {
903ea2384d3Sbellard         return -EACCES;
90433e3963eSbellard     }
90533e3963eSbellard 
906ee181196SKevin Wolf     backing_drv = bs->backing_hd->drv;
9074dca4b63SNaphtali Sprei     ro = bs->backing_hd->read_only;
9084dca4b63SNaphtali Sprei     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
9094dca4b63SNaphtali Sprei     open_flags =  bs->backing_hd->open_flags;
9104dca4b63SNaphtali Sprei 
9114dca4b63SNaphtali Sprei     if (ro) {
9124dca4b63SNaphtali Sprei         /* re-open as RW */
9134dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9144dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9154dca4b63SNaphtali Sprei         bs_rw = bdrv_new("");
916ee181196SKevin Wolf         rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
917ee181196SKevin Wolf             backing_drv);
9184dca4b63SNaphtali Sprei         if (rw_ret < 0) {
9194dca4b63SNaphtali Sprei             bdrv_delete(bs_rw);
9204dca4b63SNaphtali Sprei             /* try to re-open read-only */
9214dca4b63SNaphtali Sprei             bs_ro = bdrv_new("");
922ee181196SKevin Wolf             ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
923ee181196SKevin Wolf                 backing_drv);
9244dca4b63SNaphtali Sprei             if (ret < 0) {
9254dca4b63SNaphtali Sprei                 bdrv_delete(bs_ro);
9264dca4b63SNaphtali Sprei                 /* drive not functional anymore */
9274dca4b63SNaphtali Sprei                 bs->drv = NULL;
9284dca4b63SNaphtali Sprei                 return ret;
9294dca4b63SNaphtali Sprei             }
9304dca4b63SNaphtali Sprei             bs->backing_hd = bs_ro;
9314dca4b63SNaphtali Sprei             return rw_ret;
9324dca4b63SNaphtali Sprei         }
9334dca4b63SNaphtali Sprei         bs->backing_hd = bs_rw;
934ea2384d3Sbellard     }
935ea2384d3Sbellard 
9366ea44308SJan Kiszka     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
9377267c094SAnthony Liguori     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
9388a426614SKevin Wolf 
9398a426614SKevin Wolf     for (sector = 0; sector < total_sectors; sector += n) {
9408a426614SKevin Wolf         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
9418a426614SKevin Wolf 
9428a426614SKevin Wolf             if (bdrv_read(bs, sector, buf, n) != 0) {
9434dca4b63SNaphtali Sprei                 ret = -EIO;
9444dca4b63SNaphtali Sprei                 goto ro_cleanup;
94533e3963eSbellard             }
94633e3963eSbellard 
9478a426614SKevin Wolf             if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
9484dca4b63SNaphtali Sprei                 ret = -EIO;
9494dca4b63SNaphtali Sprei                 goto ro_cleanup;
95033e3963eSbellard             }
95133e3963eSbellard         }
95233e3963eSbellard     }
95395389c86Sbellard 
9541d44952fSChristoph Hellwig     if (drv->bdrv_make_empty) {
9551d44952fSChristoph Hellwig         ret = drv->bdrv_make_empty(bs);
9561d44952fSChristoph Hellwig         bdrv_flush(bs);
9571d44952fSChristoph Hellwig     }
95895389c86Sbellard 
9593f5075aeSChristoph Hellwig     /*
9603f5075aeSChristoph Hellwig      * Make sure all data we wrote to the backing device is actually
9613f5075aeSChristoph Hellwig      * stable on disk.
9623f5075aeSChristoph Hellwig      */
9633f5075aeSChristoph Hellwig     if (bs->backing_hd)
9643f5075aeSChristoph Hellwig         bdrv_flush(bs->backing_hd);
9654dca4b63SNaphtali Sprei 
9664dca4b63SNaphtali Sprei ro_cleanup:
9677267c094SAnthony Liguori     g_free(buf);
9684dca4b63SNaphtali Sprei 
9694dca4b63SNaphtali Sprei     if (ro) {
9704dca4b63SNaphtali Sprei         /* re-open as RO */
9714dca4b63SNaphtali Sprei         bdrv_delete(bs->backing_hd);
9724dca4b63SNaphtali Sprei         bs->backing_hd = NULL;
9734dca4b63SNaphtali Sprei         bs_ro = bdrv_new("");
974ee181196SKevin Wolf         ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
975ee181196SKevin Wolf             backing_drv);
9764dca4b63SNaphtali Sprei         if (ret < 0) {
9774dca4b63SNaphtali Sprei             bdrv_delete(bs_ro);
9784dca4b63SNaphtali Sprei             /* drive not functional anymore */
9794dca4b63SNaphtali Sprei             bs->drv = NULL;
9804dca4b63SNaphtali Sprei             return ret;
9814dca4b63SNaphtali Sprei         }
9824dca4b63SNaphtali Sprei         bs->backing_hd = bs_ro;
9834dca4b63SNaphtali Sprei         bs->backing_hd->keep_read_only = 0;
9844dca4b63SNaphtali Sprei     }
9854dca4b63SNaphtali Sprei 
9861d44952fSChristoph Hellwig     return ret;
98733e3963eSbellard }
98833e3963eSbellard 
9896ab4b5abSMarkus Armbruster void bdrv_commit_all(void)
9906ab4b5abSMarkus Armbruster {
9916ab4b5abSMarkus Armbruster     BlockDriverState *bs;
9926ab4b5abSMarkus Armbruster 
9936ab4b5abSMarkus Armbruster     QTAILQ_FOREACH(bs, &bdrv_states, list) {
9946ab4b5abSMarkus Armbruster         bdrv_commit(bs);
9956ab4b5abSMarkus Armbruster     }
9966ab4b5abSMarkus Armbruster }
9976ab4b5abSMarkus Armbruster 
998756e6736SKevin Wolf /*
999756e6736SKevin Wolf  * Return values:
1000756e6736SKevin Wolf  * 0        - success
1001756e6736SKevin Wolf  * -EINVAL  - backing format specified, but no file
1002756e6736SKevin Wolf  * -ENOSPC  - can't update the backing file because no space is left in the
1003756e6736SKevin Wolf  *            image file header
1004756e6736SKevin Wolf  * -ENOTSUP - format driver doesn't support changing the backing file
1005756e6736SKevin Wolf  */
1006756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs,
1007756e6736SKevin Wolf     const char *backing_file, const char *backing_fmt)
1008756e6736SKevin Wolf {
1009756e6736SKevin Wolf     BlockDriver *drv = bs->drv;
1010756e6736SKevin Wolf 
1011756e6736SKevin Wolf     if (drv->bdrv_change_backing_file != NULL) {
1012756e6736SKevin Wolf         return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
1013756e6736SKevin Wolf     } else {
1014756e6736SKevin Wolf         return -ENOTSUP;
1015756e6736SKevin Wolf     }
1016756e6736SKevin Wolf }
1017756e6736SKevin Wolf 
101871d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
101971d0770cSaliguori                                    size_t size)
102071d0770cSaliguori {
102171d0770cSaliguori     int64_t len;
102271d0770cSaliguori 
102371d0770cSaliguori     if (!bdrv_is_inserted(bs))
102471d0770cSaliguori         return -ENOMEDIUM;
102571d0770cSaliguori 
102671d0770cSaliguori     if (bs->growable)
102771d0770cSaliguori         return 0;
102871d0770cSaliguori 
102971d0770cSaliguori     len = bdrv_getlength(bs);
103071d0770cSaliguori 
1031fbb7b4e0SKevin Wolf     if (offset < 0)
1032fbb7b4e0SKevin Wolf         return -EIO;
1033fbb7b4e0SKevin Wolf 
1034fbb7b4e0SKevin Wolf     if ((offset > len) || (len - offset < size))
103571d0770cSaliguori         return -EIO;
103671d0770cSaliguori 
103771d0770cSaliguori     return 0;
103871d0770cSaliguori }
103971d0770cSaliguori 
104071d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
104171d0770cSaliguori                               int nb_sectors)
104271d0770cSaliguori {
1043eb5a3165SJes Sorensen     return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
1044eb5a3165SJes Sorensen                                    nb_sectors * BDRV_SECTOR_SIZE);
104571d0770cSaliguori }
104671d0770cSaliguori 
1047e7a8a783SKevin Wolf static inline bool bdrv_has_async_rw(BlockDriver *drv)
1048e7a8a783SKevin Wolf {
1049e7a8a783SKevin Wolf     return drv->bdrv_co_readv != bdrv_co_readv_em
1050e7a8a783SKevin Wolf         || drv->bdrv_aio_readv != bdrv_aio_readv_em;
1051e7a8a783SKevin Wolf }
1052e7a8a783SKevin Wolf 
1053e7a8a783SKevin Wolf static inline bool bdrv_has_async_flush(BlockDriver *drv)
1054e7a8a783SKevin Wolf {
1055e7a8a783SKevin Wolf     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
1056e7a8a783SKevin Wolf }
1057e7a8a783SKevin Wolf 
10581c9805a3SStefan Hajnoczi typedef struct RwCo {
10591c9805a3SStefan Hajnoczi     BlockDriverState *bs;
10601c9805a3SStefan Hajnoczi     int64_t sector_num;
10611c9805a3SStefan Hajnoczi     int nb_sectors;
10621c9805a3SStefan Hajnoczi     QEMUIOVector *qiov;
10631c9805a3SStefan Hajnoczi     bool is_write;
10641c9805a3SStefan Hajnoczi     int ret;
10651c9805a3SStefan Hajnoczi } RwCo;
10661c9805a3SStefan Hajnoczi 
10671c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque)
1068fc01f7e7Sbellard {
10691c9805a3SStefan Hajnoczi     RwCo *rwco = opaque;
1070fc01f7e7Sbellard 
10711c9805a3SStefan Hajnoczi     if (!rwco->is_write) {
10721c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
10731c9805a3SStefan Hajnoczi                                      rwco->nb_sectors, rwco->qiov);
10741c9805a3SStefan Hajnoczi     } else {
10751c9805a3SStefan Hajnoczi         rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
10761c9805a3SStefan Hajnoczi                                       rwco->nb_sectors, rwco->qiov);
10771c9805a3SStefan Hajnoczi     }
10781c9805a3SStefan Hajnoczi }
1079e7a8a783SKevin Wolf 
10801c9805a3SStefan Hajnoczi /*
10811c9805a3SStefan Hajnoczi  * Process a synchronous request using coroutines
10821c9805a3SStefan Hajnoczi  */
10831c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
10841c9805a3SStefan Hajnoczi                       int nb_sectors, bool is_write)
10851c9805a3SStefan Hajnoczi {
1086e7a8a783SKevin Wolf     QEMUIOVector qiov;
1087e7a8a783SKevin Wolf     struct iovec iov = {
1088e7a8a783SKevin Wolf         .iov_base = (void *)buf,
1089e7a8a783SKevin Wolf         .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
1090e7a8a783SKevin Wolf     };
10911c9805a3SStefan Hajnoczi     Coroutine *co;
10921c9805a3SStefan Hajnoczi     RwCo rwco = {
10931c9805a3SStefan Hajnoczi         .bs = bs,
10941c9805a3SStefan Hajnoczi         .sector_num = sector_num,
10951c9805a3SStefan Hajnoczi         .nb_sectors = nb_sectors,
10961c9805a3SStefan Hajnoczi         .qiov = &qiov,
10971c9805a3SStefan Hajnoczi         .is_write = is_write,
10981c9805a3SStefan Hajnoczi         .ret = NOT_DONE,
10991c9805a3SStefan Hajnoczi     };
1100e7a8a783SKevin Wolf 
1101e7a8a783SKevin Wolf     qemu_iovec_init_external(&qiov, &iov, 1);
11021c9805a3SStefan Hajnoczi 
11031c9805a3SStefan Hajnoczi     if (qemu_in_coroutine()) {
11041c9805a3SStefan Hajnoczi         /* Fast-path if already in coroutine context */
11051c9805a3SStefan Hajnoczi         bdrv_rw_co_entry(&rwco);
11061c9805a3SStefan Hajnoczi     } else {
11071c9805a3SStefan Hajnoczi         co = qemu_coroutine_create(bdrv_rw_co_entry);
11081c9805a3SStefan Hajnoczi         qemu_coroutine_enter(co, &rwco);
11091c9805a3SStefan Hajnoczi         while (rwco.ret == NOT_DONE) {
11101c9805a3SStefan Hajnoczi             qemu_aio_wait();
11111c9805a3SStefan Hajnoczi         }
11121c9805a3SStefan Hajnoczi     }
11131c9805a3SStefan Hajnoczi     return rwco.ret;
1114e7a8a783SKevin Wolf }
1115e7a8a783SKevin Wolf 
11161c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */
11171c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num,
11181c9805a3SStefan Hajnoczi               uint8_t *buf, int nb_sectors)
11191c9805a3SStefan Hajnoczi {
11201c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
112183f64091Sbellard }
1122fc01f7e7Sbellard 
11237cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
11247cd1e32aSlirans@il.ibm.com                              int nb_sectors, int dirty)
11257cd1e32aSlirans@il.ibm.com {
11267cd1e32aSlirans@il.ibm.com     int64_t start, end;
1127c6d22830SJan Kiszka     unsigned long val, idx, bit;
1128a55eb92cSJan Kiszka 
11296ea44308SJan Kiszka     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
1130c6d22830SJan Kiszka     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
11317cd1e32aSlirans@il.ibm.com 
11327cd1e32aSlirans@il.ibm.com     for (; start <= end; start++) {
1133c6d22830SJan Kiszka         idx = start / (sizeof(unsigned long) * 8);
1134c6d22830SJan Kiszka         bit = start % (sizeof(unsigned long) * 8);
1135c6d22830SJan Kiszka         val = bs->dirty_bitmap[idx];
1136c6d22830SJan Kiszka         if (dirty) {
11376d59fec1SMarcelo Tosatti             if (!(val & (1UL << bit))) {
1138aaa0eb75SLiran Schour                 bs->dirty_count++;
11396d59fec1SMarcelo Tosatti                 val |= 1UL << bit;
1140aaa0eb75SLiran Schour             }
1141c6d22830SJan Kiszka         } else {
11426d59fec1SMarcelo Tosatti             if (val & (1UL << bit)) {
1143aaa0eb75SLiran Schour                 bs->dirty_count--;
11446d59fec1SMarcelo Tosatti                 val &= ~(1UL << bit);
1145c6d22830SJan Kiszka             }
1146aaa0eb75SLiran Schour         }
1147c6d22830SJan Kiszka         bs->dirty_bitmap[idx] = val;
11487cd1e32aSlirans@il.ibm.com     }
11497cd1e32aSlirans@il.ibm.com }
11507cd1e32aSlirans@il.ibm.com 
115119cb3738Sbellard /* Return < 0 if error. Important errors are:
115219cb3738Sbellard   -EIO         generic I/O error (may happen for all errors)
115319cb3738Sbellard   -ENOMEDIUM   No media inserted.
115419cb3738Sbellard   -EINVAL      Invalid sector number or nb_sectors
115519cb3738Sbellard   -EACCES      Trying to write a read-only device
115619cb3738Sbellard */
1157fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1158fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
1159fc01f7e7Sbellard {
11601c9805a3SStefan Hajnoczi     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
116183f64091Sbellard }
116283f64091Sbellard 
1163eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset,
1164eda578e5Saliguori                void *buf, int count1)
116583f64091Sbellard {
11666ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
116783f64091Sbellard     int len, nb_sectors, count;
116883f64091Sbellard     int64_t sector_num;
11699a8c4cceSKevin Wolf     int ret;
117083f64091Sbellard 
117183f64091Sbellard     count = count1;
117283f64091Sbellard     /* first read to align to sector start */
11736ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
117483f64091Sbellard     if (len > count)
117583f64091Sbellard         len = count;
11766ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
117783f64091Sbellard     if (len > 0) {
11789a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
11799a8c4cceSKevin Wolf             return ret;
11806ea44308SJan Kiszka         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
118183f64091Sbellard         count -= len;
118283f64091Sbellard         if (count == 0)
118383f64091Sbellard             return count1;
118483f64091Sbellard         sector_num++;
118583f64091Sbellard         buf += len;
118683f64091Sbellard     }
118783f64091Sbellard 
118883f64091Sbellard     /* read the sectors "in place" */
11896ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
119083f64091Sbellard     if (nb_sectors > 0) {
11919a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
11929a8c4cceSKevin Wolf             return ret;
119383f64091Sbellard         sector_num += nb_sectors;
11946ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
119583f64091Sbellard         buf += len;
119683f64091Sbellard         count -= len;
119783f64091Sbellard     }
119883f64091Sbellard 
119983f64091Sbellard     /* add data from the last sector */
120083f64091Sbellard     if (count > 0) {
12019a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12029a8c4cceSKevin Wolf             return ret;
120383f64091Sbellard         memcpy(buf, tmp_buf, count);
120483f64091Sbellard     }
120583f64091Sbellard     return count1;
120683f64091Sbellard }
120783f64091Sbellard 
1208eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1209eda578e5Saliguori                 const void *buf, int count1)
121083f64091Sbellard {
12116ea44308SJan Kiszka     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
121283f64091Sbellard     int len, nb_sectors, count;
121383f64091Sbellard     int64_t sector_num;
12149a8c4cceSKevin Wolf     int ret;
121583f64091Sbellard 
121683f64091Sbellard     count = count1;
121783f64091Sbellard     /* first write to align to sector start */
12186ea44308SJan Kiszka     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
121983f64091Sbellard     if (len > count)
122083f64091Sbellard         len = count;
12216ea44308SJan Kiszka     sector_num = offset >> BDRV_SECTOR_BITS;
122283f64091Sbellard     if (len > 0) {
12239a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12249a8c4cceSKevin Wolf             return ret;
12256ea44308SJan Kiszka         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
12269a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12279a8c4cceSKevin Wolf             return ret;
122883f64091Sbellard         count -= len;
122983f64091Sbellard         if (count == 0)
123083f64091Sbellard             return count1;
123183f64091Sbellard         sector_num++;
123283f64091Sbellard         buf += len;
123383f64091Sbellard     }
123483f64091Sbellard 
123583f64091Sbellard     /* write the sectors "in place" */
12366ea44308SJan Kiszka     nb_sectors = count >> BDRV_SECTOR_BITS;
123783f64091Sbellard     if (nb_sectors > 0) {
12389a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
12399a8c4cceSKevin Wolf             return ret;
124083f64091Sbellard         sector_num += nb_sectors;
12416ea44308SJan Kiszka         len = nb_sectors << BDRV_SECTOR_BITS;
124283f64091Sbellard         buf += len;
124383f64091Sbellard         count -= len;
124483f64091Sbellard     }
124583f64091Sbellard 
124683f64091Sbellard     /* add data from the last sector */
124783f64091Sbellard     if (count > 0) {
12489a8c4cceSKevin Wolf         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
12499a8c4cceSKevin Wolf             return ret;
125083f64091Sbellard         memcpy(tmp_buf, buf, count);
12519a8c4cceSKevin Wolf         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
12529a8c4cceSKevin Wolf             return ret;
125383f64091Sbellard     }
125483f64091Sbellard     return count1;
125583f64091Sbellard }
125683f64091Sbellard 
1257f08145feSKevin Wolf /*
1258f08145feSKevin Wolf  * Writes to the file and ensures that no writes are reordered across this
1259f08145feSKevin Wolf  * request (acts as a barrier)
1260f08145feSKevin Wolf  *
1261f08145feSKevin Wolf  * Returns 0 on success, -errno in error cases.
1262f08145feSKevin Wolf  */
1263f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
1264f08145feSKevin Wolf     const void *buf, int count)
1265f08145feSKevin Wolf {
1266f08145feSKevin Wolf     int ret;
1267f08145feSKevin Wolf 
1268f08145feSKevin Wolf     ret = bdrv_pwrite(bs, offset, buf, count);
1269f08145feSKevin Wolf     if (ret < 0) {
1270f08145feSKevin Wolf         return ret;
1271f08145feSKevin Wolf     }
1272f08145feSKevin Wolf 
127392196b2fSStefan Hajnoczi     /* No flush needed for cache modes that use O_DSYNC */
127492196b2fSStefan Hajnoczi     if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
1275f08145feSKevin Wolf         bdrv_flush(bs);
1276f08145feSKevin Wolf     }
1277f08145feSKevin Wolf 
1278f08145feSKevin Wolf     return 0;
1279f08145feSKevin Wolf }
1280f08145feSKevin Wolf 
1281c5fbe571SStefan Hajnoczi /*
1282c5fbe571SStefan Hajnoczi  * Handle a read request in coroutine context
1283c5fbe571SStefan Hajnoczi  */
1284c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
1285c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1286da1fa91dSKevin Wolf {
1287da1fa91dSKevin Wolf     BlockDriver *drv = bs->drv;
1288da1fa91dSKevin Wolf 
1289da1fa91dSKevin Wolf     if (!drv) {
1290da1fa91dSKevin Wolf         return -ENOMEDIUM;
1291da1fa91dSKevin Wolf     }
1292da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1293da1fa91dSKevin Wolf         return -EIO;
1294da1fa91dSKevin Wolf     }
1295da1fa91dSKevin Wolf 
1296da1fa91dSKevin Wolf     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
1297da1fa91dSKevin Wolf }
1298da1fa91dSKevin Wolf 
1299c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
1300da1fa91dSKevin Wolf     int nb_sectors, QEMUIOVector *qiov)
1301da1fa91dSKevin Wolf {
1302c5fbe571SStefan Hajnoczi     trace_bdrv_co_readv(bs, sector_num, nb_sectors);
1303da1fa91dSKevin Wolf 
1304c5fbe571SStefan Hajnoczi     return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
1305c5fbe571SStefan Hajnoczi }
1306c5fbe571SStefan Hajnoczi 
1307c5fbe571SStefan Hajnoczi /*
1308c5fbe571SStefan Hajnoczi  * Handle a write request in coroutine context
1309c5fbe571SStefan Hajnoczi  */
1310c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
1311c5fbe571SStefan Hajnoczi     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
1312c5fbe571SStefan Hajnoczi {
1313c5fbe571SStefan Hajnoczi     BlockDriver *drv = bs->drv;
1314da1fa91dSKevin Wolf 
1315da1fa91dSKevin Wolf     if (!bs->drv) {
1316da1fa91dSKevin Wolf         return -ENOMEDIUM;
1317da1fa91dSKevin Wolf     }
1318da1fa91dSKevin Wolf     if (bs->read_only) {
1319da1fa91dSKevin Wolf         return -EACCES;
1320da1fa91dSKevin Wolf     }
1321da1fa91dSKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors)) {
1322da1fa91dSKevin Wolf         return -EIO;
1323da1fa91dSKevin Wolf     }
1324da1fa91dSKevin Wolf 
1325da1fa91dSKevin Wolf     if (bs->dirty_bitmap) {
1326da1fa91dSKevin Wolf         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
1327da1fa91dSKevin Wolf     }
1328da1fa91dSKevin Wolf 
1329da1fa91dSKevin Wolf     if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
1330da1fa91dSKevin Wolf         bs->wr_highest_sector = sector_num + nb_sectors - 1;
1331da1fa91dSKevin Wolf     }
1332da1fa91dSKevin Wolf 
1333da1fa91dSKevin Wolf     return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
1334da1fa91dSKevin Wolf }
1335da1fa91dSKevin Wolf 
1336c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
1337c5fbe571SStefan Hajnoczi     int nb_sectors, QEMUIOVector *qiov)
1338c5fbe571SStefan Hajnoczi {
1339c5fbe571SStefan Hajnoczi     trace_bdrv_co_writev(bs, sector_num, nb_sectors);
1340c5fbe571SStefan Hajnoczi 
1341c5fbe571SStefan Hajnoczi     return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
1342c5fbe571SStefan Hajnoczi }
1343c5fbe571SStefan Hajnoczi 
134483f64091Sbellard /**
134583f64091Sbellard  * Truncate file to 'offset' bytes (needed only for file protocols)
134683f64091Sbellard  */
134783f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset)
134883f64091Sbellard {
134983f64091Sbellard     BlockDriver *drv = bs->drv;
135051762288SStefan Hajnoczi     int ret;
135183f64091Sbellard     if (!drv)
135219cb3738Sbellard         return -ENOMEDIUM;
135383f64091Sbellard     if (!drv->bdrv_truncate)
135483f64091Sbellard         return -ENOTSUP;
135559f2689dSNaphtali Sprei     if (bs->read_only)
135659f2689dSNaphtali Sprei         return -EACCES;
13578591675fSMarcelo Tosatti     if (bdrv_in_use(bs))
13588591675fSMarcelo Tosatti         return -EBUSY;
135951762288SStefan Hajnoczi     ret = drv->bdrv_truncate(bs, offset);
136051762288SStefan Hajnoczi     if (ret == 0) {
136151762288SStefan Hajnoczi         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
1362145feb17SMarkus Armbruster         bdrv_dev_resize_cb(bs);
136351762288SStefan Hajnoczi     }
136451762288SStefan Hajnoczi     return ret;
136583f64091Sbellard }
136683f64091Sbellard 
136783f64091Sbellard /**
13684a1d5e1fSFam Zheng  * Length of a allocated file in bytes. Sparse files are counted by actual
13694a1d5e1fSFam Zheng  * allocated space. Return < 0 if error or unknown.
13704a1d5e1fSFam Zheng  */
13714a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
13724a1d5e1fSFam Zheng {
13734a1d5e1fSFam Zheng     BlockDriver *drv = bs->drv;
13744a1d5e1fSFam Zheng     if (!drv) {
13754a1d5e1fSFam Zheng         return -ENOMEDIUM;
13764a1d5e1fSFam Zheng     }
13774a1d5e1fSFam Zheng     if (drv->bdrv_get_allocated_file_size) {
13784a1d5e1fSFam Zheng         return drv->bdrv_get_allocated_file_size(bs);
13794a1d5e1fSFam Zheng     }
13804a1d5e1fSFam Zheng     if (bs->file) {
13814a1d5e1fSFam Zheng         return bdrv_get_allocated_file_size(bs->file);
13824a1d5e1fSFam Zheng     }
13834a1d5e1fSFam Zheng     return -ENOTSUP;
13844a1d5e1fSFam Zheng }
13854a1d5e1fSFam Zheng 
13864a1d5e1fSFam Zheng /**
138783f64091Sbellard  * Length of a file in bytes. Return < 0 if error or unknown.
138883f64091Sbellard  */
138983f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs)
139083f64091Sbellard {
139183f64091Sbellard     BlockDriver *drv = bs->drv;
139283f64091Sbellard     if (!drv)
139319cb3738Sbellard         return -ENOMEDIUM;
139451762288SStefan Hajnoczi 
13952c6942faSMarkus Armbruster     if (bs->growable || bdrv_dev_has_removable_media(bs)) {
139646a4e4e6SStefan Hajnoczi         if (drv->bdrv_getlength) {
139783f64091Sbellard             return drv->bdrv_getlength(bs);
1398fc01f7e7Sbellard         }
139946a4e4e6SStefan Hajnoczi     }
140046a4e4e6SStefan Hajnoczi     return bs->total_sectors * BDRV_SECTOR_SIZE;
140146a4e4e6SStefan Hajnoczi }
1402fc01f7e7Sbellard 
140319cb3738Sbellard /* return 0 as number of sectors if no device present or error */
140496b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1405fc01f7e7Sbellard {
140619cb3738Sbellard     int64_t length;
140719cb3738Sbellard     length = bdrv_getlength(bs);
140819cb3738Sbellard     if (length < 0)
140919cb3738Sbellard         length = 0;
141019cb3738Sbellard     else
14116ea44308SJan Kiszka         length = length >> BDRV_SECTOR_BITS;
141219cb3738Sbellard     *nb_sectors_ptr = length;
1413fc01f7e7Sbellard }
1414cf98951bSbellard 
1415f3d54fc4Saliguori struct partition {
1416f3d54fc4Saliguori         uint8_t boot_ind;           /* 0x80 - active */
1417f3d54fc4Saliguori         uint8_t head;               /* starting head */
1418f3d54fc4Saliguori         uint8_t sector;             /* starting sector */
1419f3d54fc4Saliguori         uint8_t cyl;                /* starting cylinder */
1420f3d54fc4Saliguori         uint8_t sys_ind;            /* What partition type */
1421f3d54fc4Saliguori         uint8_t end_head;           /* end head */
1422f3d54fc4Saliguori         uint8_t end_sector;         /* end sector */
1423f3d54fc4Saliguori         uint8_t end_cyl;            /* end cylinder */
1424f3d54fc4Saliguori         uint32_t start_sect;        /* starting sector counting from 0 */
1425f3d54fc4Saliguori         uint32_t nr_sects;          /* nr of sectors in partition */
1426541dc0d4SStefan Weil } QEMU_PACKED;
1427f3d54fc4Saliguori 
1428f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1429f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs,
1430f3d54fc4Saliguori                            int *pcylinders, int *pheads, int *psectors)
1431f3d54fc4Saliguori {
1432eb5a3165SJes Sorensen     uint8_t buf[BDRV_SECTOR_SIZE];
1433f3d54fc4Saliguori     int ret, i, heads, sectors, cylinders;
1434f3d54fc4Saliguori     struct partition *p;
1435f3d54fc4Saliguori     uint32_t nr_sects;
1436a38131b6Sblueswir1     uint64_t nb_sectors;
1437f3d54fc4Saliguori 
1438f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1439f3d54fc4Saliguori 
1440f3d54fc4Saliguori     ret = bdrv_read(bs, 0, buf, 1);
1441f3d54fc4Saliguori     if (ret < 0)
1442f3d54fc4Saliguori         return -1;
1443f3d54fc4Saliguori     /* test msdos magic */
1444f3d54fc4Saliguori     if (buf[510] != 0x55 || buf[511] != 0xaa)
1445f3d54fc4Saliguori         return -1;
1446f3d54fc4Saliguori     for(i = 0; i < 4; i++) {
1447f3d54fc4Saliguori         p = ((struct partition *)(buf + 0x1be)) + i;
1448f3d54fc4Saliguori         nr_sects = le32_to_cpu(p->nr_sects);
1449f3d54fc4Saliguori         if (nr_sects && p->end_head) {
1450f3d54fc4Saliguori             /* We make the assumption that the partition terminates on
1451f3d54fc4Saliguori                a cylinder boundary */
1452f3d54fc4Saliguori             heads = p->end_head + 1;
1453f3d54fc4Saliguori             sectors = p->end_sector & 63;
1454f3d54fc4Saliguori             if (sectors == 0)
1455f3d54fc4Saliguori                 continue;
1456f3d54fc4Saliguori             cylinders = nb_sectors / (heads * sectors);
1457f3d54fc4Saliguori             if (cylinders < 1 || cylinders > 16383)
1458f3d54fc4Saliguori                 continue;
1459f3d54fc4Saliguori             *pheads = heads;
1460f3d54fc4Saliguori             *psectors = sectors;
1461f3d54fc4Saliguori             *pcylinders = cylinders;
1462f3d54fc4Saliguori #if 0
1463f3d54fc4Saliguori             printf("guessed geometry: LCHS=%d %d %d\n",
1464f3d54fc4Saliguori                    cylinders, heads, sectors);
1465f3d54fc4Saliguori #endif
1466f3d54fc4Saliguori             return 0;
1467f3d54fc4Saliguori         }
1468f3d54fc4Saliguori     }
1469f3d54fc4Saliguori     return -1;
1470f3d54fc4Saliguori }
1471f3d54fc4Saliguori 
1472f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1473f3d54fc4Saliguori {
1474f3d54fc4Saliguori     int translation, lba_detected = 0;
1475f3d54fc4Saliguori     int cylinders, heads, secs;
1476a38131b6Sblueswir1     uint64_t nb_sectors;
1477f3d54fc4Saliguori 
1478f3d54fc4Saliguori     /* if a geometry hint is available, use it */
1479f3d54fc4Saliguori     bdrv_get_geometry(bs, &nb_sectors);
1480f3d54fc4Saliguori     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
1481f3d54fc4Saliguori     translation = bdrv_get_translation_hint(bs);
1482f3d54fc4Saliguori     if (cylinders != 0) {
1483f3d54fc4Saliguori         *pcyls = cylinders;
1484f3d54fc4Saliguori         *pheads = heads;
1485f3d54fc4Saliguori         *psecs = secs;
1486f3d54fc4Saliguori     } else {
1487f3d54fc4Saliguori         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
1488f3d54fc4Saliguori             if (heads > 16) {
1489f3d54fc4Saliguori                 /* if heads > 16, it means that a BIOS LBA
1490f3d54fc4Saliguori                    translation was active, so the default
1491f3d54fc4Saliguori                    hardware geometry is OK */
1492f3d54fc4Saliguori                 lba_detected = 1;
1493f3d54fc4Saliguori                 goto default_geometry;
1494f3d54fc4Saliguori             } else {
1495f3d54fc4Saliguori                 *pcyls = cylinders;
1496f3d54fc4Saliguori                 *pheads = heads;
1497f3d54fc4Saliguori                 *psecs = secs;
1498f3d54fc4Saliguori                 /* disable any translation to be in sync with
1499f3d54fc4Saliguori                    the logical geometry */
1500f3d54fc4Saliguori                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1501f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1502f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_NONE);
1503f3d54fc4Saliguori                 }
1504f3d54fc4Saliguori             }
1505f3d54fc4Saliguori         } else {
1506f3d54fc4Saliguori         default_geometry:
1507f3d54fc4Saliguori             /* if no geometry, use a standard physical disk geometry */
1508f3d54fc4Saliguori             cylinders = nb_sectors / (16 * 63);
1509f3d54fc4Saliguori 
1510f3d54fc4Saliguori             if (cylinders > 16383)
1511f3d54fc4Saliguori                 cylinders = 16383;
1512f3d54fc4Saliguori             else if (cylinders < 2)
1513f3d54fc4Saliguori                 cylinders = 2;
1514f3d54fc4Saliguori             *pcyls = cylinders;
1515f3d54fc4Saliguori             *pheads = 16;
1516f3d54fc4Saliguori             *psecs = 63;
1517f3d54fc4Saliguori             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
1518f3d54fc4Saliguori                 if ((*pcyls * *pheads) <= 131072) {
1519f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1520f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LARGE);
1521f3d54fc4Saliguori                 } else {
1522f3d54fc4Saliguori                     bdrv_set_translation_hint(bs,
1523f3d54fc4Saliguori                                               BIOS_ATA_TRANSLATION_LBA);
1524f3d54fc4Saliguori                 }
1525f3d54fc4Saliguori             }
1526f3d54fc4Saliguori         }
1527f3d54fc4Saliguori         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
1528f3d54fc4Saliguori     }
1529f3d54fc4Saliguori }
1530f3d54fc4Saliguori 
1531b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs,
1532b338082bSbellard                             int cyls, int heads, int secs)
1533b338082bSbellard {
1534b338082bSbellard     bs->cyls = cyls;
1535b338082bSbellard     bs->heads = heads;
1536b338082bSbellard     bs->secs = secs;
1537b338082bSbellard }
1538b338082bSbellard 
153946d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
154046d4767dSbellard {
154146d4767dSbellard     bs->translation = translation;
154246d4767dSbellard }
154346d4767dSbellard 
1544b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs,
1545b338082bSbellard                             int *pcyls, int *pheads, int *psecs)
1546b338082bSbellard {
1547b338082bSbellard     *pcyls = bs->cyls;
1548b338082bSbellard     *pheads = bs->heads;
1549b338082bSbellard     *psecs = bs->secs;
1550b338082bSbellard }
1551b338082bSbellard 
15525bbdbb46SBlue Swirl /* Recognize floppy formats */
15535bbdbb46SBlue Swirl typedef struct FDFormat {
15545bbdbb46SBlue Swirl     FDriveType drive;
15555bbdbb46SBlue Swirl     uint8_t last_sect;
15565bbdbb46SBlue Swirl     uint8_t max_track;
15575bbdbb46SBlue Swirl     uint8_t max_head;
15585bbdbb46SBlue Swirl } FDFormat;
15595bbdbb46SBlue Swirl 
15605bbdbb46SBlue Swirl static const FDFormat fd_formats[] = {
15615bbdbb46SBlue Swirl     /* First entry is default format */
15625bbdbb46SBlue Swirl     /* 1.44 MB 3"1/2 floppy disks */
15635bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 18, 80, 1, },
15645bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 20, 80, 1, },
15655bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 80, 1, },
15665bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 82, 1, },
15675bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 21, 83, 1, },
15685bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 22, 80, 1, },
15695bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 23, 80, 1, },
15705bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 24, 80, 1, },
15715bbdbb46SBlue Swirl     /* 2.88 MB 3"1/2 floppy disks */
15725bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 36, 80, 1, },
15735bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 39, 80, 1, },
15745bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 40, 80, 1, },
15755bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 44, 80, 1, },
15765bbdbb46SBlue Swirl     { FDRIVE_DRV_288, 48, 80, 1, },
15775bbdbb46SBlue Swirl     /* 720 kB 3"1/2 floppy disks */
15785bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 1, },
15795bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 80, 1, },
15805bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 82, 1, },
15815bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 10, 83, 1, },
15825bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 13, 80, 1, },
15835bbdbb46SBlue Swirl     { FDRIVE_DRV_144, 14, 80, 1, },
15845bbdbb46SBlue Swirl     /* 1.2 MB 5"1/4 floppy disks */
15855bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 15, 80, 1, },
15865bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 80, 1, },
15875bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 82, 1, },
15885bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 18, 83, 1, },
15895bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 20, 80, 1, },
15905bbdbb46SBlue Swirl     /* 720 kB 5"1/4 floppy disks */
15915bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 80, 1, },
15925bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 11, 80, 1, },
15935bbdbb46SBlue Swirl     /* 360 kB 5"1/4 floppy disks */
15945bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 1, },
15955bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  9, 40, 0, },
15965bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 41, 1, },
15975bbdbb46SBlue Swirl     { FDRIVE_DRV_120, 10, 42, 1, },
15985bbdbb46SBlue Swirl     /* 320 kB 5"1/4 floppy disks */
15995bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 1, },
16005bbdbb46SBlue Swirl     { FDRIVE_DRV_120,  8, 40, 0, },
16015bbdbb46SBlue Swirl     /* 360 kB must match 5"1/4 better than 3"1/2... */
16025bbdbb46SBlue Swirl     { FDRIVE_DRV_144,  9, 80, 0, },
16035bbdbb46SBlue Swirl     /* end */
16045bbdbb46SBlue Swirl     { FDRIVE_DRV_NONE, -1, -1, 0, },
16055bbdbb46SBlue Swirl };
16065bbdbb46SBlue Swirl 
16075bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
16085bbdbb46SBlue Swirl                                    int *max_track, int *last_sect,
16095bbdbb46SBlue Swirl                                    FDriveType drive_in, FDriveType *drive)
16105bbdbb46SBlue Swirl {
16115bbdbb46SBlue Swirl     const FDFormat *parse;
16125bbdbb46SBlue Swirl     uint64_t nb_sectors, size;
16135bbdbb46SBlue Swirl     int i, first_match, match;
16145bbdbb46SBlue Swirl 
16155bbdbb46SBlue Swirl     bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
16165bbdbb46SBlue Swirl     if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
16175bbdbb46SBlue Swirl         /* User defined disk */
16185bbdbb46SBlue Swirl     } else {
16195bbdbb46SBlue Swirl         bdrv_get_geometry(bs, &nb_sectors);
16205bbdbb46SBlue Swirl         match = -1;
16215bbdbb46SBlue Swirl         first_match = -1;
16225bbdbb46SBlue Swirl         for (i = 0; ; i++) {
16235bbdbb46SBlue Swirl             parse = &fd_formats[i];
16245bbdbb46SBlue Swirl             if (parse->drive == FDRIVE_DRV_NONE) {
16255bbdbb46SBlue Swirl                 break;
16265bbdbb46SBlue Swirl             }
16275bbdbb46SBlue Swirl             if (drive_in == parse->drive ||
16285bbdbb46SBlue Swirl                 drive_in == FDRIVE_DRV_NONE) {
16295bbdbb46SBlue Swirl                 size = (parse->max_head + 1) * parse->max_track *
16305bbdbb46SBlue Swirl                     parse->last_sect;
16315bbdbb46SBlue Swirl                 if (nb_sectors == size) {
16325bbdbb46SBlue Swirl                     match = i;
16335bbdbb46SBlue Swirl                     break;
16345bbdbb46SBlue Swirl                 }
16355bbdbb46SBlue Swirl                 if (first_match == -1) {
16365bbdbb46SBlue Swirl                     first_match = i;
16375bbdbb46SBlue Swirl                 }
16385bbdbb46SBlue Swirl             }
16395bbdbb46SBlue Swirl         }
16405bbdbb46SBlue Swirl         if (match == -1) {
16415bbdbb46SBlue Swirl             if (first_match == -1) {
16425bbdbb46SBlue Swirl                 match = 1;
16435bbdbb46SBlue Swirl             } else {
16445bbdbb46SBlue Swirl                 match = first_match;
16455bbdbb46SBlue Swirl             }
16465bbdbb46SBlue Swirl             parse = &fd_formats[match];
16475bbdbb46SBlue Swirl         }
16485bbdbb46SBlue Swirl         *nb_heads = parse->max_head + 1;
16495bbdbb46SBlue Swirl         *max_track = parse->max_track;
16505bbdbb46SBlue Swirl         *last_sect = parse->last_sect;
16515bbdbb46SBlue Swirl         *drive = parse->drive;
16525bbdbb46SBlue Swirl     }
16535bbdbb46SBlue Swirl }
16545bbdbb46SBlue Swirl 
165546d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs)
165646d4767dSbellard {
165746d4767dSbellard     return bs->translation;
165846d4767dSbellard }
165946d4767dSbellard 
1660abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
1661abd7f68dSMarkus Armbruster                        BlockErrorAction on_write_error)
1662abd7f68dSMarkus Armbruster {
1663abd7f68dSMarkus Armbruster     bs->on_read_error = on_read_error;
1664abd7f68dSMarkus Armbruster     bs->on_write_error = on_write_error;
1665abd7f68dSMarkus Armbruster }
1666abd7f68dSMarkus Armbruster 
1667abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
1668abd7f68dSMarkus Armbruster {
1669abd7f68dSMarkus Armbruster     return is_read ? bs->on_read_error : bs->on_write_error;
1670abd7f68dSMarkus Armbruster }
1671abd7f68dSMarkus Armbruster 
1672b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs)
1673b338082bSbellard {
1674b338082bSbellard     return bs->read_only;
1675b338082bSbellard }
1676b338082bSbellard 
1677985a03b0Sths int bdrv_is_sg(BlockDriverState *bs)
1678985a03b0Sths {
1679985a03b0Sths     return bs->sg;
1680985a03b0Sths }
1681985a03b0Sths 
1682e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs)
1683e900a7b7SChristoph Hellwig {
1684e900a7b7SChristoph Hellwig     return bs->enable_write_cache;
1685e900a7b7SChristoph Hellwig }
1686e900a7b7SChristoph Hellwig 
1687ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs)
1688ea2384d3Sbellard {
1689ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted)
1690ea2384d3Sbellard         return 1;
1691ea2384d3Sbellard     return bs->encrypted;
1692ea2384d3Sbellard }
1693ea2384d3Sbellard 
1694c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs)
1695c0f4ce77Saliguori {
1696c0f4ce77Saliguori     BlockDriverState *backing_hd = bs->backing_hd;
1697c0f4ce77Saliguori 
1698c0f4ce77Saliguori     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
1699c0f4ce77Saliguori         return 1;
1700c0f4ce77Saliguori     return (bs->encrypted && !bs->valid_key);
1701c0f4ce77Saliguori }
1702c0f4ce77Saliguori 
1703ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key)
1704ea2384d3Sbellard {
1705ea2384d3Sbellard     int ret;
1706ea2384d3Sbellard     if (bs->backing_hd && bs->backing_hd->encrypted) {
1707ea2384d3Sbellard         ret = bdrv_set_key(bs->backing_hd, key);
1708ea2384d3Sbellard         if (ret < 0)
1709ea2384d3Sbellard             return ret;
1710ea2384d3Sbellard         if (!bs->encrypted)
1711ea2384d3Sbellard             return 0;
1712ea2384d3Sbellard     }
1713fd04a2aeSShahar Havivi     if (!bs->encrypted) {
1714fd04a2aeSShahar Havivi         return -EINVAL;
1715fd04a2aeSShahar Havivi     } else if (!bs->drv || !bs->drv->bdrv_set_key) {
1716fd04a2aeSShahar Havivi         return -ENOMEDIUM;
1717fd04a2aeSShahar Havivi     }
1718c0f4ce77Saliguori     ret = bs->drv->bdrv_set_key(bs, key);
1719bb5fc20fSaliguori     if (ret < 0) {
1720bb5fc20fSaliguori         bs->valid_key = 0;
1721bb5fc20fSaliguori     } else if (!bs->valid_key) {
1722bb5fc20fSaliguori         bs->valid_key = 1;
1723bb5fc20fSaliguori         /* call the change callback now, we skipped it on open */
17247d4b4ba5SMarkus Armbruster         bdrv_dev_change_media_cb(bs, true);
1725bb5fc20fSaliguori     }
1726c0f4ce77Saliguori     return ret;
1727ea2384d3Sbellard }
1728ea2384d3Sbellard 
1729ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1730ea2384d3Sbellard {
173119cb3738Sbellard     if (!bs->drv) {
1732ea2384d3Sbellard         buf[0] = '\0';
1733ea2384d3Sbellard     } else {
1734ea2384d3Sbellard         pstrcpy(buf, buf_size, bs->drv->format_name);
1735ea2384d3Sbellard     }
1736ea2384d3Sbellard }
1737ea2384d3Sbellard 
1738ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1739ea2384d3Sbellard                          void *opaque)
1740ea2384d3Sbellard {
1741ea2384d3Sbellard     BlockDriver *drv;
1742ea2384d3Sbellard 
17438a22f02aSStefan Hajnoczi     QLIST_FOREACH(drv, &bdrv_drivers, list) {
1744ea2384d3Sbellard         it(opaque, drv->format_name);
1745ea2384d3Sbellard     }
1746ea2384d3Sbellard }
1747ea2384d3Sbellard 
1748b338082bSbellard BlockDriverState *bdrv_find(const char *name)
1749b338082bSbellard {
1750b338082bSbellard     BlockDriverState *bs;
1751b338082bSbellard 
17521b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
17531b7bdbc1SStefan Hajnoczi         if (!strcmp(name, bs->device_name)) {
1754b338082bSbellard             return bs;
1755b338082bSbellard         }
17561b7bdbc1SStefan Hajnoczi     }
1757b338082bSbellard     return NULL;
1758b338082bSbellard }
1759b338082bSbellard 
17602f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs)
17612f399b0aSMarkus Armbruster {
17622f399b0aSMarkus Armbruster     if (!bs) {
17632f399b0aSMarkus Armbruster         return QTAILQ_FIRST(&bdrv_states);
17642f399b0aSMarkus Armbruster     }
17652f399b0aSMarkus Armbruster     return QTAILQ_NEXT(bs, list);
17662f399b0aSMarkus Armbruster }
17672f399b0aSMarkus Armbruster 
176851de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
176981d0912dSbellard {
177081d0912dSbellard     BlockDriverState *bs;
177181d0912dSbellard 
17721b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
177351de9760Saliguori         it(opaque, bs);
177481d0912dSbellard     }
177581d0912dSbellard }
177681d0912dSbellard 
1777ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs)
1778ea2384d3Sbellard {
1779ea2384d3Sbellard     return bs->device_name;
1780ea2384d3Sbellard }
1781ea2384d3Sbellard 
1782205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs)
17837a6cba61Spbrook {
1784016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
1785205ef796SKevin Wolf         return 0;
1786016f5cf6SAlexander Graf     }
1787016f5cf6SAlexander Graf 
1788e7a8a783SKevin Wolf     if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) {
1789e7a8a783SKevin Wolf         return bdrv_co_flush_em(bs);
1790e7a8a783SKevin Wolf     }
1791e7a8a783SKevin Wolf 
1792205ef796SKevin Wolf     if (bs->drv && bs->drv->bdrv_flush) {
1793205ef796SKevin Wolf         return bs->drv->bdrv_flush(bs);
1794205ef796SKevin Wolf     }
1795205ef796SKevin Wolf 
1796205ef796SKevin Wolf     /*
1797205ef796SKevin Wolf      * Some block drivers always operate in either writethrough or unsafe mode
1798205ef796SKevin Wolf      * and don't support bdrv_flush therefore. Usually qemu doesn't know how
1799205ef796SKevin Wolf      * the server works (because the behaviour is hardcoded or depends on
1800205ef796SKevin Wolf      * server-side configuration), so we can't ensure that everything is safe
1801205ef796SKevin Wolf      * on disk. Returning an error doesn't work because that would break guests
1802205ef796SKevin Wolf      * even if the server operates in writethrough mode.
1803205ef796SKevin Wolf      *
1804205ef796SKevin Wolf      * Let's hope the user knows what he's doing.
1805205ef796SKevin Wolf      */
1806205ef796SKevin Wolf     return 0;
18077a6cba61Spbrook }
18087a6cba61Spbrook 
1809c6ca28d6Saliguori void bdrv_flush_all(void)
1810c6ca28d6Saliguori {
1811c6ca28d6Saliguori     BlockDriverState *bs;
1812c6ca28d6Saliguori 
18131b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1814c602a489SMarkus Armbruster         if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
1815c6ca28d6Saliguori             bdrv_flush(bs);
1816c6ca28d6Saliguori         }
18171b7bdbc1SStefan Hajnoczi     }
18181b7bdbc1SStefan Hajnoczi }
1819c6ca28d6Saliguori 
1820f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs)
1821f2feebbdSKevin Wolf {
1822f2feebbdSKevin Wolf     assert(bs->drv);
1823f2feebbdSKevin Wolf 
1824336c1c12SKevin Wolf     if (bs->drv->bdrv_has_zero_init) {
1825336c1c12SKevin Wolf         return bs->drv->bdrv_has_zero_init(bs);
1826f2feebbdSKevin Wolf     }
1827f2feebbdSKevin Wolf 
1828f2feebbdSKevin Wolf     return 1;
1829f2feebbdSKevin Wolf }
1830f2feebbdSKevin Wolf 
1831bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
1832bb8bf76fSChristoph Hellwig {
1833bb8bf76fSChristoph Hellwig     if (!bs->drv) {
1834bb8bf76fSChristoph Hellwig         return -ENOMEDIUM;
1835bb8bf76fSChristoph Hellwig     }
1836bb8bf76fSChristoph Hellwig     if (!bs->drv->bdrv_discard) {
1837bb8bf76fSChristoph Hellwig         return 0;
1838bb8bf76fSChristoph Hellwig     }
1839bb8bf76fSChristoph Hellwig     return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
1840bb8bf76fSChristoph Hellwig }
1841bb8bf76fSChristoph Hellwig 
1842f58c7b35Sths /*
1843f58c7b35Sths  * Returns true iff the specified sector is present in the disk image. Drivers
1844f58c7b35Sths  * not implementing the functionality are assumed to not support backing files,
1845f58c7b35Sths  * hence all their sectors are reported as allocated.
1846f58c7b35Sths  *
1847f58c7b35Sths  * 'pnum' is set to the number of sectors (including and immediately following
1848f58c7b35Sths  * the specified sector) that are known to be in the same
1849f58c7b35Sths  * allocated/unallocated state.
1850f58c7b35Sths  *
1851f58c7b35Sths  * 'nb_sectors' is the max value 'pnum' should be set to.
1852f58c7b35Sths  */
1853f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1854f58c7b35Sths 	int *pnum)
1855f58c7b35Sths {
1856f58c7b35Sths     int64_t n;
1857f58c7b35Sths     if (!bs->drv->bdrv_is_allocated) {
1858f58c7b35Sths         if (sector_num >= bs->total_sectors) {
1859f58c7b35Sths             *pnum = 0;
1860f58c7b35Sths             return 0;
1861f58c7b35Sths         }
1862f58c7b35Sths         n = bs->total_sectors - sector_num;
1863f58c7b35Sths         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1864f58c7b35Sths         return 1;
1865f58c7b35Sths     }
1866f58c7b35Sths     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1867f58c7b35Sths }
1868f58c7b35Sths 
18692582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv,
18702582bfedSLuiz Capitulino                     BlockMonEventAction action, int is_read)
18712582bfedSLuiz Capitulino {
18722582bfedSLuiz Capitulino     QObject *data;
18732582bfedSLuiz Capitulino     const char *action_str;
18742582bfedSLuiz Capitulino 
18752582bfedSLuiz Capitulino     switch (action) {
18762582bfedSLuiz Capitulino     case BDRV_ACTION_REPORT:
18772582bfedSLuiz Capitulino         action_str = "report";
18782582bfedSLuiz Capitulino         break;
18792582bfedSLuiz Capitulino     case BDRV_ACTION_IGNORE:
18802582bfedSLuiz Capitulino         action_str = "ignore";
18812582bfedSLuiz Capitulino         break;
18822582bfedSLuiz Capitulino     case BDRV_ACTION_STOP:
18832582bfedSLuiz Capitulino         action_str = "stop";
18842582bfedSLuiz Capitulino         break;
18852582bfedSLuiz Capitulino     default:
18862582bfedSLuiz Capitulino         abort();
18872582bfedSLuiz Capitulino     }
18882582bfedSLuiz Capitulino 
18892582bfedSLuiz Capitulino     data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
18902582bfedSLuiz Capitulino                               bdrv->device_name,
18912582bfedSLuiz Capitulino                               action_str,
18922582bfedSLuiz Capitulino                               is_read ? "read" : "write");
18932582bfedSLuiz Capitulino     monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data);
18942582bfedSLuiz Capitulino 
18952582bfedSLuiz Capitulino     qobject_decref(data);
18962582bfedSLuiz Capitulino }
18972582bfedSLuiz Capitulino 
1898d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque)
1899b338082bSbellard {
1900d15e5465SLuiz Capitulino     QDict *bs_dict;
1901d15e5465SLuiz Capitulino     Monitor *mon = opaque;
1902b338082bSbellard 
1903d15e5465SLuiz Capitulino     bs_dict = qobject_to_qdict(obj);
1904d15e5465SLuiz Capitulino 
1905d8aeeb31SMarkus Armbruster     monitor_printf(mon, "%s: removable=%d",
1906d15e5465SLuiz Capitulino                         qdict_get_str(bs_dict, "device"),
1907d15e5465SLuiz Capitulino                         qdict_get_bool(bs_dict, "removable"));
1908d15e5465SLuiz Capitulino 
1909d15e5465SLuiz Capitulino     if (qdict_get_bool(bs_dict, "removable")) {
1910d15e5465SLuiz Capitulino         monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
1911e4def80bSMarkus Armbruster         monitor_printf(mon, " tray-open=%d",
1912e4def80bSMarkus Armbruster                        qdict_get_bool(bs_dict, "tray-open"));
1913b338082bSbellard     }
1914d2078cc2SLuiz Capitulino 
1915d2078cc2SLuiz Capitulino     if (qdict_haskey(bs_dict, "io-status")) {
1916d2078cc2SLuiz Capitulino         monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
1917d2078cc2SLuiz Capitulino     }
1918d2078cc2SLuiz Capitulino 
1919d15e5465SLuiz Capitulino     if (qdict_haskey(bs_dict, "inserted")) {
1920d15e5465SLuiz Capitulino         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
1921d15e5465SLuiz Capitulino 
1922376253ecSaliguori         monitor_printf(mon, " file=");
1923d15e5465SLuiz Capitulino         monitor_print_filename(mon, qdict_get_str(qdict, "file"));
1924d15e5465SLuiz Capitulino         if (qdict_haskey(qdict, "backing_file")) {
1925376253ecSaliguori             monitor_printf(mon, " backing_file=");
1926d15e5465SLuiz Capitulino             monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
1927fef30743Sths         }
1928d15e5465SLuiz Capitulino         monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
1929d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "ro"),
1930d15e5465SLuiz Capitulino                             qdict_get_str(qdict, "drv"),
1931d15e5465SLuiz Capitulino                             qdict_get_bool(qdict, "encrypted"));
1932b338082bSbellard     } else {
1933376253ecSaliguori         monitor_printf(mon, " [not inserted]");
1934b338082bSbellard     }
1935d15e5465SLuiz Capitulino 
1936376253ecSaliguori     monitor_printf(mon, "\n");
1937b338082bSbellard }
1938d15e5465SLuiz Capitulino 
1939d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data)
1940d15e5465SLuiz Capitulino {
1941d15e5465SLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
1942d15e5465SLuiz Capitulino }
1943d15e5465SLuiz Capitulino 
1944f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = {
1945f04ef601SLuiz Capitulino     [BDRV_IOS_OK] = "ok",
1946f04ef601SLuiz Capitulino     [BDRV_IOS_FAILED] = "failed",
1947f04ef601SLuiz Capitulino     [BDRV_IOS_ENOSPC] = "nospace",
1948f04ef601SLuiz Capitulino };
1949f04ef601SLuiz Capitulino 
1950d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data)
1951d15e5465SLuiz Capitulino {
1952d15e5465SLuiz Capitulino     QList *bs_list;
1953d15e5465SLuiz Capitulino     BlockDriverState *bs;
1954d15e5465SLuiz Capitulino 
1955d15e5465SLuiz Capitulino     bs_list = qlist_new();
1956d15e5465SLuiz Capitulino 
19571b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
1958d15e5465SLuiz Capitulino         QObject *bs_obj;
1959e4def80bSMarkus Armbruster         QDict *bs_dict;
1960d15e5465SLuiz Capitulino 
1961d8aeeb31SMarkus Armbruster         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
1962d15e5465SLuiz Capitulino                                     "'removable': %i, 'locked': %i }",
19632c6942faSMarkus Armbruster                                     bs->device_name,
19642c6942faSMarkus Armbruster                                     bdrv_dev_has_removable_media(bs),
1965f107639aSMarkus Armbruster                                     bdrv_dev_is_medium_locked(bs));
1966e4def80bSMarkus Armbruster         bs_dict = qobject_to_qdict(bs_obj);
1967d15e5465SLuiz Capitulino 
1968e4def80bSMarkus Armbruster         if (bdrv_dev_has_removable_media(bs)) {
1969e4def80bSMarkus Armbruster             qdict_put(bs_dict, "tray-open",
1970e4def80bSMarkus Armbruster                       qbool_from_int(bdrv_dev_is_tray_open(bs)));
1971e4def80bSMarkus Armbruster         }
1972f04ef601SLuiz Capitulino 
1973f04ef601SLuiz Capitulino         if (bdrv_iostatus_is_enabled(bs)) {
1974f04ef601SLuiz Capitulino             qdict_put(bs_dict, "io-status",
1975f04ef601SLuiz Capitulino                       qstring_from_str(io_status_name[bs->iostatus]));
1976f04ef601SLuiz Capitulino         }
1977f04ef601SLuiz Capitulino 
1978d15e5465SLuiz Capitulino         if (bs->drv) {
1979d15e5465SLuiz Capitulino             QObject *obj;
1980d15e5465SLuiz Capitulino 
1981d15e5465SLuiz Capitulino             obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
1982d15e5465SLuiz Capitulino                                      "'encrypted': %i }",
1983d15e5465SLuiz Capitulino                                      bs->filename, bs->read_only,
1984d15e5465SLuiz Capitulino                                      bs->drv->format_name,
1985d15e5465SLuiz Capitulino                                      bdrv_is_encrypted(bs));
1986d15e5465SLuiz Capitulino             if (bs->backing_file[0] != '\0') {
1987d15e5465SLuiz Capitulino                 QDict *qdict = qobject_to_qdict(obj);
1988d15e5465SLuiz Capitulino                 qdict_put(qdict, "backing_file",
1989d15e5465SLuiz Capitulino                           qstring_from_str(bs->backing_file));
1990d15e5465SLuiz Capitulino             }
1991d15e5465SLuiz Capitulino 
1992d15e5465SLuiz Capitulino             qdict_put_obj(bs_dict, "inserted", obj);
1993d15e5465SLuiz Capitulino         }
1994d15e5465SLuiz Capitulino         qlist_append_obj(bs_list, bs_obj);
1995d15e5465SLuiz Capitulino     }
1996d15e5465SLuiz Capitulino 
1997d15e5465SLuiz Capitulino     *ret_data = QOBJECT(bs_list);
1998b338082bSbellard }
1999a36e69ddSths 
2000218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque)
2001a36e69ddSths {
2002218a536aSLuiz Capitulino     QDict *qdict;
2003218a536aSLuiz Capitulino     Monitor *mon = opaque;
2004218a536aSLuiz Capitulino 
2005218a536aSLuiz Capitulino     qdict = qobject_to_qdict(data);
2006218a536aSLuiz Capitulino     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
2007218a536aSLuiz Capitulino 
2008218a536aSLuiz Capitulino     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
2009218a536aSLuiz Capitulino     monitor_printf(mon, " rd_bytes=%" PRId64
2010218a536aSLuiz Capitulino                         " wr_bytes=%" PRId64
2011218a536aSLuiz Capitulino                         " rd_operations=%" PRId64
2012218a536aSLuiz Capitulino                         " wr_operations=%" PRId64
2013e8045d67SChristoph Hellwig                         " flush_operations=%" PRId64
2014c488c7f6SChristoph Hellwig                         " wr_total_time_ns=%" PRId64
2015c488c7f6SChristoph Hellwig                         " rd_total_time_ns=%" PRId64
2016c488c7f6SChristoph Hellwig                         " flush_total_time_ns=%" PRId64
2017218a536aSLuiz Capitulino                         "\n",
2018218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_bytes"),
2019218a536aSLuiz Capitulino                         qdict_get_int(qdict, "wr_bytes"),
2020218a536aSLuiz Capitulino                         qdict_get_int(qdict, "rd_operations"),
2021e8045d67SChristoph Hellwig                         qdict_get_int(qdict, "wr_operations"),
2022c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_operations"),
2023c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "wr_total_time_ns"),
2024c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "rd_total_time_ns"),
2025c488c7f6SChristoph Hellwig                         qdict_get_int(qdict, "flush_total_time_ns"));
2026218a536aSLuiz Capitulino }
2027218a536aSLuiz Capitulino 
2028218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data)
2029218a536aSLuiz Capitulino {
2030218a536aSLuiz Capitulino     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
2031218a536aSLuiz Capitulino }
2032218a536aSLuiz Capitulino 
2033294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
2034294cc35fSKevin Wolf {
2035294cc35fSKevin Wolf     QObject *res;
2036294cc35fSKevin Wolf     QDict *dict;
2037294cc35fSKevin Wolf 
2038294cc35fSKevin Wolf     res = qobject_from_jsonf("{ 'stats': {"
2039294cc35fSKevin Wolf                              "'rd_bytes': %" PRId64 ","
2040294cc35fSKevin Wolf                              "'wr_bytes': %" PRId64 ","
2041294cc35fSKevin Wolf                              "'rd_operations': %" PRId64 ","
2042294cc35fSKevin Wolf                              "'wr_operations': %" PRId64 ","
2043e8045d67SChristoph Hellwig                              "'wr_highest_offset': %" PRId64 ","
2044c488c7f6SChristoph Hellwig                              "'flush_operations': %" PRId64 ","
2045c488c7f6SChristoph Hellwig                              "'wr_total_time_ns': %" PRId64 ","
2046c488c7f6SChristoph Hellwig                              "'rd_total_time_ns': %" PRId64 ","
2047c488c7f6SChristoph Hellwig                              "'flush_total_time_ns': %" PRId64
2048294cc35fSKevin Wolf                              "} }",
2049a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_READ],
2050a597e79cSChristoph Hellwig                              bs->nr_bytes[BDRV_ACCT_WRITE],
2051a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_READ],
2052a597e79cSChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_WRITE],
20535ffbbc67SBlue Swirl                              bs->wr_highest_sector *
2054e8045d67SChristoph Hellwig                              (uint64_t)BDRV_SECTOR_SIZE,
2055c488c7f6SChristoph Hellwig                              bs->nr_ops[BDRV_ACCT_FLUSH],
2056c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_WRITE],
2057c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_READ],
2058c488c7f6SChristoph Hellwig                              bs->total_time_ns[BDRV_ACCT_FLUSH]);
2059294cc35fSKevin Wolf     dict  = qobject_to_qdict(res);
2060294cc35fSKevin Wolf 
2061294cc35fSKevin Wolf     if (*bs->device_name) {
2062294cc35fSKevin Wolf         qdict_put(dict, "device", qstring_from_str(bs->device_name));
2063294cc35fSKevin Wolf     }
2064294cc35fSKevin Wolf 
2065294cc35fSKevin Wolf     if (bs->file) {
2066294cc35fSKevin Wolf         QObject *parent = bdrv_info_stats_bs(bs->file);
2067294cc35fSKevin Wolf         qdict_put_obj(dict, "parent", parent);
2068294cc35fSKevin Wolf     }
2069294cc35fSKevin Wolf 
2070294cc35fSKevin Wolf     return res;
2071294cc35fSKevin Wolf }
2072294cc35fSKevin Wolf 
2073218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data)
2074218a536aSLuiz Capitulino {
2075218a536aSLuiz Capitulino     QObject *obj;
2076218a536aSLuiz Capitulino     QList *devices;
2077a36e69ddSths     BlockDriverState *bs;
2078a36e69ddSths 
2079218a536aSLuiz Capitulino     devices = qlist_new();
2080218a536aSLuiz Capitulino 
20811b7bdbc1SStefan Hajnoczi     QTAILQ_FOREACH(bs, &bdrv_states, list) {
2082294cc35fSKevin Wolf         obj = bdrv_info_stats_bs(bs);
2083218a536aSLuiz Capitulino         qlist_append_obj(devices, obj);
2084a36e69ddSths     }
2085218a536aSLuiz Capitulino 
2086218a536aSLuiz Capitulino     *ret_data = QOBJECT(devices);
2087a36e69ddSths }
2088ea2384d3Sbellard 
2089045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
2090045df330Saliguori {
2091045df330Saliguori     if (bs->backing_hd && bs->backing_hd->encrypted)
2092045df330Saliguori         return bs->backing_file;
2093045df330Saliguori     else if (bs->encrypted)
2094045df330Saliguori         return bs->filename;
2095045df330Saliguori     else
2096045df330Saliguori         return NULL;
2097045df330Saliguori }
2098045df330Saliguori 
209983f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs,
210083f64091Sbellard                                char *filename, int filename_size)
210183f64091Sbellard {
2102b783e409SKevin Wolf     if (!bs->backing_file) {
210383f64091Sbellard         pstrcpy(filename, filename_size, "");
210483f64091Sbellard     } else {
210583f64091Sbellard         pstrcpy(filename, filename_size, bs->backing_file);
210683f64091Sbellard     }
210783f64091Sbellard }
210883f64091Sbellard 
2109faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
2110faea38e7Sbellard                           const uint8_t *buf, int nb_sectors)
2111faea38e7Sbellard {
2112faea38e7Sbellard     BlockDriver *drv = bs->drv;
2113faea38e7Sbellard     if (!drv)
211419cb3738Sbellard         return -ENOMEDIUM;
2115faea38e7Sbellard     if (!drv->bdrv_write_compressed)
2116faea38e7Sbellard         return -ENOTSUP;
2117fbb7b4e0SKevin Wolf     if (bdrv_check_request(bs, sector_num, nb_sectors))
2118fbb7b4e0SKevin Wolf         return -EIO;
21197cd1e32aSlirans@il.ibm.com 
2120c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
21217cd1e32aSlirans@il.ibm.com         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
21227cd1e32aSlirans@il.ibm.com     }
21237cd1e32aSlirans@il.ibm.com 
2124faea38e7Sbellard     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
2125faea38e7Sbellard }
2126faea38e7Sbellard 
2127faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
2128faea38e7Sbellard {
2129faea38e7Sbellard     BlockDriver *drv = bs->drv;
2130faea38e7Sbellard     if (!drv)
213119cb3738Sbellard         return -ENOMEDIUM;
2132faea38e7Sbellard     if (!drv->bdrv_get_info)
2133faea38e7Sbellard         return -ENOTSUP;
2134faea38e7Sbellard     memset(bdi, 0, sizeof(*bdi));
2135faea38e7Sbellard     return drv->bdrv_get_info(bs, bdi);
2136faea38e7Sbellard }
2137faea38e7Sbellard 
213845566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
213945566e9cSChristoph Hellwig                       int64_t pos, int size)
2140178e08a5Saliguori {
2141178e08a5Saliguori     BlockDriver *drv = bs->drv;
2142178e08a5Saliguori     if (!drv)
2143178e08a5Saliguori         return -ENOMEDIUM;
21447cdb1f6dSMORITA Kazutaka     if (drv->bdrv_save_vmstate)
214545566e9cSChristoph Hellwig         return drv->bdrv_save_vmstate(bs, buf, pos, size);
21467cdb1f6dSMORITA Kazutaka     if (bs->file)
21477cdb1f6dSMORITA Kazutaka         return bdrv_save_vmstate(bs->file, buf, pos, size);
21487cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2149178e08a5Saliguori }
2150178e08a5Saliguori 
215145566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
215245566e9cSChristoph Hellwig                       int64_t pos, int size)
2153178e08a5Saliguori {
2154178e08a5Saliguori     BlockDriver *drv = bs->drv;
2155178e08a5Saliguori     if (!drv)
2156178e08a5Saliguori         return -ENOMEDIUM;
21577cdb1f6dSMORITA Kazutaka     if (drv->bdrv_load_vmstate)
215845566e9cSChristoph Hellwig         return drv->bdrv_load_vmstate(bs, buf, pos, size);
21597cdb1f6dSMORITA Kazutaka     if (bs->file)
21607cdb1f6dSMORITA Kazutaka         return bdrv_load_vmstate(bs->file, buf, pos, size);
21617cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2162178e08a5Saliguori }
2163178e08a5Saliguori 
21648b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
21658b9b0cc2SKevin Wolf {
21668b9b0cc2SKevin Wolf     BlockDriver *drv = bs->drv;
21678b9b0cc2SKevin Wolf 
21688b9b0cc2SKevin Wolf     if (!drv || !drv->bdrv_debug_event) {
21698b9b0cc2SKevin Wolf         return;
21708b9b0cc2SKevin Wolf     }
21718b9b0cc2SKevin Wolf 
21728b9b0cc2SKevin Wolf     return drv->bdrv_debug_event(bs, event);
21738b9b0cc2SKevin Wolf 
21748b9b0cc2SKevin Wolf }
21758b9b0cc2SKevin Wolf 
2176faea38e7Sbellard /**************************************************************/
2177faea38e7Sbellard /* handling of snapshots */
2178faea38e7Sbellard 
2179feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs)
2180feeee5acSMiguel Di Ciurcio Filho {
2181feeee5acSMiguel Di Ciurcio Filho     BlockDriver *drv = bs->drv;
218207b70bfbSMarkus Armbruster     if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
2183feeee5acSMiguel Di Ciurcio Filho         return 0;
2184feeee5acSMiguel Di Ciurcio Filho     }
2185feeee5acSMiguel Di Ciurcio Filho 
2186feeee5acSMiguel Di Ciurcio Filho     if (!drv->bdrv_snapshot_create) {
2187feeee5acSMiguel Di Ciurcio Filho         if (bs->file != NULL) {
2188feeee5acSMiguel Di Ciurcio Filho             return bdrv_can_snapshot(bs->file);
2189feeee5acSMiguel Di Ciurcio Filho         }
2190feeee5acSMiguel Di Ciurcio Filho         return 0;
2191feeee5acSMiguel Di Ciurcio Filho     }
2192feeee5acSMiguel Di Ciurcio Filho 
2193feeee5acSMiguel Di Ciurcio Filho     return 1;
2194feeee5acSMiguel Di Ciurcio Filho }
2195feeee5acSMiguel Di Ciurcio Filho 
2196199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs)
2197199630b6SBlue Swirl {
2198199630b6SBlue Swirl     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
2199199630b6SBlue Swirl }
2200199630b6SBlue Swirl 
2201f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void)
2202f9092b10SMarkus Armbruster {
2203f9092b10SMarkus Armbruster     BlockDriverState *bs;
2204f9092b10SMarkus Armbruster 
22053ac906f7SMarkus Armbruster     if (bs_snapshots) {
2206f9092b10SMarkus Armbruster         return bs_snapshots;
22073ac906f7SMarkus Armbruster     }
2208f9092b10SMarkus Armbruster 
2209f9092b10SMarkus Armbruster     bs = NULL;
2210f9092b10SMarkus Armbruster     while ((bs = bdrv_next(bs))) {
2211f9092b10SMarkus Armbruster         if (bdrv_can_snapshot(bs)) {
22123ac906f7SMarkus Armbruster             bs_snapshots = bs;
22133ac906f7SMarkus Armbruster             return bs;
2214f9092b10SMarkus Armbruster         }
2215f9092b10SMarkus Armbruster     }
2216f9092b10SMarkus Armbruster     return NULL;
2217f9092b10SMarkus Armbruster }
2218f9092b10SMarkus Armbruster 
2219faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs,
2220faea38e7Sbellard                          QEMUSnapshotInfo *sn_info)
2221faea38e7Sbellard {
2222faea38e7Sbellard     BlockDriver *drv = bs->drv;
2223faea38e7Sbellard     if (!drv)
222419cb3738Sbellard         return -ENOMEDIUM;
22257cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_create)
2226faea38e7Sbellard         return drv->bdrv_snapshot_create(bs, sn_info);
22277cdb1f6dSMORITA Kazutaka     if (bs->file)
22287cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_create(bs->file, sn_info);
22297cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2230faea38e7Sbellard }
2231faea38e7Sbellard 
2232faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs,
2233faea38e7Sbellard                        const char *snapshot_id)
2234faea38e7Sbellard {
2235faea38e7Sbellard     BlockDriver *drv = bs->drv;
22367cdb1f6dSMORITA Kazutaka     int ret, open_ret;
22377cdb1f6dSMORITA Kazutaka 
2238faea38e7Sbellard     if (!drv)
223919cb3738Sbellard         return -ENOMEDIUM;
22407cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_goto)
2241faea38e7Sbellard         return drv->bdrv_snapshot_goto(bs, snapshot_id);
22427cdb1f6dSMORITA Kazutaka 
22437cdb1f6dSMORITA Kazutaka     if (bs->file) {
22447cdb1f6dSMORITA Kazutaka         drv->bdrv_close(bs);
22457cdb1f6dSMORITA Kazutaka         ret = bdrv_snapshot_goto(bs->file, snapshot_id);
22467cdb1f6dSMORITA Kazutaka         open_ret = drv->bdrv_open(bs, bs->open_flags);
22477cdb1f6dSMORITA Kazutaka         if (open_ret < 0) {
22487cdb1f6dSMORITA Kazutaka             bdrv_delete(bs->file);
22497cdb1f6dSMORITA Kazutaka             bs->drv = NULL;
22507cdb1f6dSMORITA Kazutaka             return open_ret;
22517cdb1f6dSMORITA Kazutaka         }
22527cdb1f6dSMORITA Kazutaka         return ret;
22537cdb1f6dSMORITA Kazutaka     }
22547cdb1f6dSMORITA Kazutaka 
22557cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2256faea38e7Sbellard }
2257faea38e7Sbellard 
2258faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
2259faea38e7Sbellard {
2260faea38e7Sbellard     BlockDriver *drv = bs->drv;
2261faea38e7Sbellard     if (!drv)
226219cb3738Sbellard         return -ENOMEDIUM;
22637cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_delete)
2264faea38e7Sbellard         return drv->bdrv_snapshot_delete(bs, snapshot_id);
22657cdb1f6dSMORITA Kazutaka     if (bs->file)
22667cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_delete(bs->file, snapshot_id);
22677cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2268faea38e7Sbellard }
2269faea38e7Sbellard 
2270faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs,
2271faea38e7Sbellard                        QEMUSnapshotInfo **psn_info)
2272faea38e7Sbellard {
2273faea38e7Sbellard     BlockDriver *drv = bs->drv;
2274faea38e7Sbellard     if (!drv)
227519cb3738Sbellard         return -ENOMEDIUM;
22767cdb1f6dSMORITA Kazutaka     if (drv->bdrv_snapshot_list)
2277faea38e7Sbellard         return drv->bdrv_snapshot_list(bs, psn_info);
22787cdb1f6dSMORITA Kazutaka     if (bs->file)
22797cdb1f6dSMORITA Kazutaka         return bdrv_snapshot_list(bs->file, psn_info);
22807cdb1f6dSMORITA Kazutaka     return -ENOTSUP;
2281faea38e7Sbellard }
2282faea38e7Sbellard 
228351ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs,
228451ef6727Sedison         const char *snapshot_name)
228551ef6727Sedison {
228651ef6727Sedison     BlockDriver *drv = bs->drv;
228751ef6727Sedison     if (!drv) {
228851ef6727Sedison         return -ENOMEDIUM;
228951ef6727Sedison     }
229051ef6727Sedison     if (!bs->read_only) {
229151ef6727Sedison         return -EINVAL;
229251ef6727Sedison     }
229351ef6727Sedison     if (drv->bdrv_snapshot_load_tmp) {
229451ef6727Sedison         return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
229551ef6727Sedison     }
229651ef6727Sedison     return -ENOTSUP;
229751ef6727Sedison }
229851ef6727Sedison 
2299faea38e7Sbellard #define NB_SUFFIXES 4
2300faea38e7Sbellard 
2301faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size)
2302faea38e7Sbellard {
2303faea38e7Sbellard     static const char suffixes[NB_SUFFIXES] = "KMGT";
2304faea38e7Sbellard     int64_t base;
2305faea38e7Sbellard     int i;
2306faea38e7Sbellard 
2307faea38e7Sbellard     if (size <= 999) {
2308faea38e7Sbellard         snprintf(buf, buf_size, "%" PRId64, size);
2309faea38e7Sbellard     } else {
2310faea38e7Sbellard         base = 1024;
2311faea38e7Sbellard         for(i = 0; i < NB_SUFFIXES; i++) {
2312faea38e7Sbellard             if (size < (10 * base)) {
2313faea38e7Sbellard                 snprintf(buf, buf_size, "%0.1f%c",
2314faea38e7Sbellard                          (double)size / base,
2315faea38e7Sbellard                          suffixes[i]);
2316faea38e7Sbellard                 break;
2317faea38e7Sbellard             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
2318faea38e7Sbellard                 snprintf(buf, buf_size, "%" PRId64 "%c",
2319faea38e7Sbellard                          ((size + (base >> 1)) / base),
2320faea38e7Sbellard                          suffixes[i]);
2321faea38e7Sbellard                 break;
2322faea38e7Sbellard             }
2323faea38e7Sbellard             base = base * 1024;
2324faea38e7Sbellard         }
2325faea38e7Sbellard     }
2326faea38e7Sbellard     return buf;
2327faea38e7Sbellard }
2328faea38e7Sbellard 
2329faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
2330faea38e7Sbellard {
2331faea38e7Sbellard     char buf1[128], date_buf[128], clock_buf[128];
23323b9f94e1Sbellard #ifdef _WIN32
23333b9f94e1Sbellard     struct tm *ptm;
23343b9f94e1Sbellard #else
2335faea38e7Sbellard     struct tm tm;
23363b9f94e1Sbellard #endif
2337faea38e7Sbellard     time_t ti;
2338faea38e7Sbellard     int64_t secs;
2339faea38e7Sbellard 
2340faea38e7Sbellard     if (!sn) {
2341faea38e7Sbellard         snprintf(buf, buf_size,
2342faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2343faea38e7Sbellard                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
2344faea38e7Sbellard     } else {
2345faea38e7Sbellard         ti = sn->date_sec;
23463b9f94e1Sbellard #ifdef _WIN32
23473b9f94e1Sbellard         ptm = localtime(&ti);
23483b9f94e1Sbellard         strftime(date_buf, sizeof(date_buf),
23493b9f94e1Sbellard                  "%Y-%m-%d %H:%M:%S", ptm);
23503b9f94e1Sbellard #else
2351faea38e7Sbellard         localtime_r(&ti, &tm);
2352faea38e7Sbellard         strftime(date_buf, sizeof(date_buf),
2353faea38e7Sbellard                  "%Y-%m-%d %H:%M:%S", &tm);
23543b9f94e1Sbellard #endif
2355faea38e7Sbellard         secs = sn->vm_clock_nsec / 1000000000;
2356faea38e7Sbellard         snprintf(clock_buf, sizeof(clock_buf),
2357faea38e7Sbellard                  "%02d:%02d:%02d.%03d",
2358faea38e7Sbellard                  (int)(secs / 3600),
2359faea38e7Sbellard                  (int)((secs / 60) % 60),
2360faea38e7Sbellard                  (int)(secs % 60),
2361faea38e7Sbellard                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
2362faea38e7Sbellard         snprintf(buf, buf_size,
2363faea38e7Sbellard                  "%-10s%-20s%7s%20s%15s",
2364faea38e7Sbellard                  sn->id_str, sn->name,
2365faea38e7Sbellard                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
2366faea38e7Sbellard                  date_buf,
2367faea38e7Sbellard                  clock_buf);
2368faea38e7Sbellard     }
2369faea38e7Sbellard     return buf;
2370faea38e7Sbellard }
2371faea38e7Sbellard 
2372ea2384d3Sbellard /**************************************************************/
237383f64091Sbellard /* async I/Os */
2374ea2384d3Sbellard 
23753b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
2376f141eafeSaliguori                                  QEMUIOVector *qiov, int nb_sectors,
237783f64091Sbellard                                  BlockDriverCompletionFunc *cb, void *opaque)
2378ea2384d3Sbellard {
2379bbf0a440SStefan Hajnoczi     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
2380bbf0a440SStefan Hajnoczi 
2381*b2a61371SStefan Hajnoczi     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
2382*b2a61371SStefan Hajnoczi                                  cb, opaque, false, bdrv_co_do_rw);
238383f64091Sbellard }
238483f64091Sbellard 
23854dcafbb1SMarcelo Tosatti typedef struct BlockCompleteData {
23864dcafbb1SMarcelo Tosatti     BlockDriverCompletionFunc *cb;
23874dcafbb1SMarcelo Tosatti     void *opaque;
23884dcafbb1SMarcelo Tosatti     BlockDriverState *bs;
23894dcafbb1SMarcelo Tosatti     int64_t sector_num;
23904dcafbb1SMarcelo Tosatti     int nb_sectors;
23914dcafbb1SMarcelo Tosatti } BlockCompleteData;
23924dcafbb1SMarcelo Tosatti 
23934dcafbb1SMarcelo Tosatti static void block_complete_cb(void *opaque, int ret)
23944dcafbb1SMarcelo Tosatti {
23954dcafbb1SMarcelo Tosatti     BlockCompleteData *b = opaque;
23964dcafbb1SMarcelo Tosatti 
23974dcafbb1SMarcelo Tosatti     if (b->bs->dirty_bitmap) {
23984dcafbb1SMarcelo Tosatti         set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1);
23994dcafbb1SMarcelo Tosatti     }
24004dcafbb1SMarcelo Tosatti     b->cb(b->opaque, ret);
24017267c094SAnthony Liguori     g_free(b);
24024dcafbb1SMarcelo Tosatti }
24034dcafbb1SMarcelo Tosatti 
24044dcafbb1SMarcelo Tosatti static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
24054dcafbb1SMarcelo Tosatti                                              int64_t sector_num,
24064dcafbb1SMarcelo Tosatti                                              int nb_sectors,
24074dcafbb1SMarcelo Tosatti                                              BlockDriverCompletionFunc *cb,
24084dcafbb1SMarcelo Tosatti                                              void *opaque)
24094dcafbb1SMarcelo Tosatti {
24107267c094SAnthony Liguori     BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData));
24114dcafbb1SMarcelo Tosatti 
24124dcafbb1SMarcelo Tosatti     blkdata->bs = bs;
24134dcafbb1SMarcelo Tosatti     blkdata->cb = cb;
24144dcafbb1SMarcelo Tosatti     blkdata->opaque = opaque;
24154dcafbb1SMarcelo Tosatti     blkdata->sector_num = sector_num;
24164dcafbb1SMarcelo Tosatti     blkdata->nb_sectors = nb_sectors;
24174dcafbb1SMarcelo Tosatti 
24184dcafbb1SMarcelo Tosatti     return blkdata;
24194dcafbb1SMarcelo Tosatti }
24204dcafbb1SMarcelo Tosatti 
2421f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
2422f141eafeSaliguori                                   QEMUIOVector *qiov, int nb_sectors,
242383f64091Sbellard                                   BlockDriverCompletionFunc *cb, void *opaque)
24247674e7bfSbellard {
242583f64091Sbellard     BlockDriver *drv = bs->drv;
2426a36e69ddSths     BlockDriverAIOCB *ret;
24274dcafbb1SMarcelo Tosatti     BlockCompleteData *blk_cb_data;
242883f64091Sbellard 
2429bbf0a440SStefan Hajnoczi     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
2430bbf0a440SStefan Hajnoczi 
243119cb3738Sbellard     if (!drv)
2432ce1a14dcSpbrook         return NULL;
243383f64091Sbellard     if (bs->read_only)
2434ce1a14dcSpbrook         return NULL;
243571d0770cSaliguori     if (bdrv_check_request(bs, sector_num, nb_sectors))
243671d0770cSaliguori         return NULL;
243783f64091Sbellard 
2438c6d22830SJan Kiszka     if (bs->dirty_bitmap) {
24394dcafbb1SMarcelo Tosatti         blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb,
24404dcafbb1SMarcelo Tosatti                                          opaque);
24414dcafbb1SMarcelo Tosatti         cb = &block_complete_cb;
24424dcafbb1SMarcelo Tosatti         opaque = blk_cb_data;
24437cd1e32aSlirans@il.ibm.com     }
24447cd1e32aSlirans@il.ibm.com 
2445f141eafeSaliguori     ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
2446f141eafeSaliguori                                cb, opaque);
2447a36e69ddSths 
2448a36e69ddSths     if (ret) {
2449294cc35fSKevin Wolf         if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
2450294cc35fSKevin Wolf             bs->wr_highest_sector = sector_num + nb_sectors - 1;
2451294cc35fSKevin Wolf         }
2452a36e69ddSths     }
2453a36e69ddSths 
2454a36e69ddSths     return ret;
245583f64091Sbellard }
245683f64091Sbellard 
245740b4f539SKevin Wolf 
245840b4f539SKevin Wolf typedef struct MultiwriteCB {
245940b4f539SKevin Wolf     int error;
246040b4f539SKevin Wolf     int num_requests;
246140b4f539SKevin Wolf     int num_callbacks;
246240b4f539SKevin Wolf     struct {
246340b4f539SKevin Wolf         BlockDriverCompletionFunc *cb;
246440b4f539SKevin Wolf         void *opaque;
246540b4f539SKevin Wolf         QEMUIOVector *free_qiov;
246640b4f539SKevin Wolf         void *free_buf;
246740b4f539SKevin Wolf     } callbacks[];
246840b4f539SKevin Wolf } MultiwriteCB;
246940b4f539SKevin Wolf 
247040b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb)
247140b4f539SKevin Wolf {
247240b4f539SKevin Wolf     int i;
247340b4f539SKevin Wolf 
247440b4f539SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
247540b4f539SKevin Wolf         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
24761e1ea48dSStefan Hajnoczi         if (mcb->callbacks[i].free_qiov) {
24771e1ea48dSStefan Hajnoczi             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
24781e1ea48dSStefan Hajnoczi         }
24797267c094SAnthony Liguori         g_free(mcb->callbacks[i].free_qiov);
2480f8a83245SHerve Poussineau         qemu_vfree(mcb->callbacks[i].free_buf);
248140b4f539SKevin Wolf     }
248240b4f539SKevin Wolf }
248340b4f539SKevin Wolf 
248440b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret)
248540b4f539SKevin Wolf {
248640b4f539SKevin Wolf     MultiwriteCB *mcb = opaque;
248740b4f539SKevin Wolf 
24886d519a5fSStefan Hajnoczi     trace_multiwrite_cb(mcb, ret);
24896d519a5fSStefan Hajnoczi 
2490cb6d3ca0SKevin Wolf     if (ret < 0 && !mcb->error) {
249140b4f539SKevin Wolf         mcb->error = ret;
249240b4f539SKevin Wolf     }
249340b4f539SKevin Wolf 
249440b4f539SKevin Wolf     mcb->num_requests--;
249540b4f539SKevin Wolf     if (mcb->num_requests == 0) {
249640b4f539SKevin Wolf         multiwrite_user_cb(mcb);
24977267c094SAnthony Liguori         g_free(mcb);
249840b4f539SKevin Wolf     }
249940b4f539SKevin Wolf }
250040b4f539SKevin Wolf 
250140b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b)
250240b4f539SKevin Wolf {
250377be4366SChristoph Hellwig     const BlockRequest *req1 = a, *req2 = b;
250477be4366SChristoph Hellwig 
250577be4366SChristoph Hellwig     /*
250677be4366SChristoph Hellwig      * Note that we can't simply subtract req2->sector from req1->sector
250777be4366SChristoph Hellwig      * here as that could overflow the return value.
250877be4366SChristoph Hellwig      */
250977be4366SChristoph Hellwig     if (req1->sector > req2->sector) {
251077be4366SChristoph Hellwig         return 1;
251177be4366SChristoph Hellwig     } else if (req1->sector < req2->sector) {
251277be4366SChristoph Hellwig         return -1;
251377be4366SChristoph Hellwig     } else {
251477be4366SChristoph Hellwig         return 0;
251577be4366SChristoph Hellwig     }
251640b4f539SKevin Wolf }
251740b4f539SKevin Wolf 
251840b4f539SKevin Wolf /*
251940b4f539SKevin Wolf  * Takes a bunch of requests and tries to merge them. Returns the number of
252040b4f539SKevin Wolf  * requests that remain after merging.
252140b4f539SKevin Wolf  */
252240b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
252340b4f539SKevin Wolf     int num_reqs, MultiwriteCB *mcb)
252440b4f539SKevin Wolf {
252540b4f539SKevin Wolf     int i, outidx;
252640b4f539SKevin Wolf 
252740b4f539SKevin Wolf     // Sort requests by start sector
252840b4f539SKevin Wolf     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
252940b4f539SKevin Wolf 
253040b4f539SKevin Wolf     // Check if adjacent requests touch the same clusters. If so, combine them,
253140b4f539SKevin Wolf     // filling up gaps with zero sectors.
253240b4f539SKevin Wolf     outidx = 0;
253340b4f539SKevin Wolf     for (i = 1; i < num_reqs; i++) {
253440b4f539SKevin Wolf         int merge = 0;
253540b4f539SKevin Wolf         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
253640b4f539SKevin Wolf 
253740b4f539SKevin Wolf         // This handles the cases that are valid for all block drivers, namely
253840b4f539SKevin Wolf         // exactly sequential writes and overlapping writes.
253940b4f539SKevin Wolf         if (reqs[i].sector <= oldreq_last) {
254040b4f539SKevin Wolf             merge = 1;
254140b4f539SKevin Wolf         }
254240b4f539SKevin Wolf 
254340b4f539SKevin Wolf         // The block driver may decide that it makes sense to combine requests
254440b4f539SKevin Wolf         // even if there is a gap of some sectors between them. In this case,
254540b4f539SKevin Wolf         // the gap is filled with zeros (therefore only applicable for yet
254640b4f539SKevin Wolf         // unused space in format like qcow2).
254740b4f539SKevin Wolf         if (!merge && bs->drv->bdrv_merge_requests) {
254840b4f539SKevin Wolf             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
254940b4f539SKevin Wolf         }
255040b4f539SKevin Wolf 
2551e2a305fbSChristoph Hellwig         if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
2552e2a305fbSChristoph Hellwig             merge = 0;
2553e2a305fbSChristoph Hellwig         }
2554e2a305fbSChristoph Hellwig 
255540b4f539SKevin Wolf         if (merge) {
255640b4f539SKevin Wolf             size_t size;
25577267c094SAnthony Liguori             QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
255840b4f539SKevin Wolf             qemu_iovec_init(qiov,
255940b4f539SKevin Wolf                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
256040b4f539SKevin Wolf 
256140b4f539SKevin Wolf             // Add the first request to the merged one. If the requests are
256240b4f539SKevin Wolf             // overlapping, drop the last sectors of the first request.
256340b4f539SKevin Wolf             size = (reqs[i].sector - reqs[outidx].sector) << 9;
256440b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
256540b4f539SKevin Wolf 
256640b4f539SKevin Wolf             // We might need to add some zeros between the two requests
256740b4f539SKevin Wolf             if (reqs[i].sector > oldreq_last) {
256840b4f539SKevin Wolf                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
256940b4f539SKevin Wolf                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
257040b4f539SKevin Wolf                 memset(buf, 0, zero_bytes);
257140b4f539SKevin Wolf                 qemu_iovec_add(qiov, buf, zero_bytes);
257240b4f539SKevin Wolf                 mcb->callbacks[i].free_buf = buf;
257340b4f539SKevin Wolf             }
257440b4f539SKevin Wolf 
257540b4f539SKevin Wolf             // Add the second request
257640b4f539SKevin Wolf             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
257740b4f539SKevin Wolf 
2578cbf1dff2SKevin Wolf             reqs[outidx].nb_sectors = qiov->size >> 9;
257940b4f539SKevin Wolf             reqs[outidx].qiov = qiov;
258040b4f539SKevin Wolf 
258140b4f539SKevin Wolf             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
258240b4f539SKevin Wolf         } else {
258340b4f539SKevin Wolf             outidx++;
258440b4f539SKevin Wolf             reqs[outidx].sector     = reqs[i].sector;
258540b4f539SKevin Wolf             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
258640b4f539SKevin Wolf             reqs[outidx].qiov       = reqs[i].qiov;
258740b4f539SKevin Wolf         }
258840b4f539SKevin Wolf     }
258940b4f539SKevin Wolf 
259040b4f539SKevin Wolf     return outidx + 1;
259140b4f539SKevin Wolf }
259240b4f539SKevin Wolf 
259340b4f539SKevin Wolf /*
259440b4f539SKevin Wolf  * Submit multiple AIO write requests at once.
259540b4f539SKevin Wolf  *
259640b4f539SKevin Wolf  * On success, the function returns 0 and all requests in the reqs array have
259740b4f539SKevin Wolf  * been submitted. In error case this function returns -1, and any of the
259840b4f539SKevin Wolf  * requests may or may not be submitted yet. In particular, this means that the
259940b4f539SKevin Wolf  * callback will be called for some of the requests, for others it won't. The
260040b4f539SKevin Wolf  * caller must check the error field of the BlockRequest to wait for the right
260140b4f539SKevin Wolf  * callbacks (if error != 0, no callback will be called).
260240b4f539SKevin Wolf  *
260340b4f539SKevin Wolf  * The implementation may modify the contents of the reqs array, e.g. to merge
260440b4f539SKevin Wolf  * requests. However, the fields opaque and error are left unmodified as they
260540b4f539SKevin Wolf  * are used to signal failure for a single request to the caller.
260640b4f539SKevin Wolf  */
260740b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
260840b4f539SKevin Wolf {
260940b4f539SKevin Wolf     BlockDriverAIOCB *acb;
261040b4f539SKevin Wolf     MultiwriteCB *mcb;
261140b4f539SKevin Wolf     int i;
261240b4f539SKevin Wolf 
2613301db7c2SRyan Harper     /* don't submit writes if we don't have a medium */
2614301db7c2SRyan Harper     if (bs->drv == NULL) {
2615301db7c2SRyan Harper         for (i = 0; i < num_reqs; i++) {
2616301db7c2SRyan Harper             reqs[i].error = -ENOMEDIUM;
2617301db7c2SRyan Harper         }
2618301db7c2SRyan Harper         return -1;
2619301db7c2SRyan Harper     }
2620301db7c2SRyan Harper 
262140b4f539SKevin Wolf     if (num_reqs == 0) {
262240b4f539SKevin Wolf         return 0;
262340b4f539SKevin Wolf     }
262440b4f539SKevin Wolf 
262540b4f539SKevin Wolf     // Create MultiwriteCB structure
26267267c094SAnthony Liguori     mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
262740b4f539SKevin Wolf     mcb->num_requests = 0;
262840b4f539SKevin Wolf     mcb->num_callbacks = num_reqs;
262940b4f539SKevin Wolf 
263040b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
263140b4f539SKevin Wolf         mcb->callbacks[i].cb = reqs[i].cb;
263240b4f539SKevin Wolf         mcb->callbacks[i].opaque = reqs[i].opaque;
263340b4f539SKevin Wolf     }
263440b4f539SKevin Wolf 
263540b4f539SKevin Wolf     // Check for mergable requests
263640b4f539SKevin Wolf     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
263740b4f539SKevin Wolf 
26386d519a5fSStefan Hajnoczi     trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
26396d519a5fSStefan Hajnoczi 
2640453f9a16SKevin Wolf     /*
2641453f9a16SKevin Wolf      * Run the aio requests. As soon as one request can't be submitted
2642453f9a16SKevin Wolf      * successfully, fail all requests that are not yet submitted (we must
2643453f9a16SKevin Wolf      * return failure for all requests anyway)
2644453f9a16SKevin Wolf      *
2645453f9a16SKevin Wolf      * num_requests cannot be set to the right value immediately: If
2646453f9a16SKevin Wolf      * bdrv_aio_writev fails for some request, num_requests would be too high
2647453f9a16SKevin Wolf      * and therefore multiwrite_cb() would never recognize the multiwrite
2648453f9a16SKevin Wolf      * request as completed. We also cannot use the loop variable i to set it
2649453f9a16SKevin Wolf      * when the first request fails because the callback may already have been
2650453f9a16SKevin Wolf      * called for previously submitted requests. Thus, num_requests must be
2651453f9a16SKevin Wolf      * incremented for each request that is submitted.
2652453f9a16SKevin Wolf      *
2653453f9a16SKevin Wolf      * The problem that callbacks may be called early also means that we need
2654453f9a16SKevin Wolf      * to take care that num_requests doesn't become 0 before all requests are
2655453f9a16SKevin Wolf      * submitted - multiwrite_cb() would consider the multiwrite request
2656453f9a16SKevin Wolf      * completed. A dummy request that is "completed" by a manual call to
2657453f9a16SKevin Wolf      * multiwrite_cb() takes care of this.
2658453f9a16SKevin Wolf      */
2659453f9a16SKevin Wolf     mcb->num_requests = 1;
2660453f9a16SKevin Wolf 
26616d519a5fSStefan Hajnoczi     // Run the aio requests
266240b4f539SKevin Wolf     for (i = 0; i < num_reqs; i++) {
2663453f9a16SKevin Wolf         mcb->num_requests++;
266440b4f539SKevin Wolf         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
266540b4f539SKevin Wolf             reqs[i].nb_sectors, multiwrite_cb, mcb);
266640b4f539SKevin Wolf 
266740b4f539SKevin Wolf         if (acb == NULL) {
266840b4f539SKevin Wolf             // We can only fail the whole thing if no request has been
266940b4f539SKevin Wolf             // submitted yet. Otherwise we'll wait for the submitted AIOs to
267040b4f539SKevin Wolf             // complete and report the error in the callback.
2671453f9a16SKevin Wolf             if (i == 0) {
26726d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_earlyfail(mcb);
267340b4f539SKevin Wolf                 goto fail;
267440b4f539SKevin Wolf             } else {
26756d519a5fSStefan Hajnoczi                 trace_bdrv_aio_multiwrite_latefail(mcb, i);
26767eb58a6cSKevin Wolf                 multiwrite_cb(mcb, -EIO);
267740b4f539SKevin Wolf                 break;
267840b4f539SKevin Wolf             }
267940b4f539SKevin Wolf         }
268040b4f539SKevin Wolf     }
268140b4f539SKevin Wolf 
2682453f9a16SKevin Wolf     /* Complete the dummy request */
2683453f9a16SKevin Wolf     multiwrite_cb(mcb, 0);
2684453f9a16SKevin Wolf 
268540b4f539SKevin Wolf     return 0;
268640b4f539SKevin Wolf 
268740b4f539SKevin Wolf fail:
2688453f9a16SKevin Wolf     for (i = 0; i < mcb->num_callbacks; i++) {
2689453f9a16SKevin Wolf         reqs[i].error = -EIO;
2690453f9a16SKevin Wolf     }
26917267c094SAnthony Liguori     g_free(mcb);
269240b4f539SKevin Wolf     return -1;
269340b4f539SKevin Wolf }
269440b4f539SKevin Wolf 
2695b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
2696b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2697b2e12bc6SChristoph Hellwig {
2698b2e12bc6SChristoph Hellwig     BlockDriver *drv = bs->drv;
2699b2e12bc6SChristoph Hellwig 
2700a13aac04SStefan Hajnoczi     trace_bdrv_aio_flush(bs, opaque);
2701a13aac04SStefan Hajnoczi 
2702016f5cf6SAlexander Graf     if (bs->open_flags & BDRV_O_NO_FLUSH) {
2703016f5cf6SAlexander Graf         return bdrv_aio_noop_em(bs, cb, opaque);
2704016f5cf6SAlexander Graf     }
2705016f5cf6SAlexander Graf 
2706b2e12bc6SChristoph Hellwig     if (!drv)
2707b2e12bc6SChristoph Hellwig         return NULL;
2708b2e12bc6SChristoph Hellwig     return drv->bdrv_aio_flush(bs, cb, opaque);
2709b2e12bc6SChristoph Hellwig }
2710b2e12bc6SChristoph Hellwig 
271183f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb)
271283f64091Sbellard {
27136bbff9a0Saliguori     acb->pool->cancel(acb);
271483f64091Sbellard }
271583f64091Sbellard 
271683f64091Sbellard 
271783f64091Sbellard /**************************************************************/
271883f64091Sbellard /* async block device emulation */
271983f64091Sbellard 
2720c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync {
2721c16b5a2cSChristoph Hellwig     BlockDriverAIOCB common;
2722c16b5a2cSChristoph Hellwig     QEMUBH *bh;
2723c16b5a2cSChristoph Hellwig     int ret;
2724c16b5a2cSChristoph Hellwig     /* vector translation state */
2725c16b5a2cSChristoph Hellwig     QEMUIOVector *qiov;
2726c16b5a2cSChristoph Hellwig     uint8_t *bounce;
2727c16b5a2cSChristoph Hellwig     int is_write;
2728c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync;
2729c16b5a2cSChristoph Hellwig 
2730c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
2731c16b5a2cSChristoph Hellwig {
2732b666d239SKevin Wolf     BlockDriverAIOCBSync *acb =
2733b666d239SKevin Wolf         container_of(blockacb, BlockDriverAIOCBSync, common);
27346a7ad299SDor Laor     qemu_bh_delete(acb->bh);
273536afc451SAvi Kivity     acb->bh = NULL;
2736c16b5a2cSChristoph Hellwig     qemu_aio_release(acb);
2737c16b5a2cSChristoph Hellwig }
2738c16b5a2cSChristoph Hellwig 
2739c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = {
2740c16b5a2cSChristoph Hellwig     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
2741c16b5a2cSChristoph Hellwig     .cancel             = bdrv_aio_cancel_em,
2742c16b5a2cSChristoph Hellwig };
2743c16b5a2cSChristoph Hellwig 
274483f64091Sbellard static void bdrv_aio_bh_cb(void *opaque)
2745beac80cdSbellard {
2746ce1a14dcSpbrook     BlockDriverAIOCBSync *acb = opaque;
2747f141eafeSaliguori 
2748f141eafeSaliguori     if (!acb->is_write)
2749f141eafeSaliguori         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
2750ceb42de8Saliguori     qemu_vfree(acb->bounce);
2751ce1a14dcSpbrook     acb->common.cb(acb->common.opaque, acb->ret);
27526a7ad299SDor Laor     qemu_bh_delete(acb->bh);
275336afc451SAvi Kivity     acb->bh = NULL;
2754ce1a14dcSpbrook     qemu_aio_release(acb);
2755beac80cdSbellard }
2756beac80cdSbellard 
2757f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
2758f141eafeSaliguori                                             int64_t sector_num,
2759f141eafeSaliguori                                             QEMUIOVector *qiov,
2760f141eafeSaliguori                                             int nb_sectors,
2761f141eafeSaliguori                                             BlockDriverCompletionFunc *cb,
2762f141eafeSaliguori                                             void *opaque,
2763f141eafeSaliguori                                             int is_write)
2764f141eafeSaliguori 
2765ea2384d3Sbellard {
2766ce1a14dcSpbrook     BlockDriverAIOCBSync *acb;
276783f64091Sbellard 
2768c16b5a2cSChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2769f141eafeSaliguori     acb->is_write = is_write;
2770f141eafeSaliguori     acb->qiov = qiov;
2771e268ca52Saliguori     acb->bounce = qemu_blockalign(bs, qiov->size);
2772f141eafeSaliguori 
2773ce1a14dcSpbrook     if (!acb->bh)
2774ce1a14dcSpbrook         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2775f141eafeSaliguori 
2776f141eafeSaliguori     if (is_write) {
2777f141eafeSaliguori         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
27781ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
2779f141eafeSaliguori     } else {
27801ed20acfSStefan Hajnoczi         acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
2781f141eafeSaliguori     }
2782f141eafeSaliguori 
2783ce1a14dcSpbrook     qemu_bh_schedule(acb->bh);
2784f141eafeSaliguori 
2785ce1a14dcSpbrook     return &acb->common;
27867a6cba61Spbrook }
27877a6cba61Spbrook 
2788f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
2789f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2790ce1a14dcSpbrook         BlockDriverCompletionFunc *cb, void *opaque)
279183f64091Sbellard {
2792f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
279383f64091Sbellard }
279483f64091Sbellard 
2795f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
2796f141eafeSaliguori         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
2797f141eafeSaliguori         BlockDriverCompletionFunc *cb, void *opaque)
2798f141eafeSaliguori {
2799f141eafeSaliguori     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
2800f141eafeSaliguori }
2801f141eafeSaliguori 
280268485420SKevin Wolf 
280368485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine {
280468485420SKevin Wolf     BlockDriverAIOCB common;
280568485420SKevin Wolf     BlockRequest req;
280668485420SKevin Wolf     bool is_write;
280768485420SKevin Wolf     QEMUBH* bh;
280868485420SKevin Wolf } BlockDriverAIOCBCoroutine;
280968485420SKevin Wolf 
281068485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
281168485420SKevin Wolf {
281268485420SKevin Wolf     qemu_aio_flush();
281368485420SKevin Wolf }
281468485420SKevin Wolf 
281568485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = {
281668485420SKevin Wolf     .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
281768485420SKevin Wolf     .cancel             = bdrv_aio_co_cancel_em,
281868485420SKevin Wolf };
281968485420SKevin Wolf 
282068485420SKevin Wolf static void bdrv_co_rw_bh(void *opaque)
282168485420SKevin Wolf {
282268485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
282368485420SKevin Wolf 
282468485420SKevin Wolf     acb->common.cb(acb->common.opaque, acb->req.error);
282568485420SKevin Wolf     qemu_bh_delete(acb->bh);
282668485420SKevin Wolf     qemu_aio_release(acb);
282768485420SKevin Wolf }
282868485420SKevin Wolf 
2829*b2a61371SStefan Hajnoczi /* Invoke .bdrv_co_readv/.bdrv_co_writev */
283068485420SKevin Wolf static void coroutine_fn bdrv_co_rw(void *opaque)
283168485420SKevin Wolf {
283268485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb = opaque;
283368485420SKevin Wolf     BlockDriverState *bs = acb->common.bs;
283468485420SKevin Wolf 
283568485420SKevin Wolf     if (!acb->is_write) {
283668485420SKevin Wolf         acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector,
283768485420SKevin Wolf             acb->req.nb_sectors, acb->req.qiov);
283868485420SKevin Wolf     } else {
283968485420SKevin Wolf         acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector,
284068485420SKevin Wolf             acb->req.nb_sectors, acb->req.qiov);
284168485420SKevin Wolf     }
284268485420SKevin Wolf 
284368485420SKevin Wolf     acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
284468485420SKevin Wolf     qemu_bh_schedule(acb->bh);
284568485420SKevin Wolf }
284668485420SKevin Wolf 
2847*b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
2848*b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque)
2849*b2a61371SStefan Hajnoczi {
2850*b2a61371SStefan Hajnoczi     BlockDriverAIOCBCoroutine *acb = opaque;
2851*b2a61371SStefan Hajnoczi     BlockDriverState *bs = acb->common.bs;
2852*b2a61371SStefan Hajnoczi 
2853*b2a61371SStefan Hajnoczi     if (!acb->is_write) {
2854*b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
2855*b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2856*b2a61371SStefan Hajnoczi     } else {
2857*b2a61371SStefan Hajnoczi         acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
2858*b2a61371SStefan Hajnoczi             acb->req.nb_sectors, acb->req.qiov);
2859*b2a61371SStefan Hajnoczi     }
2860*b2a61371SStefan Hajnoczi 
2861*b2a61371SStefan Hajnoczi     acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
2862*b2a61371SStefan Hajnoczi     qemu_bh_schedule(acb->bh);
2863*b2a61371SStefan Hajnoczi }
2864*b2a61371SStefan Hajnoczi 
286568485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
286668485420SKevin Wolf                                                int64_t sector_num,
286768485420SKevin Wolf                                                QEMUIOVector *qiov,
286868485420SKevin Wolf                                                int nb_sectors,
286968485420SKevin Wolf                                                BlockDriverCompletionFunc *cb,
287068485420SKevin Wolf                                                void *opaque,
2871*b2a61371SStefan Hajnoczi                                                bool is_write,
2872*b2a61371SStefan Hajnoczi                                                CoroutineEntry *entry)
287368485420SKevin Wolf {
287468485420SKevin Wolf     Coroutine *co;
287568485420SKevin Wolf     BlockDriverAIOCBCoroutine *acb;
287668485420SKevin Wolf 
287768485420SKevin Wolf     acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
287868485420SKevin Wolf     acb->req.sector = sector_num;
287968485420SKevin Wolf     acb->req.nb_sectors = nb_sectors;
288068485420SKevin Wolf     acb->req.qiov = qiov;
288168485420SKevin Wolf     acb->is_write = is_write;
288268485420SKevin Wolf 
2883*b2a61371SStefan Hajnoczi     co = qemu_coroutine_create(entry);
288468485420SKevin Wolf     qemu_coroutine_enter(co, acb);
288568485420SKevin Wolf 
288668485420SKevin Wolf     return &acb->common;
288768485420SKevin Wolf }
288868485420SKevin Wolf 
288968485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
289068485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
289168485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque)
289268485420SKevin Wolf {
289368485420SKevin Wolf     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
2894*b2a61371SStefan Hajnoczi                                  false, bdrv_co_rw);
289568485420SKevin Wolf }
289668485420SKevin Wolf 
289768485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
289868485420SKevin Wolf         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
289968485420SKevin Wolf         BlockDriverCompletionFunc *cb, void *opaque)
290068485420SKevin Wolf {
290168485420SKevin Wolf     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
2902*b2a61371SStefan Hajnoczi                                  true, bdrv_co_rw);
290368485420SKevin Wolf }
290468485420SKevin Wolf 
2905b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
2906b2e12bc6SChristoph Hellwig         BlockDriverCompletionFunc *cb, void *opaque)
2907b2e12bc6SChristoph Hellwig {
2908b2e12bc6SChristoph Hellwig     BlockDriverAIOCBSync *acb;
2909b2e12bc6SChristoph Hellwig 
2910b2e12bc6SChristoph Hellwig     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2911b2e12bc6SChristoph Hellwig     acb->is_write = 1; /* don't bounce in the completion hadler */
2912b2e12bc6SChristoph Hellwig     acb->qiov = NULL;
2913b2e12bc6SChristoph Hellwig     acb->bounce = NULL;
2914b2e12bc6SChristoph Hellwig     acb->ret = 0;
2915b2e12bc6SChristoph Hellwig 
2916b2e12bc6SChristoph Hellwig     if (!acb->bh)
2917b2e12bc6SChristoph Hellwig         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2918b2e12bc6SChristoph Hellwig 
2919b2e12bc6SChristoph Hellwig     bdrv_flush(bs);
2920b2e12bc6SChristoph Hellwig     qemu_bh_schedule(acb->bh);
2921b2e12bc6SChristoph Hellwig     return &acb->common;
2922b2e12bc6SChristoph Hellwig }
2923b2e12bc6SChristoph Hellwig 
2924016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
2925016f5cf6SAlexander Graf         BlockDriverCompletionFunc *cb, void *opaque)
2926016f5cf6SAlexander Graf {
2927016f5cf6SAlexander Graf     BlockDriverAIOCBSync *acb;
2928016f5cf6SAlexander Graf 
2929016f5cf6SAlexander Graf     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
2930016f5cf6SAlexander Graf     acb->is_write = 1; /* don't bounce in the completion handler */
2931016f5cf6SAlexander Graf     acb->qiov = NULL;
2932016f5cf6SAlexander Graf     acb->bounce = NULL;
2933016f5cf6SAlexander Graf     acb->ret = 0;
2934016f5cf6SAlexander Graf 
2935016f5cf6SAlexander Graf     if (!acb->bh) {
2936016f5cf6SAlexander Graf         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
2937016f5cf6SAlexander Graf     }
2938016f5cf6SAlexander Graf 
2939016f5cf6SAlexander Graf     qemu_bh_schedule(acb->bh);
2940016f5cf6SAlexander Graf     return &acb->common;
2941016f5cf6SAlexander Graf }
2942016f5cf6SAlexander Graf 
294383f64091Sbellard /**************************************************************/
294483f64091Sbellard /* sync block device emulation */
294583f64091Sbellard 
294683f64091Sbellard static void bdrv_rw_em_cb(void *opaque, int ret)
294783f64091Sbellard {
294883f64091Sbellard     *(int *)opaque = ret;
294983f64091Sbellard }
295083f64091Sbellard 
295183f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
295283f64091Sbellard                         uint8_t *buf, int nb_sectors)
295383f64091Sbellard {
2954ce1a14dcSpbrook     int async_ret;
2955ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2956f141eafeSaliguori     struct iovec iov;
2957f141eafeSaliguori     QEMUIOVector qiov;
295883f64091Sbellard 
295983f64091Sbellard     async_ret = NOT_DONE;
29603f4cb3d3Sblueswir1     iov.iov_base = (void *)buf;
2961eb5a3165SJes Sorensen     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
2962f141eafeSaliguori     qemu_iovec_init_external(&qiov, &iov, 1);
29631ed20acfSStefan Hajnoczi 
29641ed20acfSStefan Hajnoczi     acb = bs->drv->bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
296583f64091Sbellard                                   bdrv_rw_em_cb, &async_ret);
296665d6b3d8SKevin Wolf     if (acb == NULL) {
296765d6b3d8SKevin Wolf         async_ret = -1;
296865d6b3d8SKevin Wolf         goto fail;
296965d6b3d8SKevin Wolf     }
2970baf35cb9Saliguori 
297183f64091Sbellard     while (async_ret == NOT_DONE) {
297283f64091Sbellard         qemu_aio_wait();
297383f64091Sbellard     }
2974baf35cb9Saliguori 
297565d6b3d8SKevin Wolf 
297665d6b3d8SKevin Wolf fail:
297783f64091Sbellard     return async_ret;
297883f64091Sbellard }
297983f64091Sbellard 
298083f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
298183f64091Sbellard                          const uint8_t *buf, int nb_sectors)
298283f64091Sbellard {
2983ce1a14dcSpbrook     int async_ret;
2984ce1a14dcSpbrook     BlockDriverAIOCB *acb;
2985f141eafeSaliguori     struct iovec iov;
2986f141eafeSaliguori     QEMUIOVector qiov;
298783f64091Sbellard 
298883f64091Sbellard     async_ret = NOT_DONE;
2989f141eafeSaliguori     iov.iov_base = (void *)buf;
2990eb5a3165SJes Sorensen     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
2991f141eafeSaliguori     qemu_iovec_init_external(&qiov, &iov, 1);
29921ed20acfSStefan Hajnoczi 
29931ed20acfSStefan Hajnoczi     acb = bs->drv->bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
299483f64091Sbellard                                    bdrv_rw_em_cb, &async_ret);
299565d6b3d8SKevin Wolf     if (acb == NULL) {
299665d6b3d8SKevin Wolf         async_ret = -1;
299765d6b3d8SKevin Wolf         goto fail;
299865d6b3d8SKevin Wolf     }
299983f64091Sbellard     while (async_ret == NOT_DONE) {
300083f64091Sbellard         qemu_aio_wait();
300183f64091Sbellard     }
300265d6b3d8SKevin Wolf 
300365d6b3d8SKevin Wolf fail:
300483f64091Sbellard     return async_ret;
300583f64091Sbellard }
3006ea2384d3Sbellard 
3007ea2384d3Sbellard void bdrv_init(void)
3008ea2384d3Sbellard {
30095efa9d5aSAnthony Liguori     module_call_init(MODULE_INIT_BLOCK);
3010ea2384d3Sbellard }
3011ce1a14dcSpbrook 
3012eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void)
3013eb852011SMarkus Armbruster {
3014eb852011SMarkus Armbruster     use_bdrv_whitelist = 1;
3015eb852011SMarkus Armbruster     bdrv_init();
3016eb852011SMarkus Armbruster }
3017eb852011SMarkus Armbruster 
3018c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
30196bbff9a0Saliguori                    BlockDriverCompletionFunc *cb, void *opaque)
30206bbff9a0Saliguori {
3021ce1a14dcSpbrook     BlockDriverAIOCB *acb;
3022ce1a14dcSpbrook 
30236bbff9a0Saliguori     if (pool->free_aiocb) {
30246bbff9a0Saliguori         acb = pool->free_aiocb;
30256bbff9a0Saliguori         pool->free_aiocb = acb->next;
3026ce1a14dcSpbrook     } else {
30277267c094SAnthony Liguori         acb = g_malloc0(pool->aiocb_size);
30286bbff9a0Saliguori         acb->pool = pool;
3029ce1a14dcSpbrook     }
3030ce1a14dcSpbrook     acb->bs = bs;
3031ce1a14dcSpbrook     acb->cb = cb;
3032ce1a14dcSpbrook     acb->opaque = opaque;
3033ce1a14dcSpbrook     return acb;
3034ce1a14dcSpbrook }
3035ce1a14dcSpbrook 
3036ce1a14dcSpbrook void qemu_aio_release(void *p)
3037ce1a14dcSpbrook {
30386bbff9a0Saliguori     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
30396bbff9a0Saliguori     AIOPool *pool = acb->pool;
30406bbff9a0Saliguori     acb->next = pool->free_aiocb;
30416bbff9a0Saliguori     pool->free_aiocb = acb;
3042ce1a14dcSpbrook }
304319cb3738Sbellard 
304419cb3738Sbellard /**************************************************************/
3045f9f05dc5SKevin Wolf /* Coroutine block device emulation */
3046f9f05dc5SKevin Wolf 
3047f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion {
3048f9f05dc5SKevin Wolf     Coroutine *coroutine;
3049f9f05dc5SKevin Wolf     int ret;
3050f9f05dc5SKevin Wolf } CoroutineIOCompletion;
3051f9f05dc5SKevin Wolf 
3052f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret)
3053f9f05dc5SKevin Wolf {
3054f9f05dc5SKevin Wolf     CoroutineIOCompletion *co = opaque;
3055f9f05dc5SKevin Wolf 
3056f9f05dc5SKevin Wolf     co->ret = ret;
3057f9f05dc5SKevin Wolf     qemu_coroutine_enter(co->coroutine, NULL);
3058f9f05dc5SKevin Wolf }
3059f9f05dc5SKevin Wolf 
3060f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
3061f9f05dc5SKevin Wolf                                       int nb_sectors, QEMUIOVector *iov,
3062f9f05dc5SKevin Wolf                                       bool is_write)
3063f9f05dc5SKevin Wolf {
3064f9f05dc5SKevin Wolf     CoroutineIOCompletion co = {
3065f9f05dc5SKevin Wolf         .coroutine = qemu_coroutine_self(),
3066f9f05dc5SKevin Wolf     };
3067f9f05dc5SKevin Wolf     BlockDriverAIOCB *acb;
3068f9f05dc5SKevin Wolf 
3069f9f05dc5SKevin Wolf     if (is_write) {
3070a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
3071f9f05dc5SKevin Wolf                                        bdrv_co_io_em_complete, &co);
3072f9f05dc5SKevin Wolf     } else {
3073a652d160SStefan Hajnoczi         acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
3074f9f05dc5SKevin Wolf                                       bdrv_co_io_em_complete, &co);
3075f9f05dc5SKevin Wolf     }
3076f9f05dc5SKevin Wolf 
307759370aaaSStefan Hajnoczi     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
3078f9f05dc5SKevin Wolf     if (!acb) {
3079f9f05dc5SKevin Wolf         return -EIO;
3080f9f05dc5SKevin Wolf     }
3081f9f05dc5SKevin Wolf     qemu_coroutine_yield();
3082f9f05dc5SKevin Wolf 
3083f9f05dc5SKevin Wolf     return co.ret;
3084f9f05dc5SKevin Wolf }
3085f9f05dc5SKevin Wolf 
3086f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
3087f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
3088f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
3089f9f05dc5SKevin Wolf {
3090f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
3091f9f05dc5SKevin Wolf }
3092f9f05dc5SKevin Wolf 
3093f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
3094f9f05dc5SKevin Wolf                                          int64_t sector_num, int nb_sectors,
3095f9f05dc5SKevin Wolf                                          QEMUIOVector *iov)
3096f9f05dc5SKevin Wolf {
3097f9f05dc5SKevin Wolf     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
3098f9f05dc5SKevin Wolf }
3099f9f05dc5SKevin Wolf 
3100e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
3101e7a8a783SKevin Wolf {
3102e7a8a783SKevin Wolf     CoroutineIOCompletion co = {
3103e7a8a783SKevin Wolf         .coroutine = qemu_coroutine_self(),
3104e7a8a783SKevin Wolf     };
3105e7a8a783SKevin Wolf     BlockDriverAIOCB *acb;
3106e7a8a783SKevin Wolf 
3107e7a8a783SKevin Wolf     acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
3108e7a8a783SKevin Wolf     if (!acb) {
3109e7a8a783SKevin Wolf         return -EIO;
3110e7a8a783SKevin Wolf     }
3111e7a8a783SKevin Wolf     qemu_coroutine_yield();
3112e7a8a783SKevin Wolf     return co.ret;
3113e7a8a783SKevin Wolf }
3114e7a8a783SKevin Wolf 
3115f9f05dc5SKevin Wolf /**************************************************************/
311619cb3738Sbellard /* removable device support */
311719cb3738Sbellard 
311819cb3738Sbellard /**
311919cb3738Sbellard  * Return TRUE if the media is present
312019cb3738Sbellard  */
312119cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs)
312219cb3738Sbellard {
312319cb3738Sbellard     BlockDriver *drv = bs->drv;
3124a1aff5bfSMarkus Armbruster 
312519cb3738Sbellard     if (!drv)
312619cb3738Sbellard         return 0;
312719cb3738Sbellard     if (!drv->bdrv_is_inserted)
3128a1aff5bfSMarkus Armbruster         return 1;
3129a1aff5bfSMarkus Armbruster     return drv->bdrv_is_inserted(bs);
313019cb3738Sbellard }
313119cb3738Sbellard 
313219cb3738Sbellard /**
31338e49ca46SMarkus Armbruster  * Return whether the media changed since the last call to this
31348e49ca46SMarkus Armbruster  * function, or -ENOTSUP if we don't know.  Most drivers don't know.
313519cb3738Sbellard  */
313619cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs)
313719cb3738Sbellard {
313819cb3738Sbellard     BlockDriver *drv = bs->drv;
313919cb3738Sbellard 
31408e49ca46SMarkus Armbruster     if (drv && drv->bdrv_media_changed) {
31418e49ca46SMarkus Armbruster         return drv->bdrv_media_changed(bs);
31428e49ca46SMarkus Armbruster     }
31438e49ca46SMarkus Armbruster     return -ENOTSUP;
314419cb3738Sbellard }
314519cb3738Sbellard 
314619cb3738Sbellard /**
314719cb3738Sbellard  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
314819cb3738Sbellard  */
3149fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag)
315019cb3738Sbellard {
315119cb3738Sbellard     BlockDriver *drv = bs->drv;
315219cb3738Sbellard 
3153822e1cd1SMarkus Armbruster     if (drv && drv->bdrv_eject) {
3154822e1cd1SMarkus Armbruster         drv->bdrv_eject(bs, eject_flag);
315519cb3738Sbellard     }
315619cb3738Sbellard }
315719cb3738Sbellard 
315819cb3738Sbellard /**
315919cb3738Sbellard  * Lock or unlock the media (if it is locked, the user won't be able
316019cb3738Sbellard  * to eject it manually).
316119cb3738Sbellard  */
3162025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked)
316319cb3738Sbellard {
316419cb3738Sbellard     BlockDriver *drv = bs->drv;
316519cb3738Sbellard 
3166025e849aSMarkus Armbruster     trace_bdrv_lock_medium(bs, locked);
3167b8c6d095SStefan Hajnoczi 
3168025e849aSMarkus Armbruster     if (drv && drv->bdrv_lock_medium) {
3169025e849aSMarkus Armbruster         drv->bdrv_lock_medium(bs, locked);
317019cb3738Sbellard     }
317119cb3738Sbellard }
3172985a03b0Sths 
3173985a03b0Sths /* needed for generic scsi interface */
3174985a03b0Sths 
3175985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
3176985a03b0Sths {
3177985a03b0Sths     BlockDriver *drv = bs->drv;
3178985a03b0Sths 
3179985a03b0Sths     if (drv && drv->bdrv_ioctl)
3180985a03b0Sths         return drv->bdrv_ioctl(bs, req, buf);
3181985a03b0Sths     return -ENOTSUP;
3182985a03b0Sths }
31837d780669Saliguori 
3184221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
3185221f715dSaliguori         unsigned long int req, void *buf,
31867d780669Saliguori         BlockDriverCompletionFunc *cb, void *opaque)
31877d780669Saliguori {
3188221f715dSaliguori     BlockDriver *drv = bs->drv;
31897d780669Saliguori 
3190221f715dSaliguori     if (drv && drv->bdrv_aio_ioctl)
3191221f715dSaliguori         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
3192221f715dSaliguori     return NULL;
31937d780669Saliguori }
3194e268ca52Saliguori 
31957b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
31967b6f9300SMarkus Armbruster {
31977b6f9300SMarkus Armbruster     bs->buffer_alignment = align;
31987b6f9300SMarkus Armbruster }
31997cd1e32aSlirans@il.ibm.com 
3200e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size)
3201e268ca52Saliguori {
3202e268ca52Saliguori     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
3203e268ca52Saliguori }
32047cd1e32aSlirans@il.ibm.com 
32057cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
32067cd1e32aSlirans@il.ibm.com {
32077cd1e32aSlirans@il.ibm.com     int64_t bitmap_size;
3208a55eb92cSJan Kiszka 
3209aaa0eb75SLiran Schour     bs->dirty_count = 0;
32107cd1e32aSlirans@il.ibm.com     if (enable) {
3211c6d22830SJan Kiszka         if (!bs->dirty_bitmap) {
3212c6d22830SJan Kiszka             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
3213c6d22830SJan Kiszka                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
3214c6d22830SJan Kiszka             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
32157cd1e32aSlirans@il.ibm.com 
32167267c094SAnthony Liguori             bs->dirty_bitmap = g_malloc0(bitmap_size);
32177cd1e32aSlirans@il.ibm.com         }
32187cd1e32aSlirans@il.ibm.com     } else {
3219c6d22830SJan Kiszka         if (bs->dirty_bitmap) {
32207267c094SAnthony Liguori             g_free(bs->dirty_bitmap);
3221c6d22830SJan Kiszka             bs->dirty_bitmap = NULL;
32227cd1e32aSlirans@il.ibm.com         }
32237cd1e32aSlirans@il.ibm.com     }
32247cd1e32aSlirans@il.ibm.com }
32257cd1e32aSlirans@il.ibm.com 
32267cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
32277cd1e32aSlirans@il.ibm.com {
32286ea44308SJan Kiszka     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
32297cd1e32aSlirans@il.ibm.com 
3230c6d22830SJan Kiszka     if (bs->dirty_bitmap &&
3231c6d22830SJan Kiszka         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
32326d59fec1SMarcelo Tosatti         return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
32336d59fec1SMarcelo Tosatti             (1UL << (chunk % (sizeof(unsigned long) * 8))));
32347cd1e32aSlirans@il.ibm.com     } else {
32357cd1e32aSlirans@il.ibm.com         return 0;
32367cd1e32aSlirans@il.ibm.com     }
32377cd1e32aSlirans@il.ibm.com }
32387cd1e32aSlirans@il.ibm.com 
32397cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
32407cd1e32aSlirans@il.ibm.com                       int nr_sectors)
32417cd1e32aSlirans@il.ibm.com {
32427cd1e32aSlirans@il.ibm.com     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
32437cd1e32aSlirans@il.ibm.com }
3244aaa0eb75SLiran Schour 
3245aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs)
3246aaa0eb75SLiran Schour {
3247aaa0eb75SLiran Schour     return bs->dirty_count;
3248aaa0eb75SLiran Schour }
3249f88e1a42SJes Sorensen 
3250db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use)
3251db593f25SMarcelo Tosatti {
3252db593f25SMarcelo Tosatti     assert(bs->in_use != in_use);
3253db593f25SMarcelo Tosatti     bs->in_use = in_use;
3254db593f25SMarcelo Tosatti }
3255db593f25SMarcelo Tosatti 
3256db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs)
3257db593f25SMarcelo Tosatti {
3258db593f25SMarcelo Tosatti     return bs->in_use;
3259db593f25SMarcelo Tosatti }
3260db593f25SMarcelo Tosatti 
326128a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs)
326228a7282aSLuiz Capitulino {
326328a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_OK;
326428a7282aSLuiz Capitulino }
326528a7282aSLuiz Capitulino 
326628a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly
326728a7282aSLuiz Capitulino  * enables it _and_ the VM is configured to stop on errors */
326828a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
326928a7282aSLuiz Capitulino {
327028a7282aSLuiz Capitulino     return (bs->iostatus != BDRV_IOS_INVAL &&
327128a7282aSLuiz Capitulino            (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
327228a7282aSLuiz Capitulino             bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
327328a7282aSLuiz Capitulino             bs->on_read_error == BLOCK_ERR_STOP_ANY));
327428a7282aSLuiz Capitulino }
327528a7282aSLuiz Capitulino 
327628a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs)
327728a7282aSLuiz Capitulino {
327828a7282aSLuiz Capitulino     bs->iostatus = BDRV_IOS_INVAL;
327928a7282aSLuiz Capitulino }
328028a7282aSLuiz Capitulino 
328128a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs)
328228a7282aSLuiz Capitulino {
328328a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs)) {
328428a7282aSLuiz Capitulino         bs->iostatus = BDRV_IOS_OK;
328528a7282aSLuiz Capitulino     }
328628a7282aSLuiz Capitulino }
328728a7282aSLuiz Capitulino 
328828a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation
328928a7282aSLuiz Capitulino    quite simple. However, the block layer knows about the error, so it's
329028a7282aSLuiz Capitulino    possible to implement this without device models being involved */
329128a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
329228a7282aSLuiz Capitulino {
329328a7282aSLuiz Capitulino     if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
329428a7282aSLuiz Capitulino         assert(error >= 0);
329528a7282aSLuiz Capitulino         bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
329628a7282aSLuiz Capitulino     }
329728a7282aSLuiz Capitulino }
329828a7282aSLuiz Capitulino 
3299a597e79cSChristoph Hellwig void
3300a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
3301a597e79cSChristoph Hellwig         enum BlockAcctType type)
3302a597e79cSChristoph Hellwig {
3303a597e79cSChristoph Hellwig     assert(type < BDRV_MAX_IOTYPE);
3304a597e79cSChristoph Hellwig 
3305a597e79cSChristoph Hellwig     cookie->bytes = bytes;
3306c488c7f6SChristoph Hellwig     cookie->start_time_ns = get_clock();
3307a597e79cSChristoph Hellwig     cookie->type = type;
3308a597e79cSChristoph Hellwig }
3309a597e79cSChristoph Hellwig 
3310a597e79cSChristoph Hellwig void
3311a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
3312a597e79cSChristoph Hellwig {
3313a597e79cSChristoph Hellwig     assert(cookie->type < BDRV_MAX_IOTYPE);
3314a597e79cSChristoph Hellwig 
3315a597e79cSChristoph Hellwig     bs->nr_bytes[cookie->type] += cookie->bytes;
3316a597e79cSChristoph Hellwig     bs->nr_ops[cookie->type]++;
3317c488c7f6SChristoph Hellwig     bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
3318a597e79cSChristoph Hellwig }
3319a597e79cSChristoph Hellwig 
3320f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt,
3321f88e1a42SJes Sorensen                     const char *base_filename, const char *base_fmt,
3322f88e1a42SJes Sorensen                     char *options, uint64_t img_size, int flags)
3323f88e1a42SJes Sorensen {
3324f88e1a42SJes Sorensen     QEMUOptionParameter *param = NULL, *create_options = NULL;
3325d220894eSKevin Wolf     QEMUOptionParameter *backing_fmt, *backing_file, *size;
3326f88e1a42SJes Sorensen     BlockDriverState *bs = NULL;
3327f88e1a42SJes Sorensen     BlockDriver *drv, *proto_drv;
332896df67d1SStefan Hajnoczi     BlockDriver *backing_drv = NULL;
3329f88e1a42SJes Sorensen     int ret = 0;
3330f88e1a42SJes Sorensen 
3331f88e1a42SJes Sorensen     /* Find driver and parse its options */
3332f88e1a42SJes Sorensen     drv = bdrv_find_format(fmt);
3333f88e1a42SJes Sorensen     if (!drv) {
3334f88e1a42SJes Sorensen         error_report("Unknown file format '%s'", fmt);
33354f70f249SJes Sorensen         ret = -EINVAL;
3336f88e1a42SJes Sorensen         goto out;
3337f88e1a42SJes Sorensen     }
3338f88e1a42SJes Sorensen 
3339f88e1a42SJes Sorensen     proto_drv = bdrv_find_protocol(filename);
3340f88e1a42SJes Sorensen     if (!proto_drv) {
3341f88e1a42SJes Sorensen         error_report("Unknown protocol '%s'", filename);
33424f70f249SJes Sorensen         ret = -EINVAL;
3343f88e1a42SJes Sorensen         goto out;
3344f88e1a42SJes Sorensen     }
3345f88e1a42SJes Sorensen 
3346f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3347f88e1a42SJes Sorensen                                               drv->create_options);
3348f88e1a42SJes Sorensen     create_options = append_option_parameters(create_options,
3349f88e1a42SJes Sorensen                                               proto_drv->create_options);
3350f88e1a42SJes Sorensen 
3351f88e1a42SJes Sorensen     /* Create parameter list with default values */
3352f88e1a42SJes Sorensen     param = parse_option_parameters("", create_options, param);
3353f88e1a42SJes Sorensen 
3354f88e1a42SJes Sorensen     set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
3355f88e1a42SJes Sorensen 
3356f88e1a42SJes Sorensen     /* Parse -o options */
3357f88e1a42SJes Sorensen     if (options) {
3358f88e1a42SJes Sorensen         param = parse_option_parameters(options, create_options, param);
3359f88e1a42SJes Sorensen         if (param == NULL) {
3360f88e1a42SJes Sorensen             error_report("Invalid options for file format '%s'.", fmt);
33614f70f249SJes Sorensen             ret = -EINVAL;
3362f88e1a42SJes Sorensen             goto out;
3363f88e1a42SJes Sorensen         }
3364f88e1a42SJes Sorensen     }
3365f88e1a42SJes Sorensen 
3366f88e1a42SJes Sorensen     if (base_filename) {
3367f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
3368f88e1a42SJes Sorensen                                  base_filename)) {
3369f88e1a42SJes Sorensen             error_report("Backing file not supported for file format '%s'",
3370f88e1a42SJes Sorensen                          fmt);
33714f70f249SJes Sorensen             ret = -EINVAL;
3372f88e1a42SJes Sorensen             goto out;
3373f88e1a42SJes Sorensen         }
3374f88e1a42SJes Sorensen     }
3375f88e1a42SJes Sorensen 
3376f88e1a42SJes Sorensen     if (base_fmt) {
3377f88e1a42SJes Sorensen         if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
3378f88e1a42SJes Sorensen             error_report("Backing file format not supported for file "
3379f88e1a42SJes Sorensen                          "format '%s'", fmt);
33804f70f249SJes Sorensen             ret = -EINVAL;
3381f88e1a42SJes Sorensen             goto out;
3382f88e1a42SJes Sorensen         }
3383f88e1a42SJes Sorensen     }
3384f88e1a42SJes Sorensen 
3385792da93aSJes Sorensen     backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
3386792da93aSJes Sorensen     if (backing_file && backing_file->value.s) {
3387792da93aSJes Sorensen         if (!strcmp(filename, backing_file->value.s)) {
3388792da93aSJes Sorensen             error_report("Error: Trying to create an image with the "
3389792da93aSJes Sorensen                          "same filename as the backing file");
33904f70f249SJes Sorensen             ret = -EINVAL;
3391792da93aSJes Sorensen             goto out;
3392792da93aSJes Sorensen         }
3393792da93aSJes Sorensen     }
3394792da93aSJes Sorensen 
3395f88e1a42SJes Sorensen     backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
3396f88e1a42SJes Sorensen     if (backing_fmt && backing_fmt->value.s) {
339796df67d1SStefan Hajnoczi         backing_drv = bdrv_find_format(backing_fmt->value.s);
339896df67d1SStefan Hajnoczi         if (!backing_drv) {
3399f88e1a42SJes Sorensen             error_report("Unknown backing file format '%s'",
3400f88e1a42SJes Sorensen                          backing_fmt->value.s);
34014f70f249SJes Sorensen             ret = -EINVAL;
3402f88e1a42SJes Sorensen             goto out;
3403f88e1a42SJes Sorensen         }
3404f88e1a42SJes Sorensen     }
3405f88e1a42SJes Sorensen 
3406f88e1a42SJes Sorensen     // The size for the image must always be specified, with one exception:
3407f88e1a42SJes Sorensen     // If we are using a backing file, we can obtain the size from there
3408d220894eSKevin Wolf     size = get_option_parameter(param, BLOCK_OPT_SIZE);
3409d220894eSKevin Wolf     if (size && size->value.n == -1) {
3410f88e1a42SJes Sorensen         if (backing_file && backing_file->value.s) {
3411f88e1a42SJes Sorensen             uint64_t size;
3412f88e1a42SJes Sorensen             char buf[32];
3413f88e1a42SJes Sorensen 
3414f88e1a42SJes Sorensen             bs = bdrv_new("");
3415f88e1a42SJes Sorensen 
341696df67d1SStefan Hajnoczi             ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv);
3417f88e1a42SJes Sorensen             if (ret < 0) {
341896df67d1SStefan Hajnoczi                 error_report("Could not open '%s'", backing_file->value.s);
3419f88e1a42SJes Sorensen                 goto out;
3420f88e1a42SJes Sorensen             }
3421f88e1a42SJes Sorensen             bdrv_get_geometry(bs, &size);
3422f88e1a42SJes Sorensen             size *= 512;
3423f88e1a42SJes Sorensen 
3424f88e1a42SJes Sorensen             snprintf(buf, sizeof(buf), "%" PRId64, size);
3425f88e1a42SJes Sorensen             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
3426f88e1a42SJes Sorensen         } else {
3427f88e1a42SJes Sorensen             error_report("Image creation needs a size parameter");
34284f70f249SJes Sorensen             ret = -EINVAL;
3429f88e1a42SJes Sorensen             goto out;
3430f88e1a42SJes Sorensen         }
3431f88e1a42SJes Sorensen     }
3432f88e1a42SJes Sorensen 
3433f88e1a42SJes Sorensen     printf("Formatting '%s', fmt=%s ", filename, fmt);
3434f88e1a42SJes Sorensen     print_option_parameters(param);
3435f88e1a42SJes Sorensen     puts("");
3436f88e1a42SJes Sorensen 
3437f88e1a42SJes Sorensen     ret = bdrv_create(drv, filename, param);
3438f88e1a42SJes Sorensen 
3439f88e1a42SJes Sorensen     if (ret < 0) {
3440f88e1a42SJes Sorensen         if (ret == -ENOTSUP) {
3441f88e1a42SJes Sorensen             error_report("Formatting or formatting option not supported for "
3442f88e1a42SJes Sorensen                          "file format '%s'", fmt);
3443f88e1a42SJes Sorensen         } else if (ret == -EFBIG) {
3444f88e1a42SJes Sorensen             error_report("The image size is too large for file format '%s'",
3445f88e1a42SJes Sorensen                          fmt);
3446f88e1a42SJes Sorensen         } else {
3447f88e1a42SJes Sorensen             error_report("%s: error while creating %s: %s", filename, fmt,
3448f88e1a42SJes Sorensen                          strerror(-ret));
3449f88e1a42SJes Sorensen         }
3450f88e1a42SJes Sorensen     }
3451f88e1a42SJes Sorensen 
3452f88e1a42SJes Sorensen out:
3453f88e1a42SJes Sorensen     free_option_parameters(create_options);
3454f88e1a42SJes Sorensen     free_option_parameters(param);
3455f88e1a42SJes Sorensen 
3456f88e1a42SJes Sorensen     if (bs) {
3457f88e1a42SJes Sorensen         bdrv_delete(bs);
3458f88e1a42SJes Sorensen     }
34594f70f249SJes Sorensen 
34604f70f249SJes Sorensen     return ret;
3461f88e1a42SJes Sorensen }
3462