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); 81b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 82b2a61371SStefan Hajnoczi int64_t sector_num, 83b2a61371SStefan Hajnoczi QEMUIOVector *qiov, 84b2a61371SStefan Hajnoczi int nb_sectors, 85b2a61371SStefan Hajnoczi BlockDriverCompletionFunc *cb, 86b2a61371SStefan Hajnoczi void *opaque, 87b2a61371SStefan Hajnoczi bool is_write, 88b2a61371SStefan Hajnoczi CoroutineEntry *entry); 89b2a61371SStefan 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; 13146b7cb247SStefan Hajnoczi int ret; 1315da1fa91dSKevin Wolf 1316da1fa91dSKevin Wolf if (!bs->drv) { 1317da1fa91dSKevin Wolf return -ENOMEDIUM; 1318da1fa91dSKevin Wolf } 1319da1fa91dSKevin Wolf if (bs->read_only) { 1320da1fa91dSKevin Wolf return -EACCES; 1321da1fa91dSKevin Wolf } 1322da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1323da1fa91dSKevin Wolf return -EIO; 1324da1fa91dSKevin Wolf } 1325da1fa91dSKevin Wolf 13266b7cb247SStefan Hajnoczi ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); 13276b7cb247SStefan Hajnoczi 1328da1fa91dSKevin Wolf if (bs->dirty_bitmap) { 1329da1fa91dSKevin Wolf set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 1330da1fa91dSKevin Wolf } 1331da1fa91dSKevin Wolf 1332da1fa91dSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 1333da1fa91dSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 1334da1fa91dSKevin Wolf } 1335da1fa91dSKevin Wolf 13366b7cb247SStefan Hajnoczi return ret; 1337da1fa91dSKevin Wolf } 1338da1fa91dSKevin Wolf 1339c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, 1340c5fbe571SStefan Hajnoczi int nb_sectors, QEMUIOVector *qiov) 1341c5fbe571SStefan Hajnoczi { 1342c5fbe571SStefan Hajnoczi trace_bdrv_co_writev(bs, sector_num, nb_sectors); 1343c5fbe571SStefan Hajnoczi 1344c5fbe571SStefan Hajnoczi return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov); 1345c5fbe571SStefan Hajnoczi } 1346c5fbe571SStefan Hajnoczi 134783f64091Sbellard /** 134883f64091Sbellard * Truncate file to 'offset' bytes (needed only for file protocols) 134983f64091Sbellard */ 135083f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset) 135183f64091Sbellard { 135283f64091Sbellard BlockDriver *drv = bs->drv; 135351762288SStefan Hajnoczi int ret; 135483f64091Sbellard if (!drv) 135519cb3738Sbellard return -ENOMEDIUM; 135683f64091Sbellard if (!drv->bdrv_truncate) 135783f64091Sbellard return -ENOTSUP; 135859f2689dSNaphtali Sprei if (bs->read_only) 135959f2689dSNaphtali Sprei return -EACCES; 13608591675fSMarcelo Tosatti if (bdrv_in_use(bs)) 13618591675fSMarcelo Tosatti return -EBUSY; 136251762288SStefan Hajnoczi ret = drv->bdrv_truncate(bs, offset); 136351762288SStefan Hajnoczi if (ret == 0) { 136451762288SStefan Hajnoczi ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); 1365145feb17SMarkus Armbruster bdrv_dev_resize_cb(bs); 136651762288SStefan Hajnoczi } 136751762288SStefan Hajnoczi return ret; 136883f64091Sbellard } 136983f64091Sbellard 137083f64091Sbellard /** 13714a1d5e1fSFam Zheng * Length of a allocated file in bytes. Sparse files are counted by actual 13724a1d5e1fSFam Zheng * allocated space. Return < 0 if error or unknown. 13734a1d5e1fSFam Zheng */ 13744a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) 13754a1d5e1fSFam Zheng { 13764a1d5e1fSFam Zheng BlockDriver *drv = bs->drv; 13774a1d5e1fSFam Zheng if (!drv) { 13784a1d5e1fSFam Zheng return -ENOMEDIUM; 13794a1d5e1fSFam Zheng } 13804a1d5e1fSFam Zheng if (drv->bdrv_get_allocated_file_size) { 13814a1d5e1fSFam Zheng return drv->bdrv_get_allocated_file_size(bs); 13824a1d5e1fSFam Zheng } 13834a1d5e1fSFam Zheng if (bs->file) { 13844a1d5e1fSFam Zheng return bdrv_get_allocated_file_size(bs->file); 13854a1d5e1fSFam Zheng } 13864a1d5e1fSFam Zheng return -ENOTSUP; 13874a1d5e1fSFam Zheng } 13884a1d5e1fSFam Zheng 13894a1d5e1fSFam Zheng /** 139083f64091Sbellard * Length of a file in bytes. Return < 0 if error or unknown. 139183f64091Sbellard */ 139283f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs) 139383f64091Sbellard { 139483f64091Sbellard BlockDriver *drv = bs->drv; 139583f64091Sbellard if (!drv) 139619cb3738Sbellard return -ENOMEDIUM; 139751762288SStefan Hajnoczi 13982c6942faSMarkus Armbruster if (bs->growable || bdrv_dev_has_removable_media(bs)) { 139946a4e4e6SStefan Hajnoczi if (drv->bdrv_getlength) { 140083f64091Sbellard return drv->bdrv_getlength(bs); 1401fc01f7e7Sbellard } 140246a4e4e6SStefan Hajnoczi } 140346a4e4e6SStefan Hajnoczi return bs->total_sectors * BDRV_SECTOR_SIZE; 140446a4e4e6SStefan Hajnoczi } 1405fc01f7e7Sbellard 140619cb3738Sbellard /* return 0 as number of sectors if no device present or error */ 140796b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 1408fc01f7e7Sbellard { 140919cb3738Sbellard int64_t length; 141019cb3738Sbellard length = bdrv_getlength(bs); 141119cb3738Sbellard if (length < 0) 141219cb3738Sbellard length = 0; 141319cb3738Sbellard else 14146ea44308SJan Kiszka length = length >> BDRV_SECTOR_BITS; 141519cb3738Sbellard *nb_sectors_ptr = length; 1416fc01f7e7Sbellard } 1417cf98951bSbellard 1418f3d54fc4Saliguori struct partition { 1419f3d54fc4Saliguori uint8_t boot_ind; /* 0x80 - active */ 1420f3d54fc4Saliguori uint8_t head; /* starting head */ 1421f3d54fc4Saliguori uint8_t sector; /* starting sector */ 1422f3d54fc4Saliguori uint8_t cyl; /* starting cylinder */ 1423f3d54fc4Saliguori uint8_t sys_ind; /* What partition type */ 1424f3d54fc4Saliguori uint8_t end_head; /* end head */ 1425f3d54fc4Saliguori uint8_t end_sector; /* end sector */ 1426f3d54fc4Saliguori uint8_t end_cyl; /* end cylinder */ 1427f3d54fc4Saliguori uint32_t start_sect; /* starting sector counting from 0 */ 1428f3d54fc4Saliguori uint32_t nr_sects; /* nr of sectors in partition */ 1429541dc0d4SStefan Weil } QEMU_PACKED; 1430f3d54fc4Saliguori 1431f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 1432f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs, 1433f3d54fc4Saliguori int *pcylinders, int *pheads, int *psectors) 1434f3d54fc4Saliguori { 1435eb5a3165SJes Sorensen uint8_t buf[BDRV_SECTOR_SIZE]; 1436f3d54fc4Saliguori int ret, i, heads, sectors, cylinders; 1437f3d54fc4Saliguori struct partition *p; 1438f3d54fc4Saliguori uint32_t nr_sects; 1439a38131b6Sblueswir1 uint64_t nb_sectors; 1440f3d54fc4Saliguori 1441f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1442f3d54fc4Saliguori 1443f3d54fc4Saliguori ret = bdrv_read(bs, 0, buf, 1); 1444f3d54fc4Saliguori if (ret < 0) 1445f3d54fc4Saliguori return -1; 1446f3d54fc4Saliguori /* test msdos magic */ 1447f3d54fc4Saliguori if (buf[510] != 0x55 || buf[511] != 0xaa) 1448f3d54fc4Saliguori return -1; 1449f3d54fc4Saliguori for(i = 0; i < 4; i++) { 1450f3d54fc4Saliguori p = ((struct partition *)(buf + 0x1be)) + i; 1451f3d54fc4Saliguori nr_sects = le32_to_cpu(p->nr_sects); 1452f3d54fc4Saliguori if (nr_sects && p->end_head) { 1453f3d54fc4Saliguori /* We make the assumption that the partition terminates on 1454f3d54fc4Saliguori a cylinder boundary */ 1455f3d54fc4Saliguori heads = p->end_head + 1; 1456f3d54fc4Saliguori sectors = p->end_sector & 63; 1457f3d54fc4Saliguori if (sectors == 0) 1458f3d54fc4Saliguori continue; 1459f3d54fc4Saliguori cylinders = nb_sectors / (heads * sectors); 1460f3d54fc4Saliguori if (cylinders < 1 || cylinders > 16383) 1461f3d54fc4Saliguori continue; 1462f3d54fc4Saliguori *pheads = heads; 1463f3d54fc4Saliguori *psectors = sectors; 1464f3d54fc4Saliguori *pcylinders = cylinders; 1465f3d54fc4Saliguori #if 0 1466f3d54fc4Saliguori printf("guessed geometry: LCHS=%d %d %d\n", 1467f3d54fc4Saliguori cylinders, heads, sectors); 1468f3d54fc4Saliguori #endif 1469f3d54fc4Saliguori return 0; 1470f3d54fc4Saliguori } 1471f3d54fc4Saliguori } 1472f3d54fc4Saliguori return -1; 1473f3d54fc4Saliguori } 1474f3d54fc4Saliguori 1475f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 1476f3d54fc4Saliguori { 1477f3d54fc4Saliguori int translation, lba_detected = 0; 1478f3d54fc4Saliguori int cylinders, heads, secs; 1479a38131b6Sblueswir1 uint64_t nb_sectors; 1480f3d54fc4Saliguori 1481f3d54fc4Saliguori /* if a geometry hint is available, use it */ 1482f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1483f3d54fc4Saliguori bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 1484f3d54fc4Saliguori translation = bdrv_get_translation_hint(bs); 1485f3d54fc4Saliguori if (cylinders != 0) { 1486f3d54fc4Saliguori *pcyls = cylinders; 1487f3d54fc4Saliguori *pheads = heads; 1488f3d54fc4Saliguori *psecs = secs; 1489f3d54fc4Saliguori } else { 1490f3d54fc4Saliguori if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 1491f3d54fc4Saliguori if (heads > 16) { 1492f3d54fc4Saliguori /* if heads > 16, it means that a BIOS LBA 1493f3d54fc4Saliguori translation was active, so the default 1494f3d54fc4Saliguori hardware geometry is OK */ 1495f3d54fc4Saliguori lba_detected = 1; 1496f3d54fc4Saliguori goto default_geometry; 1497f3d54fc4Saliguori } else { 1498f3d54fc4Saliguori *pcyls = cylinders; 1499f3d54fc4Saliguori *pheads = heads; 1500f3d54fc4Saliguori *psecs = secs; 1501f3d54fc4Saliguori /* disable any translation to be in sync with 1502f3d54fc4Saliguori the logical geometry */ 1503f3d54fc4Saliguori if (translation == BIOS_ATA_TRANSLATION_AUTO) { 1504f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1505f3d54fc4Saliguori BIOS_ATA_TRANSLATION_NONE); 1506f3d54fc4Saliguori } 1507f3d54fc4Saliguori } 1508f3d54fc4Saliguori } else { 1509f3d54fc4Saliguori default_geometry: 1510f3d54fc4Saliguori /* if no geometry, use a standard physical disk geometry */ 1511f3d54fc4Saliguori cylinders = nb_sectors / (16 * 63); 1512f3d54fc4Saliguori 1513f3d54fc4Saliguori if (cylinders > 16383) 1514f3d54fc4Saliguori cylinders = 16383; 1515f3d54fc4Saliguori else if (cylinders < 2) 1516f3d54fc4Saliguori cylinders = 2; 1517f3d54fc4Saliguori *pcyls = cylinders; 1518f3d54fc4Saliguori *pheads = 16; 1519f3d54fc4Saliguori *psecs = 63; 1520f3d54fc4Saliguori if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 1521f3d54fc4Saliguori if ((*pcyls * *pheads) <= 131072) { 1522f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1523f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LARGE); 1524f3d54fc4Saliguori } else { 1525f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1526f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LBA); 1527f3d54fc4Saliguori } 1528f3d54fc4Saliguori } 1529f3d54fc4Saliguori } 1530f3d54fc4Saliguori bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 1531f3d54fc4Saliguori } 1532f3d54fc4Saliguori } 1533f3d54fc4Saliguori 1534b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs, 1535b338082bSbellard int cyls, int heads, int secs) 1536b338082bSbellard { 1537b338082bSbellard bs->cyls = cyls; 1538b338082bSbellard bs->heads = heads; 1539b338082bSbellard bs->secs = secs; 1540b338082bSbellard } 1541b338082bSbellard 154246d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 154346d4767dSbellard { 154446d4767dSbellard bs->translation = translation; 154546d4767dSbellard } 154646d4767dSbellard 1547b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs, 1548b338082bSbellard int *pcyls, int *pheads, int *psecs) 1549b338082bSbellard { 1550b338082bSbellard *pcyls = bs->cyls; 1551b338082bSbellard *pheads = bs->heads; 1552b338082bSbellard *psecs = bs->secs; 1553b338082bSbellard } 1554b338082bSbellard 15555bbdbb46SBlue Swirl /* Recognize floppy formats */ 15565bbdbb46SBlue Swirl typedef struct FDFormat { 15575bbdbb46SBlue Swirl FDriveType drive; 15585bbdbb46SBlue Swirl uint8_t last_sect; 15595bbdbb46SBlue Swirl uint8_t max_track; 15605bbdbb46SBlue Swirl uint8_t max_head; 15615bbdbb46SBlue Swirl } FDFormat; 15625bbdbb46SBlue Swirl 15635bbdbb46SBlue Swirl static const FDFormat fd_formats[] = { 15645bbdbb46SBlue Swirl /* First entry is default format */ 15655bbdbb46SBlue Swirl /* 1.44 MB 3"1/2 floppy disks */ 15665bbdbb46SBlue Swirl { FDRIVE_DRV_144, 18, 80, 1, }, 15675bbdbb46SBlue Swirl { FDRIVE_DRV_144, 20, 80, 1, }, 15685bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 80, 1, }, 15695bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 82, 1, }, 15705bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 83, 1, }, 15715bbdbb46SBlue Swirl { FDRIVE_DRV_144, 22, 80, 1, }, 15725bbdbb46SBlue Swirl { FDRIVE_DRV_144, 23, 80, 1, }, 15735bbdbb46SBlue Swirl { FDRIVE_DRV_144, 24, 80, 1, }, 15745bbdbb46SBlue Swirl /* 2.88 MB 3"1/2 floppy disks */ 15755bbdbb46SBlue Swirl { FDRIVE_DRV_288, 36, 80, 1, }, 15765bbdbb46SBlue Swirl { FDRIVE_DRV_288, 39, 80, 1, }, 15775bbdbb46SBlue Swirl { FDRIVE_DRV_288, 40, 80, 1, }, 15785bbdbb46SBlue Swirl { FDRIVE_DRV_288, 44, 80, 1, }, 15795bbdbb46SBlue Swirl { FDRIVE_DRV_288, 48, 80, 1, }, 15805bbdbb46SBlue Swirl /* 720 kB 3"1/2 floppy disks */ 15815bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 1, }, 15825bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 80, 1, }, 15835bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 82, 1, }, 15845bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 83, 1, }, 15855bbdbb46SBlue Swirl { FDRIVE_DRV_144, 13, 80, 1, }, 15865bbdbb46SBlue Swirl { FDRIVE_DRV_144, 14, 80, 1, }, 15875bbdbb46SBlue Swirl /* 1.2 MB 5"1/4 floppy disks */ 15885bbdbb46SBlue Swirl { FDRIVE_DRV_120, 15, 80, 1, }, 15895bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 80, 1, }, 15905bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 82, 1, }, 15915bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 83, 1, }, 15925bbdbb46SBlue Swirl { FDRIVE_DRV_120, 20, 80, 1, }, 15935bbdbb46SBlue Swirl /* 720 kB 5"1/4 floppy disks */ 15945bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 80, 1, }, 15955bbdbb46SBlue Swirl { FDRIVE_DRV_120, 11, 80, 1, }, 15965bbdbb46SBlue Swirl /* 360 kB 5"1/4 floppy disks */ 15975bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 1, }, 15985bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 0, }, 15995bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 41, 1, }, 16005bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 42, 1, }, 16015bbdbb46SBlue Swirl /* 320 kB 5"1/4 floppy disks */ 16025bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 1, }, 16035bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 0, }, 16045bbdbb46SBlue Swirl /* 360 kB must match 5"1/4 better than 3"1/2... */ 16055bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 0, }, 16065bbdbb46SBlue Swirl /* end */ 16075bbdbb46SBlue Swirl { FDRIVE_DRV_NONE, -1, -1, 0, }, 16085bbdbb46SBlue Swirl }; 16095bbdbb46SBlue Swirl 16105bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, 16115bbdbb46SBlue Swirl int *max_track, int *last_sect, 16125bbdbb46SBlue Swirl FDriveType drive_in, FDriveType *drive) 16135bbdbb46SBlue Swirl { 16145bbdbb46SBlue Swirl const FDFormat *parse; 16155bbdbb46SBlue Swirl uint64_t nb_sectors, size; 16165bbdbb46SBlue Swirl int i, first_match, match; 16175bbdbb46SBlue Swirl 16185bbdbb46SBlue Swirl bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect); 16195bbdbb46SBlue Swirl if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) { 16205bbdbb46SBlue Swirl /* User defined disk */ 16215bbdbb46SBlue Swirl } else { 16225bbdbb46SBlue Swirl bdrv_get_geometry(bs, &nb_sectors); 16235bbdbb46SBlue Swirl match = -1; 16245bbdbb46SBlue Swirl first_match = -1; 16255bbdbb46SBlue Swirl for (i = 0; ; i++) { 16265bbdbb46SBlue Swirl parse = &fd_formats[i]; 16275bbdbb46SBlue Swirl if (parse->drive == FDRIVE_DRV_NONE) { 16285bbdbb46SBlue Swirl break; 16295bbdbb46SBlue Swirl } 16305bbdbb46SBlue Swirl if (drive_in == parse->drive || 16315bbdbb46SBlue Swirl drive_in == FDRIVE_DRV_NONE) { 16325bbdbb46SBlue Swirl size = (parse->max_head + 1) * parse->max_track * 16335bbdbb46SBlue Swirl parse->last_sect; 16345bbdbb46SBlue Swirl if (nb_sectors == size) { 16355bbdbb46SBlue Swirl match = i; 16365bbdbb46SBlue Swirl break; 16375bbdbb46SBlue Swirl } 16385bbdbb46SBlue Swirl if (first_match == -1) { 16395bbdbb46SBlue Swirl first_match = i; 16405bbdbb46SBlue Swirl } 16415bbdbb46SBlue Swirl } 16425bbdbb46SBlue Swirl } 16435bbdbb46SBlue Swirl if (match == -1) { 16445bbdbb46SBlue Swirl if (first_match == -1) { 16455bbdbb46SBlue Swirl match = 1; 16465bbdbb46SBlue Swirl } else { 16475bbdbb46SBlue Swirl match = first_match; 16485bbdbb46SBlue Swirl } 16495bbdbb46SBlue Swirl parse = &fd_formats[match]; 16505bbdbb46SBlue Swirl } 16515bbdbb46SBlue Swirl *nb_heads = parse->max_head + 1; 16525bbdbb46SBlue Swirl *max_track = parse->max_track; 16535bbdbb46SBlue Swirl *last_sect = parse->last_sect; 16545bbdbb46SBlue Swirl *drive = parse->drive; 16555bbdbb46SBlue Swirl } 16565bbdbb46SBlue Swirl } 16575bbdbb46SBlue Swirl 165846d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs) 165946d4767dSbellard { 166046d4767dSbellard return bs->translation; 166146d4767dSbellard } 166246d4767dSbellard 1663abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error, 1664abd7f68dSMarkus Armbruster BlockErrorAction on_write_error) 1665abd7f68dSMarkus Armbruster { 1666abd7f68dSMarkus Armbruster bs->on_read_error = on_read_error; 1667abd7f68dSMarkus Armbruster bs->on_write_error = on_write_error; 1668abd7f68dSMarkus Armbruster } 1669abd7f68dSMarkus Armbruster 1670abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read) 1671abd7f68dSMarkus Armbruster { 1672abd7f68dSMarkus Armbruster return is_read ? bs->on_read_error : bs->on_write_error; 1673abd7f68dSMarkus Armbruster } 1674abd7f68dSMarkus Armbruster 1675b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs) 1676b338082bSbellard { 1677b338082bSbellard return bs->read_only; 1678b338082bSbellard } 1679b338082bSbellard 1680985a03b0Sths int bdrv_is_sg(BlockDriverState *bs) 1681985a03b0Sths { 1682985a03b0Sths return bs->sg; 1683985a03b0Sths } 1684985a03b0Sths 1685e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs) 1686e900a7b7SChristoph Hellwig { 1687e900a7b7SChristoph Hellwig return bs->enable_write_cache; 1688e900a7b7SChristoph Hellwig } 1689e900a7b7SChristoph Hellwig 1690ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs) 1691ea2384d3Sbellard { 1692ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) 1693ea2384d3Sbellard return 1; 1694ea2384d3Sbellard return bs->encrypted; 1695ea2384d3Sbellard } 1696ea2384d3Sbellard 1697c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs) 1698c0f4ce77Saliguori { 1699c0f4ce77Saliguori BlockDriverState *backing_hd = bs->backing_hd; 1700c0f4ce77Saliguori 1701c0f4ce77Saliguori if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 1702c0f4ce77Saliguori return 1; 1703c0f4ce77Saliguori return (bs->encrypted && !bs->valid_key); 1704c0f4ce77Saliguori } 1705c0f4ce77Saliguori 1706ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key) 1707ea2384d3Sbellard { 1708ea2384d3Sbellard int ret; 1709ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) { 1710ea2384d3Sbellard ret = bdrv_set_key(bs->backing_hd, key); 1711ea2384d3Sbellard if (ret < 0) 1712ea2384d3Sbellard return ret; 1713ea2384d3Sbellard if (!bs->encrypted) 1714ea2384d3Sbellard return 0; 1715ea2384d3Sbellard } 1716fd04a2aeSShahar Havivi if (!bs->encrypted) { 1717fd04a2aeSShahar Havivi return -EINVAL; 1718fd04a2aeSShahar Havivi } else if (!bs->drv || !bs->drv->bdrv_set_key) { 1719fd04a2aeSShahar Havivi return -ENOMEDIUM; 1720fd04a2aeSShahar Havivi } 1721c0f4ce77Saliguori ret = bs->drv->bdrv_set_key(bs, key); 1722bb5fc20fSaliguori if (ret < 0) { 1723bb5fc20fSaliguori bs->valid_key = 0; 1724bb5fc20fSaliguori } else if (!bs->valid_key) { 1725bb5fc20fSaliguori bs->valid_key = 1; 1726bb5fc20fSaliguori /* call the change callback now, we skipped it on open */ 17277d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 1728bb5fc20fSaliguori } 1729c0f4ce77Saliguori return ret; 1730ea2384d3Sbellard } 1731ea2384d3Sbellard 1732ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 1733ea2384d3Sbellard { 173419cb3738Sbellard if (!bs->drv) { 1735ea2384d3Sbellard buf[0] = '\0'; 1736ea2384d3Sbellard } else { 1737ea2384d3Sbellard pstrcpy(buf, buf_size, bs->drv->format_name); 1738ea2384d3Sbellard } 1739ea2384d3Sbellard } 1740ea2384d3Sbellard 1741ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 1742ea2384d3Sbellard void *opaque) 1743ea2384d3Sbellard { 1744ea2384d3Sbellard BlockDriver *drv; 1745ea2384d3Sbellard 17468a22f02aSStefan Hajnoczi QLIST_FOREACH(drv, &bdrv_drivers, list) { 1747ea2384d3Sbellard it(opaque, drv->format_name); 1748ea2384d3Sbellard } 1749ea2384d3Sbellard } 1750ea2384d3Sbellard 1751b338082bSbellard BlockDriverState *bdrv_find(const char *name) 1752b338082bSbellard { 1753b338082bSbellard BlockDriverState *bs; 1754b338082bSbellard 17551b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 17561b7bdbc1SStefan Hajnoczi if (!strcmp(name, bs->device_name)) { 1757b338082bSbellard return bs; 1758b338082bSbellard } 17591b7bdbc1SStefan Hajnoczi } 1760b338082bSbellard return NULL; 1761b338082bSbellard } 1762b338082bSbellard 17632f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs) 17642f399b0aSMarkus Armbruster { 17652f399b0aSMarkus Armbruster if (!bs) { 17662f399b0aSMarkus Armbruster return QTAILQ_FIRST(&bdrv_states); 17672f399b0aSMarkus Armbruster } 17682f399b0aSMarkus Armbruster return QTAILQ_NEXT(bs, list); 17692f399b0aSMarkus Armbruster } 17702f399b0aSMarkus Armbruster 177151de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 177281d0912dSbellard { 177381d0912dSbellard BlockDriverState *bs; 177481d0912dSbellard 17751b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 177651de9760Saliguori it(opaque, bs); 177781d0912dSbellard } 177881d0912dSbellard } 177981d0912dSbellard 1780ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs) 1781ea2384d3Sbellard { 1782ea2384d3Sbellard return bs->device_name; 1783ea2384d3Sbellard } 1784ea2384d3Sbellard 1785205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs) 17867a6cba61Spbrook { 1787016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 1788205ef796SKevin Wolf return 0; 1789016f5cf6SAlexander Graf } 1790016f5cf6SAlexander Graf 1791e7a8a783SKevin Wolf if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) { 1792e7a8a783SKevin Wolf return bdrv_co_flush_em(bs); 1793e7a8a783SKevin Wolf } 1794e7a8a783SKevin Wolf 1795205ef796SKevin Wolf if (bs->drv && bs->drv->bdrv_flush) { 1796205ef796SKevin Wolf return bs->drv->bdrv_flush(bs); 1797205ef796SKevin Wolf } 1798205ef796SKevin Wolf 1799205ef796SKevin Wolf /* 1800205ef796SKevin Wolf * Some block drivers always operate in either writethrough or unsafe mode 1801205ef796SKevin Wolf * and don't support bdrv_flush therefore. Usually qemu doesn't know how 1802205ef796SKevin Wolf * the server works (because the behaviour is hardcoded or depends on 1803205ef796SKevin Wolf * server-side configuration), so we can't ensure that everything is safe 1804205ef796SKevin Wolf * on disk. Returning an error doesn't work because that would break guests 1805205ef796SKevin Wolf * even if the server operates in writethrough mode. 1806205ef796SKevin Wolf * 1807205ef796SKevin Wolf * Let's hope the user knows what he's doing. 1808205ef796SKevin Wolf */ 1809205ef796SKevin Wolf return 0; 18107a6cba61Spbrook } 18117a6cba61Spbrook 1812c6ca28d6Saliguori void bdrv_flush_all(void) 1813c6ca28d6Saliguori { 1814c6ca28d6Saliguori BlockDriverState *bs; 1815c6ca28d6Saliguori 18161b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1817c602a489SMarkus Armbruster if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) { 1818c6ca28d6Saliguori bdrv_flush(bs); 1819c6ca28d6Saliguori } 18201b7bdbc1SStefan Hajnoczi } 18211b7bdbc1SStefan Hajnoczi } 1822c6ca28d6Saliguori 1823f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs) 1824f2feebbdSKevin Wolf { 1825f2feebbdSKevin Wolf assert(bs->drv); 1826f2feebbdSKevin Wolf 1827336c1c12SKevin Wolf if (bs->drv->bdrv_has_zero_init) { 1828336c1c12SKevin Wolf return bs->drv->bdrv_has_zero_init(bs); 1829f2feebbdSKevin Wolf } 1830f2feebbdSKevin Wolf 1831f2feebbdSKevin Wolf return 1; 1832f2feebbdSKevin Wolf } 1833f2feebbdSKevin Wolf 1834bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) 1835bb8bf76fSChristoph Hellwig { 1836bb8bf76fSChristoph Hellwig if (!bs->drv) { 1837bb8bf76fSChristoph Hellwig return -ENOMEDIUM; 1838bb8bf76fSChristoph Hellwig } 1839bb8bf76fSChristoph Hellwig if (!bs->drv->bdrv_discard) { 1840bb8bf76fSChristoph Hellwig return 0; 1841bb8bf76fSChristoph Hellwig } 1842bb8bf76fSChristoph Hellwig return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); 1843bb8bf76fSChristoph Hellwig } 1844bb8bf76fSChristoph Hellwig 1845f58c7b35Sths /* 1846f58c7b35Sths * Returns true iff the specified sector is present in the disk image. Drivers 1847f58c7b35Sths * not implementing the functionality are assumed to not support backing files, 1848f58c7b35Sths * hence all their sectors are reported as allocated. 1849f58c7b35Sths * 1850f58c7b35Sths * 'pnum' is set to the number of sectors (including and immediately following 1851f58c7b35Sths * the specified sector) that are known to be in the same 1852f58c7b35Sths * allocated/unallocated state. 1853f58c7b35Sths * 1854f58c7b35Sths * 'nb_sectors' is the max value 'pnum' should be set to. 1855f58c7b35Sths */ 1856f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1857f58c7b35Sths int *pnum) 1858f58c7b35Sths { 1859f58c7b35Sths int64_t n; 1860f58c7b35Sths if (!bs->drv->bdrv_is_allocated) { 1861f58c7b35Sths if (sector_num >= bs->total_sectors) { 1862f58c7b35Sths *pnum = 0; 1863f58c7b35Sths return 0; 1864f58c7b35Sths } 1865f58c7b35Sths n = bs->total_sectors - sector_num; 1866f58c7b35Sths *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1867f58c7b35Sths return 1; 1868f58c7b35Sths } 1869f58c7b35Sths return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1870f58c7b35Sths } 1871f58c7b35Sths 18722582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv, 18732582bfedSLuiz Capitulino BlockMonEventAction action, int is_read) 18742582bfedSLuiz Capitulino { 18752582bfedSLuiz Capitulino QObject *data; 18762582bfedSLuiz Capitulino const char *action_str; 18772582bfedSLuiz Capitulino 18782582bfedSLuiz Capitulino switch (action) { 18792582bfedSLuiz Capitulino case BDRV_ACTION_REPORT: 18802582bfedSLuiz Capitulino action_str = "report"; 18812582bfedSLuiz Capitulino break; 18822582bfedSLuiz Capitulino case BDRV_ACTION_IGNORE: 18832582bfedSLuiz Capitulino action_str = "ignore"; 18842582bfedSLuiz Capitulino break; 18852582bfedSLuiz Capitulino case BDRV_ACTION_STOP: 18862582bfedSLuiz Capitulino action_str = "stop"; 18872582bfedSLuiz Capitulino break; 18882582bfedSLuiz Capitulino default: 18892582bfedSLuiz Capitulino abort(); 18902582bfedSLuiz Capitulino } 18912582bfedSLuiz Capitulino 18922582bfedSLuiz Capitulino data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", 18932582bfedSLuiz Capitulino bdrv->device_name, 18942582bfedSLuiz Capitulino action_str, 18952582bfedSLuiz Capitulino is_read ? "read" : "write"); 18962582bfedSLuiz Capitulino monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data); 18972582bfedSLuiz Capitulino 18982582bfedSLuiz Capitulino qobject_decref(data); 18992582bfedSLuiz Capitulino } 19002582bfedSLuiz Capitulino 1901d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque) 1902b338082bSbellard { 1903d15e5465SLuiz Capitulino QDict *bs_dict; 1904d15e5465SLuiz Capitulino Monitor *mon = opaque; 1905b338082bSbellard 1906d15e5465SLuiz Capitulino bs_dict = qobject_to_qdict(obj); 1907d15e5465SLuiz Capitulino 1908d8aeeb31SMarkus Armbruster monitor_printf(mon, "%s: removable=%d", 1909d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "device"), 1910d15e5465SLuiz Capitulino qdict_get_bool(bs_dict, "removable")); 1911d15e5465SLuiz Capitulino 1912d15e5465SLuiz Capitulino if (qdict_get_bool(bs_dict, "removable")) { 1913d15e5465SLuiz Capitulino monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); 1914e4def80bSMarkus Armbruster monitor_printf(mon, " tray-open=%d", 1915e4def80bSMarkus Armbruster qdict_get_bool(bs_dict, "tray-open")); 1916b338082bSbellard } 1917d2078cc2SLuiz Capitulino 1918d2078cc2SLuiz Capitulino if (qdict_haskey(bs_dict, "io-status")) { 1919d2078cc2SLuiz Capitulino monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status")); 1920d2078cc2SLuiz Capitulino } 1921d2078cc2SLuiz Capitulino 1922d15e5465SLuiz Capitulino if (qdict_haskey(bs_dict, "inserted")) { 1923d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); 1924d15e5465SLuiz Capitulino 1925376253ecSaliguori monitor_printf(mon, " file="); 1926d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "file")); 1927d15e5465SLuiz Capitulino if (qdict_haskey(qdict, "backing_file")) { 1928376253ecSaliguori monitor_printf(mon, " backing_file="); 1929d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); 1930fef30743Sths } 1931d15e5465SLuiz Capitulino monitor_printf(mon, " ro=%d drv=%s encrypted=%d", 1932d15e5465SLuiz Capitulino qdict_get_bool(qdict, "ro"), 1933d15e5465SLuiz Capitulino qdict_get_str(qdict, "drv"), 1934d15e5465SLuiz Capitulino qdict_get_bool(qdict, "encrypted")); 1935b338082bSbellard } else { 1936376253ecSaliguori monitor_printf(mon, " [not inserted]"); 1937b338082bSbellard } 1938d15e5465SLuiz Capitulino 1939376253ecSaliguori monitor_printf(mon, "\n"); 1940b338082bSbellard } 1941d15e5465SLuiz Capitulino 1942d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data) 1943d15e5465SLuiz Capitulino { 1944d15e5465SLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); 1945d15e5465SLuiz Capitulino } 1946d15e5465SLuiz Capitulino 1947f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = { 1948f04ef601SLuiz Capitulino [BDRV_IOS_OK] = "ok", 1949f04ef601SLuiz Capitulino [BDRV_IOS_FAILED] = "failed", 1950f04ef601SLuiz Capitulino [BDRV_IOS_ENOSPC] = "nospace", 1951f04ef601SLuiz Capitulino }; 1952f04ef601SLuiz Capitulino 1953d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data) 1954d15e5465SLuiz Capitulino { 1955d15e5465SLuiz Capitulino QList *bs_list; 1956d15e5465SLuiz Capitulino BlockDriverState *bs; 1957d15e5465SLuiz Capitulino 1958d15e5465SLuiz Capitulino bs_list = qlist_new(); 1959d15e5465SLuiz Capitulino 19601b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1961d15e5465SLuiz Capitulino QObject *bs_obj; 1962e4def80bSMarkus Armbruster QDict *bs_dict; 1963d15e5465SLuiz Capitulino 1964d8aeeb31SMarkus Armbruster bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', " 1965d15e5465SLuiz Capitulino "'removable': %i, 'locked': %i }", 19662c6942faSMarkus Armbruster bs->device_name, 19672c6942faSMarkus Armbruster bdrv_dev_has_removable_media(bs), 1968f107639aSMarkus Armbruster bdrv_dev_is_medium_locked(bs)); 1969e4def80bSMarkus Armbruster bs_dict = qobject_to_qdict(bs_obj); 1970d15e5465SLuiz Capitulino 1971e4def80bSMarkus Armbruster if (bdrv_dev_has_removable_media(bs)) { 1972e4def80bSMarkus Armbruster qdict_put(bs_dict, "tray-open", 1973e4def80bSMarkus Armbruster qbool_from_int(bdrv_dev_is_tray_open(bs))); 1974e4def80bSMarkus Armbruster } 1975f04ef601SLuiz Capitulino 1976f04ef601SLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 1977f04ef601SLuiz Capitulino qdict_put(bs_dict, "io-status", 1978f04ef601SLuiz Capitulino qstring_from_str(io_status_name[bs->iostatus])); 1979f04ef601SLuiz Capitulino } 1980f04ef601SLuiz Capitulino 1981d15e5465SLuiz Capitulino if (bs->drv) { 1982d15e5465SLuiz Capitulino QObject *obj; 1983d15e5465SLuiz Capitulino 1984d15e5465SLuiz Capitulino obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " 1985d15e5465SLuiz Capitulino "'encrypted': %i }", 1986d15e5465SLuiz Capitulino bs->filename, bs->read_only, 1987d15e5465SLuiz Capitulino bs->drv->format_name, 1988d15e5465SLuiz Capitulino bdrv_is_encrypted(bs)); 1989d15e5465SLuiz Capitulino if (bs->backing_file[0] != '\0') { 1990d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(obj); 1991d15e5465SLuiz Capitulino qdict_put(qdict, "backing_file", 1992d15e5465SLuiz Capitulino qstring_from_str(bs->backing_file)); 1993d15e5465SLuiz Capitulino } 1994d15e5465SLuiz Capitulino 1995d15e5465SLuiz Capitulino qdict_put_obj(bs_dict, "inserted", obj); 1996d15e5465SLuiz Capitulino } 1997d15e5465SLuiz Capitulino qlist_append_obj(bs_list, bs_obj); 1998d15e5465SLuiz Capitulino } 1999d15e5465SLuiz Capitulino 2000d15e5465SLuiz Capitulino *ret_data = QOBJECT(bs_list); 2001b338082bSbellard } 2002a36e69ddSths 2003218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque) 2004a36e69ddSths { 2005218a536aSLuiz Capitulino QDict *qdict; 2006218a536aSLuiz Capitulino Monitor *mon = opaque; 2007218a536aSLuiz Capitulino 2008218a536aSLuiz Capitulino qdict = qobject_to_qdict(data); 2009218a536aSLuiz Capitulino monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 2010218a536aSLuiz Capitulino 2011218a536aSLuiz Capitulino qdict = qobject_to_qdict(qdict_get(qdict, "stats")); 2012218a536aSLuiz Capitulino monitor_printf(mon, " rd_bytes=%" PRId64 2013218a536aSLuiz Capitulino " wr_bytes=%" PRId64 2014218a536aSLuiz Capitulino " rd_operations=%" PRId64 2015218a536aSLuiz Capitulino " wr_operations=%" PRId64 2016e8045d67SChristoph Hellwig " flush_operations=%" PRId64 2017c488c7f6SChristoph Hellwig " wr_total_time_ns=%" PRId64 2018c488c7f6SChristoph Hellwig " rd_total_time_ns=%" PRId64 2019c488c7f6SChristoph Hellwig " flush_total_time_ns=%" PRId64 2020218a536aSLuiz Capitulino "\n", 2021218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_bytes"), 2022218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_bytes"), 2023218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_operations"), 2024e8045d67SChristoph Hellwig qdict_get_int(qdict, "wr_operations"), 2025c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_operations"), 2026c488c7f6SChristoph Hellwig qdict_get_int(qdict, "wr_total_time_ns"), 2027c488c7f6SChristoph Hellwig qdict_get_int(qdict, "rd_total_time_ns"), 2028c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_total_time_ns")); 2029218a536aSLuiz Capitulino } 2030218a536aSLuiz Capitulino 2031218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data) 2032218a536aSLuiz Capitulino { 2033218a536aSLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); 2034218a536aSLuiz Capitulino } 2035218a536aSLuiz Capitulino 2036294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs) 2037294cc35fSKevin Wolf { 2038294cc35fSKevin Wolf QObject *res; 2039294cc35fSKevin Wolf QDict *dict; 2040294cc35fSKevin Wolf 2041294cc35fSKevin Wolf res = qobject_from_jsonf("{ 'stats': {" 2042294cc35fSKevin Wolf "'rd_bytes': %" PRId64 "," 2043294cc35fSKevin Wolf "'wr_bytes': %" PRId64 "," 2044294cc35fSKevin Wolf "'rd_operations': %" PRId64 "," 2045294cc35fSKevin Wolf "'wr_operations': %" PRId64 "," 2046e8045d67SChristoph Hellwig "'wr_highest_offset': %" PRId64 "," 2047c488c7f6SChristoph Hellwig "'flush_operations': %" PRId64 "," 2048c488c7f6SChristoph Hellwig "'wr_total_time_ns': %" PRId64 "," 2049c488c7f6SChristoph Hellwig "'rd_total_time_ns': %" PRId64 "," 2050c488c7f6SChristoph Hellwig "'flush_total_time_ns': %" PRId64 2051294cc35fSKevin Wolf "} }", 2052a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_READ], 2053a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_WRITE], 2054a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_READ], 2055a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_WRITE], 20565ffbbc67SBlue Swirl bs->wr_highest_sector * 2057e8045d67SChristoph Hellwig (uint64_t)BDRV_SECTOR_SIZE, 2058c488c7f6SChristoph Hellwig bs->nr_ops[BDRV_ACCT_FLUSH], 2059c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_WRITE], 2060c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_READ], 2061c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_FLUSH]); 2062294cc35fSKevin Wolf dict = qobject_to_qdict(res); 2063294cc35fSKevin Wolf 2064294cc35fSKevin Wolf if (*bs->device_name) { 2065294cc35fSKevin Wolf qdict_put(dict, "device", qstring_from_str(bs->device_name)); 2066294cc35fSKevin Wolf } 2067294cc35fSKevin Wolf 2068294cc35fSKevin Wolf if (bs->file) { 2069294cc35fSKevin Wolf QObject *parent = bdrv_info_stats_bs(bs->file); 2070294cc35fSKevin Wolf qdict_put_obj(dict, "parent", parent); 2071294cc35fSKevin Wolf } 2072294cc35fSKevin Wolf 2073294cc35fSKevin Wolf return res; 2074294cc35fSKevin Wolf } 2075294cc35fSKevin Wolf 2076218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data) 2077218a536aSLuiz Capitulino { 2078218a536aSLuiz Capitulino QObject *obj; 2079218a536aSLuiz Capitulino QList *devices; 2080a36e69ddSths BlockDriverState *bs; 2081a36e69ddSths 2082218a536aSLuiz Capitulino devices = qlist_new(); 2083218a536aSLuiz Capitulino 20841b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 2085294cc35fSKevin Wolf obj = bdrv_info_stats_bs(bs); 2086218a536aSLuiz Capitulino qlist_append_obj(devices, obj); 2087a36e69ddSths } 2088218a536aSLuiz Capitulino 2089218a536aSLuiz Capitulino *ret_data = QOBJECT(devices); 2090a36e69ddSths } 2091ea2384d3Sbellard 2092045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs) 2093045df330Saliguori { 2094045df330Saliguori if (bs->backing_hd && bs->backing_hd->encrypted) 2095045df330Saliguori return bs->backing_file; 2096045df330Saliguori else if (bs->encrypted) 2097045df330Saliguori return bs->filename; 2098045df330Saliguori else 2099045df330Saliguori return NULL; 2100045df330Saliguori } 2101045df330Saliguori 210283f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs, 210383f64091Sbellard char *filename, int filename_size) 210483f64091Sbellard { 2105b783e409SKevin Wolf if (!bs->backing_file) { 210683f64091Sbellard pstrcpy(filename, filename_size, ""); 210783f64091Sbellard } else { 210883f64091Sbellard pstrcpy(filename, filename_size, bs->backing_file); 210983f64091Sbellard } 211083f64091Sbellard } 211183f64091Sbellard 2112faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 2113faea38e7Sbellard const uint8_t *buf, int nb_sectors) 2114faea38e7Sbellard { 2115faea38e7Sbellard BlockDriver *drv = bs->drv; 2116faea38e7Sbellard if (!drv) 211719cb3738Sbellard return -ENOMEDIUM; 2118faea38e7Sbellard if (!drv->bdrv_write_compressed) 2119faea38e7Sbellard return -ENOTSUP; 2120fbb7b4e0SKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) 2121fbb7b4e0SKevin Wolf return -EIO; 21227cd1e32aSlirans@il.ibm.com 2123c6d22830SJan Kiszka if (bs->dirty_bitmap) { 21247cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 21257cd1e32aSlirans@il.ibm.com } 21267cd1e32aSlirans@il.ibm.com 2127faea38e7Sbellard return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 2128faea38e7Sbellard } 2129faea38e7Sbellard 2130faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 2131faea38e7Sbellard { 2132faea38e7Sbellard BlockDriver *drv = bs->drv; 2133faea38e7Sbellard if (!drv) 213419cb3738Sbellard return -ENOMEDIUM; 2135faea38e7Sbellard if (!drv->bdrv_get_info) 2136faea38e7Sbellard return -ENOTSUP; 2137faea38e7Sbellard memset(bdi, 0, sizeof(*bdi)); 2138faea38e7Sbellard return drv->bdrv_get_info(bs, bdi); 2139faea38e7Sbellard } 2140faea38e7Sbellard 214145566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 214245566e9cSChristoph Hellwig int64_t pos, int size) 2143178e08a5Saliguori { 2144178e08a5Saliguori BlockDriver *drv = bs->drv; 2145178e08a5Saliguori if (!drv) 2146178e08a5Saliguori return -ENOMEDIUM; 21477cdb1f6dSMORITA Kazutaka if (drv->bdrv_save_vmstate) 214845566e9cSChristoph Hellwig return drv->bdrv_save_vmstate(bs, buf, pos, size); 21497cdb1f6dSMORITA Kazutaka if (bs->file) 21507cdb1f6dSMORITA Kazutaka return bdrv_save_vmstate(bs->file, buf, pos, size); 21517cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2152178e08a5Saliguori } 2153178e08a5Saliguori 215445566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, 215545566e9cSChristoph Hellwig int64_t pos, int size) 2156178e08a5Saliguori { 2157178e08a5Saliguori BlockDriver *drv = bs->drv; 2158178e08a5Saliguori if (!drv) 2159178e08a5Saliguori return -ENOMEDIUM; 21607cdb1f6dSMORITA Kazutaka if (drv->bdrv_load_vmstate) 216145566e9cSChristoph Hellwig return drv->bdrv_load_vmstate(bs, buf, pos, size); 21627cdb1f6dSMORITA Kazutaka if (bs->file) 21637cdb1f6dSMORITA Kazutaka return bdrv_load_vmstate(bs->file, buf, pos, size); 21647cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2165178e08a5Saliguori } 2166178e08a5Saliguori 21678b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) 21688b9b0cc2SKevin Wolf { 21698b9b0cc2SKevin Wolf BlockDriver *drv = bs->drv; 21708b9b0cc2SKevin Wolf 21718b9b0cc2SKevin Wolf if (!drv || !drv->bdrv_debug_event) { 21728b9b0cc2SKevin Wolf return; 21738b9b0cc2SKevin Wolf } 21748b9b0cc2SKevin Wolf 21758b9b0cc2SKevin Wolf return drv->bdrv_debug_event(bs, event); 21768b9b0cc2SKevin Wolf 21778b9b0cc2SKevin Wolf } 21788b9b0cc2SKevin Wolf 2179faea38e7Sbellard /**************************************************************/ 2180faea38e7Sbellard /* handling of snapshots */ 2181faea38e7Sbellard 2182feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs) 2183feeee5acSMiguel Di Ciurcio Filho { 2184feeee5acSMiguel Di Ciurcio Filho BlockDriver *drv = bs->drv; 218507b70bfbSMarkus Armbruster if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { 2186feeee5acSMiguel Di Ciurcio Filho return 0; 2187feeee5acSMiguel Di Ciurcio Filho } 2188feeee5acSMiguel Di Ciurcio Filho 2189feeee5acSMiguel Di Ciurcio Filho if (!drv->bdrv_snapshot_create) { 2190feeee5acSMiguel Di Ciurcio Filho if (bs->file != NULL) { 2191feeee5acSMiguel Di Ciurcio Filho return bdrv_can_snapshot(bs->file); 2192feeee5acSMiguel Di Ciurcio Filho } 2193feeee5acSMiguel Di Ciurcio Filho return 0; 2194feeee5acSMiguel Di Ciurcio Filho } 2195feeee5acSMiguel Di Ciurcio Filho 2196feeee5acSMiguel Di Ciurcio Filho return 1; 2197feeee5acSMiguel Di Ciurcio Filho } 2198feeee5acSMiguel Di Ciurcio Filho 2199199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs) 2200199630b6SBlue Swirl { 2201199630b6SBlue Swirl return !!(bs->open_flags & BDRV_O_SNAPSHOT); 2202199630b6SBlue Swirl } 2203199630b6SBlue Swirl 2204f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void) 2205f9092b10SMarkus Armbruster { 2206f9092b10SMarkus Armbruster BlockDriverState *bs; 2207f9092b10SMarkus Armbruster 22083ac906f7SMarkus Armbruster if (bs_snapshots) { 2209f9092b10SMarkus Armbruster return bs_snapshots; 22103ac906f7SMarkus Armbruster } 2211f9092b10SMarkus Armbruster 2212f9092b10SMarkus Armbruster bs = NULL; 2213f9092b10SMarkus Armbruster while ((bs = bdrv_next(bs))) { 2214f9092b10SMarkus Armbruster if (bdrv_can_snapshot(bs)) { 22153ac906f7SMarkus Armbruster bs_snapshots = bs; 22163ac906f7SMarkus Armbruster return bs; 2217f9092b10SMarkus Armbruster } 2218f9092b10SMarkus Armbruster } 2219f9092b10SMarkus Armbruster return NULL; 2220f9092b10SMarkus Armbruster } 2221f9092b10SMarkus Armbruster 2222faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs, 2223faea38e7Sbellard QEMUSnapshotInfo *sn_info) 2224faea38e7Sbellard { 2225faea38e7Sbellard BlockDriver *drv = bs->drv; 2226faea38e7Sbellard if (!drv) 222719cb3738Sbellard return -ENOMEDIUM; 22287cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_create) 2229faea38e7Sbellard return drv->bdrv_snapshot_create(bs, sn_info); 22307cdb1f6dSMORITA Kazutaka if (bs->file) 22317cdb1f6dSMORITA Kazutaka return bdrv_snapshot_create(bs->file, sn_info); 22327cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2233faea38e7Sbellard } 2234faea38e7Sbellard 2235faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs, 2236faea38e7Sbellard const char *snapshot_id) 2237faea38e7Sbellard { 2238faea38e7Sbellard BlockDriver *drv = bs->drv; 22397cdb1f6dSMORITA Kazutaka int ret, open_ret; 22407cdb1f6dSMORITA Kazutaka 2241faea38e7Sbellard if (!drv) 224219cb3738Sbellard return -ENOMEDIUM; 22437cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_goto) 2244faea38e7Sbellard return drv->bdrv_snapshot_goto(bs, snapshot_id); 22457cdb1f6dSMORITA Kazutaka 22467cdb1f6dSMORITA Kazutaka if (bs->file) { 22477cdb1f6dSMORITA Kazutaka drv->bdrv_close(bs); 22487cdb1f6dSMORITA Kazutaka ret = bdrv_snapshot_goto(bs->file, snapshot_id); 22497cdb1f6dSMORITA Kazutaka open_ret = drv->bdrv_open(bs, bs->open_flags); 22507cdb1f6dSMORITA Kazutaka if (open_ret < 0) { 22517cdb1f6dSMORITA Kazutaka bdrv_delete(bs->file); 22527cdb1f6dSMORITA Kazutaka bs->drv = NULL; 22537cdb1f6dSMORITA Kazutaka return open_ret; 22547cdb1f6dSMORITA Kazutaka } 22557cdb1f6dSMORITA Kazutaka return ret; 22567cdb1f6dSMORITA Kazutaka } 22577cdb1f6dSMORITA Kazutaka 22587cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2259faea38e7Sbellard } 2260faea38e7Sbellard 2261faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 2262faea38e7Sbellard { 2263faea38e7Sbellard BlockDriver *drv = bs->drv; 2264faea38e7Sbellard if (!drv) 226519cb3738Sbellard return -ENOMEDIUM; 22667cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_delete) 2267faea38e7Sbellard return drv->bdrv_snapshot_delete(bs, snapshot_id); 22687cdb1f6dSMORITA Kazutaka if (bs->file) 22697cdb1f6dSMORITA Kazutaka return bdrv_snapshot_delete(bs->file, snapshot_id); 22707cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2271faea38e7Sbellard } 2272faea38e7Sbellard 2273faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs, 2274faea38e7Sbellard QEMUSnapshotInfo **psn_info) 2275faea38e7Sbellard { 2276faea38e7Sbellard BlockDriver *drv = bs->drv; 2277faea38e7Sbellard if (!drv) 227819cb3738Sbellard return -ENOMEDIUM; 22797cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_list) 2280faea38e7Sbellard return drv->bdrv_snapshot_list(bs, psn_info); 22817cdb1f6dSMORITA Kazutaka if (bs->file) 22827cdb1f6dSMORITA Kazutaka return bdrv_snapshot_list(bs->file, psn_info); 22837cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2284faea38e7Sbellard } 2285faea38e7Sbellard 228651ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs, 228751ef6727Sedison const char *snapshot_name) 228851ef6727Sedison { 228951ef6727Sedison BlockDriver *drv = bs->drv; 229051ef6727Sedison if (!drv) { 229151ef6727Sedison return -ENOMEDIUM; 229251ef6727Sedison } 229351ef6727Sedison if (!bs->read_only) { 229451ef6727Sedison return -EINVAL; 229551ef6727Sedison } 229651ef6727Sedison if (drv->bdrv_snapshot_load_tmp) { 229751ef6727Sedison return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); 229851ef6727Sedison } 229951ef6727Sedison return -ENOTSUP; 230051ef6727Sedison } 230151ef6727Sedison 2302faea38e7Sbellard #define NB_SUFFIXES 4 2303faea38e7Sbellard 2304faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size) 2305faea38e7Sbellard { 2306faea38e7Sbellard static const char suffixes[NB_SUFFIXES] = "KMGT"; 2307faea38e7Sbellard int64_t base; 2308faea38e7Sbellard int i; 2309faea38e7Sbellard 2310faea38e7Sbellard if (size <= 999) { 2311faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64, size); 2312faea38e7Sbellard } else { 2313faea38e7Sbellard base = 1024; 2314faea38e7Sbellard for(i = 0; i < NB_SUFFIXES; i++) { 2315faea38e7Sbellard if (size < (10 * base)) { 2316faea38e7Sbellard snprintf(buf, buf_size, "%0.1f%c", 2317faea38e7Sbellard (double)size / base, 2318faea38e7Sbellard suffixes[i]); 2319faea38e7Sbellard break; 2320faea38e7Sbellard } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 2321faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64 "%c", 2322faea38e7Sbellard ((size + (base >> 1)) / base), 2323faea38e7Sbellard suffixes[i]); 2324faea38e7Sbellard break; 2325faea38e7Sbellard } 2326faea38e7Sbellard base = base * 1024; 2327faea38e7Sbellard } 2328faea38e7Sbellard } 2329faea38e7Sbellard return buf; 2330faea38e7Sbellard } 2331faea38e7Sbellard 2332faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 2333faea38e7Sbellard { 2334faea38e7Sbellard char buf1[128], date_buf[128], clock_buf[128]; 23353b9f94e1Sbellard #ifdef _WIN32 23363b9f94e1Sbellard struct tm *ptm; 23373b9f94e1Sbellard #else 2338faea38e7Sbellard struct tm tm; 23393b9f94e1Sbellard #endif 2340faea38e7Sbellard time_t ti; 2341faea38e7Sbellard int64_t secs; 2342faea38e7Sbellard 2343faea38e7Sbellard if (!sn) { 2344faea38e7Sbellard snprintf(buf, buf_size, 2345faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2346faea38e7Sbellard "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 2347faea38e7Sbellard } else { 2348faea38e7Sbellard ti = sn->date_sec; 23493b9f94e1Sbellard #ifdef _WIN32 23503b9f94e1Sbellard ptm = localtime(&ti); 23513b9f94e1Sbellard strftime(date_buf, sizeof(date_buf), 23523b9f94e1Sbellard "%Y-%m-%d %H:%M:%S", ptm); 23533b9f94e1Sbellard #else 2354faea38e7Sbellard localtime_r(&ti, &tm); 2355faea38e7Sbellard strftime(date_buf, sizeof(date_buf), 2356faea38e7Sbellard "%Y-%m-%d %H:%M:%S", &tm); 23573b9f94e1Sbellard #endif 2358faea38e7Sbellard secs = sn->vm_clock_nsec / 1000000000; 2359faea38e7Sbellard snprintf(clock_buf, sizeof(clock_buf), 2360faea38e7Sbellard "%02d:%02d:%02d.%03d", 2361faea38e7Sbellard (int)(secs / 3600), 2362faea38e7Sbellard (int)((secs / 60) % 60), 2363faea38e7Sbellard (int)(secs % 60), 2364faea38e7Sbellard (int)((sn->vm_clock_nsec / 1000000) % 1000)); 2365faea38e7Sbellard snprintf(buf, buf_size, 2366faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2367faea38e7Sbellard sn->id_str, sn->name, 2368faea38e7Sbellard get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 2369faea38e7Sbellard date_buf, 2370faea38e7Sbellard clock_buf); 2371faea38e7Sbellard } 2372faea38e7Sbellard return buf; 2373faea38e7Sbellard } 2374faea38e7Sbellard 2375ea2384d3Sbellard /**************************************************************/ 237683f64091Sbellard /* async I/Os */ 2377ea2384d3Sbellard 23783b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 2379f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 238083f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 2381ea2384d3Sbellard { 2382bbf0a440SStefan Hajnoczi trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); 2383bbf0a440SStefan Hajnoczi 2384b2a61371SStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 2385b2a61371SStefan Hajnoczi cb, opaque, false, bdrv_co_do_rw); 238683f64091Sbellard } 238783f64091Sbellard 2388f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 2389f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 239083f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 23917674e7bfSbellard { 2392bbf0a440SStefan Hajnoczi trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); 2393bbf0a440SStefan Hajnoczi 2394*1a6e115bSStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 2395*1a6e115bSStefan Hajnoczi cb, opaque, true, bdrv_co_do_rw); 239683f64091Sbellard } 239783f64091Sbellard 239840b4f539SKevin Wolf 239940b4f539SKevin Wolf typedef struct MultiwriteCB { 240040b4f539SKevin Wolf int error; 240140b4f539SKevin Wolf int num_requests; 240240b4f539SKevin Wolf int num_callbacks; 240340b4f539SKevin Wolf struct { 240440b4f539SKevin Wolf BlockDriverCompletionFunc *cb; 240540b4f539SKevin Wolf void *opaque; 240640b4f539SKevin Wolf QEMUIOVector *free_qiov; 240740b4f539SKevin Wolf void *free_buf; 240840b4f539SKevin Wolf } callbacks[]; 240940b4f539SKevin Wolf } MultiwriteCB; 241040b4f539SKevin Wolf 241140b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb) 241240b4f539SKevin Wolf { 241340b4f539SKevin Wolf int i; 241440b4f539SKevin Wolf 241540b4f539SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 241640b4f539SKevin Wolf mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); 24171e1ea48dSStefan Hajnoczi if (mcb->callbacks[i].free_qiov) { 24181e1ea48dSStefan Hajnoczi qemu_iovec_destroy(mcb->callbacks[i].free_qiov); 24191e1ea48dSStefan Hajnoczi } 24207267c094SAnthony Liguori g_free(mcb->callbacks[i].free_qiov); 2421f8a83245SHerve Poussineau qemu_vfree(mcb->callbacks[i].free_buf); 242240b4f539SKevin Wolf } 242340b4f539SKevin Wolf } 242440b4f539SKevin Wolf 242540b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret) 242640b4f539SKevin Wolf { 242740b4f539SKevin Wolf MultiwriteCB *mcb = opaque; 242840b4f539SKevin Wolf 24296d519a5fSStefan Hajnoczi trace_multiwrite_cb(mcb, ret); 24306d519a5fSStefan Hajnoczi 2431cb6d3ca0SKevin Wolf if (ret < 0 && !mcb->error) { 243240b4f539SKevin Wolf mcb->error = ret; 243340b4f539SKevin Wolf } 243440b4f539SKevin Wolf 243540b4f539SKevin Wolf mcb->num_requests--; 243640b4f539SKevin Wolf if (mcb->num_requests == 0) { 243740b4f539SKevin Wolf multiwrite_user_cb(mcb); 24387267c094SAnthony Liguori g_free(mcb); 243940b4f539SKevin Wolf } 244040b4f539SKevin Wolf } 244140b4f539SKevin Wolf 244240b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b) 244340b4f539SKevin Wolf { 244477be4366SChristoph Hellwig const BlockRequest *req1 = a, *req2 = b; 244577be4366SChristoph Hellwig 244677be4366SChristoph Hellwig /* 244777be4366SChristoph Hellwig * Note that we can't simply subtract req2->sector from req1->sector 244877be4366SChristoph Hellwig * here as that could overflow the return value. 244977be4366SChristoph Hellwig */ 245077be4366SChristoph Hellwig if (req1->sector > req2->sector) { 245177be4366SChristoph Hellwig return 1; 245277be4366SChristoph Hellwig } else if (req1->sector < req2->sector) { 245377be4366SChristoph Hellwig return -1; 245477be4366SChristoph Hellwig } else { 245577be4366SChristoph Hellwig return 0; 245677be4366SChristoph Hellwig } 245740b4f539SKevin Wolf } 245840b4f539SKevin Wolf 245940b4f539SKevin Wolf /* 246040b4f539SKevin Wolf * Takes a bunch of requests and tries to merge them. Returns the number of 246140b4f539SKevin Wolf * requests that remain after merging. 246240b4f539SKevin Wolf */ 246340b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, 246440b4f539SKevin Wolf int num_reqs, MultiwriteCB *mcb) 246540b4f539SKevin Wolf { 246640b4f539SKevin Wolf int i, outidx; 246740b4f539SKevin Wolf 246840b4f539SKevin Wolf // Sort requests by start sector 246940b4f539SKevin Wolf qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); 247040b4f539SKevin Wolf 247140b4f539SKevin Wolf // Check if adjacent requests touch the same clusters. If so, combine them, 247240b4f539SKevin Wolf // filling up gaps with zero sectors. 247340b4f539SKevin Wolf outidx = 0; 247440b4f539SKevin Wolf for (i = 1; i < num_reqs; i++) { 247540b4f539SKevin Wolf int merge = 0; 247640b4f539SKevin Wolf int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; 247740b4f539SKevin Wolf 247840b4f539SKevin Wolf // This handles the cases that are valid for all block drivers, namely 247940b4f539SKevin Wolf // exactly sequential writes and overlapping writes. 248040b4f539SKevin Wolf if (reqs[i].sector <= oldreq_last) { 248140b4f539SKevin Wolf merge = 1; 248240b4f539SKevin Wolf } 248340b4f539SKevin Wolf 248440b4f539SKevin Wolf // The block driver may decide that it makes sense to combine requests 248540b4f539SKevin Wolf // even if there is a gap of some sectors between them. In this case, 248640b4f539SKevin Wolf // the gap is filled with zeros (therefore only applicable for yet 248740b4f539SKevin Wolf // unused space in format like qcow2). 248840b4f539SKevin Wolf if (!merge && bs->drv->bdrv_merge_requests) { 248940b4f539SKevin Wolf merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); 249040b4f539SKevin Wolf } 249140b4f539SKevin Wolf 2492e2a305fbSChristoph Hellwig if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { 2493e2a305fbSChristoph Hellwig merge = 0; 2494e2a305fbSChristoph Hellwig } 2495e2a305fbSChristoph Hellwig 249640b4f539SKevin Wolf if (merge) { 249740b4f539SKevin Wolf size_t size; 24987267c094SAnthony Liguori QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); 249940b4f539SKevin Wolf qemu_iovec_init(qiov, 250040b4f539SKevin Wolf reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); 250140b4f539SKevin Wolf 250240b4f539SKevin Wolf // Add the first request to the merged one. If the requests are 250340b4f539SKevin Wolf // overlapping, drop the last sectors of the first request. 250440b4f539SKevin Wolf size = (reqs[i].sector - reqs[outidx].sector) << 9; 250540b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[outidx].qiov, size); 250640b4f539SKevin Wolf 250740b4f539SKevin Wolf // We might need to add some zeros between the two requests 250840b4f539SKevin Wolf if (reqs[i].sector > oldreq_last) { 250940b4f539SKevin Wolf size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9; 251040b4f539SKevin Wolf uint8_t *buf = qemu_blockalign(bs, zero_bytes); 251140b4f539SKevin Wolf memset(buf, 0, zero_bytes); 251240b4f539SKevin Wolf qemu_iovec_add(qiov, buf, zero_bytes); 251340b4f539SKevin Wolf mcb->callbacks[i].free_buf = buf; 251440b4f539SKevin Wolf } 251540b4f539SKevin Wolf 251640b4f539SKevin Wolf // Add the second request 251740b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size); 251840b4f539SKevin Wolf 2519cbf1dff2SKevin Wolf reqs[outidx].nb_sectors = qiov->size >> 9; 252040b4f539SKevin Wolf reqs[outidx].qiov = qiov; 252140b4f539SKevin Wolf 252240b4f539SKevin Wolf mcb->callbacks[i].free_qiov = reqs[outidx].qiov; 252340b4f539SKevin Wolf } else { 252440b4f539SKevin Wolf outidx++; 252540b4f539SKevin Wolf reqs[outidx].sector = reqs[i].sector; 252640b4f539SKevin Wolf reqs[outidx].nb_sectors = reqs[i].nb_sectors; 252740b4f539SKevin Wolf reqs[outidx].qiov = reqs[i].qiov; 252840b4f539SKevin Wolf } 252940b4f539SKevin Wolf } 253040b4f539SKevin Wolf 253140b4f539SKevin Wolf return outidx + 1; 253240b4f539SKevin Wolf } 253340b4f539SKevin Wolf 253440b4f539SKevin Wolf /* 253540b4f539SKevin Wolf * Submit multiple AIO write requests at once. 253640b4f539SKevin Wolf * 253740b4f539SKevin Wolf * On success, the function returns 0 and all requests in the reqs array have 253840b4f539SKevin Wolf * been submitted. In error case this function returns -1, and any of the 253940b4f539SKevin Wolf * requests may or may not be submitted yet. In particular, this means that the 254040b4f539SKevin Wolf * callback will be called for some of the requests, for others it won't. The 254140b4f539SKevin Wolf * caller must check the error field of the BlockRequest to wait for the right 254240b4f539SKevin Wolf * callbacks (if error != 0, no callback will be called). 254340b4f539SKevin Wolf * 254440b4f539SKevin Wolf * The implementation may modify the contents of the reqs array, e.g. to merge 254540b4f539SKevin Wolf * requests. However, the fields opaque and error are left unmodified as they 254640b4f539SKevin Wolf * are used to signal failure for a single request to the caller. 254740b4f539SKevin Wolf */ 254840b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) 254940b4f539SKevin Wolf { 255040b4f539SKevin Wolf BlockDriverAIOCB *acb; 255140b4f539SKevin Wolf MultiwriteCB *mcb; 255240b4f539SKevin Wolf int i; 255340b4f539SKevin Wolf 2554301db7c2SRyan Harper /* don't submit writes if we don't have a medium */ 2555301db7c2SRyan Harper if (bs->drv == NULL) { 2556301db7c2SRyan Harper for (i = 0; i < num_reqs; i++) { 2557301db7c2SRyan Harper reqs[i].error = -ENOMEDIUM; 2558301db7c2SRyan Harper } 2559301db7c2SRyan Harper return -1; 2560301db7c2SRyan Harper } 2561301db7c2SRyan Harper 256240b4f539SKevin Wolf if (num_reqs == 0) { 256340b4f539SKevin Wolf return 0; 256440b4f539SKevin Wolf } 256540b4f539SKevin Wolf 256640b4f539SKevin Wolf // Create MultiwriteCB structure 25677267c094SAnthony Liguori mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); 256840b4f539SKevin Wolf mcb->num_requests = 0; 256940b4f539SKevin Wolf mcb->num_callbacks = num_reqs; 257040b4f539SKevin Wolf 257140b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 257240b4f539SKevin Wolf mcb->callbacks[i].cb = reqs[i].cb; 257340b4f539SKevin Wolf mcb->callbacks[i].opaque = reqs[i].opaque; 257440b4f539SKevin Wolf } 257540b4f539SKevin Wolf 257640b4f539SKevin Wolf // Check for mergable requests 257740b4f539SKevin Wolf num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); 257840b4f539SKevin Wolf 25796d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); 25806d519a5fSStefan Hajnoczi 2581453f9a16SKevin Wolf /* 2582453f9a16SKevin Wolf * Run the aio requests. As soon as one request can't be submitted 2583453f9a16SKevin Wolf * successfully, fail all requests that are not yet submitted (we must 2584453f9a16SKevin Wolf * return failure for all requests anyway) 2585453f9a16SKevin Wolf * 2586453f9a16SKevin Wolf * num_requests cannot be set to the right value immediately: If 2587453f9a16SKevin Wolf * bdrv_aio_writev fails for some request, num_requests would be too high 2588453f9a16SKevin Wolf * and therefore multiwrite_cb() would never recognize the multiwrite 2589453f9a16SKevin Wolf * request as completed. We also cannot use the loop variable i to set it 2590453f9a16SKevin Wolf * when the first request fails because the callback may already have been 2591453f9a16SKevin Wolf * called for previously submitted requests. Thus, num_requests must be 2592453f9a16SKevin Wolf * incremented for each request that is submitted. 2593453f9a16SKevin Wolf * 2594453f9a16SKevin Wolf * The problem that callbacks may be called early also means that we need 2595453f9a16SKevin Wolf * to take care that num_requests doesn't become 0 before all requests are 2596453f9a16SKevin Wolf * submitted - multiwrite_cb() would consider the multiwrite request 2597453f9a16SKevin Wolf * completed. A dummy request that is "completed" by a manual call to 2598453f9a16SKevin Wolf * multiwrite_cb() takes care of this. 2599453f9a16SKevin Wolf */ 2600453f9a16SKevin Wolf mcb->num_requests = 1; 2601453f9a16SKevin Wolf 26026d519a5fSStefan Hajnoczi // Run the aio requests 260340b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 2604453f9a16SKevin Wolf mcb->num_requests++; 260540b4f539SKevin Wolf acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, 260640b4f539SKevin Wolf reqs[i].nb_sectors, multiwrite_cb, mcb); 260740b4f539SKevin Wolf 260840b4f539SKevin Wolf if (acb == NULL) { 260940b4f539SKevin Wolf // We can only fail the whole thing if no request has been 261040b4f539SKevin Wolf // submitted yet. Otherwise we'll wait for the submitted AIOs to 261140b4f539SKevin Wolf // complete and report the error in the callback. 2612453f9a16SKevin Wolf if (i == 0) { 26136d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_earlyfail(mcb); 261440b4f539SKevin Wolf goto fail; 261540b4f539SKevin Wolf } else { 26166d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_latefail(mcb, i); 26177eb58a6cSKevin Wolf multiwrite_cb(mcb, -EIO); 261840b4f539SKevin Wolf break; 261940b4f539SKevin Wolf } 262040b4f539SKevin Wolf } 262140b4f539SKevin Wolf } 262240b4f539SKevin Wolf 2623453f9a16SKevin Wolf /* Complete the dummy request */ 2624453f9a16SKevin Wolf multiwrite_cb(mcb, 0); 2625453f9a16SKevin Wolf 262640b4f539SKevin Wolf return 0; 262740b4f539SKevin Wolf 262840b4f539SKevin Wolf fail: 2629453f9a16SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 2630453f9a16SKevin Wolf reqs[i].error = -EIO; 2631453f9a16SKevin Wolf } 26327267c094SAnthony Liguori g_free(mcb); 263340b4f539SKevin Wolf return -1; 263440b4f539SKevin Wolf } 263540b4f539SKevin Wolf 2636b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 2637b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2638b2e12bc6SChristoph Hellwig { 2639b2e12bc6SChristoph Hellwig BlockDriver *drv = bs->drv; 2640b2e12bc6SChristoph Hellwig 2641a13aac04SStefan Hajnoczi trace_bdrv_aio_flush(bs, opaque); 2642a13aac04SStefan Hajnoczi 2643016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 2644016f5cf6SAlexander Graf return bdrv_aio_noop_em(bs, cb, opaque); 2645016f5cf6SAlexander Graf } 2646016f5cf6SAlexander Graf 2647b2e12bc6SChristoph Hellwig if (!drv) 2648b2e12bc6SChristoph Hellwig return NULL; 2649b2e12bc6SChristoph Hellwig return drv->bdrv_aio_flush(bs, cb, opaque); 2650b2e12bc6SChristoph Hellwig } 2651b2e12bc6SChristoph Hellwig 265283f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb) 265383f64091Sbellard { 26546bbff9a0Saliguori acb->pool->cancel(acb); 265583f64091Sbellard } 265683f64091Sbellard 265783f64091Sbellard 265883f64091Sbellard /**************************************************************/ 265983f64091Sbellard /* async block device emulation */ 266083f64091Sbellard 2661c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync { 2662c16b5a2cSChristoph Hellwig BlockDriverAIOCB common; 2663c16b5a2cSChristoph Hellwig QEMUBH *bh; 2664c16b5a2cSChristoph Hellwig int ret; 2665c16b5a2cSChristoph Hellwig /* vector translation state */ 2666c16b5a2cSChristoph Hellwig QEMUIOVector *qiov; 2667c16b5a2cSChristoph Hellwig uint8_t *bounce; 2668c16b5a2cSChristoph Hellwig int is_write; 2669c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync; 2670c16b5a2cSChristoph Hellwig 2671c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 2672c16b5a2cSChristoph Hellwig { 2673b666d239SKevin Wolf BlockDriverAIOCBSync *acb = 2674b666d239SKevin Wolf container_of(blockacb, BlockDriverAIOCBSync, common); 26756a7ad299SDor Laor qemu_bh_delete(acb->bh); 267636afc451SAvi Kivity acb->bh = NULL; 2677c16b5a2cSChristoph Hellwig qemu_aio_release(acb); 2678c16b5a2cSChristoph Hellwig } 2679c16b5a2cSChristoph Hellwig 2680c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = { 2681c16b5a2cSChristoph Hellwig .aiocb_size = sizeof(BlockDriverAIOCBSync), 2682c16b5a2cSChristoph Hellwig .cancel = bdrv_aio_cancel_em, 2683c16b5a2cSChristoph Hellwig }; 2684c16b5a2cSChristoph Hellwig 268583f64091Sbellard static void bdrv_aio_bh_cb(void *opaque) 2686beac80cdSbellard { 2687ce1a14dcSpbrook BlockDriverAIOCBSync *acb = opaque; 2688f141eafeSaliguori 2689f141eafeSaliguori if (!acb->is_write) 2690f141eafeSaliguori qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 2691ceb42de8Saliguori qemu_vfree(acb->bounce); 2692ce1a14dcSpbrook acb->common.cb(acb->common.opaque, acb->ret); 26936a7ad299SDor Laor qemu_bh_delete(acb->bh); 269436afc451SAvi Kivity acb->bh = NULL; 2695ce1a14dcSpbrook qemu_aio_release(acb); 2696beac80cdSbellard } 2697beac80cdSbellard 2698f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 2699f141eafeSaliguori int64_t sector_num, 2700f141eafeSaliguori QEMUIOVector *qiov, 2701f141eafeSaliguori int nb_sectors, 2702f141eafeSaliguori BlockDriverCompletionFunc *cb, 2703f141eafeSaliguori void *opaque, 2704f141eafeSaliguori int is_write) 2705f141eafeSaliguori 2706ea2384d3Sbellard { 2707ce1a14dcSpbrook BlockDriverAIOCBSync *acb; 270883f64091Sbellard 2709c16b5a2cSChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2710f141eafeSaliguori acb->is_write = is_write; 2711f141eafeSaliguori acb->qiov = qiov; 2712e268ca52Saliguori acb->bounce = qemu_blockalign(bs, qiov->size); 2713f141eafeSaliguori 2714ce1a14dcSpbrook if (!acb->bh) 2715ce1a14dcSpbrook acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2716f141eafeSaliguori 2717f141eafeSaliguori if (is_write) { 2718f141eafeSaliguori qemu_iovec_to_buffer(acb->qiov, acb->bounce); 27191ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 2720f141eafeSaliguori } else { 27211ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 2722f141eafeSaliguori } 2723f141eafeSaliguori 2724ce1a14dcSpbrook qemu_bh_schedule(acb->bh); 2725f141eafeSaliguori 2726ce1a14dcSpbrook return &acb->common; 27277a6cba61Spbrook } 27287a6cba61Spbrook 2729f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 2730f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2731ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque) 273283f64091Sbellard { 2733f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 273483f64091Sbellard } 273583f64091Sbellard 2736f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 2737f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2738f141eafeSaliguori BlockDriverCompletionFunc *cb, void *opaque) 2739f141eafeSaliguori { 2740f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 2741f141eafeSaliguori } 2742f141eafeSaliguori 274368485420SKevin Wolf 274468485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine { 274568485420SKevin Wolf BlockDriverAIOCB common; 274668485420SKevin Wolf BlockRequest req; 274768485420SKevin Wolf bool is_write; 274868485420SKevin Wolf QEMUBH* bh; 274968485420SKevin Wolf } BlockDriverAIOCBCoroutine; 275068485420SKevin Wolf 275168485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) 275268485420SKevin Wolf { 275368485420SKevin Wolf qemu_aio_flush(); 275468485420SKevin Wolf } 275568485420SKevin Wolf 275668485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = { 275768485420SKevin Wolf .aiocb_size = sizeof(BlockDriverAIOCBCoroutine), 275868485420SKevin Wolf .cancel = bdrv_aio_co_cancel_em, 275968485420SKevin Wolf }; 276068485420SKevin Wolf 276168485420SKevin Wolf static void bdrv_co_rw_bh(void *opaque) 276268485420SKevin Wolf { 276368485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 276468485420SKevin Wolf 276568485420SKevin Wolf acb->common.cb(acb->common.opaque, acb->req.error); 276668485420SKevin Wolf qemu_bh_delete(acb->bh); 276768485420SKevin Wolf qemu_aio_release(acb); 276868485420SKevin Wolf } 276968485420SKevin Wolf 2770b2a61371SStefan Hajnoczi /* Invoke .bdrv_co_readv/.bdrv_co_writev */ 277168485420SKevin Wolf static void coroutine_fn bdrv_co_rw(void *opaque) 277268485420SKevin Wolf { 277368485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 277468485420SKevin Wolf BlockDriverState *bs = acb->common.bs; 277568485420SKevin Wolf 277668485420SKevin Wolf if (!acb->is_write) { 277768485420SKevin Wolf acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector, 277868485420SKevin Wolf acb->req.nb_sectors, acb->req.qiov); 277968485420SKevin Wolf } else { 278068485420SKevin Wolf acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector, 278168485420SKevin Wolf acb->req.nb_sectors, acb->req.qiov); 278268485420SKevin Wolf } 278368485420SKevin Wolf 278468485420SKevin Wolf acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb); 278568485420SKevin Wolf qemu_bh_schedule(acb->bh); 278668485420SKevin Wolf } 278768485420SKevin Wolf 2788b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */ 2789b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque) 2790b2a61371SStefan Hajnoczi { 2791b2a61371SStefan Hajnoczi BlockDriverAIOCBCoroutine *acb = opaque; 2792b2a61371SStefan Hajnoczi BlockDriverState *bs = acb->common.bs; 2793b2a61371SStefan Hajnoczi 2794b2a61371SStefan Hajnoczi if (!acb->is_write) { 2795b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, 2796b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2797b2a61371SStefan Hajnoczi } else { 2798b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_writev(bs, acb->req.sector, 2799b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2800b2a61371SStefan Hajnoczi } 2801b2a61371SStefan Hajnoczi 2802b2a61371SStefan Hajnoczi acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb); 2803b2a61371SStefan Hajnoczi qemu_bh_schedule(acb->bh); 2804b2a61371SStefan Hajnoczi } 2805b2a61371SStefan Hajnoczi 280668485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 280768485420SKevin Wolf int64_t sector_num, 280868485420SKevin Wolf QEMUIOVector *qiov, 280968485420SKevin Wolf int nb_sectors, 281068485420SKevin Wolf BlockDriverCompletionFunc *cb, 281168485420SKevin Wolf void *opaque, 2812b2a61371SStefan Hajnoczi bool is_write, 2813b2a61371SStefan Hajnoczi CoroutineEntry *entry) 281468485420SKevin Wolf { 281568485420SKevin Wolf Coroutine *co; 281668485420SKevin Wolf BlockDriverAIOCBCoroutine *acb; 281768485420SKevin Wolf 281868485420SKevin Wolf acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); 281968485420SKevin Wolf acb->req.sector = sector_num; 282068485420SKevin Wolf acb->req.nb_sectors = nb_sectors; 282168485420SKevin Wolf acb->req.qiov = qiov; 282268485420SKevin Wolf acb->is_write = is_write; 282368485420SKevin Wolf 2824b2a61371SStefan Hajnoczi co = qemu_coroutine_create(entry); 282568485420SKevin Wolf qemu_coroutine_enter(co, acb); 282668485420SKevin Wolf 282768485420SKevin Wolf return &acb->common; 282868485420SKevin Wolf } 282968485420SKevin Wolf 283068485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs, 283168485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 283268485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque) 283368485420SKevin Wolf { 283468485420SKevin Wolf return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 2835b2a61371SStefan Hajnoczi false, bdrv_co_rw); 283668485420SKevin Wolf } 283768485420SKevin Wolf 283868485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs, 283968485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 284068485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque) 284168485420SKevin Wolf { 284268485420SKevin Wolf return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 2843b2a61371SStefan Hajnoczi true, bdrv_co_rw); 284468485420SKevin Wolf } 284568485420SKevin Wolf 2846b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 2847b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2848b2e12bc6SChristoph Hellwig { 2849b2e12bc6SChristoph Hellwig BlockDriverAIOCBSync *acb; 2850b2e12bc6SChristoph Hellwig 2851b2e12bc6SChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2852b2e12bc6SChristoph Hellwig acb->is_write = 1; /* don't bounce in the completion hadler */ 2853b2e12bc6SChristoph Hellwig acb->qiov = NULL; 2854b2e12bc6SChristoph Hellwig acb->bounce = NULL; 2855b2e12bc6SChristoph Hellwig acb->ret = 0; 2856b2e12bc6SChristoph Hellwig 2857b2e12bc6SChristoph Hellwig if (!acb->bh) 2858b2e12bc6SChristoph Hellwig acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2859b2e12bc6SChristoph Hellwig 2860b2e12bc6SChristoph Hellwig bdrv_flush(bs); 2861b2e12bc6SChristoph Hellwig qemu_bh_schedule(acb->bh); 2862b2e12bc6SChristoph Hellwig return &acb->common; 2863b2e12bc6SChristoph Hellwig } 2864b2e12bc6SChristoph Hellwig 2865016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, 2866016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque) 2867016f5cf6SAlexander Graf { 2868016f5cf6SAlexander Graf BlockDriverAIOCBSync *acb; 2869016f5cf6SAlexander Graf 2870016f5cf6SAlexander Graf acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2871016f5cf6SAlexander Graf acb->is_write = 1; /* don't bounce in the completion handler */ 2872016f5cf6SAlexander Graf acb->qiov = NULL; 2873016f5cf6SAlexander Graf acb->bounce = NULL; 2874016f5cf6SAlexander Graf acb->ret = 0; 2875016f5cf6SAlexander Graf 2876016f5cf6SAlexander Graf if (!acb->bh) { 2877016f5cf6SAlexander Graf acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2878016f5cf6SAlexander Graf } 2879016f5cf6SAlexander Graf 2880016f5cf6SAlexander Graf qemu_bh_schedule(acb->bh); 2881016f5cf6SAlexander Graf return &acb->common; 2882016f5cf6SAlexander Graf } 2883016f5cf6SAlexander Graf 288483f64091Sbellard /**************************************************************/ 288583f64091Sbellard /* sync block device emulation */ 288683f64091Sbellard 288783f64091Sbellard static void bdrv_rw_em_cb(void *opaque, int ret) 288883f64091Sbellard { 288983f64091Sbellard *(int *)opaque = ret; 289083f64091Sbellard } 289183f64091Sbellard 289283f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 289383f64091Sbellard uint8_t *buf, int nb_sectors) 289483f64091Sbellard { 2895ce1a14dcSpbrook int async_ret; 2896ce1a14dcSpbrook BlockDriverAIOCB *acb; 2897f141eafeSaliguori struct iovec iov; 2898f141eafeSaliguori QEMUIOVector qiov; 289983f64091Sbellard 290083f64091Sbellard async_ret = NOT_DONE; 29013f4cb3d3Sblueswir1 iov.iov_base = (void *)buf; 2902eb5a3165SJes Sorensen iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; 2903f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 29041ed20acfSStefan Hajnoczi 29051ed20acfSStefan Hajnoczi acb = bs->drv->bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors, 290683f64091Sbellard bdrv_rw_em_cb, &async_ret); 290765d6b3d8SKevin Wolf if (acb == NULL) { 290865d6b3d8SKevin Wolf async_ret = -1; 290965d6b3d8SKevin Wolf goto fail; 291065d6b3d8SKevin Wolf } 2911baf35cb9Saliguori 291283f64091Sbellard while (async_ret == NOT_DONE) { 291383f64091Sbellard qemu_aio_wait(); 291483f64091Sbellard } 2915baf35cb9Saliguori 291665d6b3d8SKevin Wolf 291765d6b3d8SKevin Wolf fail: 291883f64091Sbellard return async_ret; 291983f64091Sbellard } 292083f64091Sbellard 292183f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 292283f64091Sbellard const uint8_t *buf, int nb_sectors) 292383f64091Sbellard { 2924ce1a14dcSpbrook int async_ret; 2925ce1a14dcSpbrook BlockDriverAIOCB *acb; 2926f141eafeSaliguori struct iovec iov; 2927f141eafeSaliguori QEMUIOVector qiov; 292883f64091Sbellard 292983f64091Sbellard async_ret = NOT_DONE; 2930f141eafeSaliguori iov.iov_base = (void *)buf; 2931eb5a3165SJes Sorensen iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; 2932f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 29331ed20acfSStefan Hajnoczi 29341ed20acfSStefan Hajnoczi acb = bs->drv->bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors, 293583f64091Sbellard bdrv_rw_em_cb, &async_ret); 293665d6b3d8SKevin Wolf if (acb == NULL) { 293765d6b3d8SKevin Wolf async_ret = -1; 293865d6b3d8SKevin Wolf goto fail; 293965d6b3d8SKevin Wolf } 294083f64091Sbellard while (async_ret == NOT_DONE) { 294183f64091Sbellard qemu_aio_wait(); 294283f64091Sbellard } 294365d6b3d8SKevin Wolf 294465d6b3d8SKevin Wolf fail: 294583f64091Sbellard return async_ret; 294683f64091Sbellard } 2947ea2384d3Sbellard 2948ea2384d3Sbellard void bdrv_init(void) 2949ea2384d3Sbellard { 29505efa9d5aSAnthony Liguori module_call_init(MODULE_INIT_BLOCK); 2951ea2384d3Sbellard } 2952ce1a14dcSpbrook 2953eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void) 2954eb852011SMarkus Armbruster { 2955eb852011SMarkus Armbruster use_bdrv_whitelist = 1; 2956eb852011SMarkus Armbruster bdrv_init(); 2957eb852011SMarkus Armbruster } 2958eb852011SMarkus Armbruster 2959c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 29606bbff9a0Saliguori BlockDriverCompletionFunc *cb, void *opaque) 29616bbff9a0Saliguori { 2962ce1a14dcSpbrook BlockDriverAIOCB *acb; 2963ce1a14dcSpbrook 29646bbff9a0Saliguori if (pool->free_aiocb) { 29656bbff9a0Saliguori acb = pool->free_aiocb; 29666bbff9a0Saliguori pool->free_aiocb = acb->next; 2967ce1a14dcSpbrook } else { 29687267c094SAnthony Liguori acb = g_malloc0(pool->aiocb_size); 29696bbff9a0Saliguori acb->pool = pool; 2970ce1a14dcSpbrook } 2971ce1a14dcSpbrook acb->bs = bs; 2972ce1a14dcSpbrook acb->cb = cb; 2973ce1a14dcSpbrook acb->opaque = opaque; 2974ce1a14dcSpbrook return acb; 2975ce1a14dcSpbrook } 2976ce1a14dcSpbrook 2977ce1a14dcSpbrook void qemu_aio_release(void *p) 2978ce1a14dcSpbrook { 29796bbff9a0Saliguori BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 29806bbff9a0Saliguori AIOPool *pool = acb->pool; 29816bbff9a0Saliguori acb->next = pool->free_aiocb; 29826bbff9a0Saliguori pool->free_aiocb = acb; 2983ce1a14dcSpbrook } 298419cb3738Sbellard 298519cb3738Sbellard /**************************************************************/ 2986f9f05dc5SKevin Wolf /* Coroutine block device emulation */ 2987f9f05dc5SKevin Wolf 2988f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion { 2989f9f05dc5SKevin Wolf Coroutine *coroutine; 2990f9f05dc5SKevin Wolf int ret; 2991f9f05dc5SKevin Wolf } CoroutineIOCompletion; 2992f9f05dc5SKevin Wolf 2993f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret) 2994f9f05dc5SKevin Wolf { 2995f9f05dc5SKevin Wolf CoroutineIOCompletion *co = opaque; 2996f9f05dc5SKevin Wolf 2997f9f05dc5SKevin Wolf co->ret = ret; 2998f9f05dc5SKevin Wolf qemu_coroutine_enter(co->coroutine, NULL); 2999f9f05dc5SKevin Wolf } 3000f9f05dc5SKevin Wolf 3001f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, 3002f9f05dc5SKevin Wolf int nb_sectors, QEMUIOVector *iov, 3003f9f05dc5SKevin Wolf bool is_write) 3004f9f05dc5SKevin Wolf { 3005f9f05dc5SKevin Wolf CoroutineIOCompletion co = { 3006f9f05dc5SKevin Wolf .coroutine = qemu_coroutine_self(), 3007f9f05dc5SKevin Wolf }; 3008f9f05dc5SKevin Wolf BlockDriverAIOCB *acb; 3009f9f05dc5SKevin Wolf 3010f9f05dc5SKevin Wolf if (is_write) { 3011a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, 3012f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 3013f9f05dc5SKevin Wolf } else { 3014a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, 3015f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 3016f9f05dc5SKevin Wolf } 3017f9f05dc5SKevin Wolf 301859370aaaSStefan Hajnoczi trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); 3019f9f05dc5SKevin Wolf if (!acb) { 3020f9f05dc5SKevin Wolf return -EIO; 3021f9f05dc5SKevin Wolf } 3022f9f05dc5SKevin Wolf qemu_coroutine_yield(); 3023f9f05dc5SKevin Wolf 3024f9f05dc5SKevin Wolf return co.ret; 3025f9f05dc5SKevin Wolf } 3026f9f05dc5SKevin Wolf 3027f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 3028f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 3029f9f05dc5SKevin Wolf QEMUIOVector *iov) 3030f9f05dc5SKevin Wolf { 3031f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); 3032f9f05dc5SKevin Wolf } 3033f9f05dc5SKevin Wolf 3034f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 3035f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 3036f9f05dc5SKevin Wolf QEMUIOVector *iov) 3037f9f05dc5SKevin Wolf { 3038f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); 3039f9f05dc5SKevin Wolf } 3040f9f05dc5SKevin Wolf 3041e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs) 3042e7a8a783SKevin Wolf { 3043e7a8a783SKevin Wolf CoroutineIOCompletion co = { 3044e7a8a783SKevin Wolf .coroutine = qemu_coroutine_self(), 3045e7a8a783SKevin Wolf }; 3046e7a8a783SKevin Wolf BlockDriverAIOCB *acb; 3047e7a8a783SKevin Wolf 3048e7a8a783SKevin Wolf acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); 3049e7a8a783SKevin Wolf if (!acb) { 3050e7a8a783SKevin Wolf return -EIO; 3051e7a8a783SKevin Wolf } 3052e7a8a783SKevin Wolf qemu_coroutine_yield(); 3053e7a8a783SKevin Wolf return co.ret; 3054e7a8a783SKevin Wolf } 3055e7a8a783SKevin Wolf 3056f9f05dc5SKevin Wolf /**************************************************************/ 305719cb3738Sbellard /* removable device support */ 305819cb3738Sbellard 305919cb3738Sbellard /** 306019cb3738Sbellard * Return TRUE if the media is present 306119cb3738Sbellard */ 306219cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs) 306319cb3738Sbellard { 306419cb3738Sbellard BlockDriver *drv = bs->drv; 3065a1aff5bfSMarkus Armbruster 306619cb3738Sbellard if (!drv) 306719cb3738Sbellard return 0; 306819cb3738Sbellard if (!drv->bdrv_is_inserted) 3069a1aff5bfSMarkus Armbruster return 1; 3070a1aff5bfSMarkus Armbruster return drv->bdrv_is_inserted(bs); 307119cb3738Sbellard } 307219cb3738Sbellard 307319cb3738Sbellard /** 30748e49ca46SMarkus Armbruster * Return whether the media changed since the last call to this 30758e49ca46SMarkus Armbruster * function, or -ENOTSUP if we don't know. Most drivers don't know. 307619cb3738Sbellard */ 307719cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs) 307819cb3738Sbellard { 307919cb3738Sbellard BlockDriver *drv = bs->drv; 308019cb3738Sbellard 30818e49ca46SMarkus Armbruster if (drv && drv->bdrv_media_changed) { 30828e49ca46SMarkus Armbruster return drv->bdrv_media_changed(bs); 30838e49ca46SMarkus Armbruster } 30848e49ca46SMarkus Armbruster return -ENOTSUP; 308519cb3738Sbellard } 308619cb3738Sbellard 308719cb3738Sbellard /** 308819cb3738Sbellard * If eject_flag is TRUE, eject the media. Otherwise, close the tray 308919cb3738Sbellard */ 3090fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag) 309119cb3738Sbellard { 309219cb3738Sbellard BlockDriver *drv = bs->drv; 309319cb3738Sbellard 3094822e1cd1SMarkus Armbruster if (drv && drv->bdrv_eject) { 3095822e1cd1SMarkus Armbruster drv->bdrv_eject(bs, eject_flag); 309619cb3738Sbellard } 309719cb3738Sbellard } 309819cb3738Sbellard 309919cb3738Sbellard /** 310019cb3738Sbellard * Lock or unlock the media (if it is locked, the user won't be able 310119cb3738Sbellard * to eject it manually). 310219cb3738Sbellard */ 3103025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked) 310419cb3738Sbellard { 310519cb3738Sbellard BlockDriver *drv = bs->drv; 310619cb3738Sbellard 3107025e849aSMarkus Armbruster trace_bdrv_lock_medium(bs, locked); 3108b8c6d095SStefan Hajnoczi 3109025e849aSMarkus Armbruster if (drv && drv->bdrv_lock_medium) { 3110025e849aSMarkus Armbruster drv->bdrv_lock_medium(bs, locked); 311119cb3738Sbellard } 311219cb3738Sbellard } 3113985a03b0Sths 3114985a03b0Sths /* needed for generic scsi interface */ 3115985a03b0Sths 3116985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 3117985a03b0Sths { 3118985a03b0Sths BlockDriver *drv = bs->drv; 3119985a03b0Sths 3120985a03b0Sths if (drv && drv->bdrv_ioctl) 3121985a03b0Sths return drv->bdrv_ioctl(bs, req, buf); 3122985a03b0Sths return -ENOTSUP; 3123985a03b0Sths } 31247d780669Saliguori 3125221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 3126221f715dSaliguori unsigned long int req, void *buf, 31277d780669Saliguori BlockDriverCompletionFunc *cb, void *opaque) 31287d780669Saliguori { 3129221f715dSaliguori BlockDriver *drv = bs->drv; 31307d780669Saliguori 3131221f715dSaliguori if (drv && drv->bdrv_aio_ioctl) 3132221f715dSaliguori return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 3133221f715dSaliguori return NULL; 31347d780669Saliguori } 3135e268ca52Saliguori 31367b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) 31377b6f9300SMarkus Armbruster { 31387b6f9300SMarkus Armbruster bs->buffer_alignment = align; 31397b6f9300SMarkus Armbruster } 31407cd1e32aSlirans@il.ibm.com 3141e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size) 3142e268ca52Saliguori { 3143e268ca52Saliguori return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 3144e268ca52Saliguori } 31457cd1e32aSlirans@il.ibm.com 31467cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) 31477cd1e32aSlirans@il.ibm.com { 31487cd1e32aSlirans@il.ibm.com int64_t bitmap_size; 3149a55eb92cSJan Kiszka 3150aaa0eb75SLiran Schour bs->dirty_count = 0; 31517cd1e32aSlirans@il.ibm.com if (enable) { 3152c6d22830SJan Kiszka if (!bs->dirty_bitmap) { 3153c6d22830SJan Kiszka bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + 3154c6d22830SJan Kiszka BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; 3155c6d22830SJan Kiszka bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; 31567cd1e32aSlirans@il.ibm.com 31577267c094SAnthony Liguori bs->dirty_bitmap = g_malloc0(bitmap_size); 31587cd1e32aSlirans@il.ibm.com } 31597cd1e32aSlirans@il.ibm.com } else { 3160c6d22830SJan Kiszka if (bs->dirty_bitmap) { 31617267c094SAnthony Liguori g_free(bs->dirty_bitmap); 3162c6d22830SJan Kiszka bs->dirty_bitmap = NULL; 31637cd1e32aSlirans@il.ibm.com } 31647cd1e32aSlirans@il.ibm.com } 31657cd1e32aSlirans@il.ibm.com } 31667cd1e32aSlirans@il.ibm.com 31677cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) 31687cd1e32aSlirans@il.ibm.com { 31696ea44308SJan Kiszka int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; 31707cd1e32aSlirans@il.ibm.com 3171c6d22830SJan Kiszka if (bs->dirty_bitmap && 3172c6d22830SJan Kiszka (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { 31736d59fec1SMarcelo Tosatti return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & 31746d59fec1SMarcelo Tosatti (1UL << (chunk % (sizeof(unsigned long) * 8)))); 31757cd1e32aSlirans@il.ibm.com } else { 31767cd1e32aSlirans@il.ibm.com return 0; 31777cd1e32aSlirans@il.ibm.com } 31787cd1e32aSlirans@il.ibm.com } 31797cd1e32aSlirans@il.ibm.com 31807cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, 31817cd1e32aSlirans@il.ibm.com int nr_sectors) 31827cd1e32aSlirans@il.ibm.com { 31837cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); 31847cd1e32aSlirans@il.ibm.com } 3185aaa0eb75SLiran Schour 3186aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs) 3187aaa0eb75SLiran Schour { 3188aaa0eb75SLiran Schour return bs->dirty_count; 3189aaa0eb75SLiran Schour } 3190f88e1a42SJes Sorensen 3191db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use) 3192db593f25SMarcelo Tosatti { 3193db593f25SMarcelo Tosatti assert(bs->in_use != in_use); 3194db593f25SMarcelo Tosatti bs->in_use = in_use; 3195db593f25SMarcelo Tosatti } 3196db593f25SMarcelo Tosatti 3197db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs) 3198db593f25SMarcelo Tosatti { 3199db593f25SMarcelo Tosatti return bs->in_use; 3200db593f25SMarcelo Tosatti } 3201db593f25SMarcelo Tosatti 320228a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs) 320328a7282aSLuiz Capitulino { 320428a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 320528a7282aSLuiz Capitulino } 320628a7282aSLuiz Capitulino 320728a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly 320828a7282aSLuiz Capitulino * enables it _and_ the VM is configured to stop on errors */ 320928a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) 321028a7282aSLuiz Capitulino { 321128a7282aSLuiz Capitulino return (bs->iostatus != BDRV_IOS_INVAL && 321228a7282aSLuiz Capitulino (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || 321328a7282aSLuiz Capitulino bs->on_write_error == BLOCK_ERR_STOP_ANY || 321428a7282aSLuiz Capitulino bs->on_read_error == BLOCK_ERR_STOP_ANY)); 321528a7282aSLuiz Capitulino } 321628a7282aSLuiz Capitulino 321728a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs) 321828a7282aSLuiz Capitulino { 321928a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_INVAL; 322028a7282aSLuiz Capitulino } 322128a7282aSLuiz Capitulino 322228a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs) 322328a7282aSLuiz Capitulino { 322428a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 322528a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 322628a7282aSLuiz Capitulino } 322728a7282aSLuiz Capitulino } 322828a7282aSLuiz Capitulino 322928a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation 323028a7282aSLuiz Capitulino quite simple. However, the block layer knows about the error, so it's 323128a7282aSLuiz Capitulino possible to implement this without device models being involved */ 323228a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error) 323328a7282aSLuiz Capitulino { 323428a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { 323528a7282aSLuiz Capitulino assert(error >= 0); 323628a7282aSLuiz Capitulino bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; 323728a7282aSLuiz Capitulino } 323828a7282aSLuiz Capitulino } 323928a7282aSLuiz Capitulino 3240a597e79cSChristoph Hellwig void 3241a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, 3242a597e79cSChristoph Hellwig enum BlockAcctType type) 3243a597e79cSChristoph Hellwig { 3244a597e79cSChristoph Hellwig assert(type < BDRV_MAX_IOTYPE); 3245a597e79cSChristoph Hellwig 3246a597e79cSChristoph Hellwig cookie->bytes = bytes; 3247c488c7f6SChristoph Hellwig cookie->start_time_ns = get_clock(); 3248a597e79cSChristoph Hellwig cookie->type = type; 3249a597e79cSChristoph Hellwig } 3250a597e79cSChristoph Hellwig 3251a597e79cSChristoph Hellwig void 3252a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) 3253a597e79cSChristoph Hellwig { 3254a597e79cSChristoph Hellwig assert(cookie->type < BDRV_MAX_IOTYPE); 3255a597e79cSChristoph Hellwig 3256a597e79cSChristoph Hellwig bs->nr_bytes[cookie->type] += cookie->bytes; 3257a597e79cSChristoph Hellwig bs->nr_ops[cookie->type]++; 3258c488c7f6SChristoph Hellwig bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; 3259a597e79cSChristoph Hellwig } 3260a597e79cSChristoph Hellwig 3261f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt, 3262f88e1a42SJes Sorensen const char *base_filename, const char *base_fmt, 3263f88e1a42SJes Sorensen char *options, uint64_t img_size, int flags) 3264f88e1a42SJes Sorensen { 3265f88e1a42SJes Sorensen QEMUOptionParameter *param = NULL, *create_options = NULL; 3266d220894eSKevin Wolf QEMUOptionParameter *backing_fmt, *backing_file, *size; 3267f88e1a42SJes Sorensen BlockDriverState *bs = NULL; 3268f88e1a42SJes Sorensen BlockDriver *drv, *proto_drv; 326996df67d1SStefan Hajnoczi BlockDriver *backing_drv = NULL; 3270f88e1a42SJes Sorensen int ret = 0; 3271f88e1a42SJes Sorensen 3272f88e1a42SJes Sorensen /* Find driver and parse its options */ 3273f88e1a42SJes Sorensen drv = bdrv_find_format(fmt); 3274f88e1a42SJes Sorensen if (!drv) { 3275f88e1a42SJes Sorensen error_report("Unknown file format '%s'", fmt); 32764f70f249SJes Sorensen ret = -EINVAL; 3277f88e1a42SJes Sorensen goto out; 3278f88e1a42SJes Sorensen } 3279f88e1a42SJes Sorensen 3280f88e1a42SJes Sorensen proto_drv = bdrv_find_protocol(filename); 3281f88e1a42SJes Sorensen if (!proto_drv) { 3282f88e1a42SJes Sorensen error_report("Unknown protocol '%s'", filename); 32834f70f249SJes Sorensen ret = -EINVAL; 3284f88e1a42SJes Sorensen goto out; 3285f88e1a42SJes Sorensen } 3286f88e1a42SJes Sorensen 3287f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3288f88e1a42SJes Sorensen drv->create_options); 3289f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3290f88e1a42SJes Sorensen proto_drv->create_options); 3291f88e1a42SJes Sorensen 3292f88e1a42SJes Sorensen /* Create parameter list with default values */ 3293f88e1a42SJes Sorensen param = parse_option_parameters("", create_options, param); 3294f88e1a42SJes Sorensen 3295f88e1a42SJes Sorensen set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); 3296f88e1a42SJes Sorensen 3297f88e1a42SJes Sorensen /* Parse -o options */ 3298f88e1a42SJes Sorensen if (options) { 3299f88e1a42SJes Sorensen param = parse_option_parameters(options, create_options, param); 3300f88e1a42SJes Sorensen if (param == NULL) { 3301f88e1a42SJes Sorensen error_report("Invalid options for file format '%s'.", fmt); 33024f70f249SJes Sorensen ret = -EINVAL; 3303f88e1a42SJes Sorensen goto out; 3304f88e1a42SJes Sorensen } 3305f88e1a42SJes Sorensen } 3306f88e1a42SJes Sorensen 3307f88e1a42SJes Sorensen if (base_filename) { 3308f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, 3309f88e1a42SJes Sorensen base_filename)) { 3310f88e1a42SJes Sorensen error_report("Backing file not supported for file format '%s'", 3311f88e1a42SJes Sorensen fmt); 33124f70f249SJes Sorensen ret = -EINVAL; 3313f88e1a42SJes Sorensen goto out; 3314f88e1a42SJes Sorensen } 3315f88e1a42SJes Sorensen } 3316f88e1a42SJes Sorensen 3317f88e1a42SJes Sorensen if (base_fmt) { 3318f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { 3319f88e1a42SJes Sorensen error_report("Backing file format not supported for file " 3320f88e1a42SJes Sorensen "format '%s'", fmt); 33214f70f249SJes Sorensen ret = -EINVAL; 3322f88e1a42SJes Sorensen goto out; 3323f88e1a42SJes Sorensen } 3324f88e1a42SJes Sorensen } 3325f88e1a42SJes Sorensen 3326792da93aSJes Sorensen backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); 3327792da93aSJes Sorensen if (backing_file && backing_file->value.s) { 3328792da93aSJes Sorensen if (!strcmp(filename, backing_file->value.s)) { 3329792da93aSJes Sorensen error_report("Error: Trying to create an image with the " 3330792da93aSJes Sorensen "same filename as the backing file"); 33314f70f249SJes Sorensen ret = -EINVAL; 3332792da93aSJes Sorensen goto out; 3333792da93aSJes Sorensen } 3334792da93aSJes Sorensen } 3335792da93aSJes Sorensen 3336f88e1a42SJes Sorensen backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); 3337f88e1a42SJes Sorensen if (backing_fmt && backing_fmt->value.s) { 333896df67d1SStefan Hajnoczi backing_drv = bdrv_find_format(backing_fmt->value.s); 333996df67d1SStefan Hajnoczi if (!backing_drv) { 3340f88e1a42SJes Sorensen error_report("Unknown backing file format '%s'", 3341f88e1a42SJes Sorensen backing_fmt->value.s); 33424f70f249SJes Sorensen ret = -EINVAL; 3343f88e1a42SJes Sorensen goto out; 3344f88e1a42SJes Sorensen } 3345f88e1a42SJes Sorensen } 3346f88e1a42SJes Sorensen 3347f88e1a42SJes Sorensen // The size for the image must always be specified, with one exception: 3348f88e1a42SJes Sorensen // If we are using a backing file, we can obtain the size from there 3349d220894eSKevin Wolf size = get_option_parameter(param, BLOCK_OPT_SIZE); 3350d220894eSKevin Wolf if (size && size->value.n == -1) { 3351f88e1a42SJes Sorensen if (backing_file && backing_file->value.s) { 3352f88e1a42SJes Sorensen uint64_t size; 3353f88e1a42SJes Sorensen char buf[32]; 3354f88e1a42SJes Sorensen 3355f88e1a42SJes Sorensen bs = bdrv_new(""); 3356f88e1a42SJes Sorensen 335796df67d1SStefan Hajnoczi ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv); 3358f88e1a42SJes Sorensen if (ret < 0) { 335996df67d1SStefan Hajnoczi error_report("Could not open '%s'", backing_file->value.s); 3360f88e1a42SJes Sorensen goto out; 3361f88e1a42SJes Sorensen } 3362f88e1a42SJes Sorensen bdrv_get_geometry(bs, &size); 3363f88e1a42SJes Sorensen size *= 512; 3364f88e1a42SJes Sorensen 3365f88e1a42SJes Sorensen snprintf(buf, sizeof(buf), "%" PRId64, size); 3366f88e1a42SJes Sorensen set_option_parameter(param, BLOCK_OPT_SIZE, buf); 3367f88e1a42SJes Sorensen } else { 3368f88e1a42SJes Sorensen error_report("Image creation needs a size parameter"); 33694f70f249SJes Sorensen ret = -EINVAL; 3370f88e1a42SJes Sorensen goto out; 3371f88e1a42SJes Sorensen } 3372f88e1a42SJes Sorensen } 3373f88e1a42SJes Sorensen 3374f88e1a42SJes Sorensen printf("Formatting '%s', fmt=%s ", filename, fmt); 3375f88e1a42SJes Sorensen print_option_parameters(param); 3376f88e1a42SJes Sorensen puts(""); 3377f88e1a42SJes Sorensen 3378f88e1a42SJes Sorensen ret = bdrv_create(drv, filename, param); 3379f88e1a42SJes Sorensen 3380f88e1a42SJes Sorensen if (ret < 0) { 3381f88e1a42SJes Sorensen if (ret == -ENOTSUP) { 3382f88e1a42SJes Sorensen error_report("Formatting or formatting option not supported for " 3383f88e1a42SJes Sorensen "file format '%s'", fmt); 3384f88e1a42SJes Sorensen } else if (ret == -EFBIG) { 3385f88e1a42SJes Sorensen error_report("The image size is too large for file format '%s'", 3386f88e1a42SJes Sorensen fmt); 3387f88e1a42SJes Sorensen } else { 3388f88e1a42SJes Sorensen error_report("%s: error while creating %s: %s", filename, fmt, 3389f88e1a42SJes Sorensen strerror(-ret)); 3390f88e1a42SJes Sorensen } 3391f88e1a42SJes Sorensen } 3392f88e1a42SJes Sorensen 3393f88e1a42SJes Sorensen out: 3394f88e1a42SJes Sorensen free_option_parameters(create_options); 3395f88e1a42SJes Sorensen free_option_parameters(param); 3396f88e1a42SJes Sorensen 3397f88e1a42SJes Sorensen if (bs) { 3398f88e1a42SJes Sorensen bdrv_delete(bs); 3399f88e1a42SJes Sorensen } 34004f70f249SJes Sorensen 34014f70f249SJes Sorensen return ret; 3402f88e1a42SJes Sorensen } 3403