1fc01f7e7Sbellard /* 2fc01f7e7Sbellard * QEMU System Emulator block driver 3fc01f7e7Sbellard * 4fc01f7e7Sbellard * Copyright (c) 2003 Fabrice Bellard 5fc01f7e7Sbellard * 6fc01f7e7Sbellard * Permission is hereby granted, free of charge, to any person obtaining a copy 7fc01f7e7Sbellard * of this software and associated documentation files (the "Software"), to deal 8fc01f7e7Sbellard * in the Software without restriction, including without limitation the rights 9fc01f7e7Sbellard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10fc01f7e7Sbellard * copies of the Software, and to permit persons to whom the Software is 11fc01f7e7Sbellard * furnished to do so, subject to the following conditions: 12fc01f7e7Sbellard * 13fc01f7e7Sbellard * The above copyright notice and this permission notice shall be included in 14fc01f7e7Sbellard * all copies or substantial portions of the Software. 15fc01f7e7Sbellard * 16fc01f7e7Sbellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17fc01f7e7Sbellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18fc01f7e7Sbellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19fc01f7e7Sbellard * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20fc01f7e7Sbellard * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21fc01f7e7Sbellard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22fc01f7e7Sbellard * THE SOFTWARE. 23fc01f7e7Sbellard */ 243990d09aSblueswir1 #include "config-host.h" 25faf07963Spbrook #include "qemu-common.h" 266d519a5fSStefan Hajnoczi #include "trace.h" 27376253ecSaliguori #include "monitor.h" 28ea2384d3Sbellard #include "block_int.h" 295efa9d5aSAnthony Liguori #include "module.h" 30d15e5465SLuiz Capitulino #include "qemu-objects.h" 3168485420SKevin Wolf #include "qemu-coroutine.h" 32fc01f7e7Sbellard 3371e72a19SJuan Quintela #ifdef CONFIG_BSD 347674e7bfSbellard #include <sys/types.h> 357674e7bfSbellard #include <sys/stat.h> 367674e7bfSbellard #include <sys/ioctl.h> 3772cf2d4fSBlue Swirl #include <sys/queue.h> 38c5e97233Sblueswir1 #ifndef __DragonFly__ 397674e7bfSbellard #include <sys/disk.h> 407674e7bfSbellard #endif 41c5e97233Sblueswir1 #endif 427674e7bfSbellard 4349dc768dSaliguori #ifdef _WIN32 4449dc768dSaliguori #include <windows.h> 4549dc768dSaliguori #endif 4649dc768dSaliguori 471c9805a3SStefan Hajnoczi #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ 481c9805a3SStefan Hajnoczi 497d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); 50f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 51f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 52c87c0672Saliguori BlockDriverCompletionFunc *cb, void *opaque); 53f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 54f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 55ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque); 56b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 57b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque); 58016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, 59016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque); 60f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 61f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 62f9f05dc5SKevin Wolf QEMUIOVector *iov); 63f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 64f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 65f9f05dc5SKevin Wolf QEMUIOVector *iov); 66e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs); 67c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, 68c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); 691c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, 701c9805a3SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); 71b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 72b2a61371SStefan Hajnoczi int64_t sector_num, 73b2a61371SStefan Hajnoczi QEMUIOVector *qiov, 74b2a61371SStefan Hajnoczi int nb_sectors, 75b2a61371SStefan Hajnoczi BlockDriverCompletionFunc *cb, 76b2a61371SStefan Hajnoczi void *opaque, 778c5873d6SStefan Hajnoczi bool is_write); 78b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque); 79ec530c81Sbellard 801b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states = 811b7bdbc1SStefan Hajnoczi QTAILQ_HEAD_INITIALIZER(bdrv_states); 827ee930d0Sblueswir1 838a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers = 848a22f02aSStefan Hajnoczi QLIST_HEAD_INITIALIZER(bdrv_drivers); 85ea2384d3Sbellard 86f9092b10SMarkus Armbruster /* The device to use for VM snapshots */ 87f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots; 88f9092b10SMarkus Armbruster 89eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */ 90eb852011SMarkus Armbruster static int use_bdrv_whitelist; 91eb852011SMarkus Armbruster 929e0b22f4SStefan Hajnoczi #ifdef _WIN32 939e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename) 949e0b22f4SStefan Hajnoczi { 959e0b22f4SStefan Hajnoczi return (((filename[0] >= 'a' && filename[0] <= 'z') || 969e0b22f4SStefan Hajnoczi (filename[0] >= 'A' && filename[0] <= 'Z')) && 979e0b22f4SStefan Hajnoczi filename[1] == ':'); 989e0b22f4SStefan Hajnoczi } 999e0b22f4SStefan Hajnoczi 1009e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename) 1019e0b22f4SStefan Hajnoczi { 1029e0b22f4SStefan Hajnoczi if (is_windows_drive_prefix(filename) && 1039e0b22f4SStefan Hajnoczi filename[2] == '\0') 1049e0b22f4SStefan Hajnoczi return 1; 1059e0b22f4SStefan Hajnoczi if (strstart(filename, "\\\\.\\", NULL) || 1069e0b22f4SStefan Hajnoczi strstart(filename, "//./", NULL)) 1079e0b22f4SStefan Hajnoczi return 1; 1089e0b22f4SStefan Hajnoczi return 0; 1099e0b22f4SStefan Hajnoczi } 1109e0b22f4SStefan Hajnoczi #endif 1119e0b22f4SStefan Hajnoczi 1129e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */ 1139e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path) 1149e0b22f4SStefan Hajnoczi { 1159e0b22f4SStefan Hajnoczi #ifdef _WIN32 1169e0b22f4SStefan Hajnoczi if (is_windows_drive(path) || 1179e0b22f4SStefan Hajnoczi is_windows_drive_prefix(path)) { 1189e0b22f4SStefan Hajnoczi return 0; 1199e0b22f4SStefan Hajnoczi } 1209e0b22f4SStefan Hajnoczi #endif 1219e0b22f4SStefan Hajnoczi 1229e0b22f4SStefan Hajnoczi return strchr(path, ':') != NULL; 1239e0b22f4SStefan Hajnoczi } 1249e0b22f4SStefan Hajnoczi 12583f64091Sbellard int path_is_absolute(const char *path) 12683f64091Sbellard { 12783f64091Sbellard const char *p; 12821664424Sbellard #ifdef _WIN32 12921664424Sbellard /* specific case for names like: "\\.\d:" */ 13021664424Sbellard if (*path == '/' || *path == '\\') 13121664424Sbellard return 1; 13221664424Sbellard #endif 13383f64091Sbellard p = strchr(path, ':'); 13483f64091Sbellard if (p) 13583f64091Sbellard p++; 13683f64091Sbellard else 13783f64091Sbellard p = path; 1383b9f94e1Sbellard #ifdef _WIN32 1393b9f94e1Sbellard return (*p == '/' || *p == '\\'); 1403b9f94e1Sbellard #else 1413b9f94e1Sbellard return (*p == '/'); 1423b9f94e1Sbellard #endif 14383f64091Sbellard } 14483f64091Sbellard 14583f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a 14683f64091Sbellard path to it by considering it is relative to base_path. URL are 14783f64091Sbellard supported. */ 14883f64091Sbellard void path_combine(char *dest, int dest_size, 14983f64091Sbellard const char *base_path, 15083f64091Sbellard const char *filename) 15183f64091Sbellard { 15283f64091Sbellard const char *p, *p1; 15383f64091Sbellard int len; 15483f64091Sbellard 15583f64091Sbellard if (dest_size <= 0) 15683f64091Sbellard return; 15783f64091Sbellard if (path_is_absolute(filename)) { 15883f64091Sbellard pstrcpy(dest, dest_size, filename); 15983f64091Sbellard } else { 16083f64091Sbellard p = strchr(base_path, ':'); 16183f64091Sbellard if (p) 16283f64091Sbellard p++; 16383f64091Sbellard else 16483f64091Sbellard p = base_path; 1653b9f94e1Sbellard p1 = strrchr(base_path, '/'); 1663b9f94e1Sbellard #ifdef _WIN32 1673b9f94e1Sbellard { 1683b9f94e1Sbellard const char *p2; 1693b9f94e1Sbellard p2 = strrchr(base_path, '\\'); 1703b9f94e1Sbellard if (!p1 || p2 > p1) 1713b9f94e1Sbellard p1 = p2; 1723b9f94e1Sbellard } 1733b9f94e1Sbellard #endif 17483f64091Sbellard if (p1) 17583f64091Sbellard p1++; 17683f64091Sbellard else 17783f64091Sbellard p1 = base_path; 17883f64091Sbellard if (p1 > p) 17983f64091Sbellard p = p1; 18083f64091Sbellard len = p - base_path; 18183f64091Sbellard if (len > dest_size - 1) 18283f64091Sbellard len = dest_size - 1; 18383f64091Sbellard memcpy(dest, base_path, len); 18483f64091Sbellard dest[len] = '\0'; 18583f64091Sbellard pstrcat(dest, dest_size, filename); 18683f64091Sbellard } 18783f64091Sbellard } 18883f64091Sbellard 1895efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv) 190ea2384d3Sbellard { 1918c5873d6SStefan Hajnoczi /* Block drivers without coroutine functions need emulation */ 1928c5873d6SStefan Hajnoczi if (!bdrv->bdrv_co_readv) { 193f9f05dc5SKevin Wolf bdrv->bdrv_co_readv = bdrv_co_readv_em; 194f9f05dc5SKevin Wolf bdrv->bdrv_co_writev = bdrv_co_writev_em; 195f9f05dc5SKevin Wolf 196f8c35c1dSStefan Hajnoczi /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if 197f8c35c1dSStefan Hajnoczi * the block driver lacks aio we need to emulate that too. 198f8c35c1dSStefan Hajnoczi */ 199f9f05dc5SKevin Wolf if (!bdrv->bdrv_aio_readv) { 20083f64091Sbellard /* add AIO emulation layer */ 201f141eafeSaliguori bdrv->bdrv_aio_readv = bdrv_aio_readv_em; 202f141eafeSaliguori bdrv->bdrv_aio_writev = bdrv_aio_writev_em; 20383f64091Sbellard } 204f9f05dc5SKevin Wolf } 205b2e12bc6SChristoph Hellwig 206b2e12bc6SChristoph Hellwig if (!bdrv->bdrv_aio_flush) 207b2e12bc6SChristoph Hellwig bdrv->bdrv_aio_flush = bdrv_aio_flush_em; 208b2e12bc6SChristoph Hellwig 2098a22f02aSStefan Hajnoczi QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); 210ea2384d3Sbellard } 211b338082bSbellard 212b338082bSbellard /* create a new block device (by default it is empty) */ 213b338082bSbellard BlockDriverState *bdrv_new(const char *device_name) 214fc01f7e7Sbellard { 2151b7bdbc1SStefan Hajnoczi BlockDriverState *bs; 216b338082bSbellard 2177267c094SAnthony Liguori bs = g_malloc0(sizeof(BlockDriverState)); 218b338082bSbellard pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 219ea2384d3Sbellard if (device_name[0] != '\0') { 2201b7bdbc1SStefan Hajnoczi QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); 221ea2384d3Sbellard } 22228a7282aSLuiz Capitulino bdrv_iostatus_disable(bs); 223b338082bSbellard return bs; 224b338082bSbellard } 225b338082bSbellard 226ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name) 227ea2384d3Sbellard { 228ea2384d3Sbellard BlockDriver *drv1; 2298a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 2308a22f02aSStefan Hajnoczi if (!strcmp(drv1->format_name, format_name)) { 231ea2384d3Sbellard return drv1; 232ea2384d3Sbellard } 2338a22f02aSStefan Hajnoczi } 234ea2384d3Sbellard return NULL; 235ea2384d3Sbellard } 236ea2384d3Sbellard 237eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv) 238eb852011SMarkus Armbruster { 239eb852011SMarkus Armbruster static const char *whitelist[] = { 240eb852011SMarkus Armbruster CONFIG_BDRV_WHITELIST 241eb852011SMarkus Armbruster }; 242eb852011SMarkus Armbruster const char **p; 243eb852011SMarkus Armbruster 244eb852011SMarkus Armbruster if (!whitelist[0]) 245eb852011SMarkus Armbruster return 1; /* no whitelist, anything goes */ 246eb852011SMarkus Armbruster 247eb852011SMarkus Armbruster for (p = whitelist; *p; p++) { 248eb852011SMarkus Armbruster if (!strcmp(drv->format_name, *p)) { 249eb852011SMarkus Armbruster return 1; 250eb852011SMarkus Armbruster } 251eb852011SMarkus Armbruster } 252eb852011SMarkus Armbruster return 0; 253eb852011SMarkus Armbruster } 254eb852011SMarkus Armbruster 255eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name) 256eb852011SMarkus Armbruster { 257eb852011SMarkus Armbruster BlockDriver *drv = bdrv_find_format(format_name); 258eb852011SMarkus Armbruster return drv && bdrv_is_whitelisted(drv) ? drv : NULL; 259eb852011SMarkus Armbruster } 260eb852011SMarkus Armbruster 2610e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename, 2620e7e1989SKevin Wolf QEMUOptionParameter *options) 263ea2384d3Sbellard { 264ea2384d3Sbellard if (!drv->bdrv_create) 265ea2384d3Sbellard return -ENOTSUP; 2660e7e1989SKevin Wolf 2670e7e1989SKevin Wolf return drv->bdrv_create(filename, options); 268ea2384d3Sbellard } 269ea2384d3Sbellard 27084a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options) 27184a12e66SChristoph Hellwig { 27284a12e66SChristoph Hellwig BlockDriver *drv; 27384a12e66SChristoph Hellwig 274b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 27584a12e66SChristoph Hellwig if (drv == NULL) { 27616905d71SStefan Hajnoczi return -ENOENT; 27784a12e66SChristoph Hellwig } 27884a12e66SChristoph Hellwig 27984a12e66SChristoph Hellwig return bdrv_create(drv, filename, options); 28084a12e66SChristoph Hellwig } 28184a12e66SChristoph Hellwig 282d5249393Sbellard #ifdef _WIN32 28395389c86Sbellard void get_tmp_filename(char *filename, int size) 284d5249393Sbellard { 2853b9f94e1Sbellard char temp_dir[MAX_PATH]; 2863b9f94e1Sbellard 2873b9f94e1Sbellard GetTempPath(MAX_PATH, temp_dir); 2883b9f94e1Sbellard GetTempFileName(temp_dir, "qem", 0, filename); 289d5249393Sbellard } 290d5249393Sbellard #else 29195389c86Sbellard void get_tmp_filename(char *filename, int size) 292ea2384d3Sbellard { 293ea2384d3Sbellard int fd; 2947ccfb2ebSblueswir1 const char *tmpdir; 295d5249393Sbellard /* XXX: race condition possible */ 2960badc1eeSaurel32 tmpdir = getenv("TMPDIR"); 2970badc1eeSaurel32 if (!tmpdir) 2980badc1eeSaurel32 tmpdir = "/tmp"; 2990badc1eeSaurel32 snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 300ea2384d3Sbellard fd = mkstemp(filename); 301ea2384d3Sbellard close(fd); 302ea2384d3Sbellard } 303d5249393Sbellard #endif 304ea2384d3Sbellard 305f3a5d3f8SChristoph Hellwig /* 306f3a5d3f8SChristoph Hellwig * Detect host devices. By convention, /dev/cdrom[N] is always 307f3a5d3f8SChristoph Hellwig * recognized as a host CDROM. 308f3a5d3f8SChristoph Hellwig */ 309f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename) 310f3a5d3f8SChristoph Hellwig { 311508c7cb3SChristoph Hellwig int score_max = 0, score; 312508c7cb3SChristoph Hellwig BlockDriver *drv = NULL, *d; 313f3a5d3f8SChristoph Hellwig 3148a22f02aSStefan Hajnoczi QLIST_FOREACH(d, &bdrv_drivers, list) { 315508c7cb3SChristoph Hellwig if (d->bdrv_probe_device) { 316508c7cb3SChristoph Hellwig score = d->bdrv_probe_device(filename); 317508c7cb3SChristoph Hellwig if (score > score_max) { 318508c7cb3SChristoph Hellwig score_max = score; 319508c7cb3SChristoph Hellwig drv = d; 320f3a5d3f8SChristoph Hellwig } 321508c7cb3SChristoph Hellwig } 322f3a5d3f8SChristoph Hellwig } 323f3a5d3f8SChristoph Hellwig 324508c7cb3SChristoph Hellwig return drv; 325f3a5d3f8SChristoph Hellwig } 326f3a5d3f8SChristoph Hellwig 327b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename) 32884a12e66SChristoph Hellwig { 32984a12e66SChristoph Hellwig BlockDriver *drv1; 33084a12e66SChristoph Hellwig char protocol[128]; 33184a12e66SChristoph Hellwig int len; 33284a12e66SChristoph Hellwig const char *p; 33384a12e66SChristoph Hellwig 33466f82ceeSKevin Wolf /* TODO Drivers without bdrv_file_open must be specified explicitly */ 33566f82ceeSKevin Wolf 33639508e7aSChristoph Hellwig /* 33739508e7aSChristoph Hellwig * XXX(hch): we really should not let host device detection 33839508e7aSChristoph Hellwig * override an explicit protocol specification, but moving this 33939508e7aSChristoph Hellwig * later breaks access to device names with colons in them. 34039508e7aSChristoph Hellwig * Thanks to the brain-dead persistent naming schemes on udev- 34139508e7aSChristoph Hellwig * based Linux systems those actually are quite common. 34239508e7aSChristoph Hellwig */ 34384a12e66SChristoph Hellwig drv1 = find_hdev_driver(filename); 34439508e7aSChristoph Hellwig if (drv1) { 34584a12e66SChristoph Hellwig return drv1; 34684a12e66SChristoph Hellwig } 34739508e7aSChristoph Hellwig 3489e0b22f4SStefan Hajnoczi if (!path_has_protocol(filename)) { 34939508e7aSChristoph Hellwig return bdrv_find_format("file"); 35039508e7aSChristoph Hellwig } 3519e0b22f4SStefan Hajnoczi p = strchr(filename, ':'); 3529e0b22f4SStefan Hajnoczi assert(p != NULL); 35384a12e66SChristoph Hellwig len = p - filename; 35484a12e66SChristoph Hellwig if (len > sizeof(protocol) - 1) 35584a12e66SChristoph Hellwig len = sizeof(protocol) - 1; 35684a12e66SChristoph Hellwig memcpy(protocol, filename, len); 35784a12e66SChristoph Hellwig protocol[len] = '\0'; 35884a12e66SChristoph Hellwig QLIST_FOREACH(drv1, &bdrv_drivers, list) { 35984a12e66SChristoph Hellwig if (drv1->protocol_name && 36084a12e66SChristoph Hellwig !strcmp(drv1->protocol_name, protocol)) { 36184a12e66SChristoph Hellwig return drv1; 36284a12e66SChristoph Hellwig } 36384a12e66SChristoph Hellwig } 36484a12e66SChristoph Hellwig return NULL; 36584a12e66SChristoph Hellwig } 36684a12e66SChristoph Hellwig 367c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv) 368ea2384d3Sbellard { 36983f64091Sbellard int ret, score, score_max; 370ea2384d3Sbellard BlockDriver *drv1, *drv; 37183f64091Sbellard uint8_t buf[2048]; 37283f64091Sbellard BlockDriverState *bs; 373ea2384d3Sbellard 374f5edb014SNaphtali Sprei ret = bdrv_file_open(&bs, filename, 0); 375c98ac35dSStefan Weil if (ret < 0) { 376c98ac35dSStefan Weil *pdrv = NULL; 377c98ac35dSStefan Weil return ret; 378c98ac35dSStefan Weil } 379f8ea0b00SNicholas Bellinger 38008a00559SKevin Wolf /* Return the raw BlockDriver * to scsi-generic devices or empty drives */ 38108a00559SKevin Wolf if (bs->sg || !bdrv_is_inserted(bs)) { 3821a396859SNicholas A. Bellinger bdrv_delete(bs); 383c98ac35dSStefan Weil drv = bdrv_find_format("raw"); 384c98ac35dSStefan Weil if (!drv) { 385c98ac35dSStefan Weil ret = -ENOENT; 386c98ac35dSStefan Weil } 387c98ac35dSStefan Weil *pdrv = drv; 388c98ac35dSStefan Weil return ret; 3891a396859SNicholas A. Bellinger } 390f8ea0b00SNicholas Bellinger 39183f64091Sbellard ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 39283f64091Sbellard bdrv_delete(bs); 393ea2384d3Sbellard if (ret < 0) { 394c98ac35dSStefan Weil *pdrv = NULL; 395c98ac35dSStefan Weil return ret; 396ea2384d3Sbellard } 397ea2384d3Sbellard 398ea2384d3Sbellard score_max = 0; 39984a12e66SChristoph Hellwig drv = NULL; 4008a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 40183f64091Sbellard if (drv1->bdrv_probe) { 402ea2384d3Sbellard score = drv1->bdrv_probe(buf, ret, filename); 403ea2384d3Sbellard if (score > score_max) { 404ea2384d3Sbellard score_max = score; 405ea2384d3Sbellard drv = drv1; 406ea2384d3Sbellard } 407ea2384d3Sbellard } 40883f64091Sbellard } 409c98ac35dSStefan Weil if (!drv) { 410c98ac35dSStefan Weil ret = -ENOENT; 411c98ac35dSStefan Weil } 412c98ac35dSStefan Weil *pdrv = drv; 413c98ac35dSStefan Weil return ret; 414ea2384d3Sbellard } 415ea2384d3Sbellard 41651762288SStefan Hajnoczi /** 41751762288SStefan Hajnoczi * Set the current 'total_sectors' value 41851762288SStefan Hajnoczi */ 41951762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) 42051762288SStefan Hajnoczi { 42151762288SStefan Hajnoczi BlockDriver *drv = bs->drv; 42251762288SStefan Hajnoczi 423396759adSNicholas Bellinger /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */ 424396759adSNicholas Bellinger if (bs->sg) 425396759adSNicholas Bellinger return 0; 426396759adSNicholas Bellinger 42751762288SStefan Hajnoczi /* query actual device if possible, otherwise just trust the hint */ 42851762288SStefan Hajnoczi if (drv->bdrv_getlength) { 42951762288SStefan Hajnoczi int64_t length = drv->bdrv_getlength(bs); 43051762288SStefan Hajnoczi if (length < 0) { 43151762288SStefan Hajnoczi return length; 43251762288SStefan Hajnoczi } 43351762288SStefan Hajnoczi hint = length >> BDRV_SECTOR_BITS; 43451762288SStefan Hajnoczi } 43551762288SStefan Hajnoczi 43651762288SStefan Hajnoczi bs->total_sectors = hint; 43751762288SStefan Hajnoczi return 0; 43851762288SStefan Hajnoczi } 43951762288SStefan Hajnoczi 440c3993cdcSStefan Hajnoczi /** 441c3993cdcSStefan Hajnoczi * Set open flags for a given cache mode 442c3993cdcSStefan Hajnoczi * 443c3993cdcSStefan Hajnoczi * Return 0 on success, -1 if the cache mode was invalid. 444c3993cdcSStefan Hajnoczi */ 445c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags) 446c3993cdcSStefan Hajnoczi { 447c3993cdcSStefan Hajnoczi *flags &= ~BDRV_O_CACHE_MASK; 448c3993cdcSStefan Hajnoczi 449c3993cdcSStefan Hajnoczi if (!strcmp(mode, "off") || !strcmp(mode, "none")) { 450c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; 45192196b2fSStefan Hajnoczi } else if (!strcmp(mode, "directsync")) { 45292196b2fSStefan Hajnoczi *flags |= BDRV_O_NOCACHE; 453c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writeback")) { 454c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 455c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "unsafe")) { 456c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 457c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NO_FLUSH; 458c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writethrough")) { 459c3993cdcSStefan Hajnoczi /* this is the default */ 460c3993cdcSStefan Hajnoczi } else { 461c3993cdcSStefan Hajnoczi return -1; 462c3993cdcSStefan Hajnoczi } 463c3993cdcSStefan Hajnoczi 464c3993cdcSStefan Hajnoczi return 0; 465c3993cdcSStefan Hajnoczi } 466c3993cdcSStefan Hajnoczi 467b6ce07aaSKevin Wolf /* 46857915332SKevin Wolf * Common part for opening disk images and files 46957915332SKevin Wolf */ 47057915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename, 47157915332SKevin Wolf int flags, BlockDriver *drv) 47257915332SKevin Wolf { 47357915332SKevin Wolf int ret, open_flags; 47457915332SKevin Wolf 47557915332SKevin Wolf assert(drv != NULL); 47657915332SKevin Wolf 47728dcee10SStefan Hajnoczi trace_bdrv_open_common(bs, filename, flags, drv->format_name); 47828dcee10SStefan Hajnoczi 47966f82ceeSKevin Wolf bs->file = NULL; 48051762288SStefan Hajnoczi bs->total_sectors = 0; 48157915332SKevin Wolf bs->encrypted = 0; 48257915332SKevin Wolf bs->valid_key = 0; 48357915332SKevin Wolf bs->open_flags = flags; 48457915332SKevin Wolf bs->buffer_alignment = 512; 48557915332SKevin Wolf 48657915332SKevin Wolf pstrcpy(bs->filename, sizeof(bs->filename), filename); 48757915332SKevin Wolf 48857915332SKevin Wolf if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { 48957915332SKevin Wolf return -ENOTSUP; 49057915332SKevin Wolf } 49157915332SKevin Wolf 49257915332SKevin Wolf bs->drv = drv; 4937267c094SAnthony Liguori bs->opaque = g_malloc0(drv->instance_size); 49457915332SKevin Wolf 495a6599793SChristoph Hellwig if (flags & BDRV_O_CACHE_WB) 49657915332SKevin Wolf bs->enable_write_cache = 1; 49757915332SKevin Wolf 49857915332SKevin Wolf /* 49957915332SKevin Wolf * Clear flags that are internal to the block layer before opening the 50057915332SKevin Wolf * image. 50157915332SKevin Wolf */ 50257915332SKevin Wolf open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 50357915332SKevin Wolf 50457915332SKevin Wolf /* 505ebabb67aSStefan Weil * Snapshots should be writable. 50657915332SKevin Wolf */ 50757915332SKevin Wolf if (bs->is_temporary) { 50857915332SKevin Wolf open_flags |= BDRV_O_RDWR; 50957915332SKevin Wolf } 51057915332SKevin Wolf 51166f82ceeSKevin Wolf /* Open the image, either directly or using a protocol */ 51266f82ceeSKevin Wolf if (drv->bdrv_file_open) { 51366f82ceeSKevin Wolf ret = drv->bdrv_file_open(bs, filename, open_flags); 51466f82ceeSKevin Wolf } else { 51566f82ceeSKevin Wolf ret = bdrv_file_open(&bs->file, filename, open_flags); 51666f82ceeSKevin Wolf if (ret >= 0) { 51766f82ceeSKevin Wolf ret = drv->bdrv_open(bs, open_flags); 51866f82ceeSKevin Wolf } 51966f82ceeSKevin Wolf } 52066f82ceeSKevin Wolf 52157915332SKevin Wolf if (ret < 0) { 52257915332SKevin Wolf goto free_and_fail; 52357915332SKevin Wolf } 52457915332SKevin Wolf 52557915332SKevin Wolf bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); 52651762288SStefan Hajnoczi 52751762288SStefan Hajnoczi ret = refresh_total_sectors(bs, bs->total_sectors); 52851762288SStefan Hajnoczi if (ret < 0) { 52951762288SStefan Hajnoczi goto free_and_fail; 53057915332SKevin Wolf } 53151762288SStefan Hajnoczi 53257915332SKevin Wolf #ifndef _WIN32 53357915332SKevin Wolf if (bs->is_temporary) { 53457915332SKevin Wolf unlink(filename); 53557915332SKevin Wolf } 53657915332SKevin Wolf #endif 53757915332SKevin Wolf return 0; 53857915332SKevin Wolf 53957915332SKevin Wolf free_and_fail: 54066f82ceeSKevin Wolf if (bs->file) { 54166f82ceeSKevin Wolf bdrv_delete(bs->file); 54266f82ceeSKevin Wolf bs->file = NULL; 54366f82ceeSKevin Wolf } 5447267c094SAnthony Liguori g_free(bs->opaque); 54557915332SKevin Wolf bs->opaque = NULL; 54657915332SKevin Wolf bs->drv = NULL; 54757915332SKevin Wolf return ret; 54857915332SKevin Wolf } 54957915332SKevin Wolf 55057915332SKevin Wolf /* 551b6ce07aaSKevin Wolf * Opens a file using a protocol (file, host_device, nbd, ...) 552b6ce07aaSKevin Wolf */ 55383f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 554b338082bSbellard { 55583f64091Sbellard BlockDriverState *bs; 5566db95603SChristoph Hellwig BlockDriver *drv; 55783f64091Sbellard int ret; 5583b0d4f61Sbellard 559b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 5606db95603SChristoph Hellwig if (!drv) { 5616db95603SChristoph Hellwig return -ENOENT; 5626db95603SChristoph Hellwig } 5636db95603SChristoph Hellwig 56483f64091Sbellard bs = bdrv_new(""); 565b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 56683f64091Sbellard if (ret < 0) { 56783f64091Sbellard bdrv_delete(bs); 56883f64091Sbellard return ret; 5693b0d4f61Sbellard } 57071d0770cSaliguori bs->growable = 1; 57183f64091Sbellard *pbs = bs; 57283f64091Sbellard return 0; 5733b0d4f61Sbellard } 5743b0d4f61Sbellard 575b6ce07aaSKevin Wolf /* 576b6ce07aaSKevin Wolf * Opens a disk image (raw, qcow2, vmdk, ...) 577b6ce07aaSKevin Wolf */ 578d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags, 579ea2384d3Sbellard BlockDriver *drv) 580ea2384d3Sbellard { 581b6ce07aaSKevin Wolf int ret; 58233e3963eSbellard 58383f64091Sbellard if (flags & BDRV_O_SNAPSHOT) { 584ea2384d3Sbellard BlockDriverState *bs1; 585ea2384d3Sbellard int64_t total_size; 5867c96d46eSaliguori int is_protocol = 0; 58791a073a9SKevin Wolf BlockDriver *bdrv_qcow2; 58891a073a9SKevin Wolf QEMUOptionParameter *options; 589b6ce07aaSKevin Wolf char tmp_filename[PATH_MAX]; 590b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 59133e3963eSbellard 592ea2384d3Sbellard /* if snapshot, we create a temporary backing file and open it 593ea2384d3Sbellard instead of opening 'filename' directly */ 594ea2384d3Sbellard 595ea2384d3Sbellard /* if there is a backing file, use it */ 596ea2384d3Sbellard bs1 = bdrv_new(""); 597d6e9098eSKevin Wolf ret = bdrv_open(bs1, filename, 0, drv); 59851d7c00cSaliguori if (ret < 0) { 599ea2384d3Sbellard bdrv_delete(bs1); 60051d7c00cSaliguori return ret; 601ea2384d3Sbellard } 6023e82990bSJes Sorensen total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; 6037c96d46eSaliguori 6047c96d46eSaliguori if (bs1->drv && bs1->drv->protocol_name) 6057c96d46eSaliguori is_protocol = 1; 6067c96d46eSaliguori 607ea2384d3Sbellard bdrv_delete(bs1); 608ea2384d3Sbellard 609ea2384d3Sbellard get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 6107c96d46eSaliguori 6117c96d46eSaliguori /* Real path is meaningless for protocols */ 6127c96d46eSaliguori if (is_protocol) 6137c96d46eSaliguori snprintf(backing_filename, sizeof(backing_filename), 6147c96d46eSaliguori "%s", filename); 615114cdfa9SKirill A. Shutemov else if (!realpath(filename, backing_filename)) 616114cdfa9SKirill A. Shutemov return -errno; 6177c96d46eSaliguori 61891a073a9SKevin Wolf bdrv_qcow2 = bdrv_find_format("qcow2"); 61991a073a9SKevin Wolf options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); 62091a073a9SKevin Wolf 6213e82990bSJes Sorensen set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size); 62291a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename); 62391a073a9SKevin Wolf if (drv) { 62491a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FMT, 62591a073a9SKevin Wolf drv->format_name); 62691a073a9SKevin Wolf } 62791a073a9SKevin Wolf 62891a073a9SKevin Wolf ret = bdrv_create(bdrv_qcow2, tmp_filename, options); 629d748768cSJan Kiszka free_option_parameters(options); 63051d7c00cSaliguori if (ret < 0) { 63151d7c00cSaliguori return ret; 632ea2384d3Sbellard } 63391a073a9SKevin Wolf 634ea2384d3Sbellard filename = tmp_filename; 63591a073a9SKevin Wolf drv = bdrv_qcow2; 636ea2384d3Sbellard bs->is_temporary = 1; 637ea2384d3Sbellard } 638ea2384d3Sbellard 639b6ce07aaSKevin Wolf /* Find the right image format driver */ 6406db95603SChristoph Hellwig if (!drv) { 641c98ac35dSStefan Weil ret = find_image_format(filename, &drv); 642ea2384d3Sbellard } 6436987307cSChristoph Hellwig 64451d7c00cSaliguori if (!drv) { 64551d7c00cSaliguori goto unlink_and_fail; 64683f64091Sbellard } 647b6ce07aaSKevin Wolf 648b6ce07aaSKevin Wolf /* Open the image */ 649b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 650b6ce07aaSKevin Wolf if (ret < 0) { 6516987307cSChristoph Hellwig goto unlink_and_fail; 6526987307cSChristoph Hellwig } 6536987307cSChristoph Hellwig 654b6ce07aaSKevin Wolf /* If there is a backing file, use it */ 655b6ce07aaSKevin Wolf if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { 656b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 657b6ce07aaSKevin Wolf int back_flags; 658b6ce07aaSKevin Wolf BlockDriver *back_drv = NULL; 659b6ce07aaSKevin Wolf 660b6ce07aaSKevin Wolf bs->backing_hd = bdrv_new(""); 661df2dbb4aSStefan Hajnoczi 662df2dbb4aSStefan Hajnoczi if (path_has_protocol(bs->backing_file)) { 663df2dbb4aSStefan Hajnoczi pstrcpy(backing_filename, sizeof(backing_filename), 664df2dbb4aSStefan Hajnoczi bs->backing_file); 665df2dbb4aSStefan Hajnoczi } else { 666b6ce07aaSKevin Wolf path_combine(backing_filename, sizeof(backing_filename), 667b6ce07aaSKevin Wolf filename, bs->backing_file); 668df2dbb4aSStefan Hajnoczi } 669df2dbb4aSStefan Hajnoczi 670df2dbb4aSStefan Hajnoczi if (bs->backing_format[0] != '\0') { 671b6ce07aaSKevin Wolf back_drv = bdrv_find_format(bs->backing_format); 672df2dbb4aSStefan Hajnoczi } 673b6ce07aaSKevin Wolf 674b6ce07aaSKevin Wolf /* backing files always opened read-only */ 675b6ce07aaSKevin Wolf back_flags = 676b6ce07aaSKevin Wolf flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 677b6ce07aaSKevin Wolf 678b6ce07aaSKevin Wolf ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv); 679b6ce07aaSKevin Wolf if (ret < 0) { 680b6ce07aaSKevin Wolf bdrv_close(bs); 681b6ce07aaSKevin Wolf return ret; 682b6ce07aaSKevin Wolf } 683b6ce07aaSKevin Wolf if (bs->is_temporary) { 684b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); 685b6ce07aaSKevin Wolf } else { 686b6ce07aaSKevin Wolf /* base image inherits from "parent" */ 687b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = bs->keep_read_only; 688b6ce07aaSKevin Wolf } 689b6ce07aaSKevin Wolf } 690b6ce07aaSKevin Wolf 691b6ce07aaSKevin Wolf if (!bdrv_key_required(bs)) { 6927d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 693b6ce07aaSKevin Wolf } 694b6ce07aaSKevin Wolf 695b6ce07aaSKevin Wolf return 0; 696b6ce07aaSKevin Wolf 697b6ce07aaSKevin Wolf unlink_and_fail: 698b6ce07aaSKevin Wolf if (bs->is_temporary) { 699b6ce07aaSKevin Wolf unlink(filename); 700b6ce07aaSKevin Wolf } 701b6ce07aaSKevin Wolf return ret; 702b6ce07aaSKevin Wolf } 703b6ce07aaSKevin Wolf 704fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs) 705fc01f7e7Sbellard { 70619cb3738Sbellard if (bs->drv) { 707f9092b10SMarkus Armbruster if (bs == bs_snapshots) { 708f9092b10SMarkus Armbruster bs_snapshots = NULL; 709f9092b10SMarkus Armbruster } 710557df6acSStefan Hajnoczi if (bs->backing_hd) { 711ea2384d3Sbellard bdrv_delete(bs->backing_hd); 712557df6acSStefan Hajnoczi bs->backing_hd = NULL; 713557df6acSStefan Hajnoczi } 714ea2384d3Sbellard bs->drv->bdrv_close(bs); 7157267c094SAnthony Liguori g_free(bs->opaque); 716ea2384d3Sbellard #ifdef _WIN32 717ea2384d3Sbellard if (bs->is_temporary) { 718ea2384d3Sbellard unlink(bs->filename); 719ea2384d3Sbellard } 72067b915a5Sbellard #endif 721ea2384d3Sbellard bs->opaque = NULL; 722ea2384d3Sbellard bs->drv = NULL; 723b338082bSbellard 72466f82ceeSKevin Wolf if (bs->file != NULL) { 72566f82ceeSKevin Wolf bdrv_close(bs->file); 72666f82ceeSKevin Wolf } 72766f82ceeSKevin Wolf 7287d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, false); 729b338082bSbellard } 730b338082bSbellard } 731b338082bSbellard 7322bc93fedSMORITA Kazutaka void bdrv_close_all(void) 7332bc93fedSMORITA Kazutaka { 7342bc93fedSMORITA Kazutaka BlockDriverState *bs; 7352bc93fedSMORITA Kazutaka 7362bc93fedSMORITA Kazutaka QTAILQ_FOREACH(bs, &bdrv_states, list) { 7372bc93fedSMORITA Kazutaka bdrv_close(bs); 7382bc93fedSMORITA Kazutaka } 7392bc93fedSMORITA Kazutaka } 7402bc93fedSMORITA Kazutaka 741d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list. 742d22b2f41SRyan Harper Also, NULL terminate the device_name to prevent double remove */ 743d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs) 744d22b2f41SRyan Harper { 745d22b2f41SRyan Harper if (bs->device_name[0] != '\0') { 746d22b2f41SRyan Harper QTAILQ_REMOVE(&bdrv_states, bs, list); 747d22b2f41SRyan Harper } 748d22b2f41SRyan Harper bs->device_name[0] = '\0'; 749d22b2f41SRyan Harper } 750d22b2f41SRyan Harper 751b338082bSbellard void bdrv_delete(BlockDriverState *bs) 752b338082bSbellard { 753fa879d62SMarkus Armbruster assert(!bs->dev); 75418846deeSMarkus Armbruster 7551b7bdbc1SStefan Hajnoczi /* remove from list, if necessary */ 756d22b2f41SRyan Harper bdrv_make_anon(bs); 75734c6f050Saurel32 758b338082bSbellard bdrv_close(bs); 75966f82ceeSKevin Wolf if (bs->file != NULL) { 76066f82ceeSKevin Wolf bdrv_delete(bs->file); 76166f82ceeSKevin Wolf } 76266f82ceeSKevin Wolf 763f9092b10SMarkus Armbruster assert(bs != bs_snapshots); 7647267c094SAnthony Liguori g_free(bs); 765fc01f7e7Sbellard } 766fc01f7e7Sbellard 767fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev) 768fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 76918846deeSMarkus Armbruster { 770fa879d62SMarkus Armbruster if (bs->dev) { 77118846deeSMarkus Armbruster return -EBUSY; 77218846deeSMarkus Armbruster } 773fa879d62SMarkus Armbruster bs->dev = dev; 77428a7282aSLuiz Capitulino bdrv_iostatus_reset(bs); 77518846deeSMarkus Armbruster return 0; 77618846deeSMarkus Armbruster } 77718846deeSMarkus Armbruster 778fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */ 779fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) 78018846deeSMarkus Armbruster { 781fa879d62SMarkus Armbruster if (bdrv_attach_dev(bs, dev) < 0) { 782fa879d62SMarkus Armbruster abort(); 783fa879d62SMarkus Armbruster } 784fa879d62SMarkus Armbruster } 785fa879d62SMarkus Armbruster 786fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev) 787fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 788fa879d62SMarkus Armbruster { 789fa879d62SMarkus Armbruster assert(bs->dev == dev); 790fa879d62SMarkus Armbruster bs->dev = NULL; 7910e49de52SMarkus Armbruster bs->dev_ops = NULL; 7920e49de52SMarkus Armbruster bs->dev_opaque = NULL; 79329e05f20SMarkus Armbruster bs->buffer_alignment = 512; 79418846deeSMarkus Armbruster } 79518846deeSMarkus Armbruster 796fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 797fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs) 79818846deeSMarkus Armbruster { 799fa879d62SMarkus Armbruster return bs->dev; 80018846deeSMarkus Armbruster } 80118846deeSMarkus Armbruster 8020e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, 8030e49de52SMarkus Armbruster void *opaque) 8040e49de52SMarkus Armbruster { 8050e49de52SMarkus Armbruster bs->dev_ops = ops; 8060e49de52SMarkus Armbruster bs->dev_opaque = opaque; 8072c6942faSMarkus Armbruster if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) { 8082c6942faSMarkus Armbruster bs_snapshots = NULL; 8092c6942faSMarkus Armbruster } 8100e49de52SMarkus Armbruster } 8110e49de52SMarkus Armbruster 8127d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) 8130e49de52SMarkus Armbruster { 814145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->change_media_cb) { 8157d4b4ba5SMarkus Armbruster bs->dev_ops->change_media_cb(bs->dev_opaque, load); 816145feb17SMarkus Armbruster } 817145feb17SMarkus Armbruster } 818145feb17SMarkus Armbruster 8192c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs) 8202c6942faSMarkus Armbruster { 8212c6942faSMarkus Armbruster return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); 8222c6942faSMarkus Armbruster } 8232c6942faSMarkus Armbruster 824e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs) 825e4def80bSMarkus Armbruster { 826e4def80bSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_tray_open) { 827e4def80bSMarkus Armbruster return bs->dev_ops->is_tray_open(bs->dev_opaque); 828e4def80bSMarkus Armbruster } 829e4def80bSMarkus Armbruster return false; 830e4def80bSMarkus Armbruster } 831e4def80bSMarkus Armbruster 832145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs) 833145feb17SMarkus Armbruster { 834145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->resize_cb) { 835145feb17SMarkus Armbruster bs->dev_ops->resize_cb(bs->dev_opaque); 8360e49de52SMarkus Armbruster } 8370e49de52SMarkus Armbruster } 8380e49de52SMarkus Armbruster 839f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs) 840f107639aSMarkus Armbruster { 841f107639aSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_medium_locked) { 842f107639aSMarkus Armbruster return bs->dev_ops->is_medium_locked(bs->dev_opaque); 843f107639aSMarkus Armbruster } 844f107639aSMarkus Armbruster return false; 845f107639aSMarkus Armbruster } 846f107639aSMarkus Armbruster 847e97fc193Saliguori /* 848e97fc193Saliguori * Run consistency checks on an image 849e97fc193Saliguori * 850e076f338SKevin Wolf * Returns 0 if the check could be completed (it doesn't mean that the image is 851a1c7273bSStefan Weil * free of errors) or -errno when an internal error occurred. The results of the 852e076f338SKevin Wolf * check are stored in res. 853e97fc193Saliguori */ 854e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res) 855e97fc193Saliguori { 856e97fc193Saliguori if (bs->drv->bdrv_check == NULL) { 857e97fc193Saliguori return -ENOTSUP; 858e97fc193Saliguori } 859e97fc193Saliguori 860e076f338SKevin Wolf memset(res, 0, sizeof(*res)); 8619ac228e0SKevin Wolf return bs->drv->bdrv_check(bs, res); 862e97fc193Saliguori } 863e97fc193Saliguori 8648a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048 8658a426614SKevin Wolf 86633e3963eSbellard /* commit COW file into the raw image */ 86733e3963eSbellard int bdrv_commit(BlockDriverState *bs) 86833e3963eSbellard { 86919cb3738Sbellard BlockDriver *drv = bs->drv; 870ee181196SKevin Wolf BlockDriver *backing_drv; 8718a426614SKevin Wolf int64_t sector, total_sectors; 8728a426614SKevin Wolf int n, ro, open_flags; 8734dca4b63SNaphtali Sprei int ret = 0, rw_ret = 0; 8748a426614SKevin Wolf uint8_t *buf; 8754dca4b63SNaphtali Sprei char filename[1024]; 8764dca4b63SNaphtali Sprei BlockDriverState *bs_rw, *bs_ro; 87733e3963eSbellard 87819cb3738Sbellard if (!drv) 87919cb3738Sbellard return -ENOMEDIUM; 88033e3963eSbellard 8814dca4b63SNaphtali Sprei if (!bs->backing_hd) { 8824dca4b63SNaphtali Sprei return -ENOTSUP; 8834dca4b63SNaphtali Sprei } 8844dca4b63SNaphtali Sprei 8854dca4b63SNaphtali Sprei if (bs->backing_hd->keep_read_only) { 886ea2384d3Sbellard return -EACCES; 88733e3963eSbellard } 88833e3963eSbellard 889ee181196SKevin Wolf backing_drv = bs->backing_hd->drv; 8904dca4b63SNaphtali Sprei ro = bs->backing_hd->read_only; 8914dca4b63SNaphtali Sprei strncpy(filename, bs->backing_hd->filename, sizeof(filename)); 8924dca4b63SNaphtali Sprei open_flags = bs->backing_hd->open_flags; 8934dca4b63SNaphtali Sprei 8944dca4b63SNaphtali Sprei if (ro) { 8954dca4b63SNaphtali Sprei /* re-open as RW */ 8964dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 8974dca4b63SNaphtali Sprei bs->backing_hd = NULL; 8984dca4b63SNaphtali Sprei bs_rw = bdrv_new(""); 899ee181196SKevin Wolf rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, 900ee181196SKevin Wolf backing_drv); 9014dca4b63SNaphtali Sprei if (rw_ret < 0) { 9024dca4b63SNaphtali Sprei bdrv_delete(bs_rw); 9034dca4b63SNaphtali Sprei /* try to re-open read-only */ 9044dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 905ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 906ee181196SKevin Wolf backing_drv); 9074dca4b63SNaphtali Sprei if (ret < 0) { 9084dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9094dca4b63SNaphtali Sprei /* drive not functional anymore */ 9104dca4b63SNaphtali Sprei bs->drv = NULL; 9114dca4b63SNaphtali Sprei return ret; 9124dca4b63SNaphtali Sprei } 9134dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9144dca4b63SNaphtali Sprei return rw_ret; 9154dca4b63SNaphtali Sprei } 9164dca4b63SNaphtali Sprei bs->backing_hd = bs_rw; 917ea2384d3Sbellard } 918ea2384d3Sbellard 9196ea44308SJan Kiszka total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; 9207267c094SAnthony Liguori buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); 9218a426614SKevin Wolf 9228a426614SKevin Wolf for (sector = 0; sector < total_sectors; sector += n) { 9238a426614SKevin Wolf if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { 9248a426614SKevin Wolf 9258a426614SKevin Wolf if (bdrv_read(bs, sector, buf, n) != 0) { 9264dca4b63SNaphtali Sprei ret = -EIO; 9274dca4b63SNaphtali Sprei goto ro_cleanup; 92833e3963eSbellard } 92933e3963eSbellard 9308a426614SKevin Wolf if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) { 9314dca4b63SNaphtali Sprei ret = -EIO; 9324dca4b63SNaphtali Sprei goto ro_cleanup; 93333e3963eSbellard } 93433e3963eSbellard } 93533e3963eSbellard } 93695389c86Sbellard 9371d44952fSChristoph Hellwig if (drv->bdrv_make_empty) { 9381d44952fSChristoph Hellwig ret = drv->bdrv_make_empty(bs); 9391d44952fSChristoph Hellwig bdrv_flush(bs); 9401d44952fSChristoph Hellwig } 94195389c86Sbellard 9423f5075aeSChristoph Hellwig /* 9433f5075aeSChristoph Hellwig * Make sure all data we wrote to the backing device is actually 9443f5075aeSChristoph Hellwig * stable on disk. 9453f5075aeSChristoph Hellwig */ 9463f5075aeSChristoph Hellwig if (bs->backing_hd) 9473f5075aeSChristoph Hellwig bdrv_flush(bs->backing_hd); 9484dca4b63SNaphtali Sprei 9494dca4b63SNaphtali Sprei ro_cleanup: 9507267c094SAnthony Liguori g_free(buf); 9514dca4b63SNaphtali Sprei 9524dca4b63SNaphtali Sprei if (ro) { 9534dca4b63SNaphtali Sprei /* re-open as RO */ 9544dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 9554dca4b63SNaphtali Sprei bs->backing_hd = NULL; 9564dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 957ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 958ee181196SKevin Wolf backing_drv); 9594dca4b63SNaphtali Sprei if (ret < 0) { 9604dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9614dca4b63SNaphtali Sprei /* drive not functional anymore */ 9624dca4b63SNaphtali Sprei bs->drv = NULL; 9634dca4b63SNaphtali Sprei return ret; 9644dca4b63SNaphtali Sprei } 9654dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9664dca4b63SNaphtali Sprei bs->backing_hd->keep_read_only = 0; 9674dca4b63SNaphtali Sprei } 9684dca4b63SNaphtali Sprei 9691d44952fSChristoph Hellwig return ret; 97033e3963eSbellard } 97133e3963eSbellard 9726ab4b5abSMarkus Armbruster void bdrv_commit_all(void) 9736ab4b5abSMarkus Armbruster { 9746ab4b5abSMarkus Armbruster BlockDriverState *bs; 9756ab4b5abSMarkus Armbruster 9766ab4b5abSMarkus Armbruster QTAILQ_FOREACH(bs, &bdrv_states, list) { 9776ab4b5abSMarkus Armbruster bdrv_commit(bs); 9786ab4b5abSMarkus Armbruster } 9796ab4b5abSMarkus Armbruster } 9806ab4b5abSMarkus Armbruster 981756e6736SKevin Wolf /* 982756e6736SKevin Wolf * Return values: 983756e6736SKevin Wolf * 0 - success 984756e6736SKevin Wolf * -EINVAL - backing format specified, but no file 985756e6736SKevin Wolf * -ENOSPC - can't update the backing file because no space is left in the 986756e6736SKevin Wolf * image file header 987756e6736SKevin Wolf * -ENOTSUP - format driver doesn't support changing the backing file 988756e6736SKevin Wolf */ 989756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs, 990756e6736SKevin Wolf const char *backing_file, const char *backing_fmt) 991756e6736SKevin Wolf { 992756e6736SKevin Wolf BlockDriver *drv = bs->drv; 993756e6736SKevin Wolf 994756e6736SKevin Wolf if (drv->bdrv_change_backing_file != NULL) { 995756e6736SKevin Wolf return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt); 996756e6736SKevin Wolf } else { 997756e6736SKevin Wolf return -ENOTSUP; 998756e6736SKevin Wolf } 999756e6736SKevin Wolf } 1000756e6736SKevin Wolf 100171d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, 100271d0770cSaliguori size_t size) 100371d0770cSaliguori { 100471d0770cSaliguori int64_t len; 100571d0770cSaliguori 100671d0770cSaliguori if (!bdrv_is_inserted(bs)) 100771d0770cSaliguori return -ENOMEDIUM; 100871d0770cSaliguori 100971d0770cSaliguori if (bs->growable) 101071d0770cSaliguori return 0; 101171d0770cSaliguori 101271d0770cSaliguori len = bdrv_getlength(bs); 101371d0770cSaliguori 1014fbb7b4e0SKevin Wolf if (offset < 0) 1015fbb7b4e0SKevin Wolf return -EIO; 1016fbb7b4e0SKevin Wolf 1017fbb7b4e0SKevin Wolf if ((offset > len) || (len - offset < size)) 101871d0770cSaliguori return -EIO; 101971d0770cSaliguori 102071d0770cSaliguori return 0; 102171d0770cSaliguori } 102271d0770cSaliguori 102371d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, 102471d0770cSaliguori int nb_sectors) 102571d0770cSaliguori { 1026eb5a3165SJes Sorensen return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE, 1027eb5a3165SJes Sorensen nb_sectors * BDRV_SECTOR_SIZE); 102871d0770cSaliguori } 102971d0770cSaliguori 1030e7a8a783SKevin Wolf static inline bool bdrv_has_async_flush(BlockDriver *drv) 1031e7a8a783SKevin Wolf { 1032e7a8a783SKevin Wolf return drv->bdrv_aio_flush != bdrv_aio_flush_em; 1033e7a8a783SKevin Wolf } 1034e7a8a783SKevin Wolf 10351c9805a3SStefan Hajnoczi typedef struct RwCo { 10361c9805a3SStefan Hajnoczi BlockDriverState *bs; 10371c9805a3SStefan Hajnoczi int64_t sector_num; 10381c9805a3SStefan Hajnoczi int nb_sectors; 10391c9805a3SStefan Hajnoczi QEMUIOVector *qiov; 10401c9805a3SStefan Hajnoczi bool is_write; 10411c9805a3SStefan Hajnoczi int ret; 10421c9805a3SStefan Hajnoczi } RwCo; 10431c9805a3SStefan Hajnoczi 10441c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque) 1045fc01f7e7Sbellard { 10461c9805a3SStefan Hajnoczi RwCo *rwco = opaque; 1047fc01f7e7Sbellard 10481c9805a3SStefan Hajnoczi if (!rwco->is_write) { 10491c9805a3SStefan Hajnoczi rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num, 10501c9805a3SStefan Hajnoczi rwco->nb_sectors, rwco->qiov); 10511c9805a3SStefan Hajnoczi } else { 10521c9805a3SStefan Hajnoczi rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num, 10531c9805a3SStefan Hajnoczi rwco->nb_sectors, rwco->qiov); 10541c9805a3SStefan Hajnoczi } 10551c9805a3SStefan Hajnoczi } 1056e7a8a783SKevin Wolf 10571c9805a3SStefan Hajnoczi /* 10581c9805a3SStefan Hajnoczi * Process a synchronous request using coroutines 10591c9805a3SStefan Hajnoczi */ 10601c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, 10611c9805a3SStefan Hajnoczi int nb_sectors, bool is_write) 10621c9805a3SStefan Hajnoczi { 1063e7a8a783SKevin Wolf QEMUIOVector qiov; 1064e7a8a783SKevin Wolf struct iovec iov = { 1065e7a8a783SKevin Wolf .iov_base = (void *)buf, 1066e7a8a783SKevin Wolf .iov_len = nb_sectors * BDRV_SECTOR_SIZE, 1067e7a8a783SKevin Wolf }; 10681c9805a3SStefan Hajnoczi Coroutine *co; 10691c9805a3SStefan Hajnoczi RwCo rwco = { 10701c9805a3SStefan Hajnoczi .bs = bs, 10711c9805a3SStefan Hajnoczi .sector_num = sector_num, 10721c9805a3SStefan Hajnoczi .nb_sectors = nb_sectors, 10731c9805a3SStefan Hajnoczi .qiov = &qiov, 10741c9805a3SStefan Hajnoczi .is_write = is_write, 10751c9805a3SStefan Hajnoczi .ret = NOT_DONE, 10761c9805a3SStefan Hajnoczi }; 1077e7a8a783SKevin Wolf 1078e7a8a783SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 10791c9805a3SStefan Hajnoczi 10801c9805a3SStefan Hajnoczi if (qemu_in_coroutine()) { 10811c9805a3SStefan Hajnoczi /* Fast-path if already in coroutine context */ 10821c9805a3SStefan Hajnoczi bdrv_rw_co_entry(&rwco); 10831c9805a3SStefan Hajnoczi } else { 10841c9805a3SStefan Hajnoczi co = qemu_coroutine_create(bdrv_rw_co_entry); 10851c9805a3SStefan Hajnoczi qemu_coroutine_enter(co, &rwco); 10861c9805a3SStefan Hajnoczi while (rwco.ret == NOT_DONE) { 10871c9805a3SStefan Hajnoczi qemu_aio_wait(); 10881c9805a3SStefan Hajnoczi } 10891c9805a3SStefan Hajnoczi } 10901c9805a3SStefan Hajnoczi return rwco.ret; 1091e7a8a783SKevin Wolf } 1092e7a8a783SKevin Wolf 10931c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */ 10941c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num, 10951c9805a3SStefan Hajnoczi uint8_t *buf, int nb_sectors) 10961c9805a3SStefan Hajnoczi { 10971c9805a3SStefan Hajnoczi return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false); 109883f64091Sbellard } 1099fc01f7e7Sbellard 11007cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, 11017cd1e32aSlirans@il.ibm.com int nb_sectors, int dirty) 11027cd1e32aSlirans@il.ibm.com { 11037cd1e32aSlirans@il.ibm.com int64_t start, end; 1104c6d22830SJan Kiszka unsigned long val, idx, bit; 1105a55eb92cSJan Kiszka 11066ea44308SJan Kiszka start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; 1107c6d22830SJan Kiszka end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK; 11087cd1e32aSlirans@il.ibm.com 11097cd1e32aSlirans@il.ibm.com for (; start <= end; start++) { 1110c6d22830SJan Kiszka idx = start / (sizeof(unsigned long) * 8); 1111c6d22830SJan Kiszka bit = start % (sizeof(unsigned long) * 8); 1112c6d22830SJan Kiszka val = bs->dirty_bitmap[idx]; 1113c6d22830SJan Kiszka if (dirty) { 11146d59fec1SMarcelo Tosatti if (!(val & (1UL << bit))) { 1115aaa0eb75SLiran Schour bs->dirty_count++; 11166d59fec1SMarcelo Tosatti val |= 1UL << bit; 1117aaa0eb75SLiran Schour } 1118c6d22830SJan Kiszka } else { 11196d59fec1SMarcelo Tosatti if (val & (1UL << bit)) { 1120aaa0eb75SLiran Schour bs->dirty_count--; 11216d59fec1SMarcelo Tosatti val &= ~(1UL << bit); 1122c6d22830SJan Kiszka } 1123aaa0eb75SLiran Schour } 1124c6d22830SJan Kiszka bs->dirty_bitmap[idx] = val; 11257cd1e32aSlirans@il.ibm.com } 11267cd1e32aSlirans@il.ibm.com } 11277cd1e32aSlirans@il.ibm.com 112819cb3738Sbellard /* Return < 0 if error. Important errors are: 112919cb3738Sbellard -EIO generic I/O error (may happen for all errors) 113019cb3738Sbellard -ENOMEDIUM No media inserted. 113119cb3738Sbellard -EINVAL Invalid sector number or nb_sectors 113219cb3738Sbellard -EACCES Trying to write a read-only device 113319cb3738Sbellard */ 1134fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num, 1135fc01f7e7Sbellard const uint8_t *buf, int nb_sectors) 1136fc01f7e7Sbellard { 11371c9805a3SStefan Hajnoczi return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true); 113883f64091Sbellard } 113983f64091Sbellard 1140eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset, 1141eda578e5Saliguori void *buf, int count1) 114283f64091Sbellard { 11436ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 114483f64091Sbellard int len, nb_sectors, count; 114583f64091Sbellard int64_t sector_num; 11469a8c4cceSKevin Wolf int ret; 114783f64091Sbellard 114883f64091Sbellard count = count1; 114983f64091Sbellard /* first read to align to sector start */ 11506ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 115183f64091Sbellard if (len > count) 115283f64091Sbellard len = count; 11536ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 115483f64091Sbellard if (len > 0) { 11559a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11569a8c4cceSKevin Wolf return ret; 11576ea44308SJan Kiszka memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); 115883f64091Sbellard count -= len; 115983f64091Sbellard if (count == 0) 116083f64091Sbellard return count1; 116183f64091Sbellard sector_num++; 116283f64091Sbellard buf += len; 116383f64091Sbellard } 116483f64091Sbellard 116583f64091Sbellard /* read the sectors "in place" */ 11666ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 116783f64091Sbellard if (nb_sectors > 0) { 11689a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0) 11699a8c4cceSKevin Wolf return ret; 117083f64091Sbellard sector_num += nb_sectors; 11716ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 117283f64091Sbellard buf += len; 117383f64091Sbellard count -= len; 117483f64091Sbellard } 117583f64091Sbellard 117683f64091Sbellard /* add data from the last sector */ 117783f64091Sbellard if (count > 0) { 11789a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11799a8c4cceSKevin Wolf return ret; 118083f64091Sbellard memcpy(buf, tmp_buf, count); 118183f64091Sbellard } 118283f64091Sbellard return count1; 118383f64091Sbellard } 118483f64091Sbellard 1185eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 1186eda578e5Saliguori const void *buf, int count1) 118783f64091Sbellard { 11886ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 118983f64091Sbellard int len, nb_sectors, count; 119083f64091Sbellard int64_t sector_num; 11919a8c4cceSKevin Wolf int ret; 119283f64091Sbellard 119383f64091Sbellard count = count1; 119483f64091Sbellard /* first write to align to sector start */ 11956ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 119683f64091Sbellard if (len > count) 119783f64091Sbellard len = count; 11986ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 119983f64091Sbellard if (len > 0) { 12009a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 12019a8c4cceSKevin Wolf return ret; 12026ea44308SJan Kiszka memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len); 12039a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 12049a8c4cceSKevin Wolf return ret; 120583f64091Sbellard count -= len; 120683f64091Sbellard if (count == 0) 120783f64091Sbellard return count1; 120883f64091Sbellard sector_num++; 120983f64091Sbellard buf += len; 121083f64091Sbellard } 121183f64091Sbellard 121283f64091Sbellard /* write the sectors "in place" */ 12136ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 121483f64091Sbellard if (nb_sectors > 0) { 12159a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0) 12169a8c4cceSKevin Wolf return ret; 121783f64091Sbellard sector_num += nb_sectors; 12186ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 121983f64091Sbellard buf += len; 122083f64091Sbellard count -= len; 122183f64091Sbellard } 122283f64091Sbellard 122383f64091Sbellard /* add data from the last sector */ 122483f64091Sbellard if (count > 0) { 12259a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 12269a8c4cceSKevin Wolf return ret; 122783f64091Sbellard memcpy(tmp_buf, buf, count); 12289a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 12299a8c4cceSKevin Wolf return ret; 123083f64091Sbellard } 123183f64091Sbellard return count1; 123283f64091Sbellard } 123383f64091Sbellard 1234f08145feSKevin Wolf /* 1235f08145feSKevin Wolf * Writes to the file and ensures that no writes are reordered across this 1236f08145feSKevin Wolf * request (acts as a barrier) 1237f08145feSKevin Wolf * 1238f08145feSKevin Wolf * Returns 0 on success, -errno in error cases. 1239f08145feSKevin Wolf */ 1240f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, 1241f08145feSKevin Wolf const void *buf, int count) 1242f08145feSKevin Wolf { 1243f08145feSKevin Wolf int ret; 1244f08145feSKevin Wolf 1245f08145feSKevin Wolf ret = bdrv_pwrite(bs, offset, buf, count); 1246f08145feSKevin Wolf if (ret < 0) { 1247f08145feSKevin Wolf return ret; 1248f08145feSKevin Wolf } 1249f08145feSKevin Wolf 125092196b2fSStefan Hajnoczi /* No flush needed for cache modes that use O_DSYNC */ 125192196b2fSStefan Hajnoczi if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) { 1252f08145feSKevin Wolf bdrv_flush(bs); 1253f08145feSKevin Wolf } 1254f08145feSKevin Wolf 1255f08145feSKevin Wolf return 0; 1256f08145feSKevin Wolf } 1257f08145feSKevin Wolf 1258c5fbe571SStefan Hajnoczi /* 1259c5fbe571SStefan Hajnoczi * Handle a read request in coroutine context 1260c5fbe571SStefan Hajnoczi */ 1261c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, 1262c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) 1263da1fa91dSKevin Wolf { 1264da1fa91dSKevin Wolf BlockDriver *drv = bs->drv; 1265da1fa91dSKevin Wolf 1266da1fa91dSKevin Wolf if (!drv) { 1267da1fa91dSKevin Wolf return -ENOMEDIUM; 1268da1fa91dSKevin Wolf } 1269da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1270da1fa91dSKevin Wolf return -EIO; 1271da1fa91dSKevin Wolf } 1272da1fa91dSKevin Wolf 1273da1fa91dSKevin Wolf return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); 1274da1fa91dSKevin Wolf } 1275da1fa91dSKevin Wolf 1276c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, 1277da1fa91dSKevin Wolf int nb_sectors, QEMUIOVector *qiov) 1278da1fa91dSKevin Wolf { 1279c5fbe571SStefan Hajnoczi trace_bdrv_co_readv(bs, sector_num, nb_sectors); 1280da1fa91dSKevin Wolf 1281c5fbe571SStefan Hajnoczi return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov); 1282c5fbe571SStefan Hajnoczi } 1283c5fbe571SStefan Hajnoczi 1284c5fbe571SStefan Hajnoczi /* 1285c5fbe571SStefan Hajnoczi * Handle a write request in coroutine context 1286c5fbe571SStefan Hajnoczi */ 1287c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, 1288c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) 1289c5fbe571SStefan Hajnoczi { 1290c5fbe571SStefan Hajnoczi BlockDriver *drv = bs->drv; 12916b7cb247SStefan Hajnoczi int ret; 1292da1fa91dSKevin Wolf 1293da1fa91dSKevin Wolf if (!bs->drv) { 1294da1fa91dSKevin Wolf return -ENOMEDIUM; 1295da1fa91dSKevin Wolf } 1296da1fa91dSKevin Wolf if (bs->read_only) { 1297da1fa91dSKevin Wolf return -EACCES; 1298da1fa91dSKevin Wolf } 1299da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1300da1fa91dSKevin Wolf return -EIO; 1301da1fa91dSKevin Wolf } 1302da1fa91dSKevin Wolf 13036b7cb247SStefan Hajnoczi ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); 13046b7cb247SStefan Hajnoczi 1305da1fa91dSKevin Wolf if (bs->dirty_bitmap) { 1306da1fa91dSKevin Wolf set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 1307da1fa91dSKevin Wolf } 1308da1fa91dSKevin Wolf 1309da1fa91dSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 1310da1fa91dSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 1311da1fa91dSKevin Wolf } 1312da1fa91dSKevin Wolf 13136b7cb247SStefan Hajnoczi return ret; 1314da1fa91dSKevin Wolf } 1315da1fa91dSKevin Wolf 1316c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, 1317c5fbe571SStefan Hajnoczi int nb_sectors, QEMUIOVector *qiov) 1318c5fbe571SStefan Hajnoczi { 1319c5fbe571SStefan Hajnoczi trace_bdrv_co_writev(bs, sector_num, nb_sectors); 1320c5fbe571SStefan Hajnoczi 1321c5fbe571SStefan Hajnoczi return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov); 1322c5fbe571SStefan Hajnoczi } 1323c5fbe571SStefan Hajnoczi 132483f64091Sbellard /** 132583f64091Sbellard * Truncate file to 'offset' bytes (needed only for file protocols) 132683f64091Sbellard */ 132783f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset) 132883f64091Sbellard { 132983f64091Sbellard BlockDriver *drv = bs->drv; 133051762288SStefan Hajnoczi int ret; 133183f64091Sbellard if (!drv) 133219cb3738Sbellard return -ENOMEDIUM; 133383f64091Sbellard if (!drv->bdrv_truncate) 133483f64091Sbellard return -ENOTSUP; 133559f2689dSNaphtali Sprei if (bs->read_only) 133659f2689dSNaphtali Sprei return -EACCES; 13378591675fSMarcelo Tosatti if (bdrv_in_use(bs)) 13388591675fSMarcelo Tosatti return -EBUSY; 133951762288SStefan Hajnoczi ret = drv->bdrv_truncate(bs, offset); 134051762288SStefan Hajnoczi if (ret == 0) { 134151762288SStefan Hajnoczi ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); 1342145feb17SMarkus Armbruster bdrv_dev_resize_cb(bs); 134351762288SStefan Hajnoczi } 134451762288SStefan Hajnoczi return ret; 134583f64091Sbellard } 134683f64091Sbellard 134783f64091Sbellard /** 13484a1d5e1fSFam Zheng * Length of a allocated file in bytes. Sparse files are counted by actual 13494a1d5e1fSFam Zheng * allocated space. Return < 0 if error or unknown. 13504a1d5e1fSFam Zheng */ 13514a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) 13524a1d5e1fSFam Zheng { 13534a1d5e1fSFam Zheng BlockDriver *drv = bs->drv; 13544a1d5e1fSFam Zheng if (!drv) { 13554a1d5e1fSFam Zheng return -ENOMEDIUM; 13564a1d5e1fSFam Zheng } 13574a1d5e1fSFam Zheng if (drv->bdrv_get_allocated_file_size) { 13584a1d5e1fSFam Zheng return drv->bdrv_get_allocated_file_size(bs); 13594a1d5e1fSFam Zheng } 13604a1d5e1fSFam Zheng if (bs->file) { 13614a1d5e1fSFam Zheng return bdrv_get_allocated_file_size(bs->file); 13624a1d5e1fSFam Zheng } 13634a1d5e1fSFam Zheng return -ENOTSUP; 13644a1d5e1fSFam Zheng } 13654a1d5e1fSFam Zheng 13664a1d5e1fSFam Zheng /** 136783f64091Sbellard * Length of a file in bytes. Return < 0 if error or unknown. 136883f64091Sbellard */ 136983f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs) 137083f64091Sbellard { 137183f64091Sbellard BlockDriver *drv = bs->drv; 137283f64091Sbellard if (!drv) 137319cb3738Sbellard return -ENOMEDIUM; 137451762288SStefan Hajnoczi 13752c6942faSMarkus Armbruster if (bs->growable || bdrv_dev_has_removable_media(bs)) { 137646a4e4e6SStefan Hajnoczi if (drv->bdrv_getlength) { 137783f64091Sbellard return drv->bdrv_getlength(bs); 1378fc01f7e7Sbellard } 137946a4e4e6SStefan Hajnoczi } 138046a4e4e6SStefan Hajnoczi return bs->total_sectors * BDRV_SECTOR_SIZE; 138146a4e4e6SStefan Hajnoczi } 1382fc01f7e7Sbellard 138319cb3738Sbellard /* return 0 as number of sectors if no device present or error */ 138496b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 1385fc01f7e7Sbellard { 138619cb3738Sbellard int64_t length; 138719cb3738Sbellard length = bdrv_getlength(bs); 138819cb3738Sbellard if (length < 0) 138919cb3738Sbellard length = 0; 139019cb3738Sbellard else 13916ea44308SJan Kiszka length = length >> BDRV_SECTOR_BITS; 139219cb3738Sbellard *nb_sectors_ptr = length; 1393fc01f7e7Sbellard } 1394cf98951bSbellard 1395f3d54fc4Saliguori struct partition { 1396f3d54fc4Saliguori uint8_t boot_ind; /* 0x80 - active */ 1397f3d54fc4Saliguori uint8_t head; /* starting head */ 1398f3d54fc4Saliguori uint8_t sector; /* starting sector */ 1399f3d54fc4Saliguori uint8_t cyl; /* starting cylinder */ 1400f3d54fc4Saliguori uint8_t sys_ind; /* What partition type */ 1401f3d54fc4Saliguori uint8_t end_head; /* end head */ 1402f3d54fc4Saliguori uint8_t end_sector; /* end sector */ 1403f3d54fc4Saliguori uint8_t end_cyl; /* end cylinder */ 1404f3d54fc4Saliguori uint32_t start_sect; /* starting sector counting from 0 */ 1405f3d54fc4Saliguori uint32_t nr_sects; /* nr of sectors in partition */ 1406541dc0d4SStefan Weil } QEMU_PACKED; 1407f3d54fc4Saliguori 1408f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 1409f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs, 1410f3d54fc4Saliguori int *pcylinders, int *pheads, int *psectors) 1411f3d54fc4Saliguori { 1412eb5a3165SJes Sorensen uint8_t buf[BDRV_SECTOR_SIZE]; 1413f3d54fc4Saliguori int ret, i, heads, sectors, cylinders; 1414f3d54fc4Saliguori struct partition *p; 1415f3d54fc4Saliguori uint32_t nr_sects; 1416a38131b6Sblueswir1 uint64_t nb_sectors; 1417f3d54fc4Saliguori 1418f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1419f3d54fc4Saliguori 1420f3d54fc4Saliguori ret = bdrv_read(bs, 0, buf, 1); 1421f3d54fc4Saliguori if (ret < 0) 1422f3d54fc4Saliguori return -1; 1423f3d54fc4Saliguori /* test msdos magic */ 1424f3d54fc4Saliguori if (buf[510] != 0x55 || buf[511] != 0xaa) 1425f3d54fc4Saliguori return -1; 1426f3d54fc4Saliguori for(i = 0; i < 4; i++) { 1427f3d54fc4Saliguori p = ((struct partition *)(buf + 0x1be)) + i; 1428f3d54fc4Saliguori nr_sects = le32_to_cpu(p->nr_sects); 1429f3d54fc4Saliguori if (nr_sects && p->end_head) { 1430f3d54fc4Saliguori /* We make the assumption that the partition terminates on 1431f3d54fc4Saliguori a cylinder boundary */ 1432f3d54fc4Saliguori heads = p->end_head + 1; 1433f3d54fc4Saliguori sectors = p->end_sector & 63; 1434f3d54fc4Saliguori if (sectors == 0) 1435f3d54fc4Saliguori continue; 1436f3d54fc4Saliguori cylinders = nb_sectors / (heads * sectors); 1437f3d54fc4Saliguori if (cylinders < 1 || cylinders > 16383) 1438f3d54fc4Saliguori continue; 1439f3d54fc4Saliguori *pheads = heads; 1440f3d54fc4Saliguori *psectors = sectors; 1441f3d54fc4Saliguori *pcylinders = cylinders; 1442f3d54fc4Saliguori #if 0 1443f3d54fc4Saliguori printf("guessed geometry: LCHS=%d %d %d\n", 1444f3d54fc4Saliguori cylinders, heads, sectors); 1445f3d54fc4Saliguori #endif 1446f3d54fc4Saliguori return 0; 1447f3d54fc4Saliguori } 1448f3d54fc4Saliguori } 1449f3d54fc4Saliguori return -1; 1450f3d54fc4Saliguori } 1451f3d54fc4Saliguori 1452f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 1453f3d54fc4Saliguori { 1454f3d54fc4Saliguori int translation, lba_detected = 0; 1455f3d54fc4Saliguori int cylinders, heads, secs; 1456a38131b6Sblueswir1 uint64_t nb_sectors; 1457f3d54fc4Saliguori 1458f3d54fc4Saliguori /* if a geometry hint is available, use it */ 1459f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1460f3d54fc4Saliguori bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 1461f3d54fc4Saliguori translation = bdrv_get_translation_hint(bs); 1462f3d54fc4Saliguori if (cylinders != 0) { 1463f3d54fc4Saliguori *pcyls = cylinders; 1464f3d54fc4Saliguori *pheads = heads; 1465f3d54fc4Saliguori *psecs = secs; 1466f3d54fc4Saliguori } else { 1467f3d54fc4Saliguori if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 1468f3d54fc4Saliguori if (heads > 16) { 1469f3d54fc4Saliguori /* if heads > 16, it means that a BIOS LBA 1470f3d54fc4Saliguori translation was active, so the default 1471f3d54fc4Saliguori hardware geometry is OK */ 1472f3d54fc4Saliguori lba_detected = 1; 1473f3d54fc4Saliguori goto default_geometry; 1474f3d54fc4Saliguori } else { 1475f3d54fc4Saliguori *pcyls = cylinders; 1476f3d54fc4Saliguori *pheads = heads; 1477f3d54fc4Saliguori *psecs = secs; 1478f3d54fc4Saliguori /* disable any translation to be in sync with 1479f3d54fc4Saliguori the logical geometry */ 1480f3d54fc4Saliguori if (translation == BIOS_ATA_TRANSLATION_AUTO) { 1481f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1482f3d54fc4Saliguori BIOS_ATA_TRANSLATION_NONE); 1483f3d54fc4Saliguori } 1484f3d54fc4Saliguori } 1485f3d54fc4Saliguori } else { 1486f3d54fc4Saliguori default_geometry: 1487f3d54fc4Saliguori /* if no geometry, use a standard physical disk geometry */ 1488f3d54fc4Saliguori cylinders = nb_sectors / (16 * 63); 1489f3d54fc4Saliguori 1490f3d54fc4Saliguori if (cylinders > 16383) 1491f3d54fc4Saliguori cylinders = 16383; 1492f3d54fc4Saliguori else if (cylinders < 2) 1493f3d54fc4Saliguori cylinders = 2; 1494f3d54fc4Saliguori *pcyls = cylinders; 1495f3d54fc4Saliguori *pheads = 16; 1496f3d54fc4Saliguori *psecs = 63; 1497f3d54fc4Saliguori if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 1498f3d54fc4Saliguori if ((*pcyls * *pheads) <= 131072) { 1499f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1500f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LARGE); 1501f3d54fc4Saliguori } else { 1502f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1503f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LBA); 1504f3d54fc4Saliguori } 1505f3d54fc4Saliguori } 1506f3d54fc4Saliguori } 1507f3d54fc4Saliguori bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 1508f3d54fc4Saliguori } 1509f3d54fc4Saliguori } 1510f3d54fc4Saliguori 1511b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs, 1512b338082bSbellard int cyls, int heads, int secs) 1513b338082bSbellard { 1514b338082bSbellard bs->cyls = cyls; 1515b338082bSbellard bs->heads = heads; 1516b338082bSbellard bs->secs = secs; 1517b338082bSbellard } 1518b338082bSbellard 151946d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 152046d4767dSbellard { 152146d4767dSbellard bs->translation = translation; 152246d4767dSbellard } 152346d4767dSbellard 1524b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs, 1525b338082bSbellard int *pcyls, int *pheads, int *psecs) 1526b338082bSbellard { 1527b338082bSbellard *pcyls = bs->cyls; 1528b338082bSbellard *pheads = bs->heads; 1529b338082bSbellard *psecs = bs->secs; 1530b338082bSbellard } 1531b338082bSbellard 15325bbdbb46SBlue Swirl /* Recognize floppy formats */ 15335bbdbb46SBlue Swirl typedef struct FDFormat { 15345bbdbb46SBlue Swirl FDriveType drive; 15355bbdbb46SBlue Swirl uint8_t last_sect; 15365bbdbb46SBlue Swirl uint8_t max_track; 15375bbdbb46SBlue Swirl uint8_t max_head; 15385bbdbb46SBlue Swirl } FDFormat; 15395bbdbb46SBlue Swirl 15405bbdbb46SBlue Swirl static const FDFormat fd_formats[] = { 15415bbdbb46SBlue Swirl /* First entry is default format */ 15425bbdbb46SBlue Swirl /* 1.44 MB 3"1/2 floppy disks */ 15435bbdbb46SBlue Swirl { FDRIVE_DRV_144, 18, 80, 1, }, 15445bbdbb46SBlue Swirl { FDRIVE_DRV_144, 20, 80, 1, }, 15455bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 80, 1, }, 15465bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 82, 1, }, 15475bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 83, 1, }, 15485bbdbb46SBlue Swirl { FDRIVE_DRV_144, 22, 80, 1, }, 15495bbdbb46SBlue Swirl { FDRIVE_DRV_144, 23, 80, 1, }, 15505bbdbb46SBlue Swirl { FDRIVE_DRV_144, 24, 80, 1, }, 15515bbdbb46SBlue Swirl /* 2.88 MB 3"1/2 floppy disks */ 15525bbdbb46SBlue Swirl { FDRIVE_DRV_288, 36, 80, 1, }, 15535bbdbb46SBlue Swirl { FDRIVE_DRV_288, 39, 80, 1, }, 15545bbdbb46SBlue Swirl { FDRIVE_DRV_288, 40, 80, 1, }, 15555bbdbb46SBlue Swirl { FDRIVE_DRV_288, 44, 80, 1, }, 15565bbdbb46SBlue Swirl { FDRIVE_DRV_288, 48, 80, 1, }, 15575bbdbb46SBlue Swirl /* 720 kB 3"1/2 floppy disks */ 15585bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 1, }, 15595bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 80, 1, }, 15605bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 82, 1, }, 15615bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 83, 1, }, 15625bbdbb46SBlue Swirl { FDRIVE_DRV_144, 13, 80, 1, }, 15635bbdbb46SBlue Swirl { FDRIVE_DRV_144, 14, 80, 1, }, 15645bbdbb46SBlue Swirl /* 1.2 MB 5"1/4 floppy disks */ 15655bbdbb46SBlue Swirl { FDRIVE_DRV_120, 15, 80, 1, }, 15665bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 80, 1, }, 15675bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 82, 1, }, 15685bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 83, 1, }, 15695bbdbb46SBlue Swirl { FDRIVE_DRV_120, 20, 80, 1, }, 15705bbdbb46SBlue Swirl /* 720 kB 5"1/4 floppy disks */ 15715bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 80, 1, }, 15725bbdbb46SBlue Swirl { FDRIVE_DRV_120, 11, 80, 1, }, 15735bbdbb46SBlue Swirl /* 360 kB 5"1/4 floppy disks */ 15745bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 1, }, 15755bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 0, }, 15765bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 41, 1, }, 15775bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 42, 1, }, 15785bbdbb46SBlue Swirl /* 320 kB 5"1/4 floppy disks */ 15795bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 1, }, 15805bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 0, }, 15815bbdbb46SBlue Swirl /* 360 kB must match 5"1/4 better than 3"1/2... */ 15825bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 0, }, 15835bbdbb46SBlue Swirl /* end */ 15845bbdbb46SBlue Swirl { FDRIVE_DRV_NONE, -1, -1, 0, }, 15855bbdbb46SBlue Swirl }; 15865bbdbb46SBlue Swirl 15875bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, 15885bbdbb46SBlue Swirl int *max_track, int *last_sect, 15895bbdbb46SBlue Swirl FDriveType drive_in, FDriveType *drive) 15905bbdbb46SBlue Swirl { 15915bbdbb46SBlue Swirl const FDFormat *parse; 15925bbdbb46SBlue Swirl uint64_t nb_sectors, size; 15935bbdbb46SBlue Swirl int i, first_match, match; 15945bbdbb46SBlue Swirl 15955bbdbb46SBlue Swirl bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect); 15965bbdbb46SBlue Swirl if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) { 15975bbdbb46SBlue Swirl /* User defined disk */ 15985bbdbb46SBlue Swirl } else { 15995bbdbb46SBlue Swirl bdrv_get_geometry(bs, &nb_sectors); 16005bbdbb46SBlue Swirl match = -1; 16015bbdbb46SBlue Swirl first_match = -1; 16025bbdbb46SBlue Swirl for (i = 0; ; i++) { 16035bbdbb46SBlue Swirl parse = &fd_formats[i]; 16045bbdbb46SBlue Swirl if (parse->drive == FDRIVE_DRV_NONE) { 16055bbdbb46SBlue Swirl break; 16065bbdbb46SBlue Swirl } 16075bbdbb46SBlue Swirl if (drive_in == parse->drive || 16085bbdbb46SBlue Swirl drive_in == FDRIVE_DRV_NONE) { 16095bbdbb46SBlue Swirl size = (parse->max_head + 1) * parse->max_track * 16105bbdbb46SBlue Swirl parse->last_sect; 16115bbdbb46SBlue Swirl if (nb_sectors == size) { 16125bbdbb46SBlue Swirl match = i; 16135bbdbb46SBlue Swirl break; 16145bbdbb46SBlue Swirl } 16155bbdbb46SBlue Swirl if (first_match == -1) { 16165bbdbb46SBlue Swirl first_match = i; 16175bbdbb46SBlue Swirl } 16185bbdbb46SBlue Swirl } 16195bbdbb46SBlue Swirl } 16205bbdbb46SBlue Swirl if (match == -1) { 16215bbdbb46SBlue Swirl if (first_match == -1) { 16225bbdbb46SBlue Swirl match = 1; 16235bbdbb46SBlue Swirl } else { 16245bbdbb46SBlue Swirl match = first_match; 16255bbdbb46SBlue Swirl } 16265bbdbb46SBlue Swirl parse = &fd_formats[match]; 16275bbdbb46SBlue Swirl } 16285bbdbb46SBlue Swirl *nb_heads = parse->max_head + 1; 16295bbdbb46SBlue Swirl *max_track = parse->max_track; 16305bbdbb46SBlue Swirl *last_sect = parse->last_sect; 16315bbdbb46SBlue Swirl *drive = parse->drive; 16325bbdbb46SBlue Swirl } 16335bbdbb46SBlue Swirl } 16345bbdbb46SBlue Swirl 163546d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs) 163646d4767dSbellard { 163746d4767dSbellard return bs->translation; 163846d4767dSbellard } 163946d4767dSbellard 1640abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error, 1641abd7f68dSMarkus Armbruster BlockErrorAction on_write_error) 1642abd7f68dSMarkus Armbruster { 1643abd7f68dSMarkus Armbruster bs->on_read_error = on_read_error; 1644abd7f68dSMarkus Armbruster bs->on_write_error = on_write_error; 1645abd7f68dSMarkus Armbruster } 1646abd7f68dSMarkus Armbruster 1647abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read) 1648abd7f68dSMarkus Armbruster { 1649abd7f68dSMarkus Armbruster return is_read ? bs->on_read_error : bs->on_write_error; 1650abd7f68dSMarkus Armbruster } 1651abd7f68dSMarkus Armbruster 1652b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs) 1653b338082bSbellard { 1654b338082bSbellard return bs->read_only; 1655b338082bSbellard } 1656b338082bSbellard 1657985a03b0Sths int bdrv_is_sg(BlockDriverState *bs) 1658985a03b0Sths { 1659985a03b0Sths return bs->sg; 1660985a03b0Sths } 1661985a03b0Sths 1662e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs) 1663e900a7b7SChristoph Hellwig { 1664e900a7b7SChristoph Hellwig return bs->enable_write_cache; 1665e900a7b7SChristoph Hellwig } 1666e900a7b7SChristoph Hellwig 1667ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs) 1668ea2384d3Sbellard { 1669ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) 1670ea2384d3Sbellard return 1; 1671ea2384d3Sbellard return bs->encrypted; 1672ea2384d3Sbellard } 1673ea2384d3Sbellard 1674c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs) 1675c0f4ce77Saliguori { 1676c0f4ce77Saliguori BlockDriverState *backing_hd = bs->backing_hd; 1677c0f4ce77Saliguori 1678c0f4ce77Saliguori if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 1679c0f4ce77Saliguori return 1; 1680c0f4ce77Saliguori return (bs->encrypted && !bs->valid_key); 1681c0f4ce77Saliguori } 1682c0f4ce77Saliguori 1683ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key) 1684ea2384d3Sbellard { 1685ea2384d3Sbellard int ret; 1686ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) { 1687ea2384d3Sbellard ret = bdrv_set_key(bs->backing_hd, key); 1688ea2384d3Sbellard if (ret < 0) 1689ea2384d3Sbellard return ret; 1690ea2384d3Sbellard if (!bs->encrypted) 1691ea2384d3Sbellard return 0; 1692ea2384d3Sbellard } 1693fd04a2aeSShahar Havivi if (!bs->encrypted) { 1694fd04a2aeSShahar Havivi return -EINVAL; 1695fd04a2aeSShahar Havivi } else if (!bs->drv || !bs->drv->bdrv_set_key) { 1696fd04a2aeSShahar Havivi return -ENOMEDIUM; 1697fd04a2aeSShahar Havivi } 1698c0f4ce77Saliguori ret = bs->drv->bdrv_set_key(bs, key); 1699bb5fc20fSaliguori if (ret < 0) { 1700bb5fc20fSaliguori bs->valid_key = 0; 1701bb5fc20fSaliguori } else if (!bs->valid_key) { 1702bb5fc20fSaliguori bs->valid_key = 1; 1703bb5fc20fSaliguori /* call the change callback now, we skipped it on open */ 17047d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 1705bb5fc20fSaliguori } 1706c0f4ce77Saliguori return ret; 1707ea2384d3Sbellard } 1708ea2384d3Sbellard 1709ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 1710ea2384d3Sbellard { 171119cb3738Sbellard if (!bs->drv) { 1712ea2384d3Sbellard buf[0] = '\0'; 1713ea2384d3Sbellard } else { 1714ea2384d3Sbellard pstrcpy(buf, buf_size, bs->drv->format_name); 1715ea2384d3Sbellard } 1716ea2384d3Sbellard } 1717ea2384d3Sbellard 1718ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 1719ea2384d3Sbellard void *opaque) 1720ea2384d3Sbellard { 1721ea2384d3Sbellard BlockDriver *drv; 1722ea2384d3Sbellard 17238a22f02aSStefan Hajnoczi QLIST_FOREACH(drv, &bdrv_drivers, list) { 1724ea2384d3Sbellard it(opaque, drv->format_name); 1725ea2384d3Sbellard } 1726ea2384d3Sbellard } 1727ea2384d3Sbellard 1728b338082bSbellard BlockDriverState *bdrv_find(const char *name) 1729b338082bSbellard { 1730b338082bSbellard BlockDriverState *bs; 1731b338082bSbellard 17321b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 17331b7bdbc1SStefan Hajnoczi if (!strcmp(name, bs->device_name)) { 1734b338082bSbellard return bs; 1735b338082bSbellard } 17361b7bdbc1SStefan Hajnoczi } 1737b338082bSbellard return NULL; 1738b338082bSbellard } 1739b338082bSbellard 17402f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs) 17412f399b0aSMarkus Armbruster { 17422f399b0aSMarkus Armbruster if (!bs) { 17432f399b0aSMarkus Armbruster return QTAILQ_FIRST(&bdrv_states); 17442f399b0aSMarkus Armbruster } 17452f399b0aSMarkus Armbruster return QTAILQ_NEXT(bs, list); 17462f399b0aSMarkus Armbruster } 17472f399b0aSMarkus Armbruster 174851de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 174981d0912dSbellard { 175081d0912dSbellard BlockDriverState *bs; 175181d0912dSbellard 17521b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 175351de9760Saliguori it(opaque, bs); 175481d0912dSbellard } 175581d0912dSbellard } 175681d0912dSbellard 1757ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs) 1758ea2384d3Sbellard { 1759ea2384d3Sbellard return bs->device_name; 1760ea2384d3Sbellard } 1761ea2384d3Sbellard 1762205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs) 17637a6cba61Spbrook { 1764016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 1765205ef796SKevin Wolf return 0; 1766016f5cf6SAlexander Graf } 1767016f5cf6SAlexander Graf 1768e7a8a783SKevin Wolf if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) { 1769e7a8a783SKevin Wolf return bdrv_co_flush_em(bs); 1770e7a8a783SKevin Wolf } 1771e7a8a783SKevin Wolf 1772205ef796SKevin Wolf if (bs->drv && bs->drv->bdrv_flush) { 1773205ef796SKevin Wolf return bs->drv->bdrv_flush(bs); 1774205ef796SKevin Wolf } 1775205ef796SKevin Wolf 1776205ef796SKevin Wolf /* 1777205ef796SKevin Wolf * Some block drivers always operate in either writethrough or unsafe mode 1778205ef796SKevin Wolf * and don't support bdrv_flush therefore. Usually qemu doesn't know how 1779205ef796SKevin Wolf * the server works (because the behaviour is hardcoded or depends on 1780205ef796SKevin Wolf * server-side configuration), so we can't ensure that everything is safe 1781205ef796SKevin Wolf * on disk. Returning an error doesn't work because that would break guests 1782205ef796SKevin Wolf * even if the server operates in writethrough mode. 1783205ef796SKevin Wolf * 1784205ef796SKevin Wolf * Let's hope the user knows what he's doing. 1785205ef796SKevin Wolf */ 1786205ef796SKevin Wolf return 0; 17877a6cba61Spbrook } 17887a6cba61Spbrook 1789c6ca28d6Saliguori void bdrv_flush_all(void) 1790c6ca28d6Saliguori { 1791c6ca28d6Saliguori BlockDriverState *bs; 1792c6ca28d6Saliguori 17931b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1794c602a489SMarkus Armbruster if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) { 1795c6ca28d6Saliguori bdrv_flush(bs); 1796c6ca28d6Saliguori } 17971b7bdbc1SStefan Hajnoczi } 17981b7bdbc1SStefan Hajnoczi } 1799c6ca28d6Saliguori 1800f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs) 1801f2feebbdSKevin Wolf { 1802f2feebbdSKevin Wolf assert(bs->drv); 1803f2feebbdSKevin Wolf 1804336c1c12SKevin Wolf if (bs->drv->bdrv_has_zero_init) { 1805336c1c12SKevin Wolf return bs->drv->bdrv_has_zero_init(bs); 1806f2feebbdSKevin Wolf } 1807f2feebbdSKevin Wolf 1808f2feebbdSKevin Wolf return 1; 1809f2feebbdSKevin Wolf } 1810f2feebbdSKevin Wolf 1811bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) 1812bb8bf76fSChristoph Hellwig { 1813bb8bf76fSChristoph Hellwig if (!bs->drv) { 1814bb8bf76fSChristoph Hellwig return -ENOMEDIUM; 1815bb8bf76fSChristoph Hellwig } 1816bb8bf76fSChristoph Hellwig if (!bs->drv->bdrv_discard) { 1817bb8bf76fSChristoph Hellwig return 0; 1818bb8bf76fSChristoph Hellwig } 1819bb8bf76fSChristoph Hellwig return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); 1820bb8bf76fSChristoph Hellwig } 1821bb8bf76fSChristoph Hellwig 1822f58c7b35Sths /* 1823f58c7b35Sths * Returns true iff the specified sector is present in the disk image. Drivers 1824f58c7b35Sths * not implementing the functionality are assumed to not support backing files, 1825f58c7b35Sths * hence all their sectors are reported as allocated. 1826f58c7b35Sths * 1827f58c7b35Sths * 'pnum' is set to the number of sectors (including and immediately following 1828f58c7b35Sths * the specified sector) that are known to be in the same 1829f58c7b35Sths * allocated/unallocated state. 1830f58c7b35Sths * 1831f58c7b35Sths * 'nb_sectors' is the max value 'pnum' should be set to. 1832f58c7b35Sths */ 1833f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1834f58c7b35Sths int *pnum) 1835f58c7b35Sths { 1836f58c7b35Sths int64_t n; 1837f58c7b35Sths if (!bs->drv->bdrv_is_allocated) { 1838f58c7b35Sths if (sector_num >= bs->total_sectors) { 1839f58c7b35Sths *pnum = 0; 1840f58c7b35Sths return 0; 1841f58c7b35Sths } 1842f58c7b35Sths n = bs->total_sectors - sector_num; 1843f58c7b35Sths *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1844f58c7b35Sths return 1; 1845f58c7b35Sths } 1846f58c7b35Sths return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1847f58c7b35Sths } 1848f58c7b35Sths 18492582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv, 18502582bfedSLuiz Capitulino BlockMonEventAction action, int is_read) 18512582bfedSLuiz Capitulino { 18522582bfedSLuiz Capitulino QObject *data; 18532582bfedSLuiz Capitulino const char *action_str; 18542582bfedSLuiz Capitulino 18552582bfedSLuiz Capitulino switch (action) { 18562582bfedSLuiz Capitulino case BDRV_ACTION_REPORT: 18572582bfedSLuiz Capitulino action_str = "report"; 18582582bfedSLuiz Capitulino break; 18592582bfedSLuiz Capitulino case BDRV_ACTION_IGNORE: 18602582bfedSLuiz Capitulino action_str = "ignore"; 18612582bfedSLuiz Capitulino break; 18622582bfedSLuiz Capitulino case BDRV_ACTION_STOP: 18632582bfedSLuiz Capitulino action_str = "stop"; 18642582bfedSLuiz Capitulino break; 18652582bfedSLuiz Capitulino default: 18662582bfedSLuiz Capitulino abort(); 18672582bfedSLuiz Capitulino } 18682582bfedSLuiz Capitulino 18692582bfedSLuiz Capitulino data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", 18702582bfedSLuiz Capitulino bdrv->device_name, 18712582bfedSLuiz Capitulino action_str, 18722582bfedSLuiz Capitulino is_read ? "read" : "write"); 18732582bfedSLuiz Capitulino monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data); 18742582bfedSLuiz Capitulino 18752582bfedSLuiz Capitulino qobject_decref(data); 18762582bfedSLuiz Capitulino } 18772582bfedSLuiz Capitulino 1878d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque) 1879b338082bSbellard { 1880d15e5465SLuiz Capitulino QDict *bs_dict; 1881d15e5465SLuiz Capitulino Monitor *mon = opaque; 1882b338082bSbellard 1883d15e5465SLuiz Capitulino bs_dict = qobject_to_qdict(obj); 1884d15e5465SLuiz Capitulino 1885d8aeeb31SMarkus Armbruster monitor_printf(mon, "%s: removable=%d", 1886d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "device"), 1887d15e5465SLuiz Capitulino qdict_get_bool(bs_dict, "removable")); 1888d15e5465SLuiz Capitulino 1889d15e5465SLuiz Capitulino if (qdict_get_bool(bs_dict, "removable")) { 1890d15e5465SLuiz Capitulino monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); 1891e4def80bSMarkus Armbruster monitor_printf(mon, " tray-open=%d", 1892e4def80bSMarkus Armbruster qdict_get_bool(bs_dict, "tray-open")); 1893b338082bSbellard } 1894d2078cc2SLuiz Capitulino 1895d2078cc2SLuiz Capitulino if (qdict_haskey(bs_dict, "io-status")) { 1896d2078cc2SLuiz Capitulino monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status")); 1897d2078cc2SLuiz Capitulino } 1898d2078cc2SLuiz Capitulino 1899d15e5465SLuiz Capitulino if (qdict_haskey(bs_dict, "inserted")) { 1900d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); 1901d15e5465SLuiz Capitulino 1902376253ecSaliguori monitor_printf(mon, " file="); 1903d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "file")); 1904d15e5465SLuiz Capitulino if (qdict_haskey(qdict, "backing_file")) { 1905376253ecSaliguori monitor_printf(mon, " backing_file="); 1906d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); 1907fef30743Sths } 1908d15e5465SLuiz Capitulino monitor_printf(mon, " ro=%d drv=%s encrypted=%d", 1909d15e5465SLuiz Capitulino qdict_get_bool(qdict, "ro"), 1910d15e5465SLuiz Capitulino qdict_get_str(qdict, "drv"), 1911d15e5465SLuiz Capitulino qdict_get_bool(qdict, "encrypted")); 1912b338082bSbellard } else { 1913376253ecSaliguori monitor_printf(mon, " [not inserted]"); 1914b338082bSbellard } 1915d15e5465SLuiz Capitulino 1916376253ecSaliguori monitor_printf(mon, "\n"); 1917b338082bSbellard } 1918d15e5465SLuiz Capitulino 1919d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data) 1920d15e5465SLuiz Capitulino { 1921d15e5465SLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); 1922d15e5465SLuiz Capitulino } 1923d15e5465SLuiz Capitulino 1924f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = { 1925f04ef601SLuiz Capitulino [BDRV_IOS_OK] = "ok", 1926f04ef601SLuiz Capitulino [BDRV_IOS_FAILED] = "failed", 1927f04ef601SLuiz Capitulino [BDRV_IOS_ENOSPC] = "nospace", 1928f04ef601SLuiz Capitulino }; 1929f04ef601SLuiz Capitulino 1930d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data) 1931d15e5465SLuiz Capitulino { 1932d15e5465SLuiz Capitulino QList *bs_list; 1933d15e5465SLuiz Capitulino BlockDriverState *bs; 1934d15e5465SLuiz Capitulino 1935d15e5465SLuiz Capitulino bs_list = qlist_new(); 1936d15e5465SLuiz Capitulino 19371b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1938d15e5465SLuiz Capitulino QObject *bs_obj; 1939e4def80bSMarkus Armbruster QDict *bs_dict; 1940d15e5465SLuiz Capitulino 1941d8aeeb31SMarkus Armbruster bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', " 1942d15e5465SLuiz Capitulino "'removable': %i, 'locked': %i }", 19432c6942faSMarkus Armbruster bs->device_name, 19442c6942faSMarkus Armbruster bdrv_dev_has_removable_media(bs), 1945f107639aSMarkus Armbruster bdrv_dev_is_medium_locked(bs)); 1946e4def80bSMarkus Armbruster bs_dict = qobject_to_qdict(bs_obj); 1947d15e5465SLuiz Capitulino 1948e4def80bSMarkus Armbruster if (bdrv_dev_has_removable_media(bs)) { 1949e4def80bSMarkus Armbruster qdict_put(bs_dict, "tray-open", 1950e4def80bSMarkus Armbruster qbool_from_int(bdrv_dev_is_tray_open(bs))); 1951e4def80bSMarkus Armbruster } 1952f04ef601SLuiz Capitulino 1953f04ef601SLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 1954f04ef601SLuiz Capitulino qdict_put(bs_dict, "io-status", 1955f04ef601SLuiz Capitulino qstring_from_str(io_status_name[bs->iostatus])); 1956f04ef601SLuiz Capitulino } 1957f04ef601SLuiz Capitulino 1958d15e5465SLuiz Capitulino if (bs->drv) { 1959d15e5465SLuiz Capitulino QObject *obj; 1960d15e5465SLuiz Capitulino 1961d15e5465SLuiz Capitulino obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " 1962d15e5465SLuiz Capitulino "'encrypted': %i }", 1963d15e5465SLuiz Capitulino bs->filename, bs->read_only, 1964d15e5465SLuiz Capitulino bs->drv->format_name, 1965d15e5465SLuiz Capitulino bdrv_is_encrypted(bs)); 1966d15e5465SLuiz Capitulino if (bs->backing_file[0] != '\0') { 1967d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(obj); 1968d15e5465SLuiz Capitulino qdict_put(qdict, "backing_file", 1969d15e5465SLuiz Capitulino qstring_from_str(bs->backing_file)); 1970d15e5465SLuiz Capitulino } 1971d15e5465SLuiz Capitulino 1972d15e5465SLuiz Capitulino qdict_put_obj(bs_dict, "inserted", obj); 1973d15e5465SLuiz Capitulino } 1974d15e5465SLuiz Capitulino qlist_append_obj(bs_list, bs_obj); 1975d15e5465SLuiz Capitulino } 1976d15e5465SLuiz Capitulino 1977d15e5465SLuiz Capitulino *ret_data = QOBJECT(bs_list); 1978b338082bSbellard } 1979a36e69ddSths 1980218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque) 1981a36e69ddSths { 1982218a536aSLuiz Capitulino QDict *qdict; 1983218a536aSLuiz Capitulino Monitor *mon = opaque; 1984218a536aSLuiz Capitulino 1985218a536aSLuiz Capitulino qdict = qobject_to_qdict(data); 1986218a536aSLuiz Capitulino monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 1987218a536aSLuiz Capitulino 1988218a536aSLuiz Capitulino qdict = qobject_to_qdict(qdict_get(qdict, "stats")); 1989218a536aSLuiz Capitulino monitor_printf(mon, " rd_bytes=%" PRId64 1990218a536aSLuiz Capitulino " wr_bytes=%" PRId64 1991218a536aSLuiz Capitulino " rd_operations=%" PRId64 1992218a536aSLuiz Capitulino " wr_operations=%" PRId64 1993e8045d67SChristoph Hellwig " flush_operations=%" PRId64 1994c488c7f6SChristoph Hellwig " wr_total_time_ns=%" PRId64 1995c488c7f6SChristoph Hellwig " rd_total_time_ns=%" PRId64 1996c488c7f6SChristoph Hellwig " flush_total_time_ns=%" PRId64 1997218a536aSLuiz Capitulino "\n", 1998218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_bytes"), 1999218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_bytes"), 2000218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_operations"), 2001e8045d67SChristoph Hellwig qdict_get_int(qdict, "wr_operations"), 2002c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_operations"), 2003c488c7f6SChristoph Hellwig qdict_get_int(qdict, "wr_total_time_ns"), 2004c488c7f6SChristoph Hellwig qdict_get_int(qdict, "rd_total_time_ns"), 2005c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_total_time_ns")); 2006218a536aSLuiz Capitulino } 2007218a536aSLuiz Capitulino 2008218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data) 2009218a536aSLuiz Capitulino { 2010218a536aSLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); 2011218a536aSLuiz Capitulino } 2012218a536aSLuiz Capitulino 2013294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs) 2014294cc35fSKevin Wolf { 2015294cc35fSKevin Wolf QObject *res; 2016294cc35fSKevin Wolf QDict *dict; 2017294cc35fSKevin Wolf 2018294cc35fSKevin Wolf res = qobject_from_jsonf("{ 'stats': {" 2019294cc35fSKevin Wolf "'rd_bytes': %" PRId64 "," 2020294cc35fSKevin Wolf "'wr_bytes': %" PRId64 "," 2021294cc35fSKevin Wolf "'rd_operations': %" PRId64 "," 2022294cc35fSKevin Wolf "'wr_operations': %" PRId64 "," 2023e8045d67SChristoph Hellwig "'wr_highest_offset': %" PRId64 "," 2024c488c7f6SChristoph Hellwig "'flush_operations': %" PRId64 "," 2025c488c7f6SChristoph Hellwig "'wr_total_time_ns': %" PRId64 "," 2026c488c7f6SChristoph Hellwig "'rd_total_time_ns': %" PRId64 "," 2027c488c7f6SChristoph Hellwig "'flush_total_time_ns': %" PRId64 2028294cc35fSKevin Wolf "} }", 2029a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_READ], 2030a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_WRITE], 2031a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_READ], 2032a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_WRITE], 20335ffbbc67SBlue Swirl bs->wr_highest_sector * 2034e8045d67SChristoph Hellwig (uint64_t)BDRV_SECTOR_SIZE, 2035c488c7f6SChristoph Hellwig bs->nr_ops[BDRV_ACCT_FLUSH], 2036c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_WRITE], 2037c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_READ], 2038c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_FLUSH]); 2039294cc35fSKevin Wolf dict = qobject_to_qdict(res); 2040294cc35fSKevin Wolf 2041294cc35fSKevin Wolf if (*bs->device_name) { 2042294cc35fSKevin Wolf qdict_put(dict, "device", qstring_from_str(bs->device_name)); 2043294cc35fSKevin Wolf } 2044294cc35fSKevin Wolf 2045294cc35fSKevin Wolf if (bs->file) { 2046294cc35fSKevin Wolf QObject *parent = bdrv_info_stats_bs(bs->file); 2047294cc35fSKevin Wolf qdict_put_obj(dict, "parent", parent); 2048294cc35fSKevin Wolf } 2049294cc35fSKevin Wolf 2050294cc35fSKevin Wolf return res; 2051294cc35fSKevin Wolf } 2052294cc35fSKevin Wolf 2053218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data) 2054218a536aSLuiz Capitulino { 2055218a536aSLuiz Capitulino QObject *obj; 2056218a536aSLuiz Capitulino QList *devices; 2057a36e69ddSths BlockDriverState *bs; 2058a36e69ddSths 2059218a536aSLuiz Capitulino devices = qlist_new(); 2060218a536aSLuiz Capitulino 20611b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 2062294cc35fSKevin Wolf obj = bdrv_info_stats_bs(bs); 2063218a536aSLuiz Capitulino qlist_append_obj(devices, obj); 2064a36e69ddSths } 2065218a536aSLuiz Capitulino 2066218a536aSLuiz Capitulino *ret_data = QOBJECT(devices); 2067a36e69ddSths } 2068ea2384d3Sbellard 2069045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs) 2070045df330Saliguori { 2071045df330Saliguori if (bs->backing_hd && bs->backing_hd->encrypted) 2072045df330Saliguori return bs->backing_file; 2073045df330Saliguori else if (bs->encrypted) 2074045df330Saliguori return bs->filename; 2075045df330Saliguori else 2076045df330Saliguori return NULL; 2077045df330Saliguori } 2078045df330Saliguori 207983f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs, 208083f64091Sbellard char *filename, int filename_size) 208183f64091Sbellard { 2082b783e409SKevin Wolf if (!bs->backing_file) { 208383f64091Sbellard pstrcpy(filename, filename_size, ""); 208483f64091Sbellard } else { 208583f64091Sbellard pstrcpy(filename, filename_size, bs->backing_file); 208683f64091Sbellard } 208783f64091Sbellard } 208883f64091Sbellard 2089faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 2090faea38e7Sbellard const uint8_t *buf, int nb_sectors) 2091faea38e7Sbellard { 2092faea38e7Sbellard BlockDriver *drv = bs->drv; 2093faea38e7Sbellard if (!drv) 209419cb3738Sbellard return -ENOMEDIUM; 2095faea38e7Sbellard if (!drv->bdrv_write_compressed) 2096faea38e7Sbellard return -ENOTSUP; 2097fbb7b4e0SKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) 2098fbb7b4e0SKevin Wolf return -EIO; 20997cd1e32aSlirans@il.ibm.com 2100c6d22830SJan Kiszka if (bs->dirty_bitmap) { 21017cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 21027cd1e32aSlirans@il.ibm.com } 21037cd1e32aSlirans@il.ibm.com 2104faea38e7Sbellard return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 2105faea38e7Sbellard } 2106faea38e7Sbellard 2107faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 2108faea38e7Sbellard { 2109faea38e7Sbellard BlockDriver *drv = bs->drv; 2110faea38e7Sbellard if (!drv) 211119cb3738Sbellard return -ENOMEDIUM; 2112faea38e7Sbellard if (!drv->bdrv_get_info) 2113faea38e7Sbellard return -ENOTSUP; 2114faea38e7Sbellard memset(bdi, 0, sizeof(*bdi)); 2115faea38e7Sbellard return drv->bdrv_get_info(bs, bdi); 2116faea38e7Sbellard } 2117faea38e7Sbellard 211845566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 211945566e9cSChristoph Hellwig int64_t pos, int size) 2120178e08a5Saliguori { 2121178e08a5Saliguori BlockDriver *drv = bs->drv; 2122178e08a5Saliguori if (!drv) 2123178e08a5Saliguori return -ENOMEDIUM; 21247cdb1f6dSMORITA Kazutaka if (drv->bdrv_save_vmstate) 212545566e9cSChristoph Hellwig return drv->bdrv_save_vmstate(bs, buf, pos, size); 21267cdb1f6dSMORITA Kazutaka if (bs->file) 21277cdb1f6dSMORITA Kazutaka return bdrv_save_vmstate(bs->file, buf, pos, size); 21287cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2129178e08a5Saliguori } 2130178e08a5Saliguori 213145566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, 213245566e9cSChristoph Hellwig int64_t pos, int size) 2133178e08a5Saliguori { 2134178e08a5Saliguori BlockDriver *drv = bs->drv; 2135178e08a5Saliguori if (!drv) 2136178e08a5Saliguori return -ENOMEDIUM; 21377cdb1f6dSMORITA Kazutaka if (drv->bdrv_load_vmstate) 213845566e9cSChristoph Hellwig return drv->bdrv_load_vmstate(bs, buf, pos, size); 21397cdb1f6dSMORITA Kazutaka if (bs->file) 21407cdb1f6dSMORITA Kazutaka return bdrv_load_vmstate(bs->file, buf, pos, size); 21417cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2142178e08a5Saliguori } 2143178e08a5Saliguori 21448b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) 21458b9b0cc2SKevin Wolf { 21468b9b0cc2SKevin Wolf BlockDriver *drv = bs->drv; 21478b9b0cc2SKevin Wolf 21488b9b0cc2SKevin Wolf if (!drv || !drv->bdrv_debug_event) { 21498b9b0cc2SKevin Wolf return; 21508b9b0cc2SKevin Wolf } 21518b9b0cc2SKevin Wolf 21528b9b0cc2SKevin Wolf return drv->bdrv_debug_event(bs, event); 21538b9b0cc2SKevin Wolf 21548b9b0cc2SKevin Wolf } 21558b9b0cc2SKevin Wolf 2156faea38e7Sbellard /**************************************************************/ 2157faea38e7Sbellard /* handling of snapshots */ 2158faea38e7Sbellard 2159feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs) 2160feeee5acSMiguel Di Ciurcio Filho { 2161feeee5acSMiguel Di Ciurcio Filho BlockDriver *drv = bs->drv; 216207b70bfbSMarkus Armbruster if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { 2163feeee5acSMiguel Di Ciurcio Filho return 0; 2164feeee5acSMiguel Di Ciurcio Filho } 2165feeee5acSMiguel Di Ciurcio Filho 2166feeee5acSMiguel Di Ciurcio Filho if (!drv->bdrv_snapshot_create) { 2167feeee5acSMiguel Di Ciurcio Filho if (bs->file != NULL) { 2168feeee5acSMiguel Di Ciurcio Filho return bdrv_can_snapshot(bs->file); 2169feeee5acSMiguel Di Ciurcio Filho } 2170feeee5acSMiguel Di Ciurcio Filho return 0; 2171feeee5acSMiguel Di Ciurcio Filho } 2172feeee5acSMiguel Di Ciurcio Filho 2173feeee5acSMiguel Di Ciurcio Filho return 1; 2174feeee5acSMiguel Di Ciurcio Filho } 2175feeee5acSMiguel Di Ciurcio Filho 2176199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs) 2177199630b6SBlue Swirl { 2178199630b6SBlue Swirl return !!(bs->open_flags & BDRV_O_SNAPSHOT); 2179199630b6SBlue Swirl } 2180199630b6SBlue Swirl 2181f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void) 2182f9092b10SMarkus Armbruster { 2183f9092b10SMarkus Armbruster BlockDriverState *bs; 2184f9092b10SMarkus Armbruster 21853ac906f7SMarkus Armbruster if (bs_snapshots) { 2186f9092b10SMarkus Armbruster return bs_snapshots; 21873ac906f7SMarkus Armbruster } 2188f9092b10SMarkus Armbruster 2189f9092b10SMarkus Armbruster bs = NULL; 2190f9092b10SMarkus Armbruster while ((bs = bdrv_next(bs))) { 2191f9092b10SMarkus Armbruster if (bdrv_can_snapshot(bs)) { 21923ac906f7SMarkus Armbruster bs_snapshots = bs; 21933ac906f7SMarkus Armbruster return bs; 2194f9092b10SMarkus Armbruster } 2195f9092b10SMarkus Armbruster } 2196f9092b10SMarkus Armbruster return NULL; 2197f9092b10SMarkus Armbruster } 2198f9092b10SMarkus Armbruster 2199faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs, 2200faea38e7Sbellard QEMUSnapshotInfo *sn_info) 2201faea38e7Sbellard { 2202faea38e7Sbellard BlockDriver *drv = bs->drv; 2203faea38e7Sbellard if (!drv) 220419cb3738Sbellard return -ENOMEDIUM; 22057cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_create) 2206faea38e7Sbellard return drv->bdrv_snapshot_create(bs, sn_info); 22077cdb1f6dSMORITA Kazutaka if (bs->file) 22087cdb1f6dSMORITA Kazutaka return bdrv_snapshot_create(bs->file, sn_info); 22097cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2210faea38e7Sbellard } 2211faea38e7Sbellard 2212faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs, 2213faea38e7Sbellard const char *snapshot_id) 2214faea38e7Sbellard { 2215faea38e7Sbellard BlockDriver *drv = bs->drv; 22167cdb1f6dSMORITA Kazutaka int ret, open_ret; 22177cdb1f6dSMORITA Kazutaka 2218faea38e7Sbellard if (!drv) 221919cb3738Sbellard return -ENOMEDIUM; 22207cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_goto) 2221faea38e7Sbellard return drv->bdrv_snapshot_goto(bs, snapshot_id); 22227cdb1f6dSMORITA Kazutaka 22237cdb1f6dSMORITA Kazutaka if (bs->file) { 22247cdb1f6dSMORITA Kazutaka drv->bdrv_close(bs); 22257cdb1f6dSMORITA Kazutaka ret = bdrv_snapshot_goto(bs->file, snapshot_id); 22267cdb1f6dSMORITA Kazutaka open_ret = drv->bdrv_open(bs, bs->open_flags); 22277cdb1f6dSMORITA Kazutaka if (open_ret < 0) { 22287cdb1f6dSMORITA Kazutaka bdrv_delete(bs->file); 22297cdb1f6dSMORITA Kazutaka bs->drv = NULL; 22307cdb1f6dSMORITA Kazutaka return open_ret; 22317cdb1f6dSMORITA Kazutaka } 22327cdb1f6dSMORITA Kazutaka return ret; 22337cdb1f6dSMORITA Kazutaka } 22347cdb1f6dSMORITA Kazutaka 22357cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2236faea38e7Sbellard } 2237faea38e7Sbellard 2238faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 2239faea38e7Sbellard { 2240faea38e7Sbellard BlockDriver *drv = bs->drv; 2241faea38e7Sbellard if (!drv) 224219cb3738Sbellard return -ENOMEDIUM; 22437cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_delete) 2244faea38e7Sbellard return drv->bdrv_snapshot_delete(bs, snapshot_id); 22457cdb1f6dSMORITA Kazutaka if (bs->file) 22467cdb1f6dSMORITA Kazutaka return bdrv_snapshot_delete(bs->file, snapshot_id); 22477cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2248faea38e7Sbellard } 2249faea38e7Sbellard 2250faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs, 2251faea38e7Sbellard QEMUSnapshotInfo **psn_info) 2252faea38e7Sbellard { 2253faea38e7Sbellard BlockDriver *drv = bs->drv; 2254faea38e7Sbellard if (!drv) 225519cb3738Sbellard return -ENOMEDIUM; 22567cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_list) 2257faea38e7Sbellard return drv->bdrv_snapshot_list(bs, psn_info); 22587cdb1f6dSMORITA Kazutaka if (bs->file) 22597cdb1f6dSMORITA Kazutaka return bdrv_snapshot_list(bs->file, psn_info); 22607cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2261faea38e7Sbellard } 2262faea38e7Sbellard 226351ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs, 226451ef6727Sedison const char *snapshot_name) 226551ef6727Sedison { 226651ef6727Sedison BlockDriver *drv = bs->drv; 226751ef6727Sedison if (!drv) { 226851ef6727Sedison return -ENOMEDIUM; 226951ef6727Sedison } 227051ef6727Sedison if (!bs->read_only) { 227151ef6727Sedison return -EINVAL; 227251ef6727Sedison } 227351ef6727Sedison if (drv->bdrv_snapshot_load_tmp) { 227451ef6727Sedison return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); 227551ef6727Sedison } 227651ef6727Sedison return -ENOTSUP; 227751ef6727Sedison } 227851ef6727Sedison 2279faea38e7Sbellard #define NB_SUFFIXES 4 2280faea38e7Sbellard 2281faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size) 2282faea38e7Sbellard { 2283faea38e7Sbellard static const char suffixes[NB_SUFFIXES] = "KMGT"; 2284faea38e7Sbellard int64_t base; 2285faea38e7Sbellard int i; 2286faea38e7Sbellard 2287faea38e7Sbellard if (size <= 999) { 2288faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64, size); 2289faea38e7Sbellard } else { 2290faea38e7Sbellard base = 1024; 2291faea38e7Sbellard for(i = 0; i < NB_SUFFIXES; i++) { 2292faea38e7Sbellard if (size < (10 * base)) { 2293faea38e7Sbellard snprintf(buf, buf_size, "%0.1f%c", 2294faea38e7Sbellard (double)size / base, 2295faea38e7Sbellard suffixes[i]); 2296faea38e7Sbellard break; 2297faea38e7Sbellard } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 2298faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64 "%c", 2299faea38e7Sbellard ((size + (base >> 1)) / base), 2300faea38e7Sbellard suffixes[i]); 2301faea38e7Sbellard break; 2302faea38e7Sbellard } 2303faea38e7Sbellard base = base * 1024; 2304faea38e7Sbellard } 2305faea38e7Sbellard } 2306faea38e7Sbellard return buf; 2307faea38e7Sbellard } 2308faea38e7Sbellard 2309faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 2310faea38e7Sbellard { 2311faea38e7Sbellard char buf1[128], date_buf[128], clock_buf[128]; 23123b9f94e1Sbellard #ifdef _WIN32 23133b9f94e1Sbellard struct tm *ptm; 23143b9f94e1Sbellard #else 2315faea38e7Sbellard struct tm tm; 23163b9f94e1Sbellard #endif 2317faea38e7Sbellard time_t ti; 2318faea38e7Sbellard int64_t secs; 2319faea38e7Sbellard 2320faea38e7Sbellard if (!sn) { 2321faea38e7Sbellard snprintf(buf, buf_size, 2322faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2323faea38e7Sbellard "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 2324faea38e7Sbellard } else { 2325faea38e7Sbellard ti = sn->date_sec; 23263b9f94e1Sbellard #ifdef _WIN32 23273b9f94e1Sbellard ptm = localtime(&ti); 23283b9f94e1Sbellard strftime(date_buf, sizeof(date_buf), 23293b9f94e1Sbellard "%Y-%m-%d %H:%M:%S", ptm); 23303b9f94e1Sbellard #else 2331faea38e7Sbellard localtime_r(&ti, &tm); 2332faea38e7Sbellard strftime(date_buf, sizeof(date_buf), 2333faea38e7Sbellard "%Y-%m-%d %H:%M:%S", &tm); 23343b9f94e1Sbellard #endif 2335faea38e7Sbellard secs = sn->vm_clock_nsec / 1000000000; 2336faea38e7Sbellard snprintf(clock_buf, sizeof(clock_buf), 2337faea38e7Sbellard "%02d:%02d:%02d.%03d", 2338faea38e7Sbellard (int)(secs / 3600), 2339faea38e7Sbellard (int)((secs / 60) % 60), 2340faea38e7Sbellard (int)(secs % 60), 2341faea38e7Sbellard (int)((sn->vm_clock_nsec / 1000000) % 1000)); 2342faea38e7Sbellard snprintf(buf, buf_size, 2343faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2344faea38e7Sbellard sn->id_str, sn->name, 2345faea38e7Sbellard get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 2346faea38e7Sbellard date_buf, 2347faea38e7Sbellard clock_buf); 2348faea38e7Sbellard } 2349faea38e7Sbellard return buf; 2350faea38e7Sbellard } 2351faea38e7Sbellard 2352ea2384d3Sbellard /**************************************************************/ 235383f64091Sbellard /* async I/Os */ 2354ea2384d3Sbellard 23553b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 2356f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 235783f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 2358ea2384d3Sbellard { 2359bbf0a440SStefan Hajnoczi trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); 2360bbf0a440SStefan Hajnoczi 2361b2a61371SStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 23628c5873d6SStefan Hajnoczi cb, opaque, false); 236383f64091Sbellard } 236483f64091Sbellard 2365f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 2366f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 236783f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 23687674e7bfSbellard { 2369bbf0a440SStefan Hajnoczi trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); 2370bbf0a440SStefan Hajnoczi 23711a6e115bSStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 23728c5873d6SStefan Hajnoczi cb, opaque, true); 237383f64091Sbellard } 237483f64091Sbellard 237540b4f539SKevin Wolf 237640b4f539SKevin Wolf typedef struct MultiwriteCB { 237740b4f539SKevin Wolf int error; 237840b4f539SKevin Wolf int num_requests; 237940b4f539SKevin Wolf int num_callbacks; 238040b4f539SKevin Wolf struct { 238140b4f539SKevin Wolf BlockDriverCompletionFunc *cb; 238240b4f539SKevin Wolf void *opaque; 238340b4f539SKevin Wolf QEMUIOVector *free_qiov; 238440b4f539SKevin Wolf void *free_buf; 238540b4f539SKevin Wolf } callbacks[]; 238640b4f539SKevin Wolf } MultiwriteCB; 238740b4f539SKevin Wolf 238840b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb) 238940b4f539SKevin Wolf { 239040b4f539SKevin Wolf int i; 239140b4f539SKevin Wolf 239240b4f539SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 239340b4f539SKevin Wolf mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); 23941e1ea48dSStefan Hajnoczi if (mcb->callbacks[i].free_qiov) { 23951e1ea48dSStefan Hajnoczi qemu_iovec_destroy(mcb->callbacks[i].free_qiov); 23961e1ea48dSStefan Hajnoczi } 23977267c094SAnthony Liguori g_free(mcb->callbacks[i].free_qiov); 2398f8a83245SHerve Poussineau qemu_vfree(mcb->callbacks[i].free_buf); 239940b4f539SKevin Wolf } 240040b4f539SKevin Wolf } 240140b4f539SKevin Wolf 240240b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret) 240340b4f539SKevin Wolf { 240440b4f539SKevin Wolf MultiwriteCB *mcb = opaque; 240540b4f539SKevin Wolf 24066d519a5fSStefan Hajnoczi trace_multiwrite_cb(mcb, ret); 24076d519a5fSStefan Hajnoczi 2408cb6d3ca0SKevin Wolf if (ret < 0 && !mcb->error) { 240940b4f539SKevin Wolf mcb->error = ret; 241040b4f539SKevin Wolf } 241140b4f539SKevin Wolf 241240b4f539SKevin Wolf mcb->num_requests--; 241340b4f539SKevin Wolf if (mcb->num_requests == 0) { 241440b4f539SKevin Wolf multiwrite_user_cb(mcb); 24157267c094SAnthony Liguori g_free(mcb); 241640b4f539SKevin Wolf } 241740b4f539SKevin Wolf } 241840b4f539SKevin Wolf 241940b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b) 242040b4f539SKevin Wolf { 242177be4366SChristoph Hellwig const BlockRequest *req1 = a, *req2 = b; 242277be4366SChristoph Hellwig 242377be4366SChristoph Hellwig /* 242477be4366SChristoph Hellwig * Note that we can't simply subtract req2->sector from req1->sector 242577be4366SChristoph Hellwig * here as that could overflow the return value. 242677be4366SChristoph Hellwig */ 242777be4366SChristoph Hellwig if (req1->sector > req2->sector) { 242877be4366SChristoph Hellwig return 1; 242977be4366SChristoph Hellwig } else if (req1->sector < req2->sector) { 243077be4366SChristoph Hellwig return -1; 243177be4366SChristoph Hellwig } else { 243277be4366SChristoph Hellwig return 0; 243377be4366SChristoph Hellwig } 243440b4f539SKevin Wolf } 243540b4f539SKevin Wolf 243640b4f539SKevin Wolf /* 243740b4f539SKevin Wolf * Takes a bunch of requests and tries to merge them. Returns the number of 243840b4f539SKevin Wolf * requests that remain after merging. 243940b4f539SKevin Wolf */ 244040b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, 244140b4f539SKevin Wolf int num_reqs, MultiwriteCB *mcb) 244240b4f539SKevin Wolf { 244340b4f539SKevin Wolf int i, outidx; 244440b4f539SKevin Wolf 244540b4f539SKevin Wolf // Sort requests by start sector 244640b4f539SKevin Wolf qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); 244740b4f539SKevin Wolf 244840b4f539SKevin Wolf // Check if adjacent requests touch the same clusters. If so, combine them, 244940b4f539SKevin Wolf // filling up gaps with zero sectors. 245040b4f539SKevin Wolf outidx = 0; 245140b4f539SKevin Wolf for (i = 1; i < num_reqs; i++) { 245240b4f539SKevin Wolf int merge = 0; 245340b4f539SKevin Wolf int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; 245440b4f539SKevin Wolf 245540b4f539SKevin Wolf // This handles the cases that are valid for all block drivers, namely 245640b4f539SKevin Wolf // exactly sequential writes and overlapping writes. 245740b4f539SKevin Wolf if (reqs[i].sector <= oldreq_last) { 245840b4f539SKevin Wolf merge = 1; 245940b4f539SKevin Wolf } 246040b4f539SKevin Wolf 246140b4f539SKevin Wolf // The block driver may decide that it makes sense to combine requests 246240b4f539SKevin Wolf // even if there is a gap of some sectors between them. In this case, 246340b4f539SKevin Wolf // the gap is filled with zeros (therefore only applicable for yet 246440b4f539SKevin Wolf // unused space in format like qcow2). 246540b4f539SKevin Wolf if (!merge && bs->drv->bdrv_merge_requests) { 246640b4f539SKevin Wolf merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); 246740b4f539SKevin Wolf } 246840b4f539SKevin Wolf 2469e2a305fbSChristoph Hellwig if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { 2470e2a305fbSChristoph Hellwig merge = 0; 2471e2a305fbSChristoph Hellwig } 2472e2a305fbSChristoph Hellwig 247340b4f539SKevin Wolf if (merge) { 247440b4f539SKevin Wolf size_t size; 24757267c094SAnthony Liguori QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); 247640b4f539SKevin Wolf qemu_iovec_init(qiov, 247740b4f539SKevin Wolf reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); 247840b4f539SKevin Wolf 247940b4f539SKevin Wolf // Add the first request to the merged one. If the requests are 248040b4f539SKevin Wolf // overlapping, drop the last sectors of the first request. 248140b4f539SKevin Wolf size = (reqs[i].sector - reqs[outidx].sector) << 9; 248240b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[outidx].qiov, size); 248340b4f539SKevin Wolf 248440b4f539SKevin Wolf // We might need to add some zeros between the two requests 248540b4f539SKevin Wolf if (reqs[i].sector > oldreq_last) { 248640b4f539SKevin Wolf size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9; 248740b4f539SKevin Wolf uint8_t *buf = qemu_blockalign(bs, zero_bytes); 248840b4f539SKevin Wolf memset(buf, 0, zero_bytes); 248940b4f539SKevin Wolf qemu_iovec_add(qiov, buf, zero_bytes); 249040b4f539SKevin Wolf mcb->callbacks[i].free_buf = buf; 249140b4f539SKevin Wolf } 249240b4f539SKevin Wolf 249340b4f539SKevin Wolf // Add the second request 249440b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size); 249540b4f539SKevin Wolf 2496cbf1dff2SKevin Wolf reqs[outidx].nb_sectors = qiov->size >> 9; 249740b4f539SKevin Wolf reqs[outidx].qiov = qiov; 249840b4f539SKevin Wolf 249940b4f539SKevin Wolf mcb->callbacks[i].free_qiov = reqs[outidx].qiov; 250040b4f539SKevin Wolf } else { 250140b4f539SKevin Wolf outidx++; 250240b4f539SKevin Wolf reqs[outidx].sector = reqs[i].sector; 250340b4f539SKevin Wolf reqs[outidx].nb_sectors = reqs[i].nb_sectors; 250440b4f539SKevin Wolf reqs[outidx].qiov = reqs[i].qiov; 250540b4f539SKevin Wolf } 250640b4f539SKevin Wolf } 250740b4f539SKevin Wolf 250840b4f539SKevin Wolf return outidx + 1; 250940b4f539SKevin Wolf } 251040b4f539SKevin Wolf 251140b4f539SKevin Wolf /* 251240b4f539SKevin Wolf * Submit multiple AIO write requests at once. 251340b4f539SKevin Wolf * 251440b4f539SKevin Wolf * On success, the function returns 0 and all requests in the reqs array have 251540b4f539SKevin Wolf * been submitted. In error case this function returns -1, and any of the 251640b4f539SKevin Wolf * requests may or may not be submitted yet. In particular, this means that the 251740b4f539SKevin Wolf * callback will be called for some of the requests, for others it won't. The 251840b4f539SKevin Wolf * caller must check the error field of the BlockRequest to wait for the right 251940b4f539SKevin Wolf * callbacks (if error != 0, no callback will be called). 252040b4f539SKevin Wolf * 252140b4f539SKevin Wolf * The implementation may modify the contents of the reqs array, e.g. to merge 252240b4f539SKevin Wolf * requests. However, the fields opaque and error are left unmodified as they 252340b4f539SKevin Wolf * are used to signal failure for a single request to the caller. 252440b4f539SKevin Wolf */ 252540b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) 252640b4f539SKevin Wolf { 252740b4f539SKevin Wolf BlockDriverAIOCB *acb; 252840b4f539SKevin Wolf MultiwriteCB *mcb; 252940b4f539SKevin Wolf int i; 253040b4f539SKevin Wolf 2531301db7c2SRyan Harper /* don't submit writes if we don't have a medium */ 2532301db7c2SRyan Harper if (bs->drv == NULL) { 2533301db7c2SRyan Harper for (i = 0; i < num_reqs; i++) { 2534301db7c2SRyan Harper reqs[i].error = -ENOMEDIUM; 2535301db7c2SRyan Harper } 2536301db7c2SRyan Harper return -1; 2537301db7c2SRyan Harper } 2538301db7c2SRyan Harper 253940b4f539SKevin Wolf if (num_reqs == 0) { 254040b4f539SKevin Wolf return 0; 254140b4f539SKevin Wolf } 254240b4f539SKevin Wolf 254340b4f539SKevin Wolf // Create MultiwriteCB structure 25447267c094SAnthony Liguori mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); 254540b4f539SKevin Wolf mcb->num_requests = 0; 254640b4f539SKevin Wolf mcb->num_callbacks = num_reqs; 254740b4f539SKevin Wolf 254840b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 254940b4f539SKevin Wolf mcb->callbacks[i].cb = reqs[i].cb; 255040b4f539SKevin Wolf mcb->callbacks[i].opaque = reqs[i].opaque; 255140b4f539SKevin Wolf } 255240b4f539SKevin Wolf 255340b4f539SKevin Wolf // Check for mergable requests 255440b4f539SKevin Wolf num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); 255540b4f539SKevin Wolf 25566d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); 25576d519a5fSStefan Hajnoczi 2558453f9a16SKevin Wolf /* 2559453f9a16SKevin Wolf * Run the aio requests. As soon as one request can't be submitted 2560453f9a16SKevin Wolf * successfully, fail all requests that are not yet submitted (we must 2561453f9a16SKevin Wolf * return failure for all requests anyway) 2562453f9a16SKevin Wolf * 2563453f9a16SKevin Wolf * num_requests cannot be set to the right value immediately: If 2564453f9a16SKevin Wolf * bdrv_aio_writev fails for some request, num_requests would be too high 2565453f9a16SKevin Wolf * and therefore multiwrite_cb() would never recognize the multiwrite 2566453f9a16SKevin Wolf * request as completed. We also cannot use the loop variable i to set it 2567453f9a16SKevin Wolf * when the first request fails because the callback may already have been 2568453f9a16SKevin Wolf * called for previously submitted requests. Thus, num_requests must be 2569453f9a16SKevin Wolf * incremented for each request that is submitted. 2570453f9a16SKevin Wolf * 2571453f9a16SKevin Wolf * The problem that callbacks may be called early also means that we need 2572453f9a16SKevin Wolf * to take care that num_requests doesn't become 0 before all requests are 2573453f9a16SKevin Wolf * submitted - multiwrite_cb() would consider the multiwrite request 2574453f9a16SKevin Wolf * completed. A dummy request that is "completed" by a manual call to 2575453f9a16SKevin Wolf * multiwrite_cb() takes care of this. 2576453f9a16SKevin Wolf */ 2577453f9a16SKevin Wolf mcb->num_requests = 1; 2578453f9a16SKevin Wolf 25796d519a5fSStefan Hajnoczi // Run the aio requests 258040b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 2581453f9a16SKevin Wolf mcb->num_requests++; 258240b4f539SKevin Wolf acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, 258340b4f539SKevin Wolf reqs[i].nb_sectors, multiwrite_cb, mcb); 258440b4f539SKevin Wolf 258540b4f539SKevin Wolf if (acb == NULL) { 258640b4f539SKevin Wolf // We can only fail the whole thing if no request has been 258740b4f539SKevin Wolf // submitted yet. Otherwise we'll wait for the submitted AIOs to 258840b4f539SKevin Wolf // complete and report the error in the callback. 2589453f9a16SKevin Wolf if (i == 0) { 25906d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_earlyfail(mcb); 259140b4f539SKevin Wolf goto fail; 259240b4f539SKevin Wolf } else { 25936d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_latefail(mcb, i); 25947eb58a6cSKevin Wolf multiwrite_cb(mcb, -EIO); 259540b4f539SKevin Wolf break; 259640b4f539SKevin Wolf } 259740b4f539SKevin Wolf } 259840b4f539SKevin Wolf } 259940b4f539SKevin Wolf 2600453f9a16SKevin Wolf /* Complete the dummy request */ 2601453f9a16SKevin Wolf multiwrite_cb(mcb, 0); 2602453f9a16SKevin Wolf 260340b4f539SKevin Wolf return 0; 260440b4f539SKevin Wolf 260540b4f539SKevin Wolf fail: 2606453f9a16SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 2607453f9a16SKevin Wolf reqs[i].error = -EIO; 2608453f9a16SKevin Wolf } 26097267c094SAnthony Liguori g_free(mcb); 261040b4f539SKevin Wolf return -1; 261140b4f539SKevin Wolf } 261240b4f539SKevin Wolf 2613b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 2614b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2615b2e12bc6SChristoph Hellwig { 2616b2e12bc6SChristoph Hellwig BlockDriver *drv = bs->drv; 2617b2e12bc6SChristoph Hellwig 2618a13aac04SStefan Hajnoczi trace_bdrv_aio_flush(bs, opaque); 2619a13aac04SStefan Hajnoczi 2620016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 2621016f5cf6SAlexander Graf return bdrv_aio_noop_em(bs, cb, opaque); 2622016f5cf6SAlexander Graf } 2623016f5cf6SAlexander Graf 2624b2e12bc6SChristoph Hellwig if (!drv) 2625b2e12bc6SChristoph Hellwig return NULL; 2626b2e12bc6SChristoph Hellwig return drv->bdrv_aio_flush(bs, cb, opaque); 2627b2e12bc6SChristoph Hellwig } 2628b2e12bc6SChristoph Hellwig 262983f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb) 263083f64091Sbellard { 26316bbff9a0Saliguori acb->pool->cancel(acb); 263283f64091Sbellard } 263383f64091Sbellard 263483f64091Sbellard 263583f64091Sbellard /**************************************************************/ 263683f64091Sbellard /* async block device emulation */ 263783f64091Sbellard 2638c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync { 2639c16b5a2cSChristoph Hellwig BlockDriverAIOCB common; 2640c16b5a2cSChristoph Hellwig QEMUBH *bh; 2641c16b5a2cSChristoph Hellwig int ret; 2642c16b5a2cSChristoph Hellwig /* vector translation state */ 2643c16b5a2cSChristoph Hellwig QEMUIOVector *qiov; 2644c16b5a2cSChristoph Hellwig uint8_t *bounce; 2645c16b5a2cSChristoph Hellwig int is_write; 2646c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync; 2647c16b5a2cSChristoph Hellwig 2648c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 2649c16b5a2cSChristoph Hellwig { 2650b666d239SKevin Wolf BlockDriverAIOCBSync *acb = 2651b666d239SKevin Wolf container_of(blockacb, BlockDriverAIOCBSync, common); 26526a7ad299SDor Laor qemu_bh_delete(acb->bh); 265336afc451SAvi Kivity acb->bh = NULL; 2654c16b5a2cSChristoph Hellwig qemu_aio_release(acb); 2655c16b5a2cSChristoph Hellwig } 2656c16b5a2cSChristoph Hellwig 2657c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = { 2658c16b5a2cSChristoph Hellwig .aiocb_size = sizeof(BlockDriverAIOCBSync), 2659c16b5a2cSChristoph Hellwig .cancel = bdrv_aio_cancel_em, 2660c16b5a2cSChristoph Hellwig }; 2661c16b5a2cSChristoph Hellwig 266283f64091Sbellard static void bdrv_aio_bh_cb(void *opaque) 2663beac80cdSbellard { 2664ce1a14dcSpbrook BlockDriverAIOCBSync *acb = opaque; 2665f141eafeSaliguori 2666f141eafeSaliguori if (!acb->is_write) 2667f141eafeSaliguori qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 2668ceb42de8Saliguori qemu_vfree(acb->bounce); 2669ce1a14dcSpbrook acb->common.cb(acb->common.opaque, acb->ret); 26706a7ad299SDor Laor qemu_bh_delete(acb->bh); 267136afc451SAvi Kivity acb->bh = NULL; 2672ce1a14dcSpbrook qemu_aio_release(acb); 2673beac80cdSbellard } 2674beac80cdSbellard 2675f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 2676f141eafeSaliguori int64_t sector_num, 2677f141eafeSaliguori QEMUIOVector *qiov, 2678f141eafeSaliguori int nb_sectors, 2679f141eafeSaliguori BlockDriverCompletionFunc *cb, 2680f141eafeSaliguori void *opaque, 2681f141eafeSaliguori int is_write) 2682f141eafeSaliguori 2683ea2384d3Sbellard { 2684ce1a14dcSpbrook BlockDriverAIOCBSync *acb; 268583f64091Sbellard 2686c16b5a2cSChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2687f141eafeSaliguori acb->is_write = is_write; 2688f141eafeSaliguori acb->qiov = qiov; 2689e268ca52Saliguori acb->bounce = qemu_blockalign(bs, qiov->size); 2690f141eafeSaliguori 2691ce1a14dcSpbrook if (!acb->bh) 2692ce1a14dcSpbrook acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2693f141eafeSaliguori 2694f141eafeSaliguori if (is_write) { 2695f141eafeSaliguori qemu_iovec_to_buffer(acb->qiov, acb->bounce); 26961ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 2697f141eafeSaliguori } else { 26981ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 2699f141eafeSaliguori } 2700f141eafeSaliguori 2701ce1a14dcSpbrook qemu_bh_schedule(acb->bh); 2702f141eafeSaliguori 2703ce1a14dcSpbrook return &acb->common; 27047a6cba61Spbrook } 27057a6cba61Spbrook 2706f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 2707f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2708ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque) 270983f64091Sbellard { 2710f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 271183f64091Sbellard } 271283f64091Sbellard 2713f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 2714f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2715f141eafeSaliguori BlockDriverCompletionFunc *cb, void *opaque) 2716f141eafeSaliguori { 2717f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 2718f141eafeSaliguori } 2719f141eafeSaliguori 272068485420SKevin Wolf 272168485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine { 272268485420SKevin Wolf BlockDriverAIOCB common; 272368485420SKevin Wolf BlockRequest req; 272468485420SKevin Wolf bool is_write; 272568485420SKevin Wolf QEMUBH* bh; 272668485420SKevin Wolf } BlockDriverAIOCBCoroutine; 272768485420SKevin Wolf 272868485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) 272968485420SKevin Wolf { 273068485420SKevin Wolf qemu_aio_flush(); 273168485420SKevin Wolf } 273268485420SKevin Wolf 273368485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = { 273468485420SKevin Wolf .aiocb_size = sizeof(BlockDriverAIOCBCoroutine), 273568485420SKevin Wolf .cancel = bdrv_aio_co_cancel_em, 273668485420SKevin Wolf }; 273768485420SKevin Wolf 2738*35246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque) 273968485420SKevin Wolf { 274068485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 274168485420SKevin Wolf 274268485420SKevin Wolf acb->common.cb(acb->common.opaque, acb->req.error); 274368485420SKevin Wolf qemu_bh_delete(acb->bh); 274468485420SKevin Wolf qemu_aio_release(acb); 274568485420SKevin Wolf } 274668485420SKevin Wolf 2747b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */ 2748b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque) 2749b2a61371SStefan Hajnoczi { 2750b2a61371SStefan Hajnoczi BlockDriverAIOCBCoroutine *acb = opaque; 2751b2a61371SStefan Hajnoczi BlockDriverState *bs = acb->common.bs; 2752b2a61371SStefan Hajnoczi 2753b2a61371SStefan Hajnoczi if (!acb->is_write) { 2754b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, 2755b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2756b2a61371SStefan Hajnoczi } else { 2757b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_writev(bs, acb->req.sector, 2758b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2759b2a61371SStefan Hajnoczi } 2760b2a61371SStefan Hajnoczi 2761*35246a68SPaolo Bonzini acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); 2762b2a61371SStefan Hajnoczi qemu_bh_schedule(acb->bh); 2763b2a61371SStefan Hajnoczi } 2764b2a61371SStefan Hajnoczi 276568485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 276668485420SKevin Wolf int64_t sector_num, 276768485420SKevin Wolf QEMUIOVector *qiov, 276868485420SKevin Wolf int nb_sectors, 276968485420SKevin Wolf BlockDriverCompletionFunc *cb, 277068485420SKevin Wolf void *opaque, 27718c5873d6SStefan Hajnoczi bool is_write) 277268485420SKevin Wolf { 277368485420SKevin Wolf Coroutine *co; 277468485420SKevin Wolf BlockDriverAIOCBCoroutine *acb; 277568485420SKevin Wolf 277668485420SKevin Wolf acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); 277768485420SKevin Wolf acb->req.sector = sector_num; 277868485420SKevin Wolf acb->req.nb_sectors = nb_sectors; 277968485420SKevin Wolf acb->req.qiov = qiov; 278068485420SKevin Wolf acb->is_write = is_write; 278168485420SKevin Wolf 27828c5873d6SStefan Hajnoczi co = qemu_coroutine_create(bdrv_co_do_rw); 278368485420SKevin Wolf qemu_coroutine_enter(co, acb); 278468485420SKevin Wolf 278568485420SKevin Wolf return &acb->common; 278668485420SKevin Wolf } 278768485420SKevin Wolf 2788b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 2789b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2790b2e12bc6SChristoph Hellwig { 2791b2e12bc6SChristoph Hellwig BlockDriverAIOCBSync *acb; 2792b2e12bc6SChristoph Hellwig 2793b2e12bc6SChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2794b2e12bc6SChristoph Hellwig acb->is_write = 1; /* don't bounce in the completion hadler */ 2795b2e12bc6SChristoph Hellwig acb->qiov = NULL; 2796b2e12bc6SChristoph Hellwig acb->bounce = NULL; 2797b2e12bc6SChristoph Hellwig acb->ret = 0; 2798b2e12bc6SChristoph Hellwig 2799b2e12bc6SChristoph Hellwig if (!acb->bh) 2800b2e12bc6SChristoph Hellwig acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2801b2e12bc6SChristoph Hellwig 2802b2e12bc6SChristoph Hellwig bdrv_flush(bs); 2803b2e12bc6SChristoph Hellwig qemu_bh_schedule(acb->bh); 2804b2e12bc6SChristoph Hellwig return &acb->common; 2805b2e12bc6SChristoph Hellwig } 2806b2e12bc6SChristoph Hellwig 2807016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, 2808016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque) 2809016f5cf6SAlexander Graf { 2810016f5cf6SAlexander Graf BlockDriverAIOCBSync *acb; 2811016f5cf6SAlexander Graf 2812016f5cf6SAlexander Graf acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2813016f5cf6SAlexander Graf acb->is_write = 1; /* don't bounce in the completion handler */ 2814016f5cf6SAlexander Graf acb->qiov = NULL; 2815016f5cf6SAlexander Graf acb->bounce = NULL; 2816016f5cf6SAlexander Graf acb->ret = 0; 2817016f5cf6SAlexander Graf 2818016f5cf6SAlexander Graf if (!acb->bh) { 2819016f5cf6SAlexander Graf acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2820016f5cf6SAlexander Graf } 2821016f5cf6SAlexander Graf 2822016f5cf6SAlexander Graf qemu_bh_schedule(acb->bh); 2823016f5cf6SAlexander Graf return &acb->common; 2824016f5cf6SAlexander Graf } 2825016f5cf6SAlexander Graf 2826ea2384d3Sbellard void bdrv_init(void) 2827ea2384d3Sbellard { 28285efa9d5aSAnthony Liguori module_call_init(MODULE_INIT_BLOCK); 2829ea2384d3Sbellard } 2830ce1a14dcSpbrook 2831eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void) 2832eb852011SMarkus Armbruster { 2833eb852011SMarkus Armbruster use_bdrv_whitelist = 1; 2834eb852011SMarkus Armbruster bdrv_init(); 2835eb852011SMarkus Armbruster } 2836eb852011SMarkus Armbruster 2837c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 28386bbff9a0Saliguori BlockDriverCompletionFunc *cb, void *opaque) 28396bbff9a0Saliguori { 2840ce1a14dcSpbrook BlockDriverAIOCB *acb; 2841ce1a14dcSpbrook 28426bbff9a0Saliguori if (pool->free_aiocb) { 28436bbff9a0Saliguori acb = pool->free_aiocb; 28446bbff9a0Saliguori pool->free_aiocb = acb->next; 2845ce1a14dcSpbrook } else { 28467267c094SAnthony Liguori acb = g_malloc0(pool->aiocb_size); 28476bbff9a0Saliguori acb->pool = pool; 2848ce1a14dcSpbrook } 2849ce1a14dcSpbrook acb->bs = bs; 2850ce1a14dcSpbrook acb->cb = cb; 2851ce1a14dcSpbrook acb->opaque = opaque; 2852ce1a14dcSpbrook return acb; 2853ce1a14dcSpbrook } 2854ce1a14dcSpbrook 2855ce1a14dcSpbrook void qemu_aio_release(void *p) 2856ce1a14dcSpbrook { 28576bbff9a0Saliguori BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 28586bbff9a0Saliguori AIOPool *pool = acb->pool; 28596bbff9a0Saliguori acb->next = pool->free_aiocb; 28606bbff9a0Saliguori pool->free_aiocb = acb; 2861ce1a14dcSpbrook } 286219cb3738Sbellard 286319cb3738Sbellard /**************************************************************/ 2864f9f05dc5SKevin Wolf /* Coroutine block device emulation */ 2865f9f05dc5SKevin Wolf 2866f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion { 2867f9f05dc5SKevin Wolf Coroutine *coroutine; 2868f9f05dc5SKevin Wolf int ret; 2869f9f05dc5SKevin Wolf } CoroutineIOCompletion; 2870f9f05dc5SKevin Wolf 2871f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret) 2872f9f05dc5SKevin Wolf { 2873f9f05dc5SKevin Wolf CoroutineIOCompletion *co = opaque; 2874f9f05dc5SKevin Wolf 2875f9f05dc5SKevin Wolf co->ret = ret; 2876f9f05dc5SKevin Wolf qemu_coroutine_enter(co->coroutine, NULL); 2877f9f05dc5SKevin Wolf } 2878f9f05dc5SKevin Wolf 2879f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, 2880f9f05dc5SKevin Wolf int nb_sectors, QEMUIOVector *iov, 2881f9f05dc5SKevin Wolf bool is_write) 2882f9f05dc5SKevin Wolf { 2883f9f05dc5SKevin Wolf CoroutineIOCompletion co = { 2884f9f05dc5SKevin Wolf .coroutine = qemu_coroutine_self(), 2885f9f05dc5SKevin Wolf }; 2886f9f05dc5SKevin Wolf BlockDriverAIOCB *acb; 2887f9f05dc5SKevin Wolf 2888f9f05dc5SKevin Wolf if (is_write) { 2889a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, 2890f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 2891f9f05dc5SKevin Wolf } else { 2892a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, 2893f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 2894f9f05dc5SKevin Wolf } 2895f9f05dc5SKevin Wolf 289659370aaaSStefan Hajnoczi trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); 2897f9f05dc5SKevin Wolf if (!acb) { 2898f9f05dc5SKevin Wolf return -EIO; 2899f9f05dc5SKevin Wolf } 2900f9f05dc5SKevin Wolf qemu_coroutine_yield(); 2901f9f05dc5SKevin Wolf 2902f9f05dc5SKevin Wolf return co.ret; 2903f9f05dc5SKevin Wolf } 2904f9f05dc5SKevin Wolf 2905f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 2906f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 2907f9f05dc5SKevin Wolf QEMUIOVector *iov) 2908f9f05dc5SKevin Wolf { 2909f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); 2910f9f05dc5SKevin Wolf } 2911f9f05dc5SKevin Wolf 2912f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 2913f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 2914f9f05dc5SKevin Wolf QEMUIOVector *iov) 2915f9f05dc5SKevin Wolf { 2916f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); 2917f9f05dc5SKevin Wolf } 2918f9f05dc5SKevin Wolf 2919e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs) 2920e7a8a783SKevin Wolf { 2921e7a8a783SKevin Wolf CoroutineIOCompletion co = { 2922e7a8a783SKevin Wolf .coroutine = qemu_coroutine_self(), 2923e7a8a783SKevin Wolf }; 2924e7a8a783SKevin Wolf BlockDriverAIOCB *acb; 2925e7a8a783SKevin Wolf 2926e7a8a783SKevin Wolf acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); 2927e7a8a783SKevin Wolf if (!acb) { 2928e7a8a783SKevin Wolf return -EIO; 2929e7a8a783SKevin Wolf } 2930e7a8a783SKevin Wolf qemu_coroutine_yield(); 2931e7a8a783SKevin Wolf return co.ret; 2932e7a8a783SKevin Wolf } 2933e7a8a783SKevin Wolf 2934f9f05dc5SKevin Wolf /**************************************************************/ 293519cb3738Sbellard /* removable device support */ 293619cb3738Sbellard 293719cb3738Sbellard /** 293819cb3738Sbellard * Return TRUE if the media is present 293919cb3738Sbellard */ 294019cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs) 294119cb3738Sbellard { 294219cb3738Sbellard BlockDriver *drv = bs->drv; 2943a1aff5bfSMarkus Armbruster 294419cb3738Sbellard if (!drv) 294519cb3738Sbellard return 0; 294619cb3738Sbellard if (!drv->bdrv_is_inserted) 2947a1aff5bfSMarkus Armbruster return 1; 2948a1aff5bfSMarkus Armbruster return drv->bdrv_is_inserted(bs); 294919cb3738Sbellard } 295019cb3738Sbellard 295119cb3738Sbellard /** 29528e49ca46SMarkus Armbruster * Return whether the media changed since the last call to this 29538e49ca46SMarkus Armbruster * function, or -ENOTSUP if we don't know. Most drivers don't know. 295419cb3738Sbellard */ 295519cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs) 295619cb3738Sbellard { 295719cb3738Sbellard BlockDriver *drv = bs->drv; 295819cb3738Sbellard 29598e49ca46SMarkus Armbruster if (drv && drv->bdrv_media_changed) { 29608e49ca46SMarkus Armbruster return drv->bdrv_media_changed(bs); 29618e49ca46SMarkus Armbruster } 29628e49ca46SMarkus Armbruster return -ENOTSUP; 296319cb3738Sbellard } 296419cb3738Sbellard 296519cb3738Sbellard /** 296619cb3738Sbellard * If eject_flag is TRUE, eject the media. Otherwise, close the tray 296719cb3738Sbellard */ 2968fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag) 296919cb3738Sbellard { 297019cb3738Sbellard BlockDriver *drv = bs->drv; 297119cb3738Sbellard 2972822e1cd1SMarkus Armbruster if (drv && drv->bdrv_eject) { 2973822e1cd1SMarkus Armbruster drv->bdrv_eject(bs, eject_flag); 297419cb3738Sbellard } 297519cb3738Sbellard } 297619cb3738Sbellard 297719cb3738Sbellard /** 297819cb3738Sbellard * Lock or unlock the media (if it is locked, the user won't be able 297919cb3738Sbellard * to eject it manually). 298019cb3738Sbellard */ 2981025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked) 298219cb3738Sbellard { 298319cb3738Sbellard BlockDriver *drv = bs->drv; 298419cb3738Sbellard 2985025e849aSMarkus Armbruster trace_bdrv_lock_medium(bs, locked); 2986b8c6d095SStefan Hajnoczi 2987025e849aSMarkus Armbruster if (drv && drv->bdrv_lock_medium) { 2988025e849aSMarkus Armbruster drv->bdrv_lock_medium(bs, locked); 298919cb3738Sbellard } 299019cb3738Sbellard } 2991985a03b0Sths 2992985a03b0Sths /* needed for generic scsi interface */ 2993985a03b0Sths 2994985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 2995985a03b0Sths { 2996985a03b0Sths BlockDriver *drv = bs->drv; 2997985a03b0Sths 2998985a03b0Sths if (drv && drv->bdrv_ioctl) 2999985a03b0Sths return drv->bdrv_ioctl(bs, req, buf); 3000985a03b0Sths return -ENOTSUP; 3001985a03b0Sths } 30027d780669Saliguori 3003221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 3004221f715dSaliguori unsigned long int req, void *buf, 30057d780669Saliguori BlockDriverCompletionFunc *cb, void *opaque) 30067d780669Saliguori { 3007221f715dSaliguori BlockDriver *drv = bs->drv; 30087d780669Saliguori 3009221f715dSaliguori if (drv && drv->bdrv_aio_ioctl) 3010221f715dSaliguori return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 3011221f715dSaliguori return NULL; 30127d780669Saliguori } 3013e268ca52Saliguori 30147b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) 30157b6f9300SMarkus Armbruster { 30167b6f9300SMarkus Armbruster bs->buffer_alignment = align; 30177b6f9300SMarkus Armbruster } 30187cd1e32aSlirans@il.ibm.com 3019e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size) 3020e268ca52Saliguori { 3021e268ca52Saliguori return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 3022e268ca52Saliguori } 30237cd1e32aSlirans@il.ibm.com 30247cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) 30257cd1e32aSlirans@il.ibm.com { 30267cd1e32aSlirans@il.ibm.com int64_t bitmap_size; 3027a55eb92cSJan Kiszka 3028aaa0eb75SLiran Schour bs->dirty_count = 0; 30297cd1e32aSlirans@il.ibm.com if (enable) { 3030c6d22830SJan Kiszka if (!bs->dirty_bitmap) { 3031c6d22830SJan Kiszka bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + 3032c6d22830SJan Kiszka BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; 3033c6d22830SJan Kiszka bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; 30347cd1e32aSlirans@il.ibm.com 30357267c094SAnthony Liguori bs->dirty_bitmap = g_malloc0(bitmap_size); 30367cd1e32aSlirans@il.ibm.com } 30377cd1e32aSlirans@il.ibm.com } else { 3038c6d22830SJan Kiszka if (bs->dirty_bitmap) { 30397267c094SAnthony Liguori g_free(bs->dirty_bitmap); 3040c6d22830SJan Kiszka bs->dirty_bitmap = NULL; 30417cd1e32aSlirans@il.ibm.com } 30427cd1e32aSlirans@il.ibm.com } 30437cd1e32aSlirans@il.ibm.com } 30447cd1e32aSlirans@il.ibm.com 30457cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) 30467cd1e32aSlirans@il.ibm.com { 30476ea44308SJan Kiszka int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; 30487cd1e32aSlirans@il.ibm.com 3049c6d22830SJan Kiszka if (bs->dirty_bitmap && 3050c6d22830SJan Kiszka (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { 30516d59fec1SMarcelo Tosatti return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & 30526d59fec1SMarcelo Tosatti (1UL << (chunk % (sizeof(unsigned long) * 8)))); 30537cd1e32aSlirans@il.ibm.com } else { 30547cd1e32aSlirans@il.ibm.com return 0; 30557cd1e32aSlirans@il.ibm.com } 30567cd1e32aSlirans@il.ibm.com } 30577cd1e32aSlirans@il.ibm.com 30587cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, 30597cd1e32aSlirans@il.ibm.com int nr_sectors) 30607cd1e32aSlirans@il.ibm.com { 30617cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); 30627cd1e32aSlirans@il.ibm.com } 3063aaa0eb75SLiran Schour 3064aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs) 3065aaa0eb75SLiran Schour { 3066aaa0eb75SLiran Schour return bs->dirty_count; 3067aaa0eb75SLiran Schour } 3068f88e1a42SJes Sorensen 3069db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use) 3070db593f25SMarcelo Tosatti { 3071db593f25SMarcelo Tosatti assert(bs->in_use != in_use); 3072db593f25SMarcelo Tosatti bs->in_use = in_use; 3073db593f25SMarcelo Tosatti } 3074db593f25SMarcelo Tosatti 3075db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs) 3076db593f25SMarcelo Tosatti { 3077db593f25SMarcelo Tosatti return bs->in_use; 3078db593f25SMarcelo Tosatti } 3079db593f25SMarcelo Tosatti 308028a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs) 308128a7282aSLuiz Capitulino { 308228a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 308328a7282aSLuiz Capitulino } 308428a7282aSLuiz Capitulino 308528a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly 308628a7282aSLuiz Capitulino * enables it _and_ the VM is configured to stop on errors */ 308728a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) 308828a7282aSLuiz Capitulino { 308928a7282aSLuiz Capitulino return (bs->iostatus != BDRV_IOS_INVAL && 309028a7282aSLuiz Capitulino (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || 309128a7282aSLuiz Capitulino bs->on_write_error == BLOCK_ERR_STOP_ANY || 309228a7282aSLuiz Capitulino bs->on_read_error == BLOCK_ERR_STOP_ANY)); 309328a7282aSLuiz Capitulino } 309428a7282aSLuiz Capitulino 309528a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs) 309628a7282aSLuiz Capitulino { 309728a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_INVAL; 309828a7282aSLuiz Capitulino } 309928a7282aSLuiz Capitulino 310028a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs) 310128a7282aSLuiz Capitulino { 310228a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 310328a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 310428a7282aSLuiz Capitulino } 310528a7282aSLuiz Capitulino } 310628a7282aSLuiz Capitulino 310728a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation 310828a7282aSLuiz Capitulino quite simple. However, the block layer knows about the error, so it's 310928a7282aSLuiz Capitulino possible to implement this without device models being involved */ 311028a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error) 311128a7282aSLuiz Capitulino { 311228a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { 311328a7282aSLuiz Capitulino assert(error >= 0); 311428a7282aSLuiz Capitulino bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; 311528a7282aSLuiz Capitulino } 311628a7282aSLuiz Capitulino } 311728a7282aSLuiz Capitulino 3118a597e79cSChristoph Hellwig void 3119a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, 3120a597e79cSChristoph Hellwig enum BlockAcctType type) 3121a597e79cSChristoph Hellwig { 3122a597e79cSChristoph Hellwig assert(type < BDRV_MAX_IOTYPE); 3123a597e79cSChristoph Hellwig 3124a597e79cSChristoph Hellwig cookie->bytes = bytes; 3125c488c7f6SChristoph Hellwig cookie->start_time_ns = get_clock(); 3126a597e79cSChristoph Hellwig cookie->type = type; 3127a597e79cSChristoph Hellwig } 3128a597e79cSChristoph Hellwig 3129a597e79cSChristoph Hellwig void 3130a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) 3131a597e79cSChristoph Hellwig { 3132a597e79cSChristoph Hellwig assert(cookie->type < BDRV_MAX_IOTYPE); 3133a597e79cSChristoph Hellwig 3134a597e79cSChristoph Hellwig bs->nr_bytes[cookie->type] += cookie->bytes; 3135a597e79cSChristoph Hellwig bs->nr_ops[cookie->type]++; 3136c488c7f6SChristoph Hellwig bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; 3137a597e79cSChristoph Hellwig } 3138a597e79cSChristoph Hellwig 3139f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt, 3140f88e1a42SJes Sorensen const char *base_filename, const char *base_fmt, 3141f88e1a42SJes Sorensen char *options, uint64_t img_size, int flags) 3142f88e1a42SJes Sorensen { 3143f88e1a42SJes Sorensen QEMUOptionParameter *param = NULL, *create_options = NULL; 3144d220894eSKevin Wolf QEMUOptionParameter *backing_fmt, *backing_file, *size; 3145f88e1a42SJes Sorensen BlockDriverState *bs = NULL; 3146f88e1a42SJes Sorensen BlockDriver *drv, *proto_drv; 314796df67d1SStefan Hajnoczi BlockDriver *backing_drv = NULL; 3148f88e1a42SJes Sorensen int ret = 0; 3149f88e1a42SJes Sorensen 3150f88e1a42SJes Sorensen /* Find driver and parse its options */ 3151f88e1a42SJes Sorensen drv = bdrv_find_format(fmt); 3152f88e1a42SJes Sorensen if (!drv) { 3153f88e1a42SJes Sorensen error_report("Unknown file format '%s'", fmt); 31544f70f249SJes Sorensen ret = -EINVAL; 3155f88e1a42SJes Sorensen goto out; 3156f88e1a42SJes Sorensen } 3157f88e1a42SJes Sorensen 3158f88e1a42SJes Sorensen proto_drv = bdrv_find_protocol(filename); 3159f88e1a42SJes Sorensen if (!proto_drv) { 3160f88e1a42SJes Sorensen error_report("Unknown protocol '%s'", filename); 31614f70f249SJes Sorensen ret = -EINVAL; 3162f88e1a42SJes Sorensen goto out; 3163f88e1a42SJes Sorensen } 3164f88e1a42SJes Sorensen 3165f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3166f88e1a42SJes Sorensen drv->create_options); 3167f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3168f88e1a42SJes Sorensen proto_drv->create_options); 3169f88e1a42SJes Sorensen 3170f88e1a42SJes Sorensen /* Create parameter list with default values */ 3171f88e1a42SJes Sorensen param = parse_option_parameters("", create_options, param); 3172f88e1a42SJes Sorensen 3173f88e1a42SJes Sorensen set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); 3174f88e1a42SJes Sorensen 3175f88e1a42SJes Sorensen /* Parse -o options */ 3176f88e1a42SJes Sorensen if (options) { 3177f88e1a42SJes Sorensen param = parse_option_parameters(options, create_options, param); 3178f88e1a42SJes Sorensen if (param == NULL) { 3179f88e1a42SJes Sorensen error_report("Invalid options for file format '%s'.", fmt); 31804f70f249SJes Sorensen ret = -EINVAL; 3181f88e1a42SJes Sorensen goto out; 3182f88e1a42SJes Sorensen } 3183f88e1a42SJes Sorensen } 3184f88e1a42SJes Sorensen 3185f88e1a42SJes Sorensen if (base_filename) { 3186f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, 3187f88e1a42SJes Sorensen base_filename)) { 3188f88e1a42SJes Sorensen error_report("Backing file not supported for file format '%s'", 3189f88e1a42SJes Sorensen fmt); 31904f70f249SJes Sorensen ret = -EINVAL; 3191f88e1a42SJes Sorensen goto out; 3192f88e1a42SJes Sorensen } 3193f88e1a42SJes Sorensen } 3194f88e1a42SJes Sorensen 3195f88e1a42SJes Sorensen if (base_fmt) { 3196f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { 3197f88e1a42SJes Sorensen error_report("Backing file format not supported for file " 3198f88e1a42SJes Sorensen "format '%s'", fmt); 31994f70f249SJes Sorensen ret = -EINVAL; 3200f88e1a42SJes Sorensen goto out; 3201f88e1a42SJes Sorensen } 3202f88e1a42SJes Sorensen } 3203f88e1a42SJes Sorensen 3204792da93aSJes Sorensen backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); 3205792da93aSJes Sorensen if (backing_file && backing_file->value.s) { 3206792da93aSJes Sorensen if (!strcmp(filename, backing_file->value.s)) { 3207792da93aSJes Sorensen error_report("Error: Trying to create an image with the " 3208792da93aSJes Sorensen "same filename as the backing file"); 32094f70f249SJes Sorensen ret = -EINVAL; 3210792da93aSJes Sorensen goto out; 3211792da93aSJes Sorensen } 3212792da93aSJes Sorensen } 3213792da93aSJes Sorensen 3214f88e1a42SJes Sorensen backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); 3215f88e1a42SJes Sorensen if (backing_fmt && backing_fmt->value.s) { 321696df67d1SStefan Hajnoczi backing_drv = bdrv_find_format(backing_fmt->value.s); 321796df67d1SStefan Hajnoczi if (!backing_drv) { 3218f88e1a42SJes Sorensen error_report("Unknown backing file format '%s'", 3219f88e1a42SJes Sorensen backing_fmt->value.s); 32204f70f249SJes Sorensen ret = -EINVAL; 3221f88e1a42SJes Sorensen goto out; 3222f88e1a42SJes Sorensen } 3223f88e1a42SJes Sorensen } 3224f88e1a42SJes Sorensen 3225f88e1a42SJes Sorensen // The size for the image must always be specified, with one exception: 3226f88e1a42SJes Sorensen // If we are using a backing file, we can obtain the size from there 3227d220894eSKevin Wolf size = get_option_parameter(param, BLOCK_OPT_SIZE); 3228d220894eSKevin Wolf if (size && size->value.n == -1) { 3229f88e1a42SJes Sorensen if (backing_file && backing_file->value.s) { 3230f88e1a42SJes Sorensen uint64_t size; 3231f88e1a42SJes Sorensen char buf[32]; 3232f88e1a42SJes Sorensen 3233f88e1a42SJes Sorensen bs = bdrv_new(""); 3234f88e1a42SJes Sorensen 323596df67d1SStefan Hajnoczi ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv); 3236f88e1a42SJes Sorensen if (ret < 0) { 323796df67d1SStefan Hajnoczi error_report("Could not open '%s'", backing_file->value.s); 3238f88e1a42SJes Sorensen goto out; 3239f88e1a42SJes Sorensen } 3240f88e1a42SJes Sorensen bdrv_get_geometry(bs, &size); 3241f88e1a42SJes Sorensen size *= 512; 3242f88e1a42SJes Sorensen 3243f88e1a42SJes Sorensen snprintf(buf, sizeof(buf), "%" PRId64, size); 3244f88e1a42SJes Sorensen set_option_parameter(param, BLOCK_OPT_SIZE, buf); 3245f88e1a42SJes Sorensen } else { 3246f88e1a42SJes Sorensen error_report("Image creation needs a size parameter"); 32474f70f249SJes Sorensen ret = -EINVAL; 3248f88e1a42SJes Sorensen goto out; 3249f88e1a42SJes Sorensen } 3250f88e1a42SJes Sorensen } 3251f88e1a42SJes Sorensen 3252f88e1a42SJes Sorensen printf("Formatting '%s', fmt=%s ", filename, fmt); 3253f88e1a42SJes Sorensen print_option_parameters(param); 3254f88e1a42SJes Sorensen puts(""); 3255f88e1a42SJes Sorensen 3256f88e1a42SJes Sorensen ret = bdrv_create(drv, filename, param); 3257f88e1a42SJes Sorensen 3258f88e1a42SJes Sorensen if (ret < 0) { 3259f88e1a42SJes Sorensen if (ret == -ENOTSUP) { 3260f88e1a42SJes Sorensen error_report("Formatting or formatting option not supported for " 3261f88e1a42SJes Sorensen "file format '%s'", fmt); 3262f88e1a42SJes Sorensen } else if (ret == -EFBIG) { 3263f88e1a42SJes Sorensen error_report("The image size is too large for file format '%s'", 3264f88e1a42SJes Sorensen fmt); 3265f88e1a42SJes Sorensen } else { 3266f88e1a42SJes Sorensen error_report("%s: error while creating %s: %s", filename, fmt, 3267f88e1a42SJes Sorensen strerror(-ret)); 3268f88e1a42SJes Sorensen } 3269f88e1a42SJes Sorensen } 3270f88e1a42SJes Sorensen 3271f88e1a42SJes Sorensen out: 3272f88e1a42SJes Sorensen free_option_parameters(create_options); 3273f88e1a42SJes Sorensen free_option_parameters(param); 3274f88e1a42SJes Sorensen 3275f88e1a42SJes Sorensen if (bs) { 3276f88e1a42SJes Sorensen bdrv_delete(bs); 3277f88e1a42SJes Sorensen } 32784f70f249SJes Sorensen 32794f70f249SJes Sorensen return ret; 3280f88e1a42SJes Sorensen } 3281