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); 56f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 57f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 58f9f05dc5SKevin Wolf QEMUIOVector *iov); 59f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 60f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 61f9f05dc5SKevin Wolf QEMUIOVector *iov); 62c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, 63c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); 641c9805a3SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, 651c9805a3SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); 66b2a61371SStefan Hajnoczi static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 67b2a61371SStefan Hajnoczi int64_t sector_num, 68b2a61371SStefan Hajnoczi QEMUIOVector *qiov, 69b2a61371SStefan Hajnoczi int nb_sectors, 70b2a61371SStefan Hajnoczi BlockDriverCompletionFunc *cb, 71b2a61371SStefan Hajnoczi void *opaque, 728c5873d6SStefan Hajnoczi bool is_write); 73b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque); 74ec530c81Sbellard 751b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states = 761b7bdbc1SStefan Hajnoczi QTAILQ_HEAD_INITIALIZER(bdrv_states); 777ee930d0Sblueswir1 788a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers = 798a22f02aSStefan Hajnoczi QLIST_HEAD_INITIALIZER(bdrv_drivers); 80ea2384d3Sbellard 81f9092b10SMarkus Armbruster /* The device to use for VM snapshots */ 82f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots; 83f9092b10SMarkus Armbruster 84eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */ 85eb852011SMarkus Armbruster static int use_bdrv_whitelist; 86eb852011SMarkus Armbruster 879e0b22f4SStefan Hajnoczi #ifdef _WIN32 889e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename) 899e0b22f4SStefan Hajnoczi { 909e0b22f4SStefan Hajnoczi return (((filename[0] >= 'a' && filename[0] <= 'z') || 919e0b22f4SStefan Hajnoczi (filename[0] >= 'A' && filename[0] <= 'Z')) && 929e0b22f4SStefan Hajnoczi filename[1] == ':'); 939e0b22f4SStefan Hajnoczi } 949e0b22f4SStefan Hajnoczi 959e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename) 969e0b22f4SStefan Hajnoczi { 979e0b22f4SStefan Hajnoczi if (is_windows_drive_prefix(filename) && 989e0b22f4SStefan Hajnoczi filename[2] == '\0') 999e0b22f4SStefan Hajnoczi return 1; 1009e0b22f4SStefan Hajnoczi if (strstart(filename, "\\\\.\\", NULL) || 1019e0b22f4SStefan Hajnoczi strstart(filename, "//./", NULL)) 1029e0b22f4SStefan Hajnoczi return 1; 1039e0b22f4SStefan Hajnoczi return 0; 1049e0b22f4SStefan Hajnoczi } 1059e0b22f4SStefan Hajnoczi #endif 1069e0b22f4SStefan Hajnoczi 1079e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */ 1089e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path) 1099e0b22f4SStefan Hajnoczi { 1109e0b22f4SStefan Hajnoczi #ifdef _WIN32 1119e0b22f4SStefan Hajnoczi if (is_windows_drive(path) || 1129e0b22f4SStefan Hajnoczi is_windows_drive_prefix(path)) { 1139e0b22f4SStefan Hajnoczi return 0; 1149e0b22f4SStefan Hajnoczi } 1159e0b22f4SStefan Hajnoczi #endif 1169e0b22f4SStefan Hajnoczi 1179e0b22f4SStefan Hajnoczi return strchr(path, ':') != NULL; 1189e0b22f4SStefan Hajnoczi } 1199e0b22f4SStefan Hajnoczi 12083f64091Sbellard int path_is_absolute(const char *path) 12183f64091Sbellard { 12283f64091Sbellard const char *p; 12321664424Sbellard #ifdef _WIN32 12421664424Sbellard /* specific case for names like: "\\.\d:" */ 12521664424Sbellard if (*path == '/' || *path == '\\') 12621664424Sbellard return 1; 12721664424Sbellard #endif 12883f64091Sbellard p = strchr(path, ':'); 12983f64091Sbellard if (p) 13083f64091Sbellard p++; 13183f64091Sbellard else 13283f64091Sbellard p = path; 1333b9f94e1Sbellard #ifdef _WIN32 1343b9f94e1Sbellard return (*p == '/' || *p == '\\'); 1353b9f94e1Sbellard #else 1363b9f94e1Sbellard return (*p == '/'); 1373b9f94e1Sbellard #endif 13883f64091Sbellard } 13983f64091Sbellard 14083f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a 14183f64091Sbellard path to it by considering it is relative to base_path. URL are 14283f64091Sbellard supported. */ 14383f64091Sbellard void path_combine(char *dest, int dest_size, 14483f64091Sbellard const char *base_path, 14583f64091Sbellard const char *filename) 14683f64091Sbellard { 14783f64091Sbellard const char *p, *p1; 14883f64091Sbellard int len; 14983f64091Sbellard 15083f64091Sbellard if (dest_size <= 0) 15183f64091Sbellard return; 15283f64091Sbellard if (path_is_absolute(filename)) { 15383f64091Sbellard pstrcpy(dest, dest_size, filename); 15483f64091Sbellard } else { 15583f64091Sbellard p = strchr(base_path, ':'); 15683f64091Sbellard if (p) 15783f64091Sbellard p++; 15883f64091Sbellard else 15983f64091Sbellard p = base_path; 1603b9f94e1Sbellard p1 = strrchr(base_path, '/'); 1613b9f94e1Sbellard #ifdef _WIN32 1623b9f94e1Sbellard { 1633b9f94e1Sbellard const char *p2; 1643b9f94e1Sbellard p2 = strrchr(base_path, '\\'); 1653b9f94e1Sbellard if (!p1 || p2 > p1) 1663b9f94e1Sbellard p1 = p2; 1673b9f94e1Sbellard } 1683b9f94e1Sbellard #endif 16983f64091Sbellard if (p1) 17083f64091Sbellard p1++; 17183f64091Sbellard else 17283f64091Sbellard p1 = base_path; 17383f64091Sbellard if (p1 > p) 17483f64091Sbellard p = p1; 17583f64091Sbellard len = p - base_path; 17683f64091Sbellard if (len > dest_size - 1) 17783f64091Sbellard len = dest_size - 1; 17883f64091Sbellard memcpy(dest, base_path, len); 17983f64091Sbellard dest[len] = '\0'; 18083f64091Sbellard pstrcat(dest, dest_size, filename); 18183f64091Sbellard } 18283f64091Sbellard } 18383f64091Sbellard 1845efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv) 185ea2384d3Sbellard { 1868c5873d6SStefan Hajnoczi /* Block drivers without coroutine functions need emulation */ 1878c5873d6SStefan Hajnoczi if (!bdrv->bdrv_co_readv) { 188f9f05dc5SKevin Wolf bdrv->bdrv_co_readv = bdrv_co_readv_em; 189f9f05dc5SKevin Wolf bdrv->bdrv_co_writev = bdrv_co_writev_em; 190f9f05dc5SKevin Wolf 191f8c35c1dSStefan Hajnoczi /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if 192f8c35c1dSStefan Hajnoczi * the block driver lacks aio we need to emulate that too. 193f8c35c1dSStefan Hajnoczi */ 194f9f05dc5SKevin Wolf if (!bdrv->bdrv_aio_readv) { 19583f64091Sbellard /* add AIO emulation layer */ 196f141eafeSaliguori bdrv->bdrv_aio_readv = bdrv_aio_readv_em; 197f141eafeSaliguori bdrv->bdrv_aio_writev = bdrv_aio_writev_em; 19883f64091Sbellard } 199f9f05dc5SKevin Wolf } 200b2e12bc6SChristoph Hellwig 2018a22f02aSStefan Hajnoczi QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); 202ea2384d3Sbellard } 203b338082bSbellard 204b338082bSbellard /* create a new block device (by default it is empty) */ 205b338082bSbellard BlockDriverState *bdrv_new(const char *device_name) 206fc01f7e7Sbellard { 2071b7bdbc1SStefan Hajnoczi BlockDriverState *bs; 208b338082bSbellard 2097267c094SAnthony Liguori bs = g_malloc0(sizeof(BlockDriverState)); 210b338082bSbellard pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 211ea2384d3Sbellard if (device_name[0] != '\0') { 2121b7bdbc1SStefan Hajnoczi QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); 213ea2384d3Sbellard } 21428a7282aSLuiz Capitulino bdrv_iostatus_disable(bs); 215b338082bSbellard return bs; 216b338082bSbellard } 217b338082bSbellard 218ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name) 219ea2384d3Sbellard { 220ea2384d3Sbellard BlockDriver *drv1; 2218a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 2228a22f02aSStefan Hajnoczi if (!strcmp(drv1->format_name, format_name)) { 223ea2384d3Sbellard return drv1; 224ea2384d3Sbellard } 2258a22f02aSStefan Hajnoczi } 226ea2384d3Sbellard return NULL; 227ea2384d3Sbellard } 228ea2384d3Sbellard 229eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv) 230eb852011SMarkus Armbruster { 231eb852011SMarkus Armbruster static const char *whitelist[] = { 232eb852011SMarkus Armbruster CONFIG_BDRV_WHITELIST 233eb852011SMarkus Armbruster }; 234eb852011SMarkus Armbruster const char **p; 235eb852011SMarkus Armbruster 236eb852011SMarkus Armbruster if (!whitelist[0]) 237eb852011SMarkus Armbruster return 1; /* no whitelist, anything goes */ 238eb852011SMarkus Armbruster 239eb852011SMarkus Armbruster for (p = whitelist; *p; p++) { 240eb852011SMarkus Armbruster if (!strcmp(drv->format_name, *p)) { 241eb852011SMarkus Armbruster return 1; 242eb852011SMarkus Armbruster } 243eb852011SMarkus Armbruster } 244eb852011SMarkus Armbruster return 0; 245eb852011SMarkus Armbruster } 246eb852011SMarkus Armbruster 247eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name) 248eb852011SMarkus Armbruster { 249eb852011SMarkus Armbruster BlockDriver *drv = bdrv_find_format(format_name); 250eb852011SMarkus Armbruster return drv && bdrv_is_whitelisted(drv) ? drv : NULL; 251eb852011SMarkus Armbruster } 252eb852011SMarkus Armbruster 2530e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename, 2540e7e1989SKevin Wolf QEMUOptionParameter *options) 255ea2384d3Sbellard { 256ea2384d3Sbellard if (!drv->bdrv_create) 257ea2384d3Sbellard return -ENOTSUP; 2580e7e1989SKevin Wolf 2590e7e1989SKevin Wolf return drv->bdrv_create(filename, options); 260ea2384d3Sbellard } 261ea2384d3Sbellard 26284a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options) 26384a12e66SChristoph Hellwig { 26484a12e66SChristoph Hellwig BlockDriver *drv; 26584a12e66SChristoph Hellwig 266b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 26784a12e66SChristoph Hellwig if (drv == NULL) { 26816905d71SStefan Hajnoczi return -ENOENT; 26984a12e66SChristoph Hellwig } 27084a12e66SChristoph Hellwig 27184a12e66SChristoph Hellwig return bdrv_create(drv, filename, options); 27284a12e66SChristoph Hellwig } 27384a12e66SChristoph Hellwig 274d5249393Sbellard #ifdef _WIN32 27595389c86Sbellard void get_tmp_filename(char *filename, int size) 276d5249393Sbellard { 2773b9f94e1Sbellard char temp_dir[MAX_PATH]; 2783b9f94e1Sbellard 2793b9f94e1Sbellard GetTempPath(MAX_PATH, temp_dir); 2803b9f94e1Sbellard GetTempFileName(temp_dir, "qem", 0, filename); 281d5249393Sbellard } 282d5249393Sbellard #else 28395389c86Sbellard void get_tmp_filename(char *filename, int size) 284ea2384d3Sbellard { 285ea2384d3Sbellard int fd; 2867ccfb2ebSblueswir1 const char *tmpdir; 287d5249393Sbellard /* XXX: race condition possible */ 2880badc1eeSaurel32 tmpdir = getenv("TMPDIR"); 2890badc1eeSaurel32 if (!tmpdir) 2900badc1eeSaurel32 tmpdir = "/tmp"; 2910badc1eeSaurel32 snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 292ea2384d3Sbellard fd = mkstemp(filename); 293ea2384d3Sbellard close(fd); 294ea2384d3Sbellard } 295d5249393Sbellard #endif 296ea2384d3Sbellard 297f3a5d3f8SChristoph Hellwig /* 298f3a5d3f8SChristoph Hellwig * Detect host devices. By convention, /dev/cdrom[N] is always 299f3a5d3f8SChristoph Hellwig * recognized as a host CDROM. 300f3a5d3f8SChristoph Hellwig */ 301f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename) 302f3a5d3f8SChristoph Hellwig { 303508c7cb3SChristoph Hellwig int score_max = 0, score; 304508c7cb3SChristoph Hellwig BlockDriver *drv = NULL, *d; 305f3a5d3f8SChristoph Hellwig 3068a22f02aSStefan Hajnoczi QLIST_FOREACH(d, &bdrv_drivers, list) { 307508c7cb3SChristoph Hellwig if (d->bdrv_probe_device) { 308508c7cb3SChristoph Hellwig score = d->bdrv_probe_device(filename); 309508c7cb3SChristoph Hellwig if (score > score_max) { 310508c7cb3SChristoph Hellwig score_max = score; 311508c7cb3SChristoph Hellwig drv = d; 312f3a5d3f8SChristoph Hellwig } 313508c7cb3SChristoph Hellwig } 314f3a5d3f8SChristoph Hellwig } 315f3a5d3f8SChristoph Hellwig 316508c7cb3SChristoph Hellwig return drv; 317f3a5d3f8SChristoph Hellwig } 318f3a5d3f8SChristoph Hellwig 319b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename) 32084a12e66SChristoph Hellwig { 32184a12e66SChristoph Hellwig BlockDriver *drv1; 32284a12e66SChristoph Hellwig char protocol[128]; 32384a12e66SChristoph Hellwig int len; 32484a12e66SChristoph Hellwig const char *p; 32584a12e66SChristoph Hellwig 32666f82ceeSKevin Wolf /* TODO Drivers without bdrv_file_open must be specified explicitly */ 32766f82ceeSKevin Wolf 32839508e7aSChristoph Hellwig /* 32939508e7aSChristoph Hellwig * XXX(hch): we really should not let host device detection 33039508e7aSChristoph Hellwig * override an explicit protocol specification, but moving this 33139508e7aSChristoph Hellwig * later breaks access to device names with colons in them. 33239508e7aSChristoph Hellwig * Thanks to the brain-dead persistent naming schemes on udev- 33339508e7aSChristoph Hellwig * based Linux systems those actually are quite common. 33439508e7aSChristoph Hellwig */ 33584a12e66SChristoph Hellwig drv1 = find_hdev_driver(filename); 33639508e7aSChristoph Hellwig if (drv1) { 33784a12e66SChristoph Hellwig return drv1; 33884a12e66SChristoph Hellwig } 33939508e7aSChristoph Hellwig 3409e0b22f4SStefan Hajnoczi if (!path_has_protocol(filename)) { 34139508e7aSChristoph Hellwig return bdrv_find_format("file"); 34239508e7aSChristoph Hellwig } 3439e0b22f4SStefan Hajnoczi p = strchr(filename, ':'); 3449e0b22f4SStefan Hajnoczi assert(p != NULL); 34584a12e66SChristoph Hellwig len = p - filename; 34684a12e66SChristoph Hellwig if (len > sizeof(protocol) - 1) 34784a12e66SChristoph Hellwig len = sizeof(protocol) - 1; 34884a12e66SChristoph Hellwig memcpy(protocol, filename, len); 34984a12e66SChristoph Hellwig protocol[len] = '\0'; 35084a12e66SChristoph Hellwig QLIST_FOREACH(drv1, &bdrv_drivers, list) { 35184a12e66SChristoph Hellwig if (drv1->protocol_name && 35284a12e66SChristoph Hellwig !strcmp(drv1->protocol_name, protocol)) { 35384a12e66SChristoph Hellwig return drv1; 35484a12e66SChristoph Hellwig } 35584a12e66SChristoph Hellwig } 35684a12e66SChristoph Hellwig return NULL; 35784a12e66SChristoph Hellwig } 35884a12e66SChristoph Hellwig 359c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv) 360ea2384d3Sbellard { 36183f64091Sbellard int ret, score, score_max; 362ea2384d3Sbellard BlockDriver *drv1, *drv; 36383f64091Sbellard uint8_t buf[2048]; 36483f64091Sbellard BlockDriverState *bs; 365ea2384d3Sbellard 366f5edb014SNaphtali Sprei ret = bdrv_file_open(&bs, filename, 0); 367c98ac35dSStefan Weil if (ret < 0) { 368c98ac35dSStefan Weil *pdrv = NULL; 369c98ac35dSStefan Weil return ret; 370c98ac35dSStefan Weil } 371f8ea0b00SNicholas Bellinger 37208a00559SKevin Wolf /* Return the raw BlockDriver * to scsi-generic devices or empty drives */ 37308a00559SKevin Wolf if (bs->sg || !bdrv_is_inserted(bs)) { 3741a396859SNicholas A. Bellinger bdrv_delete(bs); 375c98ac35dSStefan Weil drv = bdrv_find_format("raw"); 376c98ac35dSStefan Weil if (!drv) { 377c98ac35dSStefan Weil ret = -ENOENT; 378c98ac35dSStefan Weil } 379c98ac35dSStefan Weil *pdrv = drv; 380c98ac35dSStefan Weil return ret; 3811a396859SNicholas A. Bellinger } 382f8ea0b00SNicholas Bellinger 38383f64091Sbellard ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 38483f64091Sbellard bdrv_delete(bs); 385ea2384d3Sbellard if (ret < 0) { 386c98ac35dSStefan Weil *pdrv = NULL; 387c98ac35dSStefan Weil return ret; 388ea2384d3Sbellard } 389ea2384d3Sbellard 390ea2384d3Sbellard score_max = 0; 39184a12e66SChristoph Hellwig drv = NULL; 3928a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 39383f64091Sbellard if (drv1->bdrv_probe) { 394ea2384d3Sbellard score = drv1->bdrv_probe(buf, ret, filename); 395ea2384d3Sbellard if (score > score_max) { 396ea2384d3Sbellard score_max = score; 397ea2384d3Sbellard drv = drv1; 398ea2384d3Sbellard } 399ea2384d3Sbellard } 40083f64091Sbellard } 401c98ac35dSStefan Weil if (!drv) { 402c98ac35dSStefan Weil ret = -ENOENT; 403c98ac35dSStefan Weil } 404c98ac35dSStefan Weil *pdrv = drv; 405c98ac35dSStefan Weil return ret; 406ea2384d3Sbellard } 407ea2384d3Sbellard 40851762288SStefan Hajnoczi /** 40951762288SStefan Hajnoczi * Set the current 'total_sectors' value 41051762288SStefan Hajnoczi */ 41151762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) 41251762288SStefan Hajnoczi { 41351762288SStefan Hajnoczi BlockDriver *drv = bs->drv; 41451762288SStefan Hajnoczi 415396759adSNicholas Bellinger /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */ 416396759adSNicholas Bellinger if (bs->sg) 417396759adSNicholas Bellinger return 0; 418396759adSNicholas Bellinger 41951762288SStefan Hajnoczi /* query actual device if possible, otherwise just trust the hint */ 42051762288SStefan Hajnoczi if (drv->bdrv_getlength) { 42151762288SStefan Hajnoczi int64_t length = drv->bdrv_getlength(bs); 42251762288SStefan Hajnoczi if (length < 0) { 42351762288SStefan Hajnoczi return length; 42451762288SStefan Hajnoczi } 42551762288SStefan Hajnoczi hint = length >> BDRV_SECTOR_BITS; 42651762288SStefan Hajnoczi } 42751762288SStefan Hajnoczi 42851762288SStefan Hajnoczi bs->total_sectors = hint; 42951762288SStefan Hajnoczi return 0; 43051762288SStefan Hajnoczi } 43151762288SStefan Hajnoczi 432c3993cdcSStefan Hajnoczi /** 433c3993cdcSStefan Hajnoczi * Set open flags for a given cache mode 434c3993cdcSStefan Hajnoczi * 435c3993cdcSStefan Hajnoczi * Return 0 on success, -1 if the cache mode was invalid. 436c3993cdcSStefan Hajnoczi */ 437c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags) 438c3993cdcSStefan Hajnoczi { 439c3993cdcSStefan Hajnoczi *flags &= ~BDRV_O_CACHE_MASK; 440c3993cdcSStefan Hajnoczi 441c3993cdcSStefan Hajnoczi if (!strcmp(mode, "off") || !strcmp(mode, "none")) { 442c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; 44392196b2fSStefan Hajnoczi } else if (!strcmp(mode, "directsync")) { 44492196b2fSStefan Hajnoczi *flags |= BDRV_O_NOCACHE; 445c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writeback")) { 446c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 447c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "unsafe")) { 448c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 449c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NO_FLUSH; 450c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writethrough")) { 451c3993cdcSStefan Hajnoczi /* this is the default */ 452c3993cdcSStefan Hajnoczi } else { 453c3993cdcSStefan Hajnoczi return -1; 454c3993cdcSStefan Hajnoczi } 455c3993cdcSStefan Hajnoczi 456c3993cdcSStefan Hajnoczi return 0; 457c3993cdcSStefan Hajnoczi } 458c3993cdcSStefan Hajnoczi 459b6ce07aaSKevin Wolf /* 46057915332SKevin Wolf * Common part for opening disk images and files 46157915332SKevin Wolf */ 46257915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename, 46357915332SKevin Wolf int flags, BlockDriver *drv) 46457915332SKevin Wolf { 46557915332SKevin Wolf int ret, open_flags; 46657915332SKevin Wolf 46757915332SKevin Wolf assert(drv != NULL); 46857915332SKevin Wolf 46928dcee10SStefan Hajnoczi trace_bdrv_open_common(bs, filename, flags, drv->format_name); 47028dcee10SStefan Hajnoczi 47166f82ceeSKevin Wolf bs->file = NULL; 47251762288SStefan Hajnoczi bs->total_sectors = 0; 47357915332SKevin Wolf bs->encrypted = 0; 47457915332SKevin Wolf bs->valid_key = 0; 47557915332SKevin Wolf bs->open_flags = flags; 47657915332SKevin Wolf bs->buffer_alignment = 512; 47757915332SKevin Wolf 47857915332SKevin Wolf pstrcpy(bs->filename, sizeof(bs->filename), filename); 47957915332SKevin Wolf 48057915332SKevin Wolf if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { 48157915332SKevin Wolf return -ENOTSUP; 48257915332SKevin Wolf } 48357915332SKevin Wolf 48457915332SKevin Wolf bs->drv = drv; 4857267c094SAnthony Liguori bs->opaque = g_malloc0(drv->instance_size); 48657915332SKevin Wolf 487a6599793SChristoph Hellwig if (flags & BDRV_O_CACHE_WB) 48857915332SKevin Wolf bs->enable_write_cache = 1; 48957915332SKevin Wolf 49057915332SKevin Wolf /* 49157915332SKevin Wolf * Clear flags that are internal to the block layer before opening the 49257915332SKevin Wolf * image. 49357915332SKevin Wolf */ 49457915332SKevin Wolf open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 49557915332SKevin Wolf 49657915332SKevin Wolf /* 497ebabb67aSStefan Weil * Snapshots should be writable. 49857915332SKevin Wolf */ 49957915332SKevin Wolf if (bs->is_temporary) { 50057915332SKevin Wolf open_flags |= BDRV_O_RDWR; 50157915332SKevin Wolf } 50257915332SKevin Wolf 50366f82ceeSKevin Wolf /* Open the image, either directly or using a protocol */ 50466f82ceeSKevin Wolf if (drv->bdrv_file_open) { 50566f82ceeSKevin Wolf ret = drv->bdrv_file_open(bs, filename, open_flags); 50666f82ceeSKevin Wolf } else { 50766f82ceeSKevin Wolf ret = bdrv_file_open(&bs->file, filename, open_flags); 50866f82ceeSKevin Wolf if (ret >= 0) { 50966f82ceeSKevin Wolf ret = drv->bdrv_open(bs, open_flags); 51066f82ceeSKevin Wolf } 51166f82ceeSKevin Wolf } 51266f82ceeSKevin Wolf 51357915332SKevin Wolf if (ret < 0) { 51457915332SKevin Wolf goto free_and_fail; 51557915332SKevin Wolf } 51657915332SKevin Wolf 51757915332SKevin Wolf bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); 51851762288SStefan Hajnoczi 51951762288SStefan Hajnoczi ret = refresh_total_sectors(bs, bs->total_sectors); 52051762288SStefan Hajnoczi if (ret < 0) { 52151762288SStefan Hajnoczi goto free_and_fail; 52257915332SKevin Wolf } 52351762288SStefan Hajnoczi 52457915332SKevin Wolf #ifndef _WIN32 52557915332SKevin Wolf if (bs->is_temporary) { 52657915332SKevin Wolf unlink(filename); 52757915332SKevin Wolf } 52857915332SKevin Wolf #endif 52957915332SKevin Wolf return 0; 53057915332SKevin Wolf 53157915332SKevin Wolf free_and_fail: 53266f82ceeSKevin Wolf if (bs->file) { 53366f82ceeSKevin Wolf bdrv_delete(bs->file); 53466f82ceeSKevin Wolf bs->file = NULL; 53566f82ceeSKevin Wolf } 5367267c094SAnthony Liguori g_free(bs->opaque); 53757915332SKevin Wolf bs->opaque = NULL; 53857915332SKevin Wolf bs->drv = NULL; 53957915332SKevin Wolf return ret; 54057915332SKevin Wolf } 54157915332SKevin Wolf 54257915332SKevin Wolf /* 543b6ce07aaSKevin Wolf * Opens a file using a protocol (file, host_device, nbd, ...) 544b6ce07aaSKevin Wolf */ 54583f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 546b338082bSbellard { 54783f64091Sbellard BlockDriverState *bs; 5486db95603SChristoph Hellwig BlockDriver *drv; 54983f64091Sbellard int ret; 5503b0d4f61Sbellard 551b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 5526db95603SChristoph Hellwig if (!drv) { 5536db95603SChristoph Hellwig return -ENOENT; 5546db95603SChristoph Hellwig } 5556db95603SChristoph Hellwig 55683f64091Sbellard bs = bdrv_new(""); 557b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 55883f64091Sbellard if (ret < 0) { 55983f64091Sbellard bdrv_delete(bs); 56083f64091Sbellard return ret; 5613b0d4f61Sbellard } 56271d0770cSaliguori bs->growable = 1; 56383f64091Sbellard *pbs = bs; 56483f64091Sbellard return 0; 5653b0d4f61Sbellard } 5663b0d4f61Sbellard 567b6ce07aaSKevin Wolf /* 568b6ce07aaSKevin Wolf * Opens a disk image (raw, qcow2, vmdk, ...) 569b6ce07aaSKevin Wolf */ 570d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags, 571ea2384d3Sbellard BlockDriver *drv) 572ea2384d3Sbellard { 573b6ce07aaSKevin Wolf int ret; 57433e3963eSbellard 57583f64091Sbellard if (flags & BDRV_O_SNAPSHOT) { 576ea2384d3Sbellard BlockDriverState *bs1; 577ea2384d3Sbellard int64_t total_size; 5787c96d46eSaliguori int is_protocol = 0; 57991a073a9SKevin Wolf BlockDriver *bdrv_qcow2; 58091a073a9SKevin Wolf QEMUOptionParameter *options; 581b6ce07aaSKevin Wolf char tmp_filename[PATH_MAX]; 582b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 58333e3963eSbellard 584ea2384d3Sbellard /* if snapshot, we create a temporary backing file and open it 585ea2384d3Sbellard instead of opening 'filename' directly */ 586ea2384d3Sbellard 587ea2384d3Sbellard /* if there is a backing file, use it */ 588ea2384d3Sbellard bs1 = bdrv_new(""); 589d6e9098eSKevin Wolf ret = bdrv_open(bs1, filename, 0, drv); 59051d7c00cSaliguori if (ret < 0) { 591ea2384d3Sbellard bdrv_delete(bs1); 59251d7c00cSaliguori return ret; 593ea2384d3Sbellard } 5943e82990bSJes Sorensen total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; 5957c96d46eSaliguori 5967c96d46eSaliguori if (bs1->drv && bs1->drv->protocol_name) 5977c96d46eSaliguori is_protocol = 1; 5987c96d46eSaliguori 599ea2384d3Sbellard bdrv_delete(bs1); 600ea2384d3Sbellard 601ea2384d3Sbellard get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 6027c96d46eSaliguori 6037c96d46eSaliguori /* Real path is meaningless for protocols */ 6047c96d46eSaliguori if (is_protocol) 6057c96d46eSaliguori snprintf(backing_filename, sizeof(backing_filename), 6067c96d46eSaliguori "%s", filename); 607114cdfa9SKirill A. Shutemov else if (!realpath(filename, backing_filename)) 608114cdfa9SKirill A. Shutemov return -errno; 6097c96d46eSaliguori 61091a073a9SKevin Wolf bdrv_qcow2 = bdrv_find_format("qcow2"); 61191a073a9SKevin Wolf options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); 61291a073a9SKevin Wolf 6133e82990bSJes Sorensen set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size); 61491a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename); 61591a073a9SKevin Wolf if (drv) { 61691a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FMT, 61791a073a9SKevin Wolf drv->format_name); 61891a073a9SKevin Wolf } 61991a073a9SKevin Wolf 62091a073a9SKevin Wolf ret = bdrv_create(bdrv_qcow2, tmp_filename, options); 621d748768cSJan Kiszka free_option_parameters(options); 62251d7c00cSaliguori if (ret < 0) { 62351d7c00cSaliguori return ret; 624ea2384d3Sbellard } 62591a073a9SKevin Wolf 626ea2384d3Sbellard filename = tmp_filename; 62791a073a9SKevin Wolf drv = bdrv_qcow2; 628ea2384d3Sbellard bs->is_temporary = 1; 629ea2384d3Sbellard } 630ea2384d3Sbellard 631b6ce07aaSKevin Wolf /* Find the right image format driver */ 6326db95603SChristoph Hellwig if (!drv) { 633c98ac35dSStefan Weil ret = find_image_format(filename, &drv); 634ea2384d3Sbellard } 6356987307cSChristoph Hellwig 63651d7c00cSaliguori if (!drv) { 63751d7c00cSaliguori goto unlink_and_fail; 63883f64091Sbellard } 639b6ce07aaSKevin Wolf 640b6ce07aaSKevin Wolf /* Open the image */ 641b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 642b6ce07aaSKevin Wolf if (ret < 0) { 6436987307cSChristoph Hellwig goto unlink_and_fail; 6446987307cSChristoph Hellwig } 6456987307cSChristoph Hellwig 646b6ce07aaSKevin Wolf /* If there is a backing file, use it */ 647b6ce07aaSKevin Wolf if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { 648b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 649b6ce07aaSKevin Wolf int back_flags; 650b6ce07aaSKevin Wolf BlockDriver *back_drv = NULL; 651b6ce07aaSKevin Wolf 652b6ce07aaSKevin Wolf bs->backing_hd = bdrv_new(""); 653df2dbb4aSStefan Hajnoczi 654df2dbb4aSStefan Hajnoczi if (path_has_protocol(bs->backing_file)) { 655df2dbb4aSStefan Hajnoczi pstrcpy(backing_filename, sizeof(backing_filename), 656df2dbb4aSStefan Hajnoczi bs->backing_file); 657df2dbb4aSStefan Hajnoczi } else { 658b6ce07aaSKevin Wolf path_combine(backing_filename, sizeof(backing_filename), 659b6ce07aaSKevin Wolf filename, bs->backing_file); 660df2dbb4aSStefan Hajnoczi } 661df2dbb4aSStefan Hajnoczi 662df2dbb4aSStefan Hajnoczi if (bs->backing_format[0] != '\0') { 663b6ce07aaSKevin Wolf back_drv = bdrv_find_format(bs->backing_format); 664df2dbb4aSStefan Hajnoczi } 665b6ce07aaSKevin Wolf 666b6ce07aaSKevin Wolf /* backing files always opened read-only */ 667b6ce07aaSKevin Wolf back_flags = 668b6ce07aaSKevin Wolf flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 669b6ce07aaSKevin Wolf 670b6ce07aaSKevin Wolf ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv); 671b6ce07aaSKevin Wolf if (ret < 0) { 672b6ce07aaSKevin Wolf bdrv_close(bs); 673b6ce07aaSKevin Wolf return ret; 674b6ce07aaSKevin Wolf } 675b6ce07aaSKevin Wolf if (bs->is_temporary) { 676b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); 677b6ce07aaSKevin Wolf } else { 678b6ce07aaSKevin Wolf /* base image inherits from "parent" */ 679b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = bs->keep_read_only; 680b6ce07aaSKevin Wolf } 681b6ce07aaSKevin Wolf } 682b6ce07aaSKevin Wolf 683b6ce07aaSKevin Wolf if (!bdrv_key_required(bs)) { 6847d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 685b6ce07aaSKevin Wolf } 686b6ce07aaSKevin Wolf 687b6ce07aaSKevin Wolf return 0; 688b6ce07aaSKevin Wolf 689b6ce07aaSKevin Wolf unlink_and_fail: 690b6ce07aaSKevin Wolf if (bs->is_temporary) { 691b6ce07aaSKevin Wolf unlink(filename); 692b6ce07aaSKevin Wolf } 693b6ce07aaSKevin Wolf return ret; 694b6ce07aaSKevin Wolf } 695b6ce07aaSKevin Wolf 696fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs) 697fc01f7e7Sbellard { 69819cb3738Sbellard if (bs->drv) { 699f9092b10SMarkus Armbruster if (bs == bs_snapshots) { 700f9092b10SMarkus Armbruster bs_snapshots = NULL; 701f9092b10SMarkus Armbruster } 702557df6acSStefan Hajnoczi if (bs->backing_hd) { 703ea2384d3Sbellard bdrv_delete(bs->backing_hd); 704557df6acSStefan Hajnoczi bs->backing_hd = NULL; 705557df6acSStefan Hajnoczi } 706ea2384d3Sbellard bs->drv->bdrv_close(bs); 7077267c094SAnthony Liguori g_free(bs->opaque); 708ea2384d3Sbellard #ifdef _WIN32 709ea2384d3Sbellard if (bs->is_temporary) { 710ea2384d3Sbellard unlink(bs->filename); 711ea2384d3Sbellard } 71267b915a5Sbellard #endif 713ea2384d3Sbellard bs->opaque = NULL; 714ea2384d3Sbellard bs->drv = NULL; 715b338082bSbellard 71666f82ceeSKevin Wolf if (bs->file != NULL) { 71766f82ceeSKevin Wolf bdrv_close(bs->file); 71866f82ceeSKevin Wolf } 71966f82ceeSKevin Wolf 7207d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, false); 721b338082bSbellard } 722b338082bSbellard } 723b338082bSbellard 7242bc93fedSMORITA Kazutaka void bdrv_close_all(void) 7252bc93fedSMORITA Kazutaka { 7262bc93fedSMORITA Kazutaka BlockDriverState *bs; 7272bc93fedSMORITA Kazutaka 7282bc93fedSMORITA Kazutaka QTAILQ_FOREACH(bs, &bdrv_states, list) { 7292bc93fedSMORITA Kazutaka bdrv_close(bs); 7302bc93fedSMORITA Kazutaka } 7312bc93fedSMORITA Kazutaka } 7322bc93fedSMORITA Kazutaka 733d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list. 734d22b2f41SRyan Harper Also, NULL terminate the device_name to prevent double remove */ 735d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs) 736d22b2f41SRyan Harper { 737d22b2f41SRyan Harper if (bs->device_name[0] != '\0') { 738d22b2f41SRyan Harper QTAILQ_REMOVE(&bdrv_states, bs, list); 739d22b2f41SRyan Harper } 740d22b2f41SRyan Harper bs->device_name[0] = '\0'; 741d22b2f41SRyan Harper } 742d22b2f41SRyan Harper 743b338082bSbellard void bdrv_delete(BlockDriverState *bs) 744b338082bSbellard { 745fa879d62SMarkus Armbruster assert(!bs->dev); 74618846deeSMarkus Armbruster 7471b7bdbc1SStefan Hajnoczi /* remove from list, if necessary */ 748d22b2f41SRyan Harper bdrv_make_anon(bs); 74934c6f050Saurel32 750b338082bSbellard bdrv_close(bs); 75166f82ceeSKevin Wolf if (bs->file != NULL) { 75266f82ceeSKevin Wolf bdrv_delete(bs->file); 75366f82ceeSKevin Wolf } 75466f82ceeSKevin Wolf 755f9092b10SMarkus Armbruster assert(bs != bs_snapshots); 7567267c094SAnthony Liguori g_free(bs); 757fc01f7e7Sbellard } 758fc01f7e7Sbellard 759fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev) 760fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 76118846deeSMarkus Armbruster { 762fa879d62SMarkus Armbruster if (bs->dev) { 76318846deeSMarkus Armbruster return -EBUSY; 76418846deeSMarkus Armbruster } 765fa879d62SMarkus Armbruster bs->dev = dev; 76628a7282aSLuiz Capitulino bdrv_iostatus_reset(bs); 76718846deeSMarkus Armbruster return 0; 76818846deeSMarkus Armbruster } 76918846deeSMarkus Armbruster 770fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */ 771fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) 77218846deeSMarkus Armbruster { 773fa879d62SMarkus Armbruster if (bdrv_attach_dev(bs, dev) < 0) { 774fa879d62SMarkus Armbruster abort(); 775fa879d62SMarkus Armbruster } 776fa879d62SMarkus Armbruster } 777fa879d62SMarkus Armbruster 778fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev) 779fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 780fa879d62SMarkus Armbruster { 781fa879d62SMarkus Armbruster assert(bs->dev == dev); 782fa879d62SMarkus Armbruster bs->dev = NULL; 7830e49de52SMarkus Armbruster bs->dev_ops = NULL; 7840e49de52SMarkus Armbruster bs->dev_opaque = NULL; 78529e05f20SMarkus Armbruster bs->buffer_alignment = 512; 78618846deeSMarkus Armbruster } 78718846deeSMarkus Armbruster 788fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 789fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs) 79018846deeSMarkus Armbruster { 791fa879d62SMarkus Armbruster return bs->dev; 79218846deeSMarkus Armbruster } 79318846deeSMarkus Armbruster 7940e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, 7950e49de52SMarkus Armbruster void *opaque) 7960e49de52SMarkus Armbruster { 7970e49de52SMarkus Armbruster bs->dev_ops = ops; 7980e49de52SMarkus Armbruster bs->dev_opaque = opaque; 7992c6942faSMarkus Armbruster if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) { 8002c6942faSMarkus Armbruster bs_snapshots = NULL; 8012c6942faSMarkus Armbruster } 8020e49de52SMarkus Armbruster } 8030e49de52SMarkus Armbruster 8047d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) 8050e49de52SMarkus Armbruster { 806145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->change_media_cb) { 8077d4b4ba5SMarkus Armbruster bs->dev_ops->change_media_cb(bs->dev_opaque, load); 808145feb17SMarkus Armbruster } 809145feb17SMarkus Armbruster } 810145feb17SMarkus Armbruster 8112c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs) 8122c6942faSMarkus Armbruster { 8132c6942faSMarkus Armbruster return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); 8142c6942faSMarkus Armbruster } 8152c6942faSMarkus Armbruster 816e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs) 817e4def80bSMarkus Armbruster { 818e4def80bSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_tray_open) { 819e4def80bSMarkus Armbruster return bs->dev_ops->is_tray_open(bs->dev_opaque); 820e4def80bSMarkus Armbruster } 821e4def80bSMarkus Armbruster return false; 822e4def80bSMarkus Armbruster } 823e4def80bSMarkus Armbruster 824145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs) 825145feb17SMarkus Armbruster { 826145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->resize_cb) { 827145feb17SMarkus Armbruster bs->dev_ops->resize_cb(bs->dev_opaque); 8280e49de52SMarkus Armbruster } 8290e49de52SMarkus Armbruster } 8300e49de52SMarkus Armbruster 831f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs) 832f107639aSMarkus Armbruster { 833f107639aSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_medium_locked) { 834f107639aSMarkus Armbruster return bs->dev_ops->is_medium_locked(bs->dev_opaque); 835f107639aSMarkus Armbruster } 836f107639aSMarkus Armbruster return false; 837f107639aSMarkus Armbruster } 838f107639aSMarkus Armbruster 839e97fc193Saliguori /* 840e97fc193Saliguori * Run consistency checks on an image 841e97fc193Saliguori * 842e076f338SKevin Wolf * Returns 0 if the check could be completed (it doesn't mean that the image is 843a1c7273bSStefan Weil * free of errors) or -errno when an internal error occurred. The results of the 844e076f338SKevin Wolf * check are stored in res. 845e97fc193Saliguori */ 846e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res) 847e97fc193Saliguori { 848e97fc193Saliguori if (bs->drv->bdrv_check == NULL) { 849e97fc193Saliguori return -ENOTSUP; 850e97fc193Saliguori } 851e97fc193Saliguori 852e076f338SKevin Wolf memset(res, 0, sizeof(*res)); 8539ac228e0SKevin Wolf return bs->drv->bdrv_check(bs, res); 854e97fc193Saliguori } 855e97fc193Saliguori 8568a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048 8578a426614SKevin Wolf 85833e3963eSbellard /* commit COW file into the raw image */ 85933e3963eSbellard int bdrv_commit(BlockDriverState *bs) 86033e3963eSbellard { 86119cb3738Sbellard BlockDriver *drv = bs->drv; 862ee181196SKevin Wolf BlockDriver *backing_drv; 8638a426614SKevin Wolf int64_t sector, total_sectors; 8648a426614SKevin Wolf int n, ro, open_flags; 8654dca4b63SNaphtali Sprei int ret = 0, rw_ret = 0; 8668a426614SKevin Wolf uint8_t *buf; 8674dca4b63SNaphtali Sprei char filename[1024]; 8684dca4b63SNaphtali Sprei BlockDriverState *bs_rw, *bs_ro; 86933e3963eSbellard 87019cb3738Sbellard if (!drv) 87119cb3738Sbellard return -ENOMEDIUM; 87233e3963eSbellard 8734dca4b63SNaphtali Sprei if (!bs->backing_hd) { 8744dca4b63SNaphtali Sprei return -ENOTSUP; 8754dca4b63SNaphtali Sprei } 8764dca4b63SNaphtali Sprei 8774dca4b63SNaphtali Sprei if (bs->backing_hd->keep_read_only) { 878ea2384d3Sbellard return -EACCES; 87933e3963eSbellard } 88033e3963eSbellard 881ee181196SKevin Wolf backing_drv = bs->backing_hd->drv; 8824dca4b63SNaphtali Sprei ro = bs->backing_hd->read_only; 8834dca4b63SNaphtali Sprei strncpy(filename, bs->backing_hd->filename, sizeof(filename)); 8844dca4b63SNaphtali Sprei open_flags = bs->backing_hd->open_flags; 8854dca4b63SNaphtali Sprei 8864dca4b63SNaphtali Sprei if (ro) { 8874dca4b63SNaphtali Sprei /* re-open as RW */ 8884dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 8894dca4b63SNaphtali Sprei bs->backing_hd = NULL; 8904dca4b63SNaphtali Sprei bs_rw = bdrv_new(""); 891ee181196SKevin Wolf rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, 892ee181196SKevin Wolf backing_drv); 8934dca4b63SNaphtali Sprei if (rw_ret < 0) { 8944dca4b63SNaphtali Sprei bdrv_delete(bs_rw); 8954dca4b63SNaphtali Sprei /* try to re-open read-only */ 8964dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 897ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 898ee181196SKevin Wolf backing_drv); 8994dca4b63SNaphtali Sprei if (ret < 0) { 9004dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9014dca4b63SNaphtali Sprei /* drive not functional anymore */ 9024dca4b63SNaphtali Sprei bs->drv = NULL; 9034dca4b63SNaphtali Sprei return ret; 9044dca4b63SNaphtali Sprei } 9054dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9064dca4b63SNaphtali Sprei return rw_ret; 9074dca4b63SNaphtali Sprei } 9084dca4b63SNaphtali Sprei bs->backing_hd = bs_rw; 909ea2384d3Sbellard } 910ea2384d3Sbellard 9116ea44308SJan Kiszka total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; 9127267c094SAnthony Liguori buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); 9138a426614SKevin Wolf 9148a426614SKevin Wolf for (sector = 0; sector < total_sectors; sector += n) { 9158a426614SKevin Wolf if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { 9168a426614SKevin Wolf 9178a426614SKevin Wolf if (bdrv_read(bs, sector, buf, n) != 0) { 9184dca4b63SNaphtali Sprei ret = -EIO; 9194dca4b63SNaphtali Sprei goto ro_cleanup; 92033e3963eSbellard } 92133e3963eSbellard 9228a426614SKevin Wolf if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) { 9234dca4b63SNaphtali Sprei ret = -EIO; 9244dca4b63SNaphtali Sprei goto ro_cleanup; 92533e3963eSbellard } 92633e3963eSbellard } 92733e3963eSbellard } 92895389c86Sbellard 9291d44952fSChristoph Hellwig if (drv->bdrv_make_empty) { 9301d44952fSChristoph Hellwig ret = drv->bdrv_make_empty(bs); 9311d44952fSChristoph Hellwig bdrv_flush(bs); 9321d44952fSChristoph Hellwig } 93395389c86Sbellard 9343f5075aeSChristoph Hellwig /* 9353f5075aeSChristoph Hellwig * Make sure all data we wrote to the backing device is actually 9363f5075aeSChristoph Hellwig * stable on disk. 9373f5075aeSChristoph Hellwig */ 9383f5075aeSChristoph Hellwig if (bs->backing_hd) 9393f5075aeSChristoph Hellwig bdrv_flush(bs->backing_hd); 9404dca4b63SNaphtali Sprei 9414dca4b63SNaphtali Sprei ro_cleanup: 9427267c094SAnthony Liguori g_free(buf); 9434dca4b63SNaphtali Sprei 9444dca4b63SNaphtali Sprei if (ro) { 9454dca4b63SNaphtali Sprei /* re-open as RO */ 9464dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 9474dca4b63SNaphtali Sprei bs->backing_hd = NULL; 9484dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 949ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 950ee181196SKevin Wolf backing_drv); 9514dca4b63SNaphtali Sprei if (ret < 0) { 9524dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9534dca4b63SNaphtali Sprei /* drive not functional anymore */ 9544dca4b63SNaphtali Sprei bs->drv = NULL; 9554dca4b63SNaphtali Sprei return ret; 9564dca4b63SNaphtali Sprei } 9574dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9584dca4b63SNaphtali Sprei bs->backing_hd->keep_read_only = 0; 9594dca4b63SNaphtali Sprei } 9604dca4b63SNaphtali Sprei 9611d44952fSChristoph Hellwig return ret; 96233e3963eSbellard } 96333e3963eSbellard 9646ab4b5abSMarkus Armbruster void bdrv_commit_all(void) 9656ab4b5abSMarkus Armbruster { 9666ab4b5abSMarkus Armbruster BlockDriverState *bs; 9676ab4b5abSMarkus Armbruster 9686ab4b5abSMarkus Armbruster QTAILQ_FOREACH(bs, &bdrv_states, list) { 9696ab4b5abSMarkus Armbruster bdrv_commit(bs); 9706ab4b5abSMarkus Armbruster } 9716ab4b5abSMarkus Armbruster } 9726ab4b5abSMarkus Armbruster 973756e6736SKevin Wolf /* 974756e6736SKevin Wolf * Return values: 975756e6736SKevin Wolf * 0 - success 976756e6736SKevin Wolf * -EINVAL - backing format specified, but no file 977756e6736SKevin Wolf * -ENOSPC - can't update the backing file because no space is left in the 978756e6736SKevin Wolf * image file header 979756e6736SKevin Wolf * -ENOTSUP - format driver doesn't support changing the backing file 980756e6736SKevin Wolf */ 981756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs, 982756e6736SKevin Wolf const char *backing_file, const char *backing_fmt) 983756e6736SKevin Wolf { 984756e6736SKevin Wolf BlockDriver *drv = bs->drv; 985756e6736SKevin Wolf 986756e6736SKevin Wolf if (drv->bdrv_change_backing_file != NULL) { 987756e6736SKevin Wolf return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt); 988756e6736SKevin Wolf } else { 989756e6736SKevin Wolf return -ENOTSUP; 990756e6736SKevin Wolf } 991756e6736SKevin Wolf } 992756e6736SKevin Wolf 99371d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, 99471d0770cSaliguori size_t size) 99571d0770cSaliguori { 99671d0770cSaliguori int64_t len; 99771d0770cSaliguori 99871d0770cSaliguori if (!bdrv_is_inserted(bs)) 99971d0770cSaliguori return -ENOMEDIUM; 100071d0770cSaliguori 100171d0770cSaliguori if (bs->growable) 100271d0770cSaliguori return 0; 100371d0770cSaliguori 100471d0770cSaliguori len = bdrv_getlength(bs); 100571d0770cSaliguori 1006fbb7b4e0SKevin Wolf if (offset < 0) 1007fbb7b4e0SKevin Wolf return -EIO; 1008fbb7b4e0SKevin Wolf 1009fbb7b4e0SKevin Wolf if ((offset > len) || (len - offset < size)) 101071d0770cSaliguori return -EIO; 101171d0770cSaliguori 101271d0770cSaliguori return 0; 101371d0770cSaliguori } 101471d0770cSaliguori 101571d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, 101671d0770cSaliguori int nb_sectors) 101771d0770cSaliguori { 1018eb5a3165SJes Sorensen return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE, 1019eb5a3165SJes Sorensen nb_sectors * BDRV_SECTOR_SIZE); 102071d0770cSaliguori } 102171d0770cSaliguori 10221c9805a3SStefan Hajnoczi typedef struct RwCo { 10231c9805a3SStefan Hajnoczi BlockDriverState *bs; 10241c9805a3SStefan Hajnoczi int64_t sector_num; 10251c9805a3SStefan Hajnoczi int nb_sectors; 10261c9805a3SStefan Hajnoczi QEMUIOVector *qiov; 10271c9805a3SStefan Hajnoczi bool is_write; 10281c9805a3SStefan Hajnoczi int ret; 10291c9805a3SStefan Hajnoczi } RwCo; 10301c9805a3SStefan Hajnoczi 10311c9805a3SStefan Hajnoczi static void coroutine_fn bdrv_rw_co_entry(void *opaque) 1032fc01f7e7Sbellard { 10331c9805a3SStefan Hajnoczi RwCo *rwco = opaque; 1034fc01f7e7Sbellard 10351c9805a3SStefan Hajnoczi if (!rwco->is_write) { 10361c9805a3SStefan Hajnoczi rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num, 10371c9805a3SStefan Hajnoczi rwco->nb_sectors, rwco->qiov); 10381c9805a3SStefan Hajnoczi } else { 10391c9805a3SStefan Hajnoczi rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num, 10401c9805a3SStefan Hajnoczi rwco->nb_sectors, rwco->qiov); 10411c9805a3SStefan Hajnoczi } 10421c9805a3SStefan Hajnoczi } 1043e7a8a783SKevin Wolf 10441c9805a3SStefan Hajnoczi /* 10451c9805a3SStefan Hajnoczi * Process a synchronous request using coroutines 10461c9805a3SStefan Hajnoczi */ 10471c9805a3SStefan Hajnoczi static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, 10481c9805a3SStefan Hajnoczi int nb_sectors, bool is_write) 10491c9805a3SStefan Hajnoczi { 1050e7a8a783SKevin Wolf QEMUIOVector qiov; 1051e7a8a783SKevin Wolf struct iovec iov = { 1052e7a8a783SKevin Wolf .iov_base = (void *)buf, 1053e7a8a783SKevin Wolf .iov_len = nb_sectors * BDRV_SECTOR_SIZE, 1054e7a8a783SKevin Wolf }; 10551c9805a3SStefan Hajnoczi Coroutine *co; 10561c9805a3SStefan Hajnoczi RwCo rwco = { 10571c9805a3SStefan Hajnoczi .bs = bs, 10581c9805a3SStefan Hajnoczi .sector_num = sector_num, 10591c9805a3SStefan Hajnoczi .nb_sectors = nb_sectors, 10601c9805a3SStefan Hajnoczi .qiov = &qiov, 10611c9805a3SStefan Hajnoczi .is_write = is_write, 10621c9805a3SStefan Hajnoczi .ret = NOT_DONE, 10631c9805a3SStefan Hajnoczi }; 1064e7a8a783SKevin Wolf 1065e7a8a783SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 10661c9805a3SStefan Hajnoczi 10671c9805a3SStefan Hajnoczi if (qemu_in_coroutine()) { 10681c9805a3SStefan Hajnoczi /* Fast-path if already in coroutine context */ 10691c9805a3SStefan Hajnoczi bdrv_rw_co_entry(&rwco); 10701c9805a3SStefan Hajnoczi } else { 10711c9805a3SStefan Hajnoczi co = qemu_coroutine_create(bdrv_rw_co_entry); 10721c9805a3SStefan Hajnoczi qemu_coroutine_enter(co, &rwco); 10731c9805a3SStefan Hajnoczi while (rwco.ret == NOT_DONE) { 10741c9805a3SStefan Hajnoczi qemu_aio_wait(); 10751c9805a3SStefan Hajnoczi } 10761c9805a3SStefan Hajnoczi } 10771c9805a3SStefan Hajnoczi return rwco.ret; 1078e7a8a783SKevin Wolf } 1079e7a8a783SKevin Wolf 10801c9805a3SStefan Hajnoczi /* return < 0 if error. See bdrv_write() for the return codes */ 10811c9805a3SStefan Hajnoczi int bdrv_read(BlockDriverState *bs, int64_t sector_num, 10821c9805a3SStefan Hajnoczi uint8_t *buf, int nb_sectors) 10831c9805a3SStefan Hajnoczi { 10841c9805a3SStefan Hajnoczi return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false); 108583f64091Sbellard } 1086fc01f7e7Sbellard 10877cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, 10887cd1e32aSlirans@il.ibm.com int nb_sectors, int dirty) 10897cd1e32aSlirans@il.ibm.com { 10907cd1e32aSlirans@il.ibm.com int64_t start, end; 1091c6d22830SJan Kiszka unsigned long val, idx, bit; 1092a55eb92cSJan Kiszka 10936ea44308SJan Kiszka start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; 1094c6d22830SJan Kiszka end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK; 10957cd1e32aSlirans@il.ibm.com 10967cd1e32aSlirans@il.ibm.com for (; start <= end; start++) { 1097c6d22830SJan Kiszka idx = start / (sizeof(unsigned long) * 8); 1098c6d22830SJan Kiszka bit = start % (sizeof(unsigned long) * 8); 1099c6d22830SJan Kiszka val = bs->dirty_bitmap[idx]; 1100c6d22830SJan Kiszka if (dirty) { 11016d59fec1SMarcelo Tosatti if (!(val & (1UL << bit))) { 1102aaa0eb75SLiran Schour bs->dirty_count++; 11036d59fec1SMarcelo Tosatti val |= 1UL << bit; 1104aaa0eb75SLiran Schour } 1105c6d22830SJan Kiszka } else { 11066d59fec1SMarcelo Tosatti if (val & (1UL << bit)) { 1107aaa0eb75SLiran Schour bs->dirty_count--; 11086d59fec1SMarcelo Tosatti val &= ~(1UL << bit); 1109c6d22830SJan Kiszka } 1110aaa0eb75SLiran Schour } 1111c6d22830SJan Kiszka bs->dirty_bitmap[idx] = val; 11127cd1e32aSlirans@il.ibm.com } 11137cd1e32aSlirans@il.ibm.com } 11147cd1e32aSlirans@il.ibm.com 111519cb3738Sbellard /* Return < 0 if error. Important errors are: 111619cb3738Sbellard -EIO generic I/O error (may happen for all errors) 111719cb3738Sbellard -ENOMEDIUM No media inserted. 111819cb3738Sbellard -EINVAL Invalid sector number or nb_sectors 111919cb3738Sbellard -EACCES Trying to write a read-only device 112019cb3738Sbellard */ 1121fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num, 1122fc01f7e7Sbellard const uint8_t *buf, int nb_sectors) 1123fc01f7e7Sbellard { 11241c9805a3SStefan Hajnoczi return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true); 112583f64091Sbellard } 112683f64091Sbellard 1127eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset, 1128eda578e5Saliguori void *buf, int count1) 112983f64091Sbellard { 11306ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 113183f64091Sbellard int len, nb_sectors, count; 113283f64091Sbellard int64_t sector_num; 11339a8c4cceSKevin Wolf int ret; 113483f64091Sbellard 113583f64091Sbellard count = count1; 113683f64091Sbellard /* first read to align to sector start */ 11376ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 113883f64091Sbellard if (len > count) 113983f64091Sbellard len = count; 11406ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 114183f64091Sbellard if (len > 0) { 11429a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11439a8c4cceSKevin Wolf return ret; 11446ea44308SJan Kiszka memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); 114583f64091Sbellard count -= len; 114683f64091Sbellard if (count == 0) 114783f64091Sbellard return count1; 114883f64091Sbellard sector_num++; 114983f64091Sbellard buf += len; 115083f64091Sbellard } 115183f64091Sbellard 115283f64091Sbellard /* read the sectors "in place" */ 11536ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 115483f64091Sbellard if (nb_sectors > 0) { 11559a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0) 11569a8c4cceSKevin Wolf return ret; 115783f64091Sbellard sector_num += nb_sectors; 11586ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 115983f64091Sbellard buf += len; 116083f64091Sbellard count -= len; 116183f64091Sbellard } 116283f64091Sbellard 116383f64091Sbellard /* add data from the last sector */ 116483f64091Sbellard if (count > 0) { 11659a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11669a8c4cceSKevin Wolf return ret; 116783f64091Sbellard memcpy(buf, tmp_buf, count); 116883f64091Sbellard } 116983f64091Sbellard return count1; 117083f64091Sbellard } 117183f64091Sbellard 1172eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 1173eda578e5Saliguori const void *buf, int count1) 117483f64091Sbellard { 11756ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 117683f64091Sbellard int len, nb_sectors, count; 117783f64091Sbellard int64_t sector_num; 11789a8c4cceSKevin Wolf int ret; 117983f64091Sbellard 118083f64091Sbellard count = count1; 118183f64091Sbellard /* first write to align to sector start */ 11826ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 118383f64091Sbellard if (len > count) 118483f64091Sbellard len = count; 11856ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 118683f64091Sbellard if (len > 0) { 11879a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11889a8c4cceSKevin Wolf return ret; 11896ea44308SJan Kiszka memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len); 11909a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 11919a8c4cceSKevin Wolf return ret; 119283f64091Sbellard count -= len; 119383f64091Sbellard if (count == 0) 119483f64091Sbellard return count1; 119583f64091Sbellard sector_num++; 119683f64091Sbellard buf += len; 119783f64091Sbellard } 119883f64091Sbellard 119983f64091Sbellard /* write the sectors "in place" */ 12006ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 120183f64091Sbellard if (nb_sectors > 0) { 12029a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0) 12039a8c4cceSKevin Wolf return ret; 120483f64091Sbellard sector_num += nb_sectors; 12056ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 120683f64091Sbellard buf += len; 120783f64091Sbellard count -= len; 120883f64091Sbellard } 120983f64091Sbellard 121083f64091Sbellard /* add data from the last sector */ 121183f64091Sbellard if (count > 0) { 12129a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 12139a8c4cceSKevin Wolf return ret; 121483f64091Sbellard memcpy(tmp_buf, buf, count); 12159a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 12169a8c4cceSKevin Wolf return ret; 121783f64091Sbellard } 121883f64091Sbellard return count1; 121983f64091Sbellard } 122083f64091Sbellard 1221f08145feSKevin Wolf /* 1222f08145feSKevin Wolf * Writes to the file and ensures that no writes are reordered across this 1223f08145feSKevin Wolf * request (acts as a barrier) 1224f08145feSKevin Wolf * 1225f08145feSKevin Wolf * Returns 0 on success, -errno in error cases. 1226f08145feSKevin Wolf */ 1227f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, 1228f08145feSKevin Wolf const void *buf, int count) 1229f08145feSKevin Wolf { 1230f08145feSKevin Wolf int ret; 1231f08145feSKevin Wolf 1232f08145feSKevin Wolf ret = bdrv_pwrite(bs, offset, buf, count); 1233f08145feSKevin Wolf if (ret < 0) { 1234f08145feSKevin Wolf return ret; 1235f08145feSKevin Wolf } 1236f08145feSKevin Wolf 123792196b2fSStefan Hajnoczi /* No flush needed for cache modes that use O_DSYNC */ 123892196b2fSStefan Hajnoczi if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) { 1239f08145feSKevin Wolf bdrv_flush(bs); 1240f08145feSKevin Wolf } 1241f08145feSKevin Wolf 1242f08145feSKevin Wolf return 0; 1243f08145feSKevin Wolf } 1244f08145feSKevin Wolf 1245c5fbe571SStefan Hajnoczi /* 1246c5fbe571SStefan Hajnoczi * Handle a read request in coroutine context 1247c5fbe571SStefan Hajnoczi */ 1248c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, 1249c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) 1250da1fa91dSKevin Wolf { 1251da1fa91dSKevin Wolf BlockDriver *drv = bs->drv; 1252da1fa91dSKevin Wolf 1253da1fa91dSKevin Wolf if (!drv) { 1254da1fa91dSKevin Wolf return -ENOMEDIUM; 1255da1fa91dSKevin Wolf } 1256da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1257da1fa91dSKevin Wolf return -EIO; 1258da1fa91dSKevin Wolf } 1259da1fa91dSKevin Wolf 1260da1fa91dSKevin Wolf return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); 1261da1fa91dSKevin Wolf } 1262da1fa91dSKevin Wolf 1263c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, 1264da1fa91dSKevin Wolf int nb_sectors, QEMUIOVector *qiov) 1265da1fa91dSKevin Wolf { 1266c5fbe571SStefan Hajnoczi trace_bdrv_co_readv(bs, sector_num, nb_sectors); 1267da1fa91dSKevin Wolf 1268c5fbe571SStefan Hajnoczi return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov); 1269c5fbe571SStefan Hajnoczi } 1270c5fbe571SStefan Hajnoczi 1271c5fbe571SStefan Hajnoczi /* 1272c5fbe571SStefan Hajnoczi * Handle a write request in coroutine context 1273c5fbe571SStefan Hajnoczi */ 1274c5fbe571SStefan Hajnoczi static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, 1275c5fbe571SStefan Hajnoczi int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) 1276c5fbe571SStefan Hajnoczi { 1277c5fbe571SStefan Hajnoczi BlockDriver *drv = bs->drv; 12786b7cb247SStefan Hajnoczi int ret; 1279da1fa91dSKevin Wolf 1280da1fa91dSKevin Wolf if (!bs->drv) { 1281da1fa91dSKevin Wolf return -ENOMEDIUM; 1282da1fa91dSKevin Wolf } 1283da1fa91dSKevin Wolf if (bs->read_only) { 1284da1fa91dSKevin Wolf return -EACCES; 1285da1fa91dSKevin Wolf } 1286da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1287da1fa91dSKevin Wolf return -EIO; 1288da1fa91dSKevin Wolf } 1289da1fa91dSKevin Wolf 12906b7cb247SStefan Hajnoczi ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); 12916b7cb247SStefan Hajnoczi 1292da1fa91dSKevin Wolf if (bs->dirty_bitmap) { 1293da1fa91dSKevin Wolf set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 1294da1fa91dSKevin Wolf } 1295da1fa91dSKevin Wolf 1296da1fa91dSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 1297da1fa91dSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 1298da1fa91dSKevin Wolf } 1299da1fa91dSKevin Wolf 13006b7cb247SStefan Hajnoczi return ret; 1301da1fa91dSKevin Wolf } 1302da1fa91dSKevin Wolf 1303c5fbe571SStefan Hajnoczi int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, 1304c5fbe571SStefan Hajnoczi int nb_sectors, QEMUIOVector *qiov) 1305c5fbe571SStefan Hajnoczi { 1306c5fbe571SStefan Hajnoczi trace_bdrv_co_writev(bs, sector_num, nb_sectors); 1307c5fbe571SStefan Hajnoczi 1308c5fbe571SStefan Hajnoczi return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov); 1309c5fbe571SStefan Hajnoczi } 1310c5fbe571SStefan Hajnoczi 131183f64091Sbellard /** 131283f64091Sbellard * Truncate file to 'offset' bytes (needed only for file protocols) 131383f64091Sbellard */ 131483f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset) 131583f64091Sbellard { 131683f64091Sbellard BlockDriver *drv = bs->drv; 131751762288SStefan Hajnoczi int ret; 131883f64091Sbellard if (!drv) 131919cb3738Sbellard return -ENOMEDIUM; 132083f64091Sbellard if (!drv->bdrv_truncate) 132183f64091Sbellard return -ENOTSUP; 132259f2689dSNaphtali Sprei if (bs->read_only) 132359f2689dSNaphtali Sprei return -EACCES; 13248591675fSMarcelo Tosatti if (bdrv_in_use(bs)) 13258591675fSMarcelo Tosatti return -EBUSY; 132651762288SStefan Hajnoczi ret = drv->bdrv_truncate(bs, offset); 132751762288SStefan Hajnoczi if (ret == 0) { 132851762288SStefan Hajnoczi ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); 1329145feb17SMarkus Armbruster bdrv_dev_resize_cb(bs); 133051762288SStefan Hajnoczi } 133151762288SStefan Hajnoczi return ret; 133283f64091Sbellard } 133383f64091Sbellard 133483f64091Sbellard /** 13354a1d5e1fSFam Zheng * Length of a allocated file in bytes. Sparse files are counted by actual 13364a1d5e1fSFam Zheng * allocated space. Return < 0 if error or unknown. 13374a1d5e1fSFam Zheng */ 13384a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) 13394a1d5e1fSFam Zheng { 13404a1d5e1fSFam Zheng BlockDriver *drv = bs->drv; 13414a1d5e1fSFam Zheng if (!drv) { 13424a1d5e1fSFam Zheng return -ENOMEDIUM; 13434a1d5e1fSFam Zheng } 13444a1d5e1fSFam Zheng if (drv->bdrv_get_allocated_file_size) { 13454a1d5e1fSFam Zheng return drv->bdrv_get_allocated_file_size(bs); 13464a1d5e1fSFam Zheng } 13474a1d5e1fSFam Zheng if (bs->file) { 13484a1d5e1fSFam Zheng return bdrv_get_allocated_file_size(bs->file); 13494a1d5e1fSFam Zheng } 13504a1d5e1fSFam Zheng return -ENOTSUP; 13514a1d5e1fSFam Zheng } 13524a1d5e1fSFam Zheng 13534a1d5e1fSFam Zheng /** 135483f64091Sbellard * Length of a file in bytes. Return < 0 if error or unknown. 135583f64091Sbellard */ 135683f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs) 135783f64091Sbellard { 135883f64091Sbellard BlockDriver *drv = bs->drv; 135983f64091Sbellard if (!drv) 136019cb3738Sbellard return -ENOMEDIUM; 136151762288SStefan Hajnoczi 13622c6942faSMarkus Armbruster if (bs->growable || bdrv_dev_has_removable_media(bs)) { 136346a4e4e6SStefan Hajnoczi if (drv->bdrv_getlength) { 136483f64091Sbellard return drv->bdrv_getlength(bs); 1365fc01f7e7Sbellard } 136646a4e4e6SStefan Hajnoczi } 136746a4e4e6SStefan Hajnoczi return bs->total_sectors * BDRV_SECTOR_SIZE; 136846a4e4e6SStefan Hajnoczi } 1369fc01f7e7Sbellard 137019cb3738Sbellard /* return 0 as number of sectors if no device present or error */ 137196b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 1372fc01f7e7Sbellard { 137319cb3738Sbellard int64_t length; 137419cb3738Sbellard length = bdrv_getlength(bs); 137519cb3738Sbellard if (length < 0) 137619cb3738Sbellard length = 0; 137719cb3738Sbellard else 13786ea44308SJan Kiszka length = length >> BDRV_SECTOR_BITS; 137919cb3738Sbellard *nb_sectors_ptr = length; 1380fc01f7e7Sbellard } 1381cf98951bSbellard 1382f3d54fc4Saliguori struct partition { 1383f3d54fc4Saliguori uint8_t boot_ind; /* 0x80 - active */ 1384f3d54fc4Saliguori uint8_t head; /* starting head */ 1385f3d54fc4Saliguori uint8_t sector; /* starting sector */ 1386f3d54fc4Saliguori uint8_t cyl; /* starting cylinder */ 1387f3d54fc4Saliguori uint8_t sys_ind; /* What partition type */ 1388f3d54fc4Saliguori uint8_t end_head; /* end head */ 1389f3d54fc4Saliguori uint8_t end_sector; /* end sector */ 1390f3d54fc4Saliguori uint8_t end_cyl; /* end cylinder */ 1391f3d54fc4Saliguori uint32_t start_sect; /* starting sector counting from 0 */ 1392f3d54fc4Saliguori uint32_t nr_sects; /* nr of sectors in partition */ 1393541dc0d4SStefan Weil } QEMU_PACKED; 1394f3d54fc4Saliguori 1395f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 1396f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs, 1397f3d54fc4Saliguori int *pcylinders, int *pheads, int *psectors) 1398f3d54fc4Saliguori { 1399eb5a3165SJes Sorensen uint8_t buf[BDRV_SECTOR_SIZE]; 1400f3d54fc4Saliguori int ret, i, heads, sectors, cylinders; 1401f3d54fc4Saliguori struct partition *p; 1402f3d54fc4Saliguori uint32_t nr_sects; 1403a38131b6Sblueswir1 uint64_t nb_sectors; 1404f3d54fc4Saliguori 1405f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1406f3d54fc4Saliguori 1407f3d54fc4Saliguori ret = bdrv_read(bs, 0, buf, 1); 1408f3d54fc4Saliguori if (ret < 0) 1409f3d54fc4Saliguori return -1; 1410f3d54fc4Saliguori /* test msdos magic */ 1411f3d54fc4Saliguori if (buf[510] != 0x55 || buf[511] != 0xaa) 1412f3d54fc4Saliguori return -1; 1413f3d54fc4Saliguori for(i = 0; i < 4; i++) { 1414f3d54fc4Saliguori p = ((struct partition *)(buf + 0x1be)) + i; 1415f3d54fc4Saliguori nr_sects = le32_to_cpu(p->nr_sects); 1416f3d54fc4Saliguori if (nr_sects && p->end_head) { 1417f3d54fc4Saliguori /* We make the assumption that the partition terminates on 1418f3d54fc4Saliguori a cylinder boundary */ 1419f3d54fc4Saliguori heads = p->end_head + 1; 1420f3d54fc4Saliguori sectors = p->end_sector & 63; 1421f3d54fc4Saliguori if (sectors == 0) 1422f3d54fc4Saliguori continue; 1423f3d54fc4Saliguori cylinders = nb_sectors / (heads * sectors); 1424f3d54fc4Saliguori if (cylinders < 1 || cylinders > 16383) 1425f3d54fc4Saliguori continue; 1426f3d54fc4Saliguori *pheads = heads; 1427f3d54fc4Saliguori *psectors = sectors; 1428f3d54fc4Saliguori *pcylinders = cylinders; 1429f3d54fc4Saliguori #if 0 1430f3d54fc4Saliguori printf("guessed geometry: LCHS=%d %d %d\n", 1431f3d54fc4Saliguori cylinders, heads, sectors); 1432f3d54fc4Saliguori #endif 1433f3d54fc4Saliguori return 0; 1434f3d54fc4Saliguori } 1435f3d54fc4Saliguori } 1436f3d54fc4Saliguori return -1; 1437f3d54fc4Saliguori } 1438f3d54fc4Saliguori 1439f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 1440f3d54fc4Saliguori { 1441f3d54fc4Saliguori int translation, lba_detected = 0; 1442f3d54fc4Saliguori int cylinders, heads, secs; 1443a38131b6Sblueswir1 uint64_t nb_sectors; 1444f3d54fc4Saliguori 1445f3d54fc4Saliguori /* if a geometry hint is available, use it */ 1446f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1447f3d54fc4Saliguori bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 1448f3d54fc4Saliguori translation = bdrv_get_translation_hint(bs); 1449f3d54fc4Saliguori if (cylinders != 0) { 1450f3d54fc4Saliguori *pcyls = cylinders; 1451f3d54fc4Saliguori *pheads = heads; 1452f3d54fc4Saliguori *psecs = secs; 1453f3d54fc4Saliguori } else { 1454f3d54fc4Saliguori if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 1455f3d54fc4Saliguori if (heads > 16) { 1456f3d54fc4Saliguori /* if heads > 16, it means that a BIOS LBA 1457f3d54fc4Saliguori translation was active, so the default 1458f3d54fc4Saliguori hardware geometry is OK */ 1459f3d54fc4Saliguori lba_detected = 1; 1460f3d54fc4Saliguori goto default_geometry; 1461f3d54fc4Saliguori } else { 1462f3d54fc4Saliguori *pcyls = cylinders; 1463f3d54fc4Saliguori *pheads = heads; 1464f3d54fc4Saliguori *psecs = secs; 1465f3d54fc4Saliguori /* disable any translation to be in sync with 1466f3d54fc4Saliguori the logical geometry */ 1467f3d54fc4Saliguori if (translation == BIOS_ATA_TRANSLATION_AUTO) { 1468f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1469f3d54fc4Saliguori BIOS_ATA_TRANSLATION_NONE); 1470f3d54fc4Saliguori } 1471f3d54fc4Saliguori } 1472f3d54fc4Saliguori } else { 1473f3d54fc4Saliguori default_geometry: 1474f3d54fc4Saliguori /* if no geometry, use a standard physical disk geometry */ 1475f3d54fc4Saliguori cylinders = nb_sectors / (16 * 63); 1476f3d54fc4Saliguori 1477f3d54fc4Saliguori if (cylinders > 16383) 1478f3d54fc4Saliguori cylinders = 16383; 1479f3d54fc4Saliguori else if (cylinders < 2) 1480f3d54fc4Saliguori cylinders = 2; 1481f3d54fc4Saliguori *pcyls = cylinders; 1482f3d54fc4Saliguori *pheads = 16; 1483f3d54fc4Saliguori *psecs = 63; 1484f3d54fc4Saliguori if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 1485f3d54fc4Saliguori if ((*pcyls * *pheads) <= 131072) { 1486f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1487f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LARGE); 1488f3d54fc4Saliguori } else { 1489f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1490f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LBA); 1491f3d54fc4Saliguori } 1492f3d54fc4Saliguori } 1493f3d54fc4Saliguori } 1494f3d54fc4Saliguori bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 1495f3d54fc4Saliguori } 1496f3d54fc4Saliguori } 1497f3d54fc4Saliguori 1498b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs, 1499b338082bSbellard int cyls, int heads, int secs) 1500b338082bSbellard { 1501b338082bSbellard bs->cyls = cyls; 1502b338082bSbellard bs->heads = heads; 1503b338082bSbellard bs->secs = secs; 1504b338082bSbellard } 1505b338082bSbellard 150646d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 150746d4767dSbellard { 150846d4767dSbellard bs->translation = translation; 150946d4767dSbellard } 151046d4767dSbellard 1511b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs, 1512b338082bSbellard int *pcyls, int *pheads, int *psecs) 1513b338082bSbellard { 1514b338082bSbellard *pcyls = bs->cyls; 1515b338082bSbellard *pheads = bs->heads; 1516b338082bSbellard *psecs = bs->secs; 1517b338082bSbellard } 1518b338082bSbellard 15195bbdbb46SBlue Swirl /* Recognize floppy formats */ 15205bbdbb46SBlue Swirl typedef struct FDFormat { 15215bbdbb46SBlue Swirl FDriveType drive; 15225bbdbb46SBlue Swirl uint8_t last_sect; 15235bbdbb46SBlue Swirl uint8_t max_track; 15245bbdbb46SBlue Swirl uint8_t max_head; 15255bbdbb46SBlue Swirl } FDFormat; 15265bbdbb46SBlue Swirl 15275bbdbb46SBlue Swirl static const FDFormat fd_formats[] = { 15285bbdbb46SBlue Swirl /* First entry is default format */ 15295bbdbb46SBlue Swirl /* 1.44 MB 3"1/2 floppy disks */ 15305bbdbb46SBlue Swirl { FDRIVE_DRV_144, 18, 80, 1, }, 15315bbdbb46SBlue Swirl { FDRIVE_DRV_144, 20, 80, 1, }, 15325bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 80, 1, }, 15335bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 82, 1, }, 15345bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 83, 1, }, 15355bbdbb46SBlue Swirl { FDRIVE_DRV_144, 22, 80, 1, }, 15365bbdbb46SBlue Swirl { FDRIVE_DRV_144, 23, 80, 1, }, 15375bbdbb46SBlue Swirl { FDRIVE_DRV_144, 24, 80, 1, }, 15385bbdbb46SBlue Swirl /* 2.88 MB 3"1/2 floppy disks */ 15395bbdbb46SBlue Swirl { FDRIVE_DRV_288, 36, 80, 1, }, 15405bbdbb46SBlue Swirl { FDRIVE_DRV_288, 39, 80, 1, }, 15415bbdbb46SBlue Swirl { FDRIVE_DRV_288, 40, 80, 1, }, 15425bbdbb46SBlue Swirl { FDRIVE_DRV_288, 44, 80, 1, }, 15435bbdbb46SBlue Swirl { FDRIVE_DRV_288, 48, 80, 1, }, 15445bbdbb46SBlue Swirl /* 720 kB 3"1/2 floppy disks */ 15455bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 1, }, 15465bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 80, 1, }, 15475bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 82, 1, }, 15485bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 83, 1, }, 15495bbdbb46SBlue Swirl { FDRIVE_DRV_144, 13, 80, 1, }, 15505bbdbb46SBlue Swirl { FDRIVE_DRV_144, 14, 80, 1, }, 15515bbdbb46SBlue Swirl /* 1.2 MB 5"1/4 floppy disks */ 15525bbdbb46SBlue Swirl { FDRIVE_DRV_120, 15, 80, 1, }, 15535bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 80, 1, }, 15545bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 82, 1, }, 15555bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 83, 1, }, 15565bbdbb46SBlue Swirl { FDRIVE_DRV_120, 20, 80, 1, }, 15575bbdbb46SBlue Swirl /* 720 kB 5"1/4 floppy disks */ 15585bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 80, 1, }, 15595bbdbb46SBlue Swirl { FDRIVE_DRV_120, 11, 80, 1, }, 15605bbdbb46SBlue Swirl /* 360 kB 5"1/4 floppy disks */ 15615bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 1, }, 15625bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 0, }, 15635bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 41, 1, }, 15645bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 42, 1, }, 15655bbdbb46SBlue Swirl /* 320 kB 5"1/4 floppy disks */ 15665bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 1, }, 15675bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 0, }, 15685bbdbb46SBlue Swirl /* 360 kB must match 5"1/4 better than 3"1/2... */ 15695bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 0, }, 15705bbdbb46SBlue Swirl /* end */ 15715bbdbb46SBlue Swirl { FDRIVE_DRV_NONE, -1, -1, 0, }, 15725bbdbb46SBlue Swirl }; 15735bbdbb46SBlue Swirl 15745bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, 15755bbdbb46SBlue Swirl int *max_track, int *last_sect, 15765bbdbb46SBlue Swirl FDriveType drive_in, FDriveType *drive) 15775bbdbb46SBlue Swirl { 15785bbdbb46SBlue Swirl const FDFormat *parse; 15795bbdbb46SBlue Swirl uint64_t nb_sectors, size; 15805bbdbb46SBlue Swirl int i, first_match, match; 15815bbdbb46SBlue Swirl 15825bbdbb46SBlue Swirl bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect); 15835bbdbb46SBlue Swirl if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) { 15845bbdbb46SBlue Swirl /* User defined disk */ 15855bbdbb46SBlue Swirl } else { 15865bbdbb46SBlue Swirl bdrv_get_geometry(bs, &nb_sectors); 15875bbdbb46SBlue Swirl match = -1; 15885bbdbb46SBlue Swirl first_match = -1; 15895bbdbb46SBlue Swirl for (i = 0; ; i++) { 15905bbdbb46SBlue Swirl parse = &fd_formats[i]; 15915bbdbb46SBlue Swirl if (parse->drive == FDRIVE_DRV_NONE) { 15925bbdbb46SBlue Swirl break; 15935bbdbb46SBlue Swirl } 15945bbdbb46SBlue Swirl if (drive_in == parse->drive || 15955bbdbb46SBlue Swirl drive_in == FDRIVE_DRV_NONE) { 15965bbdbb46SBlue Swirl size = (parse->max_head + 1) * parse->max_track * 15975bbdbb46SBlue Swirl parse->last_sect; 15985bbdbb46SBlue Swirl if (nb_sectors == size) { 15995bbdbb46SBlue Swirl match = i; 16005bbdbb46SBlue Swirl break; 16015bbdbb46SBlue Swirl } 16025bbdbb46SBlue Swirl if (first_match == -1) { 16035bbdbb46SBlue Swirl first_match = i; 16045bbdbb46SBlue Swirl } 16055bbdbb46SBlue Swirl } 16065bbdbb46SBlue Swirl } 16075bbdbb46SBlue Swirl if (match == -1) { 16085bbdbb46SBlue Swirl if (first_match == -1) { 16095bbdbb46SBlue Swirl match = 1; 16105bbdbb46SBlue Swirl } else { 16115bbdbb46SBlue Swirl match = first_match; 16125bbdbb46SBlue Swirl } 16135bbdbb46SBlue Swirl parse = &fd_formats[match]; 16145bbdbb46SBlue Swirl } 16155bbdbb46SBlue Swirl *nb_heads = parse->max_head + 1; 16165bbdbb46SBlue Swirl *max_track = parse->max_track; 16175bbdbb46SBlue Swirl *last_sect = parse->last_sect; 16185bbdbb46SBlue Swirl *drive = parse->drive; 16195bbdbb46SBlue Swirl } 16205bbdbb46SBlue Swirl } 16215bbdbb46SBlue Swirl 162246d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs) 162346d4767dSbellard { 162446d4767dSbellard return bs->translation; 162546d4767dSbellard } 162646d4767dSbellard 1627abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error, 1628abd7f68dSMarkus Armbruster BlockErrorAction on_write_error) 1629abd7f68dSMarkus Armbruster { 1630abd7f68dSMarkus Armbruster bs->on_read_error = on_read_error; 1631abd7f68dSMarkus Armbruster bs->on_write_error = on_write_error; 1632abd7f68dSMarkus Armbruster } 1633abd7f68dSMarkus Armbruster 1634abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read) 1635abd7f68dSMarkus Armbruster { 1636abd7f68dSMarkus Armbruster return is_read ? bs->on_read_error : bs->on_write_error; 1637abd7f68dSMarkus Armbruster } 1638abd7f68dSMarkus Armbruster 1639b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs) 1640b338082bSbellard { 1641b338082bSbellard return bs->read_only; 1642b338082bSbellard } 1643b338082bSbellard 1644985a03b0Sths int bdrv_is_sg(BlockDriverState *bs) 1645985a03b0Sths { 1646985a03b0Sths return bs->sg; 1647985a03b0Sths } 1648985a03b0Sths 1649e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs) 1650e900a7b7SChristoph Hellwig { 1651e900a7b7SChristoph Hellwig return bs->enable_write_cache; 1652e900a7b7SChristoph Hellwig } 1653e900a7b7SChristoph Hellwig 1654ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs) 1655ea2384d3Sbellard { 1656ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) 1657ea2384d3Sbellard return 1; 1658ea2384d3Sbellard return bs->encrypted; 1659ea2384d3Sbellard } 1660ea2384d3Sbellard 1661c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs) 1662c0f4ce77Saliguori { 1663c0f4ce77Saliguori BlockDriverState *backing_hd = bs->backing_hd; 1664c0f4ce77Saliguori 1665c0f4ce77Saliguori if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 1666c0f4ce77Saliguori return 1; 1667c0f4ce77Saliguori return (bs->encrypted && !bs->valid_key); 1668c0f4ce77Saliguori } 1669c0f4ce77Saliguori 1670ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key) 1671ea2384d3Sbellard { 1672ea2384d3Sbellard int ret; 1673ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) { 1674ea2384d3Sbellard ret = bdrv_set_key(bs->backing_hd, key); 1675ea2384d3Sbellard if (ret < 0) 1676ea2384d3Sbellard return ret; 1677ea2384d3Sbellard if (!bs->encrypted) 1678ea2384d3Sbellard return 0; 1679ea2384d3Sbellard } 1680fd04a2aeSShahar Havivi if (!bs->encrypted) { 1681fd04a2aeSShahar Havivi return -EINVAL; 1682fd04a2aeSShahar Havivi } else if (!bs->drv || !bs->drv->bdrv_set_key) { 1683fd04a2aeSShahar Havivi return -ENOMEDIUM; 1684fd04a2aeSShahar Havivi } 1685c0f4ce77Saliguori ret = bs->drv->bdrv_set_key(bs, key); 1686bb5fc20fSaliguori if (ret < 0) { 1687bb5fc20fSaliguori bs->valid_key = 0; 1688bb5fc20fSaliguori } else if (!bs->valid_key) { 1689bb5fc20fSaliguori bs->valid_key = 1; 1690bb5fc20fSaliguori /* call the change callback now, we skipped it on open */ 16917d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 1692bb5fc20fSaliguori } 1693c0f4ce77Saliguori return ret; 1694ea2384d3Sbellard } 1695ea2384d3Sbellard 1696ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 1697ea2384d3Sbellard { 169819cb3738Sbellard if (!bs->drv) { 1699ea2384d3Sbellard buf[0] = '\0'; 1700ea2384d3Sbellard } else { 1701ea2384d3Sbellard pstrcpy(buf, buf_size, bs->drv->format_name); 1702ea2384d3Sbellard } 1703ea2384d3Sbellard } 1704ea2384d3Sbellard 1705ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 1706ea2384d3Sbellard void *opaque) 1707ea2384d3Sbellard { 1708ea2384d3Sbellard BlockDriver *drv; 1709ea2384d3Sbellard 17108a22f02aSStefan Hajnoczi QLIST_FOREACH(drv, &bdrv_drivers, list) { 1711ea2384d3Sbellard it(opaque, drv->format_name); 1712ea2384d3Sbellard } 1713ea2384d3Sbellard } 1714ea2384d3Sbellard 1715b338082bSbellard BlockDriverState *bdrv_find(const char *name) 1716b338082bSbellard { 1717b338082bSbellard BlockDriverState *bs; 1718b338082bSbellard 17191b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 17201b7bdbc1SStefan Hajnoczi if (!strcmp(name, bs->device_name)) { 1721b338082bSbellard return bs; 1722b338082bSbellard } 17231b7bdbc1SStefan Hajnoczi } 1724b338082bSbellard return NULL; 1725b338082bSbellard } 1726b338082bSbellard 17272f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs) 17282f399b0aSMarkus Armbruster { 17292f399b0aSMarkus Armbruster if (!bs) { 17302f399b0aSMarkus Armbruster return QTAILQ_FIRST(&bdrv_states); 17312f399b0aSMarkus Armbruster } 17322f399b0aSMarkus Armbruster return QTAILQ_NEXT(bs, list); 17332f399b0aSMarkus Armbruster } 17342f399b0aSMarkus Armbruster 173551de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 173681d0912dSbellard { 173781d0912dSbellard BlockDriverState *bs; 173881d0912dSbellard 17391b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 174051de9760Saliguori it(opaque, bs); 174181d0912dSbellard } 174281d0912dSbellard } 174381d0912dSbellard 1744ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs) 1745ea2384d3Sbellard { 1746ea2384d3Sbellard return bs->device_name; 1747ea2384d3Sbellard } 1748ea2384d3Sbellard 1749c6ca28d6Saliguori void bdrv_flush_all(void) 1750c6ca28d6Saliguori { 1751c6ca28d6Saliguori BlockDriverState *bs; 1752c6ca28d6Saliguori 17531b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1754c602a489SMarkus Armbruster if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) { 1755c6ca28d6Saliguori bdrv_flush(bs); 1756c6ca28d6Saliguori } 17571b7bdbc1SStefan Hajnoczi } 17581b7bdbc1SStefan Hajnoczi } 1759c6ca28d6Saliguori 1760f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs) 1761f2feebbdSKevin Wolf { 1762f2feebbdSKevin Wolf assert(bs->drv); 1763f2feebbdSKevin Wolf 1764336c1c12SKevin Wolf if (bs->drv->bdrv_has_zero_init) { 1765336c1c12SKevin Wolf return bs->drv->bdrv_has_zero_init(bs); 1766f2feebbdSKevin Wolf } 1767f2feebbdSKevin Wolf 1768f2feebbdSKevin Wolf return 1; 1769f2feebbdSKevin Wolf } 1770f2feebbdSKevin Wolf 1771bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) 1772bb8bf76fSChristoph Hellwig { 1773bb8bf76fSChristoph Hellwig if (!bs->drv) { 1774bb8bf76fSChristoph Hellwig return -ENOMEDIUM; 1775bb8bf76fSChristoph Hellwig } 1776bb8bf76fSChristoph Hellwig if (!bs->drv->bdrv_discard) { 1777bb8bf76fSChristoph Hellwig return 0; 1778bb8bf76fSChristoph Hellwig } 1779bb8bf76fSChristoph Hellwig return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); 1780bb8bf76fSChristoph Hellwig } 1781bb8bf76fSChristoph Hellwig 1782f58c7b35Sths /* 1783f58c7b35Sths * Returns true iff the specified sector is present in the disk image. Drivers 1784f58c7b35Sths * not implementing the functionality are assumed to not support backing files, 1785f58c7b35Sths * hence all their sectors are reported as allocated. 1786f58c7b35Sths * 1787f58c7b35Sths * 'pnum' is set to the number of sectors (including and immediately following 1788f58c7b35Sths * the specified sector) that are known to be in the same 1789f58c7b35Sths * allocated/unallocated state. 1790f58c7b35Sths * 1791f58c7b35Sths * 'nb_sectors' is the max value 'pnum' should be set to. 1792f58c7b35Sths */ 1793f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1794f58c7b35Sths int *pnum) 1795f58c7b35Sths { 1796f58c7b35Sths int64_t n; 1797f58c7b35Sths if (!bs->drv->bdrv_is_allocated) { 1798f58c7b35Sths if (sector_num >= bs->total_sectors) { 1799f58c7b35Sths *pnum = 0; 1800f58c7b35Sths return 0; 1801f58c7b35Sths } 1802f58c7b35Sths n = bs->total_sectors - sector_num; 1803f58c7b35Sths *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1804f58c7b35Sths return 1; 1805f58c7b35Sths } 1806f58c7b35Sths return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1807f58c7b35Sths } 1808f58c7b35Sths 18092582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv, 18102582bfedSLuiz Capitulino BlockMonEventAction action, int is_read) 18112582bfedSLuiz Capitulino { 18122582bfedSLuiz Capitulino QObject *data; 18132582bfedSLuiz Capitulino const char *action_str; 18142582bfedSLuiz Capitulino 18152582bfedSLuiz Capitulino switch (action) { 18162582bfedSLuiz Capitulino case BDRV_ACTION_REPORT: 18172582bfedSLuiz Capitulino action_str = "report"; 18182582bfedSLuiz Capitulino break; 18192582bfedSLuiz Capitulino case BDRV_ACTION_IGNORE: 18202582bfedSLuiz Capitulino action_str = "ignore"; 18212582bfedSLuiz Capitulino break; 18222582bfedSLuiz Capitulino case BDRV_ACTION_STOP: 18232582bfedSLuiz Capitulino action_str = "stop"; 18242582bfedSLuiz Capitulino break; 18252582bfedSLuiz Capitulino default: 18262582bfedSLuiz Capitulino abort(); 18272582bfedSLuiz Capitulino } 18282582bfedSLuiz Capitulino 18292582bfedSLuiz Capitulino data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", 18302582bfedSLuiz Capitulino bdrv->device_name, 18312582bfedSLuiz Capitulino action_str, 18322582bfedSLuiz Capitulino is_read ? "read" : "write"); 18332582bfedSLuiz Capitulino monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data); 18342582bfedSLuiz Capitulino 18352582bfedSLuiz Capitulino qobject_decref(data); 18362582bfedSLuiz Capitulino } 18372582bfedSLuiz Capitulino 1838d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque) 1839b338082bSbellard { 1840d15e5465SLuiz Capitulino QDict *bs_dict; 1841d15e5465SLuiz Capitulino Monitor *mon = opaque; 1842b338082bSbellard 1843d15e5465SLuiz Capitulino bs_dict = qobject_to_qdict(obj); 1844d15e5465SLuiz Capitulino 1845d8aeeb31SMarkus Armbruster monitor_printf(mon, "%s: removable=%d", 1846d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "device"), 1847d15e5465SLuiz Capitulino qdict_get_bool(bs_dict, "removable")); 1848d15e5465SLuiz Capitulino 1849d15e5465SLuiz Capitulino if (qdict_get_bool(bs_dict, "removable")) { 1850d15e5465SLuiz Capitulino monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); 1851e4def80bSMarkus Armbruster monitor_printf(mon, " tray-open=%d", 1852e4def80bSMarkus Armbruster qdict_get_bool(bs_dict, "tray-open")); 1853b338082bSbellard } 1854d2078cc2SLuiz Capitulino 1855d2078cc2SLuiz Capitulino if (qdict_haskey(bs_dict, "io-status")) { 1856d2078cc2SLuiz Capitulino monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status")); 1857d2078cc2SLuiz Capitulino } 1858d2078cc2SLuiz Capitulino 1859d15e5465SLuiz Capitulino if (qdict_haskey(bs_dict, "inserted")) { 1860d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); 1861d15e5465SLuiz Capitulino 1862376253ecSaliguori monitor_printf(mon, " file="); 1863d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "file")); 1864d15e5465SLuiz Capitulino if (qdict_haskey(qdict, "backing_file")) { 1865376253ecSaliguori monitor_printf(mon, " backing_file="); 1866d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); 1867fef30743Sths } 1868d15e5465SLuiz Capitulino monitor_printf(mon, " ro=%d drv=%s encrypted=%d", 1869d15e5465SLuiz Capitulino qdict_get_bool(qdict, "ro"), 1870d15e5465SLuiz Capitulino qdict_get_str(qdict, "drv"), 1871d15e5465SLuiz Capitulino qdict_get_bool(qdict, "encrypted")); 1872b338082bSbellard } else { 1873376253ecSaliguori monitor_printf(mon, " [not inserted]"); 1874b338082bSbellard } 1875d15e5465SLuiz Capitulino 1876376253ecSaliguori monitor_printf(mon, "\n"); 1877b338082bSbellard } 1878d15e5465SLuiz Capitulino 1879d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data) 1880d15e5465SLuiz Capitulino { 1881d15e5465SLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); 1882d15e5465SLuiz Capitulino } 1883d15e5465SLuiz Capitulino 1884f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = { 1885f04ef601SLuiz Capitulino [BDRV_IOS_OK] = "ok", 1886f04ef601SLuiz Capitulino [BDRV_IOS_FAILED] = "failed", 1887f04ef601SLuiz Capitulino [BDRV_IOS_ENOSPC] = "nospace", 1888f04ef601SLuiz Capitulino }; 1889f04ef601SLuiz Capitulino 1890d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data) 1891d15e5465SLuiz Capitulino { 1892d15e5465SLuiz Capitulino QList *bs_list; 1893d15e5465SLuiz Capitulino BlockDriverState *bs; 1894d15e5465SLuiz Capitulino 1895d15e5465SLuiz Capitulino bs_list = qlist_new(); 1896d15e5465SLuiz Capitulino 18971b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1898d15e5465SLuiz Capitulino QObject *bs_obj; 1899e4def80bSMarkus Armbruster QDict *bs_dict; 1900d15e5465SLuiz Capitulino 1901d8aeeb31SMarkus Armbruster bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', " 1902d15e5465SLuiz Capitulino "'removable': %i, 'locked': %i }", 19032c6942faSMarkus Armbruster bs->device_name, 19042c6942faSMarkus Armbruster bdrv_dev_has_removable_media(bs), 1905f107639aSMarkus Armbruster bdrv_dev_is_medium_locked(bs)); 1906e4def80bSMarkus Armbruster bs_dict = qobject_to_qdict(bs_obj); 1907d15e5465SLuiz Capitulino 1908e4def80bSMarkus Armbruster if (bdrv_dev_has_removable_media(bs)) { 1909e4def80bSMarkus Armbruster qdict_put(bs_dict, "tray-open", 1910e4def80bSMarkus Armbruster qbool_from_int(bdrv_dev_is_tray_open(bs))); 1911e4def80bSMarkus Armbruster } 1912f04ef601SLuiz Capitulino 1913f04ef601SLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 1914f04ef601SLuiz Capitulino qdict_put(bs_dict, "io-status", 1915f04ef601SLuiz Capitulino qstring_from_str(io_status_name[bs->iostatus])); 1916f04ef601SLuiz Capitulino } 1917f04ef601SLuiz Capitulino 1918d15e5465SLuiz Capitulino if (bs->drv) { 1919d15e5465SLuiz Capitulino QObject *obj; 1920d15e5465SLuiz Capitulino 1921d15e5465SLuiz Capitulino obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " 1922d15e5465SLuiz Capitulino "'encrypted': %i }", 1923d15e5465SLuiz Capitulino bs->filename, bs->read_only, 1924d15e5465SLuiz Capitulino bs->drv->format_name, 1925d15e5465SLuiz Capitulino bdrv_is_encrypted(bs)); 1926d15e5465SLuiz Capitulino if (bs->backing_file[0] != '\0') { 1927d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(obj); 1928d15e5465SLuiz Capitulino qdict_put(qdict, "backing_file", 1929d15e5465SLuiz Capitulino qstring_from_str(bs->backing_file)); 1930d15e5465SLuiz Capitulino } 1931d15e5465SLuiz Capitulino 1932d15e5465SLuiz Capitulino qdict_put_obj(bs_dict, "inserted", obj); 1933d15e5465SLuiz Capitulino } 1934d15e5465SLuiz Capitulino qlist_append_obj(bs_list, bs_obj); 1935d15e5465SLuiz Capitulino } 1936d15e5465SLuiz Capitulino 1937d15e5465SLuiz Capitulino *ret_data = QOBJECT(bs_list); 1938b338082bSbellard } 1939a36e69ddSths 1940218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque) 1941a36e69ddSths { 1942218a536aSLuiz Capitulino QDict *qdict; 1943218a536aSLuiz Capitulino Monitor *mon = opaque; 1944218a536aSLuiz Capitulino 1945218a536aSLuiz Capitulino qdict = qobject_to_qdict(data); 1946218a536aSLuiz Capitulino monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 1947218a536aSLuiz Capitulino 1948218a536aSLuiz Capitulino qdict = qobject_to_qdict(qdict_get(qdict, "stats")); 1949218a536aSLuiz Capitulino monitor_printf(mon, " rd_bytes=%" PRId64 1950218a536aSLuiz Capitulino " wr_bytes=%" PRId64 1951218a536aSLuiz Capitulino " rd_operations=%" PRId64 1952218a536aSLuiz Capitulino " wr_operations=%" PRId64 1953e8045d67SChristoph Hellwig " flush_operations=%" PRId64 1954c488c7f6SChristoph Hellwig " wr_total_time_ns=%" PRId64 1955c488c7f6SChristoph Hellwig " rd_total_time_ns=%" PRId64 1956c488c7f6SChristoph Hellwig " flush_total_time_ns=%" PRId64 1957218a536aSLuiz Capitulino "\n", 1958218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_bytes"), 1959218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_bytes"), 1960218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_operations"), 1961e8045d67SChristoph Hellwig qdict_get_int(qdict, "wr_operations"), 1962c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_operations"), 1963c488c7f6SChristoph Hellwig qdict_get_int(qdict, "wr_total_time_ns"), 1964c488c7f6SChristoph Hellwig qdict_get_int(qdict, "rd_total_time_ns"), 1965c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_total_time_ns")); 1966218a536aSLuiz Capitulino } 1967218a536aSLuiz Capitulino 1968218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data) 1969218a536aSLuiz Capitulino { 1970218a536aSLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); 1971218a536aSLuiz Capitulino } 1972218a536aSLuiz Capitulino 1973294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs) 1974294cc35fSKevin Wolf { 1975294cc35fSKevin Wolf QObject *res; 1976294cc35fSKevin Wolf QDict *dict; 1977294cc35fSKevin Wolf 1978294cc35fSKevin Wolf res = qobject_from_jsonf("{ 'stats': {" 1979294cc35fSKevin Wolf "'rd_bytes': %" PRId64 "," 1980294cc35fSKevin Wolf "'wr_bytes': %" PRId64 "," 1981294cc35fSKevin Wolf "'rd_operations': %" PRId64 "," 1982294cc35fSKevin Wolf "'wr_operations': %" PRId64 "," 1983e8045d67SChristoph Hellwig "'wr_highest_offset': %" PRId64 "," 1984c488c7f6SChristoph Hellwig "'flush_operations': %" PRId64 "," 1985c488c7f6SChristoph Hellwig "'wr_total_time_ns': %" PRId64 "," 1986c488c7f6SChristoph Hellwig "'rd_total_time_ns': %" PRId64 "," 1987c488c7f6SChristoph Hellwig "'flush_total_time_ns': %" PRId64 1988294cc35fSKevin Wolf "} }", 1989a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_READ], 1990a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_WRITE], 1991a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_READ], 1992a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_WRITE], 19935ffbbc67SBlue Swirl bs->wr_highest_sector * 1994e8045d67SChristoph Hellwig (uint64_t)BDRV_SECTOR_SIZE, 1995c488c7f6SChristoph Hellwig bs->nr_ops[BDRV_ACCT_FLUSH], 1996c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_WRITE], 1997c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_READ], 1998c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_FLUSH]); 1999294cc35fSKevin Wolf dict = qobject_to_qdict(res); 2000294cc35fSKevin Wolf 2001294cc35fSKevin Wolf if (*bs->device_name) { 2002294cc35fSKevin Wolf qdict_put(dict, "device", qstring_from_str(bs->device_name)); 2003294cc35fSKevin Wolf } 2004294cc35fSKevin Wolf 2005294cc35fSKevin Wolf if (bs->file) { 2006294cc35fSKevin Wolf QObject *parent = bdrv_info_stats_bs(bs->file); 2007294cc35fSKevin Wolf qdict_put_obj(dict, "parent", parent); 2008294cc35fSKevin Wolf } 2009294cc35fSKevin Wolf 2010294cc35fSKevin Wolf return res; 2011294cc35fSKevin Wolf } 2012294cc35fSKevin Wolf 2013218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data) 2014218a536aSLuiz Capitulino { 2015218a536aSLuiz Capitulino QObject *obj; 2016218a536aSLuiz Capitulino QList *devices; 2017a36e69ddSths BlockDriverState *bs; 2018a36e69ddSths 2019218a536aSLuiz Capitulino devices = qlist_new(); 2020218a536aSLuiz Capitulino 20211b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 2022294cc35fSKevin Wolf obj = bdrv_info_stats_bs(bs); 2023218a536aSLuiz Capitulino qlist_append_obj(devices, obj); 2024a36e69ddSths } 2025218a536aSLuiz Capitulino 2026218a536aSLuiz Capitulino *ret_data = QOBJECT(devices); 2027a36e69ddSths } 2028ea2384d3Sbellard 2029045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs) 2030045df330Saliguori { 2031045df330Saliguori if (bs->backing_hd && bs->backing_hd->encrypted) 2032045df330Saliguori return bs->backing_file; 2033045df330Saliguori else if (bs->encrypted) 2034045df330Saliguori return bs->filename; 2035045df330Saliguori else 2036045df330Saliguori return NULL; 2037045df330Saliguori } 2038045df330Saliguori 203983f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs, 204083f64091Sbellard char *filename, int filename_size) 204183f64091Sbellard { 2042b783e409SKevin Wolf if (!bs->backing_file) { 204383f64091Sbellard pstrcpy(filename, filename_size, ""); 204483f64091Sbellard } else { 204583f64091Sbellard pstrcpy(filename, filename_size, bs->backing_file); 204683f64091Sbellard } 204783f64091Sbellard } 204883f64091Sbellard 2049faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 2050faea38e7Sbellard const uint8_t *buf, int nb_sectors) 2051faea38e7Sbellard { 2052faea38e7Sbellard BlockDriver *drv = bs->drv; 2053faea38e7Sbellard if (!drv) 205419cb3738Sbellard return -ENOMEDIUM; 2055faea38e7Sbellard if (!drv->bdrv_write_compressed) 2056faea38e7Sbellard return -ENOTSUP; 2057fbb7b4e0SKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) 2058fbb7b4e0SKevin Wolf return -EIO; 20597cd1e32aSlirans@il.ibm.com 2060c6d22830SJan Kiszka if (bs->dirty_bitmap) { 20617cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 20627cd1e32aSlirans@il.ibm.com } 20637cd1e32aSlirans@il.ibm.com 2064faea38e7Sbellard return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 2065faea38e7Sbellard } 2066faea38e7Sbellard 2067faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 2068faea38e7Sbellard { 2069faea38e7Sbellard BlockDriver *drv = bs->drv; 2070faea38e7Sbellard if (!drv) 207119cb3738Sbellard return -ENOMEDIUM; 2072faea38e7Sbellard if (!drv->bdrv_get_info) 2073faea38e7Sbellard return -ENOTSUP; 2074faea38e7Sbellard memset(bdi, 0, sizeof(*bdi)); 2075faea38e7Sbellard return drv->bdrv_get_info(bs, bdi); 2076faea38e7Sbellard } 2077faea38e7Sbellard 207845566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 207945566e9cSChristoph Hellwig int64_t pos, int size) 2080178e08a5Saliguori { 2081178e08a5Saliguori BlockDriver *drv = bs->drv; 2082178e08a5Saliguori if (!drv) 2083178e08a5Saliguori return -ENOMEDIUM; 20847cdb1f6dSMORITA Kazutaka if (drv->bdrv_save_vmstate) 208545566e9cSChristoph Hellwig return drv->bdrv_save_vmstate(bs, buf, pos, size); 20867cdb1f6dSMORITA Kazutaka if (bs->file) 20877cdb1f6dSMORITA Kazutaka return bdrv_save_vmstate(bs->file, buf, pos, size); 20887cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2089178e08a5Saliguori } 2090178e08a5Saliguori 209145566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, 209245566e9cSChristoph Hellwig int64_t pos, int size) 2093178e08a5Saliguori { 2094178e08a5Saliguori BlockDriver *drv = bs->drv; 2095178e08a5Saliguori if (!drv) 2096178e08a5Saliguori return -ENOMEDIUM; 20977cdb1f6dSMORITA Kazutaka if (drv->bdrv_load_vmstate) 209845566e9cSChristoph Hellwig return drv->bdrv_load_vmstate(bs, buf, pos, size); 20997cdb1f6dSMORITA Kazutaka if (bs->file) 21007cdb1f6dSMORITA Kazutaka return bdrv_load_vmstate(bs->file, buf, pos, size); 21017cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2102178e08a5Saliguori } 2103178e08a5Saliguori 21048b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) 21058b9b0cc2SKevin Wolf { 21068b9b0cc2SKevin Wolf BlockDriver *drv = bs->drv; 21078b9b0cc2SKevin Wolf 21088b9b0cc2SKevin Wolf if (!drv || !drv->bdrv_debug_event) { 21098b9b0cc2SKevin Wolf return; 21108b9b0cc2SKevin Wolf } 21118b9b0cc2SKevin Wolf 21128b9b0cc2SKevin Wolf return drv->bdrv_debug_event(bs, event); 21138b9b0cc2SKevin Wolf 21148b9b0cc2SKevin Wolf } 21158b9b0cc2SKevin Wolf 2116faea38e7Sbellard /**************************************************************/ 2117faea38e7Sbellard /* handling of snapshots */ 2118faea38e7Sbellard 2119feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs) 2120feeee5acSMiguel Di Ciurcio Filho { 2121feeee5acSMiguel Di Ciurcio Filho BlockDriver *drv = bs->drv; 212207b70bfbSMarkus Armbruster if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { 2123feeee5acSMiguel Di Ciurcio Filho return 0; 2124feeee5acSMiguel Di Ciurcio Filho } 2125feeee5acSMiguel Di Ciurcio Filho 2126feeee5acSMiguel Di Ciurcio Filho if (!drv->bdrv_snapshot_create) { 2127feeee5acSMiguel Di Ciurcio Filho if (bs->file != NULL) { 2128feeee5acSMiguel Di Ciurcio Filho return bdrv_can_snapshot(bs->file); 2129feeee5acSMiguel Di Ciurcio Filho } 2130feeee5acSMiguel Di Ciurcio Filho return 0; 2131feeee5acSMiguel Di Ciurcio Filho } 2132feeee5acSMiguel Di Ciurcio Filho 2133feeee5acSMiguel Di Ciurcio Filho return 1; 2134feeee5acSMiguel Di Ciurcio Filho } 2135feeee5acSMiguel Di Ciurcio Filho 2136199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs) 2137199630b6SBlue Swirl { 2138199630b6SBlue Swirl return !!(bs->open_flags & BDRV_O_SNAPSHOT); 2139199630b6SBlue Swirl } 2140199630b6SBlue Swirl 2141f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void) 2142f9092b10SMarkus Armbruster { 2143f9092b10SMarkus Armbruster BlockDriverState *bs; 2144f9092b10SMarkus Armbruster 21453ac906f7SMarkus Armbruster if (bs_snapshots) { 2146f9092b10SMarkus Armbruster return bs_snapshots; 21473ac906f7SMarkus Armbruster } 2148f9092b10SMarkus Armbruster 2149f9092b10SMarkus Armbruster bs = NULL; 2150f9092b10SMarkus Armbruster while ((bs = bdrv_next(bs))) { 2151f9092b10SMarkus Armbruster if (bdrv_can_snapshot(bs)) { 21523ac906f7SMarkus Armbruster bs_snapshots = bs; 21533ac906f7SMarkus Armbruster return bs; 2154f9092b10SMarkus Armbruster } 2155f9092b10SMarkus Armbruster } 2156f9092b10SMarkus Armbruster return NULL; 2157f9092b10SMarkus Armbruster } 2158f9092b10SMarkus Armbruster 2159faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs, 2160faea38e7Sbellard QEMUSnapshotInfo *sn_info) 2161faea38e7Sbellard { 2162faea38e7Sbellard BlockDriver *drv = bs->drv; 2163faea38e7Sbellard if (!drv) 216419cb3738Sbellard return -ENOMEDIUM; 21657cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_create) 2166faea38e7Sbellard return drv->bdrv_snapshot_create(bs, sn_info); 21677cdb1f6dSMORITA Kazutaka if (bs->file) 21687cdb1f6dSMORITA Kazutaka return bdrv_snapshot_create(bs->file, sn_info); 21697cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2170faea38e7Sbellard } 2171faea38e7Sbellard 2172faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs, 2173faea38e7Sbellard const char *snapshot_id) 2174faea38e7Sbellard { 2175faea38e7Sbellard BlockDriver *drv = bs->drv; 21767cdb1f6dSMORITA Kazutaka int ret, open_ret; 21777cdb1f6dSMORITA Kazutaka 2178faea38e7Sbellard if (!drv) 217919cb3738Sbellard return -ENOMEDIUM; 21807cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_goto) 2181faea38e7Sbellard return drv->bdrv_snapshot_goto(bs, snapshot_id); 21827cdb1f6dSMORITA Kazutaka 21837cdb1f6dSMORITA Kazutaka if (bs->file) { 21847cdb1f6dSMORITA Kazutaka drv->bdrv_close(bs); 21857cdb1f6dSMORITA Kazutaka ret = bdrv_snapshot_goto(bs->file, snapshot_id); 21867cdb1f6dSMORITA Kazutaka open_ret = drv->bdrv_open(bs, bs->open_flags); 21877cdb1f6dSMORITA Kazutaka if (open_ret < 0) { 21887cdb1f6dSMORITA Kazutaka bdrv_delete(bs->file); 21897cdb1f6dSMORITA Kazutaka bs->drv = NULL; 21907cdb1f6dSMORITA Kazutaka return open_ret; 21917cdb1f6dSMORITA Kazutaka } 21927cdb1f6dSMORITA Kazutaka return ret; 21937cdb1f6dSMORITA Kazutaka } 21947cdb1f6dSMORITA Kazutaka 21957cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2196faea38e7Sbellard } 2197faea38e7Sbellard 2198faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 2199faea38e7Sbellard { 2200faea38e7Sbellard BlockDriver *drv = bs->drv; 2201faea38e7Sbellard if (!drv) 220219cb3738Sbellard return -ENOMEDIUM; 22037cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_delete) 2204faea38e7Sbellard return drv->bdrv_snapshot_delete(bs, snapshot_id); 22057cdb1f6dSMORITA Kazutaka if (bs->file) 22067cdb1f6dSMORITA Kazutaka return bdrv_snapshot_delete(bs->file, snapshot_id); 22077cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2208faea38e7Sbellard } 2209faea38e7Sbellard 2210faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs, 2211faea38e7Sbellard QEMUSnapshotInfo **psn_info) 2212faea38e7Sbellard { 2213faea38e7Sbellard BlockDriver *drv = bs->drv; 2214faea38e7Sbellard if (!drv) 221519cb3738Sbellard return -ENOMEDIUM; 22167cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_list) 2217faea38e7Sbellard return drv->bdrv_snapshot_list(bs, psn_info); 22187cdb1f6dSMORITA Kazutaka if (bs->file) 22197cdb1f6dSMORITA Kazutaka return bdrv_snapshot_list(bs->file, psn_info); 22207cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2221faea38e7Sbellard } 2222faea38e7Sbellard 222351ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs, 222451ef6727Sedison const char *snapshot_name) 222551ef6727Sedison { 222651ef6727Sedison BlockDriver *drv = bs->drv; 222751ef6727Sedison if (!drv) { 222851ef6727Sedison return -ENOMEDIUM; 222951ef6727Sedison } 223051ef6727Sedison if (!bs->read_only) { 223151ef6727Sedison return -EINVAL; 223251ef6727Sedison } 223351ef6727Sedison if (drv->bdrv_snapshot_load_tmp) { 223451ef6727Sedison return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); 223551ef6727Sedison } 223651ef6727Sedison return -ENOTSUP; 223751ef6727Sedison } 223851ef6727Sedison 2239faea38e7Sbellard #define NB_SUFFIXES 4 2240faea38e7Sbellard 2241faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size) 2242faea38e7Sbellard { 2243faea38e7Sbellard static const char suffixes[NB_SUFFIXES] = "KMGT"; 2244faea38e7Sbellard int64_t base; 2245faea38e7Sbellard int i; 2246faea38e7Sbellard 2247faea38e7Sbellard if (size <= 999) { 2248faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64, size); 2249faea38e7Sbellard } else { 2250faea38e7Sbellard base = 1024; 2251faea38e7Sbellard for(i = 0; i < NB_SUFFIXES; i++) { 2252faea38e7Sbellard if (size < (10 * base)) { 2253faea38e7Sbellard snprintf(buf, buf_size, "%0.1f%c", 2254faea38e7Sbellard (double)size / base, 2255faea38e7Sbellard suffixes[i]); 2256faea38e7Sbellard break; 2257faea38e7Sbellard } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 2258faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64 "%c", 2259faea38e7Sbellard ((size + (base >> 1)) / base), 2260faea38e7Sbellard suffixes[i]); 2261faea38e7Sbellard break; 2262faea38e7Sbellard } 2263faea38e7Sbellard base = base * 1024; 2264faea38e7Sbellard } 2265faea38e7Sbellard } 2266faea38e7Sbellard return buf; 2267faea38e7Sbellard } 2268faea38e7Sbellard 2269faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 2270faea38e7Sbellard { 2271faea38e7Sbellard char buf1[128], date_buf[128], clock_buf[128]; 22723b9f94e1Sbellard #ifdef _WIN32 22733b9f94e1Sbellard struct tm *ptm; 22743b9f94e1Sbellard #else 2275faea38e7Sbellard struct tm tm; 22763b9f94e1Sbellard #endif 2277faea38e7Sbellard time_t ti; 2278faea38e7Sbellard int64_t secs; 2279faea38e7Sbellard 2280faea38e7Sbellard if (!sn) { 2281faea38e7Sbellard snprintf(buf, buf_size, 2282faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2283faea38e7Sbellard "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 2284faea38e7Sbellard } else { 2285faea38e7Sbellard ti = sn->date_sec; 22863b9f94e1Sbellard #ifdef _WIN32 22873b9f94e1Sbellard ptm = localtime(&ti); 22883b9f94e1Sbellard strftime(date_buf, sizeof(date_buf), 22893b9f94e1Sbellard "%Y-%m-%d %H:%M:%S", ptm); 22903b9f94e1Sbellard #else 2291faea38e7Sbellard localtime_r(&ti, &tm); 2292faea38e7Sbellard strftime(date_buf, sizeof(date_buf), 2293faea38e7Sbellard "%Y-%m-%d %H:%M:%S", &tm); 22943b9f94e1Sbellard #endif 2295faea38e7Sbellard secs = sn->vm_clock_nsec / 1000000000; 2296faea38e7Sbellard snprintf(clock_buf, sizeof(clock_buf), 2297faea38e7Sbellard "%02d:%02d:%02d.%03d", 2298faea38e7Sbellard (int)(secs / 3600), 2299faea38e7Sbellard (int)((secs / 60) % 60), 2300faea38e7Sbellard (int)(secs % 60), 2301faea38e7Sbellard (int)((sn->vm_clock_nsec / 1000000) % 1000)); 2302faea38e7Sbellard snprintf(buf, buf_size, 2303faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2304faea38e7Sbellard sn->id_str, sn->name, 2305faea38e7Sbellard get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 2306faea38e7Sbellard date_buf, 2307faea38e7Sbellard clock_buf); 2308faea38e7Sbellard } 2309faea38e7Sbellard return buf; 2310faea38e7Sbellard } 2311faea38e7Sbellard 2312ea2384d3Sbellard /**************************************************************/ 231383f64091Sbellard /* async I/Os */ 2314ea2384d3Sbellard 23153b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 2316f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 231783f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 2318ea2384d3Sbellard { 2319bbf0a440SStefan Hajnoczi trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); 2320bbf0a440SStefan Hajnoczi 2321b2a61371SStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 23228c5873d6SStefan Hajnoczi cb, opaque, false); 232383f64091Sbellard } 232483f64091Sbellard 2325f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 2326f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 232783f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 23287674e7bfSbellard { 2329bbf0a440SStefan Hajnoczi trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); 2330bbf0a440SStefan Hajnoczi 23311a6e115bSStefan Hajnoczi return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 23328c5873d6SStefan Hajnoczi cb, opaque, true); 233383f64091Sbellard } 233483f64091Sbellard 233540b4f539SKevin Wolf 233640b4f539SKevin Wolf typedef struct MultiwriteCB { 233740b4f539SKevin Wolf int error; 233840b4f539SKevin Wolf int num_requests; 233940b4f539SKevin Wolf int num_callbacks; 234040b4f539SKevin Wolf struct { 234140b4f539SKevin Wolf BlockDriverCompletionFunc *cb; 234240b4f539SKevin Wolf void *opaque; 234340b4f539SKevin Wolf QEMUIOVector *free_qiov; 234440b4f539SKevin Wolf void *free_buf; 234540b4f539SKevin Wolf } callbacks[]; 234640b4f539SKevin Wolf } MultiwriteCB; 234740b4f539SKevin Wolf 234840b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb) 234940b4f539SKevin Wolf { 235040b4f539SKevin Wolf int i; 235140b4f539SKevin Wolf 235240b4f539SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 235340b4f539SKevin Wolf mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); 23541e1ea48dSStefan Hajnoczi if (mcb->callbacks[i].free_qiov) { 23551e1ea48dSStefan Hajnoczi qemu_iovec_destroy(mcb->callbacks[i].free_qiov); 23561e1ea48dSStefan Hajnoczi } 23577267c094SAnthony Liguori g_free(mcb->callbacks[i].free_qiov); 2358f8a83245SHerve Poussineau qemu_vfree(mcb->callbacks[i].free_buf); 235940b4f539SKevin Wolf } 236040b4f539SKevin Wolf } 236140b4f539SKevin Wolf 236240b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret) 236340b4f539SKevin Wolf { 236440b4f539SKevin Wolf MultiwriteCB *mcb = opaque; 236540b4f539SKevin Wolf 23666d519a5fSStefan Hajnoczi trace_multiwrite_cb(mcb, ret); 23676d519a5fSStefan Hajnoczi 2368cb6d3ca0SKevin Wolf if (ret < 0 && !mcb->error) { 236940b4f539SKevin Wolf mcb->error = ret; 237040b4f539SKevin Wolf } 237140b4f539SKevin Wolf 237240b4f539SKevin Wolf mcb->num_requests--; 237340b4f539SKevin Wolf if (mcb->num_requests == 0) { 237440b4f539SKevin Wolf multiwrite_user_cb(mcb); 23757267c094SAnthony Liguori g_free(mcb); 237640b4f539SKevin Wolf } 237740b4f539SKevin Wolf } 237840b4f539SKevin Wolf 237940b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b) 238040b4f539SKevin Wolf { 238177be4366SChristoph Hellwig const BlockRequest *req1 = a, *req2 = b; 238277be4366SChristoph Hellwig 238377be4366SChristoph Hellwig /* 238477be4366SChristoph Hellwig * Note that we can't simply subtract req2->sector from req1->sector 238577be4366SChristoph Hellwig * here as that could overflow the return value. 238677be4366SChristoph Hellwig */ 238777be4366SChristoph Hellwig if (req1->sector > req2->sector) { 238877be4366SChristoph Hellwig return 1; 238977be4366SChristoph Hellwig } else if (req1->sector < req2->sector) { 239077be4366SChristoph Hellwig return -1; 239177be4366SChristoph Hellwig } else { 239277be4366SChristoph Hellwig return 0; 239377be4366SChristoph Hellwig } 239440b4f539SKevin Wolf } 239540b4f539SKevin Wolf 239640b4f539SKevin Wolf /* 239740b4f539SKevin Wolf * Takes a bunch of requests and tries to merge them. Returns the number of 239840b4f539SKevin Wolf * requests that remain after merging. 239940b4f539SKevin Wolf */ 240040b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, 240140b4f539SKevin Wolf int num_reqs, MultiwriteCB *mcb) 240240b4f539SKevin Wolf { 240340b4f539SKevin Wolf int i, outidx; 240440b4f539SKevin Wolf 240540b4f539SKevin Wolf // Sort requests by start sector 240640b4f539SKevin Wolf qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); 240740b4f539SKevin Wolf 240840b4f539SKevin Wolf // Check if adjacent requests touch the same clusters. If so, combine them, 240940b4f539SKevin Wolf // filling up gaps with zero sectors. 241040b4f539SKevin Wolf outidx = 0; 241140b4f539SKevin Wolf for (i = 1; i < num_reqs; i++) { 241240b4f539SKevin Wolf int merge = 0; 241340b4f539SKevin Wolf int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; 241440b4f539SKevin Wolf 241540b4f539SKevin Wolf // This handles the cases that are valid for all block drivers, namely 241640b4f539SKevin Wolf // exactly sequential writes and overlapping writes. 241740b4f539SKevin Wolf if (reqs[i].sector <= oldreq_last) { 241840b4f539SKevin Wolf merge = 1; 241940b4f539SKevin Wolf } 242040b4f539SKevin Wolf 242140b4f539SKevin Wolf // The block driver may decide that it makes sense to combine requests 242240b4f539SKevin Wolf // even if there is a gap of some sectors between them. In this case, 242340b4f539SKevin Wolf // the gap is filled with zeros (therefore only applicable for yet 242440b4f539SKevin Wolf // unused space in format like qcow2). 242540b4f539SKevin Wolf if (!merge && bs->drv->bdrv_merge_requests) { 242640b4f539SKevin Wolf merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); 242740b4f539SKevin Wolf } 242840b4f539SKevin Wolf 2429e2a305fbSChristoph Hellwig if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { 2430e2a305fbSChristoph Hellwig merge = 0; 2431e2a305fbSChristoph Hellwig } 2432e2a305fbSChristoph Hellwig 243340b4f539SKevin Wolf if (merge) { 243440b4f539SKevin Wolf size_t size; 24357267c094SAnthony Liguori QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); 243640b4f539SKevin Wolf qemu_iovec_init(qiov, 243740b4f539SKevin Wolf reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); 243840b4f539SKevin Wolf 243940b4f539SKevin Wolf // Add the first request to the merged one. If the requests are 244040b4f539SKevin Wolf // overlapping, drop the last sectors of the first request. 244140b4f539SKevin Wolf size = (reqs[i].sector - reqs[outidx].sector) << 9; 244240b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[outidx].qiov, size); 244340b4f539SKevin Wolf 244440b4f539SKevin Wolf // We might need to add some zeros between the two requests 244540b4f539SKevin Wolf if (reqs[i].sector > oldreq_last) { 244640b4f539SKevin Wolf size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9; 244740b4f539SKevin Wolf uint8_t *buf = qemu_blockalign(bs, zero_bytes); 244840b4f539SKevin Wolf memset(buf, 0, zero_bytes); 244940b4f539SKevin Wolf qemu_iovec_add(qiov, buf, zero_bytes); 245040b4f539SKevin Wolf mcb->callbacks[i].free_buf = buf; 245140b4f539SKevin Wolf } 245240b4f539SKevin Wolf 245340b4f539SKevin Wolf // Add the second request 245440b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size); 245540b4f539SKevin Wolf 2456cbf1dff2SKevin Wolf reqs[outidx].nb_sectors = qiov->size >> 9; 245740b4f539SKevin Wolf reqs[outidx].qiov = qiov; 245840b4f539SKevin Wolf 245940b4f539SKevin Wolf mcb->callbacks[i].free_qiov = reqs[outidx].qiov; 246040b4f539SKevin Wolf } else { 246140b4f539SKevin Wolf outidx++; 246240b4f539SKevin Wolf reqs[outidx].sector = reqs[i].sector; 246340b4f539SKevin Wolf reqs[outidx].nb_sectors = reqs[i].nb_sectors; 246440b4f539SKevin Wolf reqs[outidx].qiov = reqs[i].qiov; 246540b4f539SKevin Wolf } 246640b4f539SKevin Wolf } 246740b4f539SKevin Wolf 246840b4f539SKevin Wolf return outidx + 1; 246940b4f539SKevin Wolf } 247040b4f539SKevin Wolf 247140b4f539SKevin Wolf /* 247240b4f539SKevin Wolf * Submit multiple AIO write requests at once. 247340b4f539SKevin Wolf * 247440b4f539SKevin Wolf * On success, the function returns 0 and all requests in the reqs array have 247540b4f539SKevin Wolf * been submitted. In error case this function returns -1, and any of the 247640b4f539SKevin Wolf * requests may or may not be submitted yet. In particular, this means that the 247740b4f539SKevin Wolf * callback will be called for some of the requests, for others it won't. The 247840b4f539SKevin Wolf * caller must check the error field of the BlockRequest to wait for the right 247940b4f539SKevin Wolf * callbacks (if error != 0, no callback will be called). 248040b4f539SKevin Wolf * 248140b4f539SKevin Wolf * The implementation may modify the contents of the reqs array, e.g. to merge 248240b4f539SKevin Wolf * requests. However, the fields opaque and error are left unmodified as they 248340b4f539SKevin Wolf * are used to signal failure for a single request to the caller. 248440b4f539SKevin Wolf */ 248540b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) 248640b4f539SKevin Wolf { 248740b4f539SKevin Wolf BlockDriverAIOCB *acb; 248840b4f539SKevin Wolf MultiwriteCB *mcb; 248940b4f539SKevin Wolf int i; 249040b4f539SKevin Wolf 2491301db7c2SRyan Harper /* don't submit writes if we don't have a medium */ 2492301db7c2SRyan Harper if (bs->drv == NULL) { 2493301db7c2SRyan Harper for (i = 0; i < num_reqs; i++) { 2494301db7c2SRyan Harper reqs[i].error = -ENOMEDIUM; 2495301db7c2SRyan Harper } 2496301db7c2SRyan Harper return -1; 2497301db7c2SRyan Harper } 2498301db7c2SRyan Harper 249940b4f539SKevin Wolf if (num_reqs == 0) { 250040b4f539SKevin Wolf return 0; 250140b4f539SKevin Wolf } 250240b4f539SKevin Wolf 250340b4f539SKevin Wolf // Create MultiwriteCB structure 25047267c094SAnthony Liguori mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); 250540b4f539SKevin Wolf mcb->num_requests = 0; 250640b4f539SKevin Wolf mcb->num_callbacks = num_reqs; 250740b4f539SKevin Wolf 250840b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 250940b4f539SKevin Wolf mcb->callbacks[i].cb = reqs[i].cb; 251040b4f539SKevin Wolf mcb->callbacks[i].opaque = reqs[i].opaque; 251140b4f539SKevin Wolf } 251240b4f539SKevin Wolf 251340b4f539SKevin Wolf // Check for mergable requests 251440b4f539SKevin Wolf num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); 251540b4f539SKevin Wolf 25166d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); 25176d519a5fSStefan Hajnoczi 2518453f9a16SKevin Wolf /* 2519453f9a16SKevin Wolf * Run the aio requests. As soon as one request can't be submitted 2520453f9a16SKevin Wolf * successfully, fail all requests that are not yet submitted (we must 2521453f9a16SKevin Wolf * return failure for all requests anyway) 2522453f9a16SKevin Wolf * 2523453f9a16SKevin Wolf * num_requests cannot be set to the right value immediately: If 2524453f9a16SKevin Wolf * bdrv_aio_writev fails for some request, num_requests would be too high 2525453f9a16SKevin Wolf * and therefore multiwrite_cb() would never recognize the multiwrite 2526453f9a16SKevin Wolf * request as completed. We also cannot use the loop variable i to set it 2527453f9a16SKevin Wolf * when the first request fails because the callback may already have been 2528453f9a16SKevin Wolf * called for previously submitted requests. Thus, num_requests must be 2529453f9a16SKevin Wolf * incremented for each request that is submitted. 2530453f9a16SKevin Wolf * 2531453f9a16SKevin Wolf * The problem that callbacks may be called early also means that we need 2532453f9a16SKevin Wolf * to take care that num_requests doesn't become 0 before all requests are 2533453f9a16SKevin Wolf * submitted - multiwrite_cb() would consider the multiwrite request 2534453f9a16SKevin Wolf * completed. A dummy request that is "completed" by a manual call to 2535453f9a16SKevin Wolf * multiwrite_cb() takes care of this. 2536453f9a16SKevin Wolf */ 2537453f9a16SKevin Wolf mcb->num_requests = 1; 2538453f9a16SKevin Wolf 25396d519a5fSStefan Hajnoczi // Run the aio requests 254040b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 2541453f9a16SKevin Wolf mcb->num_requests++; 254240b4f539SKevin Wolf acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, 254340b4f539SKevin Wolf reqs[i].nb_sectors, multiwrite_cb, mcb); 254440b4f539SKevin Wolf 254540b4f539SKevin Wolf if (acb == NULL) { 254640b4f539SKevin Wolf // We can only fail the whole thing if no request has been 254740b4f539SKevin Wolf // submitted yet. Otherwise we'll wait for the submitted AIOs to 254840b4f539SKevin Wolf // complete and report the error in the callback. 2549453f9a16SKevin Wolf if (i == 0) { 25506d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_earlyfail(mcb); 255140b4f539SKevin Wolf goto fail; 255240b4f539SKevin Wolf } else { 25536d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_latefail(mcb, i); 25547eb58a6cSKevin Wolf multiwrite_cb(mcb, -EIO); 255540b4f539SKevin Wolf break; 255640b4f539SKevin Wolf } 255740b4f539SKevin Wolf } 255840b4f539SKevin Wolf } 255940b4f539SKevin Wolf 2560453f9a16SKevin Wolf /* Complete the dummy request */ 2561453f9a16SKevin Wolf multiwrite_cb(mcb, 0); 2562453f9a16SKevin Wolf 256340b4f539SKevin Wolf return 0; 256440b4f539SKevin Wolf 256540b4f539SKevin Wolf fail: 2566453f9a16SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 2567453f9a16SKevin Wolf reqs[i].error = -EIO; 2568453f9a16SKevin Wolf } 25697267c094SAnthony Liguori g_free(mcb); 257040b4f539SKevin Wolf return -1; 257140b4f539SKevin Wolf } 257240b4f539SKevin Wolf 257383f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb) 257483f64091Sbellard { 25756bbff9a0Saliguori acb->pool->cancel(acb); 257683f64091Sbellard } 257783f64091Sbellard 257883f64091Sbellard 257983f64091Sbellard /**************************************************************/ 258083f64091Sbellard /* async block device emulation */ 258183f64091Sbellard 2582c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync { 2583c16b5a2cSChristoph Hellwig BlockDriverAIOCB common; 2584c16b5a2cSChristoph Hellwig QEMUBH *bh; 2585c16b5a2cSChristoph Hellwig int ret; 2586c16b5a2cSChristoph Hellwig /* vector translation state */ 2587c16b5a2cSChristoph Hellwig QEMUIOVector *qiov; 2588c16b5a2cSChristoph Hellwig uint8_t *bounce; 2589c16b5a2cSChristoph Hellwig int is_write; 2590c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync; 2591c16b5a2cSChristoph Hellwig 2592c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 2593c16b5a2cSChristoph Hellwig { 2594b666d239SKevin Wolf BlockDriverAIOCBSync *acb = 2595b666d239SKevin Wolf container_of(blockacb, BlockDriverAIOCBSync, common); 25966a7ad299SDor Laor qemu_bh_delete(acb->bh); 259736afc451SAvi Kivity acb->bh = NULL; 2598c16b5a2cSChristoph Hellwig qemu_aio_release(acb); 2599c16b5a2cSChristoph Hellwig } 2600c16b5a2cSChristoph Hellwig 2601c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = { 2602c16b5a2cSChristoph Hellwig .aiocb_size = sizeof(BlockDriverAIOCBSync), 2603c16b5a2cSChristoph Hellwig .cancel = bdrv_aio_cancel_em, 2604c16b5a2cSChristoph Hellwig }; 2605c16b5a2cSChristoph Hellwig 260683f64091Sbellard static void bdrv_aio_bh_cb(void *opaque) 2607beac80cdSbellard { 2608ce1a14dcSpbrook BlockDriverAIOCBSync *acb = opaque; 2609f141eafeSaliguori 2610f141eafeSaliguori if (!acb->is_write) 2611f141eafeSaliguori qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 2612ceb42de8Saliguori qemu_vfree(acb->bounce); 2613ce1a14dcSpbrook acb->common.cb(acb->common.opaque, acb->ret); 26146a7ad299SDor Laor qemu_bh_delete(acb->bh); 261536afc451SAvi Kivity acb->bh = NULL; 2616ce1a14dcSpbrook qemu_aio_release(acb); 2617beac80cdSbellard } 2618beac80cdSbellard 2619f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 2620f141eafeSaliguori int64_t sector_num, 2621f141eafeSaliguori QEMUIOVector *qiov, 2622f141eafeSaliguori int nb_sectors, 2623f141eafeSaliguori BlockDriverCompletionFunc *cb, 2624f141eafeSaliguori void *opaque, 2625f141eafeSaliguori int is_write) 2626f141eafeSaliguori 2627ea2384d3Sbellard { 2628ce1a14dcSpbrook BlockDriverAIOCBSync *acb; 262983f64091Sbellard 2630c16b5a2cSChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2631f141eafeSaliguori acb->is_write = is_write; 2632f141eafeSaliguori acb->qiov = qiov; 2633e268ca52Saliguori acb->bounce = qemu_blockalign(bs, qiov->size); 2634f141eafeSaliguori 2635ce1a14dcSpbrook if (!acb->bh) 2636ce1a14dcSpbrook acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2637f141eafeSaliguori 2638f141eafeSaliguori if (is_write) { 2639f141eafeSaliguori qemu_iovec_to_buffer(acb->qiov, acb->bounce); 26401ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 2641f141eafeSaliguori } else { 26421ed20acfSStefan Hajnoczi acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 2643f141eafeSaliguori } 2644f141eafeSaliguori 2645ce1a14dcSpbrook qemu_bh_schedule(acb->bh); 2646f141eafeSaliguori 2647ce1a14dcSpbrook return &acb->common; 26487a6cba61Spbrook } 26497a6cba61Spbrook 2650f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 2651f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2652ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque) 265383f64091Sbellard { 2654f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 265583f64091Sbellard } 265683f64091Sbellard 2657f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 2658f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2659f141eafeSaliguori BlockDriverCompletionFunc *cb, void *opaque) 2660f141eafeSaliguori { 2661f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 2662f141eafeSaliguori } 2663f141eafeSaliguori 266468485420SKevin Wolf 266568485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine { 266668485420SKevin Wolf BlockDriverAIOCB common; 266768485420SKevin Wolf BlockRequest req; 266868485420SKevin Wolf bool is_write; 266968485420SKevin Wolf QEMUBH* bh; 267068485420SKevin Wolf } BlockDriverAIOCBCoroutine; 267168485420SKevin Wolf 267268485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) 267368485420SKevin Wolf { 267468485420SKevin Wolf qemu_aio_flush(); 267568485420SKevin Wolf } 267668485420SKevin Wolf 267768485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = { 267868485420SKevin Wolf .aiocb_size = sizeof(BlockDriverAIOCBCoroutine), 267968485420SKevin Wolf .cancel = bdrv_aio_co_cancel_em, 268068485420SKevin Wolf }; 268168485420SKevin Wolf 268235246a68SPaolo Bonzini static void bdrv_co_em_bh(void *opaque) 268368485420SKevin Wolf { 268468485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 268568485420SKevin Wolf 268668485420SKevin Wolf acb->common.cb(acb->common.opaque, acb->req.error); 268768485420SKevin Wolf qemu_bh_delete(acb->bh); 268868485420SKevin Wolf qemu_aio_release(acb); 268968485420SKevin Wolf } 269068485420SKevin Wolf 2691b2a61371SStefan Hajnoczi /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */ 2692b2a61371SStefan Hajnoczi static void coroutine_fn bdrv_co_do_rw(void *opaque) 2693b2a61371SStefan Hajnoczi { 2694b2a61371SStefan Hajnoczi BlockDriverAIOCBCoroutine *acb = opaque; 2695b2a61371SStefan Hajnoczi BlockDriverState *bs = acb->common.bs; 2696b2a61371SStefan Hajnoczi 2697b2a61371SStefan Hajnoczi if (!acb->is_write) { 2698b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, 2699b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2700b2a61371SStefan Hajnoczi } else { 2701b2a61371SStefan Hajnoczi acb->req.error = bdrv_co_do_writev(bs, acb->req.sector, 2702b2a61371SStefan Hajnoczi acb->req.nb_sectors, acb->req.qiov); 2703b2a61371SStefan Hajnoczi } 2704b2a61371SStefan Hajnoczi 270535246a68SPaolo Bonzini acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); 2706b2a61371SStefan Hajnoczi qemu_bh_schedule(acb->bh); 2707b2a61371SStefan Hajnoczi } 2708b2a61371SStefan Hajnoczi 270968485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 271068485420SKevin Wolf int64_t sector_num, 271168485420SKevin Wolf QEMUIOVector *qiov, 271268485420SKevin Wolf int nb_sectors, 271368485420SKevin Wolf BlockDriverCompletionFunc *cb, 271468485420SKevin Wolf void *opaque, 27158c5873d6SStefan Hajnoczi bool is_write) 271668485420SKevin Wolf { 271768485420SKevin Wolf Coroutine *co; 271868485420SKevin Wolf BlockDriverAIOCBCoroutine *acb; 271968485420SKevin Wolf 272068485420SKevin Wolf acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); 272168485420SKevin Wolf acb->req.sector = sector_num; 272268485420SKevin Wolf acb->req.nb_sectors = nb_sectors; 272368485420SKevin Wolf acb->req.qiov = qiov; 272468485420SKevin Wolf acb->is_write = is_write; 272568485420SKevin Wolf 27268c5873d6SStefan Hajnoczi co = qemu_coroutine_create(bdrv_co_do_rw); 272768485420SKevin Wolf qemu_coroutine_enter(co, acb); 272868485420SKevin Wolf 272968485420SKevin Wolf return &acb->common; 273068485420SKevin Wolf } 273168485420SKevin Wolf 2732*07f07615SPaolo Bonzini static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque) 2733b2e12bc6SChristoph Hellwig { 2734*07f07615SPaolo Bonzini BlockDriverAIOCBCoroutine *acb = opaque; 2735*07f07615SPaolo Bonzini BlockDriverState *bs = acb->common.bs; 2736b2e12bc6SChristoph Hellwig 2737*07f07615SPaolo Bonzini acb->req.error = bdrv_co_flush(bs); 2738*07f07615SPaolo Bonzini acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); 2739b2e12bc6SChristoph Hellwig qemu_bh_schedule(acb->bh); 2740b2e12bc6SChristoph Hellwig } 2741b2e12bc6SChristoph Hellwig 2742*07f07615SPaolo Bonzini BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 2743016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque) 2744016f5cf6SAlexander Graf { 2745*07f07615SPaolo Bonzini trace_bdrv_aio_flush(bs, opaque); 2746016f5cf6SAlexander Graf 2747*07f07615SPaolo Bonzini Coroutine *co; 2748*07f07615SPaolo Bonzini BlockDriverAIOCBCoroutine *acb; 2749016f5cf6SAlexander Graf 2750*07f07615SPaolo Bonzini acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); 2751*07f07615SPaolo Bonzini co = qemu_coroutine_create(bdrv_aio_flush_co_entry); 2752*07f07615SPaolo Bonzini qemu_coroutine_enter(co, acb); 2753016f5cf6SAlexander Graf 2754016f5cf6SAlexander Graf return &acb->common; 2755016f5cf6SAlexander Graf } 2756016f5cf6SAlexander Graf 2757ea2384d3Sbellard void bdrv_init(void) 2758ea2384d3Sbellard { 27595efa9d5aSAnthony Liguori module_call_init(MODULE_INIT_BLOCK); 2760ea2384d3Sbellard } 2761ce1a14dcSpbrook 2762eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void) 2763eb852011SMarkus Armbruster { 2764eb852011SMarkus Armbruster use_bdrv_whitelist = 1; 2765eb852011SMarkus Armbruster bdrv_init(); 2766eb852011SMarkus Armbruster } 2767eb852011SMarkus Armbruster 2768c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 27696bbff9a0Saliguori BlockDriverCompletionFunc *cb, void *opaque) 27706bbff9a0Saliguori { 2771ce1a14dcSpbrook BlockDriverAIOCB *acb; 2772ce1a14dcSpbrook 27736bbff9a0Saliguori if (pool->free_aiocb) { 27746bbff9a0Saliguori acb = pool->free_aiocb; 27756bbff9a0Saliguori pool->free_aiocb = acb->next; 2776ce1a14dcSpbrook } else { 27777267c094SAnthony Liguori acb = g_malloc0(pool->aiocb_size); 27786bbff9a0Saliguori acb->pool = pool; 2779ce1a14dcSpbrook } 2780ce1a14dcSpbrook acb->bs = bs; 2781ce1a14dcSpbrook acb->cb = cb; 2782ce1a14dcSpbrook acb->opaque = opaque; 2783ce1a14dcSpbrook return acb; 2784ce1a14dcSpbrook } 2785ce1a14dcSpbrook 2786ce1a14dcSpbrook void qemu_aio_release(void *p) 2787ce1a14dcSpbrook { 27886bbff9a0Saliguori BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 27896bbff9a0Saliguori AIOPool *pool = acb->pool; 27906bbff9a0Saliguori acb->next = pool->free_aiocb; 27916bbff9a0Saliguori pool->free_aiocb = acb; 2792ce1a14dcSpbrook } 279319cb3738Sbellard 279419cb3738Sbellard /**************************************************************/ 2795f9f05dc5SKevin Wolf /* Coroutine block device emulation */ 2796f9f05dc5SKevin Wolf 2797f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion { 2798f9f05dc5SKevin Wolf Coroutine *coroutine; 2799f9f05dc5SKevin Wolf int ret; 2800f9f05dc5SKevin Wolf } CoroutineIOCompletion; 2801f9f05dc5SKevin Wolf 2802f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret) 2803f9f05dc5SKevin Wolf { 2804f9f05dc5SKevin Wolf CoroutineIOCompletion *co = opaque; 2805f9f05dc5SKevin Wolf 2806f9f05dc5SKevin Wolf co->ret = ret; 2807f9f05dc5SKevin Wolf qemu_coroutine_enter(co->coroutine, NULL); 2808f9f05dc5SKevin Wolf } 2809f9f05dc5SKevin Wolf 2810f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, 2811f9f05dc5SKevin Wolf int nb_sectors, QEMUIOVector *iov, 2812f9f05dc5SKevin Wolf bool is_write) 2813f9f05dc5SKevin Wolf { 2814f9f05dc5SKevin Wolf CoroutineIOCompletion co = { 2815f9f05dc5SKevin Wolf .coroutine = qemu_coroutine_self(), 2816f9f05dc5SKevin Wolf }; 2817f9f05dc5SKevin Wolf BlockDriverAIOCB *acb; 2818f9f05dc5SKevin Wolf 2819f9f05dc5SKevin Wolf if (is_write) { 2820a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, 2821f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 2822f9f05dc5SKevin Wolf } else { 2823a652d160SStefan Hajnoczi acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, 2824f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 2825f9f05dc5SKevin Wolf } 2826f9f05dc5SKevin Wolf 282759370aaaSStefan Hajnoczi trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); 2828f9f05dc5SKevin Wolf if (!acb) { 2829f9f05dc5SKevin Wolf return -EIO; 2830f9f05dc5SKevin Wolf } 2831f9f05dc5SKevin Wolf qemu_coroutine_yield(); 2832f9f05dc5SKevin Wolf 2833f9f05dc5SKevin Wolf return co.ret; 2834f9f05dc5SKevin Wolf } 2835f9f05dc5SKevin Wolf 2836f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 2837f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 2838f9f05dc5SKevin Wolf QEMUIOVector *iov) 2839f9f05dc5SKevin Wolf { 2840f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); 2841f9f05dc5SKevin Wolf } 2842f9f05dc5SKevin Wolf 2843f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 2844f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 2845f9f05dc5SKevin Wolf QEMUIOVector *iov) 2846f9f05dc5SKevin Wolf { 2847f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); 2848f9f05dc5SKevin Wolf } 2849f9f05dc5SKevin Wolf 2850*07f07615SPaolo Bonzini static void coroutine_fn bdrv_flush_co_entry(void *opaque) 2851e7a8a783SKevin Wolf { 2852*07f07615SPaolo Bonzini RwCo *rwco = opaque; 2853*07f07615SPaolo Bonzini 2854*07f07615SPaolo Bonzini rwco->ret = bdrv_co_flush(rwco->bs); 2855*07f07615SPaolo Bonzini } 2856*07f07615SPaolo Bonzini 2857*07f07615SPaolo Bonzini int coroutine_fn bdrv_co_flush(BlockDriverState *bs) 2858*07f07615SPaolo Bonzini { 2859*07f07615SPaolo Bonzini if (bs->open_flags & BDRV_O_NO_FLUSH) { 2860*07f07615SPaolo Bonzini return 0; 2861*07f07615SPaolo Bonzini } else if (!bs->drv) { 2862*07f07615SPaolo Bonzini return 0; 2863*07f07615SPaolo Bonzini } else if (bs->drv->bdrv_co_flush) { 2864*07f07615SPaolo Bonzini return bs->drv->bdrv_co_flush(bs); 2865*07f07615SPaolo Bonzini } else if (bs->drv->bdrv_aio_flush) { 2866*07f07615SPaolo Bonzini BlockDriverAIOCB *acb; 2867e7a8a783SKevin Wolf CoroutineIOCompletion co = { 2868e7a8a783SKevin Wolf .coroutine = qemu_coroutine_self(), 2869e7a8a783SKevin Wolf }; 2870e7a8a783SKevin Wolf 2871*07f07615SPaolo Bonzini acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); 2872*07f07615SPaolo Bonzini if (acb == NULL) { 2873e7a8a783SKevin Wolf return -EIO; 2874*07f07615SPaolo Bonzini } else { 2875e7a8a783SKevin Wolf qemu_coroutine_yield(); 2876e7a8a783SKevin Wolf return co.ret; 2877e7a8a783SKevin Wolf } 2878*07f07615SPaolo Bonzini } else if (bs->drv->bdrv_flush) { 2879*07f07615SPaolo Bonzini return bs->drv->bdrv_flush(bs); 2880*07f07615SPaolo Bonzini } else { 2881*07f07615SPaolo Bonzini /* 2882*07f07615SPaolo Bonzini * Some block drivers always operate in either writethrough or unsafe 2883*07f07615SPaolo Bonzini * mode and don't support bdrv_flush therefore. Usually qemu doesn't 2884*07f07615SPaolo Bonzini * know how the server works (because the behaviour is hardcoded or 2885*07f07615SPaolo Bonzini * depends on server-side configuration), so we can't ensure that 2886*07f07615SPaolo Bonzini * everything is safe on disk. Returning an error doesn't work because 2887*07f07615SPaolo Bonzini * that would break guests even if the server operates in writethrough 2888*07f07615SPaolo Bonzini * mode. 2889*07f07615SPaolo Bonzini * 2890*07f07615SPaolo Bonzini * Let's hope the user knows what he's doing. 2891*07f07615SPaolo Bonzini */ 2892*07f07615SPaolo Bonzini return 0; 2893*07f07615SPaolo Bonzini } 2894*07f07615SPaolo Bonzini } 2895*07f07615SPaolo Bonzini 2896*07f07615SPaolo Bonzini int bdrv_flush(BlockDriverState *bs) 2897*07f07615SPaolo Bonzini { 2898*07f07615SPaolo Bonzini Coroutine *co; 2899*07f07615SPaolo Bonzini RwCo rwco = { 2900*07f07615SPaolo Bonzini .bs = bs, 2901*07f07615SPaolo Bonzini .ret = NOT_DONE, 2902*07f07615SPaolo Bonzini }; 2903*07f07615SPaolo Bonzini 2904*07f07615SPaolo Bonzini if (qemu_in_coroutine()) { 2905*07f07615SPaolo Bonzini /* Fast-path if already in coroutine context */ 2906*07f07615SPaolo Bonzini bdrv_flush_co_entry(&rwco); 2907*07f07615SPaolo Bonzini } else { 2908*07f07615SPaolo Bonzini co = qemu_coroutine_create(bdrv_flush_co_entry); 2909*07f07615SPaolo Bonzini qemu_coroutine_enter(co, &rwco); 2910*07f07615SPaolo Bonzini while (rwco.ret == NOT_DONE) { 2911*07f07615SPaolo Bonzini qemu_aio_wait(); 2912*07f07615SPaolo Bonzini } 2913*07f07615SPaolo Bonzini } 2914*07f07615SPaolo Bonzini 2915*07f07615SPaolo Bonzini return rwco.ret; 2916*07f07615SPaolo Bonzini } 2917e7a8a783SKevin Wolf 2918f9f05dc5SKevin Wolf /**************************************************************/ 291919cb3738Sbellard /* removable device support */ 292019cb3738Sbellard 292119cb3738Sbellard /** 292219cb3738Sbellard * Return TRUE if the media is present 292319cb3738Sbellard */ 292419cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs) 292519cb3738Sbellard { 292619cb3738Sbellard BlockDriver *drv = bs->drv; 2927a1aff5bfSMarkus Armbruster 292819cb3738Sbellard if (!drv) 292919cb3738Sbellard return 0; 293019cb3738Sbellard if (!drv->bdrv_is_inserted) 2931a1aff5bfSMarkus Armbruster return 1; 2932a1aff5bfSMarkus Armbruster return drv->bdrv_is_inserted(bs); 293319cb3738Sbellard } 293419cb3738Sbellard 293519cb3738Sbellard /** 29368e49ca46SMarkus Armbruster * Return whether the media changed since the last call to this 29378e49ca46SMarkus Armbruster * function, or -ENOTSUP if we don't know. Most drivers don't know. 293819cb3738Sbellard */ 293919cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs) 294019cb3738Sbellard { 294119cb3738Sbellard BlockDriver *drv = bs->drv; 294219cb3738Sbellard 29438e49ca46SMarkus Armbruster if (drv && drv->bdrv_media_changed) { 29448e49ca46SMarkus Armbruster return drv->bdrv_media_changed(bs); 29458e49ca46SMarkus Armbruster } 29468e49ca46SMarkus Armbruster return -ENOTSUP; 294719cb3738Sbellard } 294819cb3738Sbellard 294919cb3738Sbellard /** 295019cb3738Sbellard * If eject_flag is TRUE, eject the media. Otherwise, close the tray 295119cb3738Sbellard */ 2952fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag) 295319cb3738Sbellard { 295419cb3738Sbellard BlockDriver *drv = bs->drv; 295519cb3738Sbellard 2956822e1cd1SMarkus Armbruster if (drv && drv->bdrv_eject) { 2957822e1cd1SMarkus Armbruster drv->bdrv_eject(bs, eject_flag); 295819cb3738Sbellard } 295919cb3738Sbellard } 296019cb3738Sbellard 296119cb3738Sbellard /** 296219cb3738Sbellard * Lock or unlock the media (if it is locked, the user won't be able 296319cb3738Sbellard * to eject it manually). 296419cb3738Sbellard */ 2965025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked) 296619cb3738Sbellard { 296719cb3738Sbellard BlockDriver *drv = bs->drv; 296819cb3738Sbellard 2969025e849aSMarkus Armbruster trace_bdrv_lock_medium(bs, locked); 2970b8c6d095SStefan Hajnoczi 2971025e849aSMarkus Armbruster if (drv && drv->bdrv_lock_medium) { 2972025e849aSMarkus Armbruster drv->bdrv_lock_medium(bs, locked); 297319cb3738Sbellard } 297419cb3738Sbellard } 2975985a03b0Sths 2976985a03b0Sths /* needed for generic scsi interface */ 2977985a03b0Sths 2978985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 2979985a03b0Sths { 2980985a03b0Sths BlockDriver *drv = bs->drv; 2981985a03b0Sths 2982985a03b0Sths if (drv && drv->bdrv_ioctl) 2983985a03b0Sths return drv->bdrv_ioctl(bs, req, buf); 2984985a03b0Sths return -ENOTSUP; 2985985a03b0Sths } 29867d780669Saliguori 2987221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 2988221f715dSaliguori unsigned long int req, void *buf, 29897d780669Saliguori BlockDriverCompletionFunc *cb, void *opaque) 29907d780669Saliguori { 2991221f715dSaliguori BlockDriver *drv = bs->drv; 29927d780669Saliguori 2993221f715dSaliguori if (drv && drv->bdrv_aio_ioctl) 2994221f715dSaliguori return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 2995221f715dSaliguori return NULL; 29967d780669Saliguori } 2997e268ca52Saliguori 29987b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) 29997b6f9300SMarkus Armbruster { 30007b6f9300SMarkus Armbruster bs->buffer_alignment = align; 30017b6f9300SMarkus Armbruster } 30027cd1e32aSlirans@il.ibm.com 3003e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size) 3004e268ca52Saliguori { 3005e268ca52Saliguori return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 3006e268ca52Saliguori } 30077cd1e32aSlirans@il.ibm.com 30087cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) 30097cd1e32aSlirans@il.ibm.com { 30107cd1e32aSlirans@il.ibm.com int64_t bitmap_size; 3011a55eb92cSJan Kiszka 3012aaa0eb75SLiran Schour bs->dirty_count = 0; 30137cd1e32aSlirans@il.ibm.com if (enable) { 3014c6d22830SJan Kiszka if (!bs->dirty_bitmap) { 3015c6d22830SJan Kiszka bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + 3016c6d22830SJan Kiszka BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; 3017c6d22830SJan Kiszka bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; 30187cd1e32aSlirans@il.ibm.com 30197267c094SAnthony Liguori bs->dirty_bitmap = g_malloc0(bitmap_size); 30207cd1e32aSlirans@il.ibm.com } 30217cd1e32aSlirans@il.ibm.com } else { 3022c6d22830SJan Kiszka if (bs->dirty_bitmap) { 30237267c094SAnthony Liguori g_free(bs->dirty_bitmap); 3024c6d22830SJan Kiszka bs->dirty_bitmap = NULL; 30257cd1e32aSlirans@il.ibm.com } 30267cd1e32aSlirans@il.ibm.com } 30277cd1e32aSlirans@il.ibm.com } 30287cd1e32aSlirans@il.ibm.com 30297cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) 30307cd1e32aSlirans@il.ibm.com { 30316ea44308SJan Kiszka int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; 30327cd1e32aSlirans@il.ibm.com 3033c6d22830SJan Kiszka if (bs->dirty_bitmap && 3034c6d22830SJan Kiszka (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { 30356d59fec1SMarcelo Tosatti return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & 30366d59fec1SMarcelo Tosatti (1UL << (chunk % (sizeof(unsigned long) * 8)))); 30377cd1e32aSlirans@il.ibm.com } else { 30387cd1e32aSlirans@il.ibm.com return 0; 30397cd1e32aSlirans@il.ibm.com } 30407cd1e32aSlirans@il.ibm.com } 30417cd1e32aSlirans@il.ibm.com 30427cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, 30437cd1e32aSlirans@il.ibm.com int nr_sectors) 30447cd1e32aSlirans@il.ibm.com { 30457cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); 30467cd1e32aSlirans@il.ibm.com } 3047aaa0eb75SLiran Schour 3048aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs) 3049aaa0eb75SLiran Schour { 3050aaa0eb75SLiran Schour return bs->dirty_count; 3051aaa0eb75SLiran Schour } 3052f88e1a42SJes Sorensen 3053db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use) 3054db593f25SMarcelo Tosatti { 3055db593f25SMarcelo Tosatti assert(bs->in_use != in_use); 3056db593f25SMarcelo Tosatti bs->in_use = in_use; 3057db593f25SMarcelo Tosatti } 3058db593f25SMarcelo Tosatti 3059db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs) 3060db593f25SMarcelo Tosatti { 3061db593f25SMarcelo Tosatti return bs->in_use; 3062db593f25SMarcelo Tosatti } 3063db593f25SMarcelo Tosatti 306428a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs) 306528a7282aSLuiz Capitulino { 306628a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 306728a7282aSLuiz Capitulino } 306828a7282aSLuiz Capitulino 306928a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly 307028a7282aSLuiz Capitulino * enables it _and_ the VM is configured to stop on errors */ 307128a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) 307228a7282aSLuiz Capitulino { 307328a7282aSLuiz Capitulino return (bs->iostatus != BDRV_IOS_INVAL && 307428a7282aSLuiz Capitulino (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || 307528a7282aSLuiz Capitulino bs->on_write_error == BLOCK_ERR_STOP_ANY || 307628a7282aSLuiz Capitulino bs->on_read_error == BLOCK_ERR_STOP_ANY)); 307728a7282aSLuiz Capitulino } 307828a7282aSLuiz Capitulino 307928a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs) 308028a7282aSLuiz Capitulino { 308128a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_INVAL; 308228a7282aSLuiz Capitulino } 308328a7282aSLuiz Capitulino 308428a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs) 308528a7282aSLuiz Capitulino { 308628a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 308728a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 308828a7282aSLuiz Capitulino } 308928a7282aSLuiz Capitulino } 309028a7282aSLuiz Capitulino 309128a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation 309228a7282aSLuiz Capitulino quite simple. However, the block layer knows about the error, so it's 309328a7282aSLuiz Capitulino possible to implement this without device models being involved */ 309428a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error) 309528a7282aSLuiz Capitulino { 309628a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { 309728a7282aSLuiz Capitulino assert(error >= 0); 309828a7282aSLuiz Capitulino bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; 309928a7282aSLuiz Capitulino } 310028a7282aSLuiz Capitulino } 310128a7282aSLuiz Capitulino 3102a597e79cSChristoph Hellwig void 3103a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, 3104a597e79cSChristoph Hellwig enum BlockAcctType type) 3105a597e79cSChristoph Hellwig { 3106a597e79cSChristoph Hellwig assert(type < BDRV_MAX_IOTYPE); 3107a597e79cSChristoph Hellwig 3108a597e79cSChristoph Hellwig cookie->bytes = bytes; 3109c488c7f6SChristoph Hellwig cookie->start_time_ns = get_clock(); 3110a597e79cSChristoph Hellwig cookie->type = type; 3111a597e79cSChristoph Hellwig } 3112a597e79cSChristoph Hellwig 3113a597e79cSChristoph Hellwig void 3114a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) 3115a597e79cSChristoph Hellwig { 3116a597e79cSChristoph Hellwig assert(cookie->type < BDRV_MAX_IOTYPE); 3117a597e79cSChristoph Hellwig 3118a597e79cSChristoph Hellwig bs->nr_bytes[cookie->type] += cookie->bytes; 3119a597e79cSChristoph Hellwig bs->nr_ops[cookie->type]++; 3120c488c7f6SChristoph Hellwig bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; 3121a597e79cSChristoph Hellwig } 3122a597e79cSChristoph Hellwig 3123f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt, 3124f88e1a42SJes Sorensen const char *base_filename, const char *base_fmt, 3125f88e1a42SJes Sorensen char *options, uint64_t img_size, int flags) 3126f88e1a42SJes Sorensen { 3127f88e1a42SJes Sorensen QEMUOptionParameter *param = NULL, *create_options = NULL; 3128d220894eSKevin Wolf QEMUOptionParameter *backing_fmt, *backing_file, *size; 3129f88e1a42SJes Sorensen BlockDriverState *bs = NULL; 3130f88e1a42SJes Sorensen BlockDriver *drv, *proto_drv; 313196df67d1SStefan Hajnoczi BlockDriver *backing_drv = NULL; 3132f88e1a42SJes Sorensen int ret = 0; 3133f88e1a42SJes Sorensen 3134f88e1a42SJes Sorensen /* Find driver and parse its options */ 3135f88e1a42SJes Sorensen drv = bdrv_find_format(fmt); 3136f88e1a42SJes Sorensen if (!drv) { 3137f88e1a42SJes Sorensen error_report("Unknown file format '%s'", fmt); 31384f70f249SJes Sorensen ret = -EINVAL; 3139f88e1a42SJes Sorensen goto out; 3140f88e1a42SJes Sorensen } 3141f88e1a42SJes Sorensen 3142f88e1a42SJes Sorensen proto_drv = bdrv_find_protocol(filename); 3143f88e1a42SJes Sorensen if (!proto_drv) { 3144f88e1a42SJes Sorensen error_report("Unknown protocol '%s'", filename); 31454f70f249SJes Sorensen ret = -EINVAL; 3146f88e1a42SJes Sorensen goto out; 3147f88e1a42SJes Sorensen } 3148f88e1a42SJes Sorensen 3149f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3150f88e1a42SJes Sorensen drv->create_options); 3151f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3152f88e1a42SJes Sorensen proto_drv->create_options); 3153f88e1a42SJes Sorensen 3154f88e1a42SJes Sorensen /* Create parameter list with default values */ 3155f88e1a42SJes Sorensen param = parse_option_parameters("", create_options, param); 3156f88e1a42SJes Sorensen 3157f88e1a42SJes Sorensen set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); 3158f88e1a42SJes Sorensen 3159f88e1a42SJes Sorensen /* Parse -o options */ 3160f88e1a42SJes Sorensen if (options) { 3161f88e1a42SJes Sorensen param = parse_option_parameters(options, create_options, param); 3162f88e1a42SJes Sorensen if (param == NULL) { 3163f88e1a42SJes Sorensen error_report("Invalid options for file format '%s'.", fmt); 31644f70f249SJes Sorensen ret = -EINVAL; 3165f88e1a42SJes Sorensen goto out; 3166f88e1a42SJes Sorensen } 3167f88e1a42SJes Sorensen } 3168f88e1a42SJes Sorensen 3169f88e1a42SJes Sorensen if (base_filename) { 3170f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, 3171f88e1a42SJes Sorensen base_filename)) { 3172f88e1a42SJes Sorensen error_report("Backing file not supported for file format '%s'", 3173f88e1a42SJes Sorensen fmt); 31744f70f249SJes Sorensen ret = -EINVAL; 3175f88e1a42SJes Sorensen goto out; 3176f88e1a42SJes Sorensen } 3177f88e1a42SJes Sorensen } 3178f88e1a42SJes Sorensen 3179f88e1a42SJes Sorensen if (base_fmt) { 3180f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { 3181f88e1a42SJes Sorensen error_report("Backing file format not supported for file " 3182f88e1a42SJes Sorensen "format '%s'", fmt); 31834f70f249SJes Sorensen ret = -EINVAL; 3184f88e1a42SJes Sorensen goto out; 3185f88e1a42SJes Sorensen } 3186f88e1a42SJes Sorensen } 3187f88e1a42SJes Sorensen 3188792da93aSJes Sorensen backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); 3189792da93aSJes Sorensen if (backing_file && backing_file->value.s) { 3190792da93aSJes Sorensen if (!strcmp(filename, backing_file->value.s)) { 3191792da93aSJes Sorensen error_report("Error: Trying to create an image with the " 3192792da93aSJes Sorensen "same filename as the backing file"); 31934f70f249SJes Sorensen ret = -EINVAL; 3194792da93aSJes Sorensen goto out; 3195792da93aSJes Sorensen } 3196792da93aSJes Sorensen } 3197792da93aSJes Sorensen 3198f88e1a42SJes Sorensen backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); 3199f88e1a42SJes Sorensen if (backing_fmt && backing_fmt->value.s) { 320096df67d1SStefan Hajnoczi backing_drv = bdrv_find_format(backing_fmt->value.s); 320196df67d1SStefan Hajnoczi if (!backing_drv) { 3202f88e1a42SJes Sorensen error_report("Unknown backing file format '%s'", 3203f88e1a42SJes Sorensen backing_fmt->value.s); 32044f70f249SJes Sorensen ret = -EINVAL; 3205f88e1a42SJes Sorensen goto out; 3206f88e1a42SJes Sorensen } 3207f88e1a42SJes Sorensen } 3208f88e1a42SJes Sorensen 3209f88e1a42SJes Sorensen // The size for the image must always be specified, with one exception: 3210f88e1a42SJes Sorensen // If we are using a backing file, we can obtain the size from there 3211d220894eSKevin Wolf size = get_option_parameter(param, BLOCK_OPT_SIZE); 3212d220894eSKevin Wolf if (size && size->value.n == -1) { 3213f88e1a42SJes Sorensen if (backing_file && backing_file->value.s) { 3214f88e1a42SJes Sorensen uint64_t size; 3215f88e1a42SJes Sorensen char buf[32]; 3216f88e1a42SJes Sorensen 3217f88e1a42SJes Sorensen bs = bdrv_new(""); 3218f88e1a42SJes Sorensen 321996df67d1SStefan Hajnoczi ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv); 3220f88e1a42SJes Sorensen if (ret < 0) { 322196df67d1SStefan Hajnoczi error_report("Could not open '%s'", backing_file->value.s); 3222f88e1a42SJes Sorensen goto out; 3223f88e1a42SJes Sorensen } 3224f88e1a42SJes Sorensen bdrv_get_geometry(bs, &size); 3225f88e1a42SJes Sorensen size *= 512; 3226f88e1a42SJes Sorensen 3227f88e1a42SJes Sorensen snprintf(buf, sizeof(buf), "%" PRId64, size); 3228f88e1a42SJes Sorensen set_option_parameter(param, BLOCK_OPT_SIZE, buf); 3229f88e1a42SJes Sorensen } else { 3230f88e1a42SJes Sorensen error_report("Image creation needs a size parameter"); 32314f70f249SJes Sorensen ret = -EINVAL; 3232f88e1a42SJes Sorensen goto out; 3233f88e1a42SJes Sorensen } 3234f88e1a42SJes Sorensen } 3235f88e1a42SJes Sorensen 3236f88e1a42SJes Sorensen printf("Formatting '%s', fmt=%s ", filename, fmt); 3237f88e1a42SJes Sorensen print_option_parameters(param); 3238f88e1a42SJes Sorensen puts(""); 3239f88e1a42SJes Sorensen 3240f88e1a42SJes Sorensen ret = bdrv_create(drv, filename, param); 3241f88e1a42SJes Sorensen 3242f88e1a42SJes Sorensen if (ret < 0) { 3243f88e1a42SJes Sorensen if (ret == -ENOTSUP) { 3244f88e1a42SJes Sorensen error_report("Formatting or formatting option not supported for " 3245f88e1a42SJes Sorensen "file format '%s'", fmt); 3246f88e1a42SJes Sorensen } else if (ret == -EFBIG) { 3247f88e1a42SJes Sorensen error_report("The image size is too large for file format '%s'", 3248f88e1a42SJes Sorensen fmt); 3249f88e1a42SJes Sorensen } else { 3250f88e1a42SJes Sorensen error_report("%s: error while creating %s: %s", filename, fmt, 3251f88e1a42SJes Sorensen strerror(-ret)); 3252f88e1a42SJes Sorensen } 3253f88e1a42SJes Sorensen } 3254f88e1a42SJes Sorensen 3255f88e1a42SJes Sorensen out: 3256f88e1a42SJes Sorensen free_option_parameters(create_options); 3257f88e1a42SJes Sorensen free_option_parameters(param); 3258f88e1a42SJes Sorensen 3259f88e1a42SJes Sorensen if (bs) { 3260f88e1a42SJes Sorensen bdrv_delete(bs); 3261f88e1a42SJes Sorensen } 32624f70f249SJes Sorensen 32634f70f249SJes Sorensen return ret; 3264f88e1a42SJes Sorensen } 3265