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 477d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); 48f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 49f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 50c87c0672Saliguori BlockDriverCompletionFunc *cb, void *opaque); 51f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 52f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 53ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque); 54b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 55b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque); 56016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, 57016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque); 5883f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 5983f64091Sbellard uint8_t *buf, int nb_sectors); 6083f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 6183f64091Sbellard const uint8_t *buf, int nb_sectors); 6268485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs, 6368485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 6468485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque); 6568485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs, 6668485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 6768485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque); 68f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 69f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 70f9f05dc5SKevin Wolf QEMUIOVector *iov); 71f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 72f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 73f9f05dc5SKevin Wolf QEMUIOVector *iov); 74e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs); 75ec530c81Sbellard 761b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states = 771b7bdbc1SStefan Hajnoczi QTAILQ_HEAD_INITIALIZER(bdrv_states); 787ee930d0Sblueswir1 798a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers = 808a22f02aSStefan Hajnoczi QLIST_HEAD_INITIALIZER(bdrv_drivers); 81ea2384d3Sbellard 82f9092b10SMarkus Armbruster /* The device to use for VM snapshots */ 83f9092b10SMarkus Armbruster static BlockDriverState *bs_snapshots; 84f9092b10SMarkus Armbruster 85eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */ 86eb852011SMarkus Armbruster static int use_bdrv_whitelist; 87eb852011SMarkus Armbruster 889e0b22f4SStefan Hajnoczi #ifdef _WIN32 899e0b22f4SStefan Hajnoczi static int is_windows_drive_prefix(const char *filename) 909e0b22f4SStefan Hajnoczi { 919e0b22f4SStefan Hajnoczi return (((filename[0] >= 'a' && filename[0] <= 'z') || 929e0b22f4SStefan Hajnoczi (filename[0] >= 'A' && filename[0] <= 'Z')) && 939e0b22f4SStefan Hajnoczi filename[1] == ':'); 949e0b22f4SStefan Hajnoczi } 959e0b22f4SStefan Hajnoczi 969e0b22f4SStefan Hajnoczi int is_windows_drive(const char *filename) 979e0b22f4SStefan Hajnoczi { 989e0b22f4SStefan Hajnoczi if (is_windows_drive_prefix(filename) && 999e0b22f4SStefan Hajnoczi filename[2] == '\0') 1009e0b22f4SStefan Hajnoczi return 1; 1019e0b22f4SStefan Hajnoczi if (strstart(filename, "\\\\.\\", NULL) || 1029e0b22f4SStefan Hajnoczi strstart(filename, "//./", NULL)) 1039e0b22f4SStefan Hajnoczi return 1; 1049e0b22f4SStefan Hajnoczi return 0; 1059e0b22f4SStefan Hajnoczi } 1069e0b22f4SStefan Hajnoczi #endif 1079e0b22f4SStefan Hajnoczi 1089e0b22f4SStefan Hajnoczi /* check if the path starts with "<protocol>:" */ 1099e0b22f4SStefan Hajnoczi static int path_has_protocol(const char *path) 1109e0b22f4SStefan Hajnoczi { 1119e0b22f4SStefan Hajnoczi #ifdef _WIN32 1129e0b22f4SStefan Hajnoczi if (is_windows_drive(path) || 1139e0b22f4SStefan Hajnoczi is_windows_drive_prefix(path)) { 1149e0b22f4SStefan Hajnoczi return 0; 1159e0b22f4SStefan Hajnoczi } 1169e0b22f4SStefan Hajnoczi #endif 1179e0b22f4SStefan Hajnoczi 1189e0b22f4SStefan Hajnoczi return strchr(path, ':') != NULL; 1199e0b22f4SStefan Hajnoczi } 1209e0b22f4SStefan Hajnoczi 12183f64091Sbellard int path_is_absolute(const char *path) 12283f64091Sbellard { 12383f64091Sbellard const char *p; 12421664424Sbellard #ifdef _WIN32 12521664424Sbellard /* specific case for names like: "\\.\d:" */ 12621664424Sbellard if (*path == '/' || *path == '\\') 12721664424Sbellard return 1; 12821664424Sbellard #endif 12983f64091Sbellard p = strchr(path, ':'); 13083f64091Sbellard if (p) 13183f64091Sbellard p++; 13283f64091Sbellard else 13383f64091Sbellard p = path; 1343b9f94e1Sbellard #ifdef _WIN32 1353b9f94e1Sbellard return (*p == '/' || *p == '\\'); 1363b9f94e1Sbellard #else 1373b9f94e1Sbellard return (*p == '/'); 1383b9f94e1Sbellard #endif 13983f64091Sbellard } 14083f64091Sbellard 14183f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a 14283f64091Sbellard path to it by considering it is relative to base_path. URL are 14383f64091Sbellard supported. */ 14483f64091Sbellard void path_combine(char *dest, int dest_size, 14583f64091Sbellard const char *base_path, 14683f64091Sbellard const char *filename) 14783f64091Sbellard { 14883f64091Sbellard const char *p, *p1; 14983f64091Sbellard int len; 15083f64091Sbellard 15183f64091Sbellard if (dest_size <= 0) 15283f64091Sbellard return; 15383f64091Sbellard if (path_is_absolute(filename)) { 15483f64091Sbellard pstrcpy(dest, dest_size, filename); 15583f64091Sbellard } else { 15683f64091Sbellard p = strchr(base_path, ':'); 15783f64091Sbellard if (p) 15883f64091Sbellard p++; 15983f64091Sbellard else 16083f64091Sbellard p = base_path; 1613b9f94e1Sbellard p1 = strrchr(base_path, '/'); 1623b9f94e1Sbellard #ifdef _WIN32 1633b9f94e1Sbellard { 1643b9f94e1Sbellard const char *p2; 1653b9f94e1Sbellard p2 = strrchr(base_path, '\\'); 1663b9f94e1Sbellard if (!p1 || p2 > p1) 1673b9f94e1Sbellard p1 = p2; 1683b9f94e1Sbellard } 1693b9f94e1Sbellard #endif 17083f64091Sbellard if (p1) 17183f64091Sbellard p1++; 17283f64091Sbellard else 17383f64091Sbellard p1 = base_path; 17483f64091Sbellard if (p1 > p) 17583f64091Sbellard p = p1; 17683f64091Sbellard len = p - base_path; 17783f64091Sbellard if (len > dest_size - 1) 17883f64091Sbellard len = dest_size - 1; 17983f64091Sbellard memcpy(dest, base_path, len); 18083f64091Sbellard dest[len] = '\0'; 18183f64091Sbellard pstrcat(dest, dest_size, filename); 18283f64091Sbellard } 18383f64091Sbellard } 18483f64091Sbellard 1855efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv) 186ea2384d3Sbellard { 18768485420SKevin Wolf if (bdrv->bdrv_co_readv) { 18868485420SKevin Wolf /* Emulate AIO by coroutines, and sync by AIO */ 18968485420SKevin Wolf bdrv->bdrv_aio_readv = bdrv_co_aio_readv_em; 19068485420SKevin Wolf bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em; 19168485420SKevin Wolf bdrv->bdrv_read = bdrv_read_em; 19268485420SKevin Wolf bdrv->bdrv_write = bdrv_write_em; 193f9f05dc5SKevin Wolf } else { 194f9f05dc5SKevin Wolf bdrv->bdrv_co_readv = bdrv_co_readv_em; 195f9f05dc5SKevin Wolf bdrv->bdrv_co_writev = bdrv_co_writev_em; 196f9f05dc5SKevin Wolf 197f9f05dc5SKevin Wolf if (!bdrv->bdrv_aio_readv) { 19883f64091Sbellard /* add AIO emulation layer */ 199f141eafeSaliguori bdrv->bdrv_aio_readv = bdrv_aio_readv_em; 200f141eafeSaliguori bdrv->bdrv_aio_writev = bdrv_aio_writev_em; 201eda578e5Saliguori } else if (!bdrv->bdrv_read) { 20283f64091Sbellard /* add synchronous IO emulation layer */ 20383f64091Sbellard bdrv->bdrv_read = bdrv_read_em; 20483f64091Sbellard bdrv->bdrv_write = bdrv_write_em; 20583f64091Sbellard } 206f9f05dc5SKevin Wolf } 207b2e12bc6SChristoph Hellwig 208b2e12bc6SChristoph Hellwig if (!bdrv->bdrv_aio_flush) 209b2e12bc6SChristoph Hellwig bdrv->bdrv_aio_flush = bdrv_aio_flush_em; 210b2e12bc6SChristoph Hellwig 2118a22f02aSStefan Hajnoczi QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); 212ea2384d3Sbellard } 213b338082bSbellard 214b338082bSbellard /* create a new block device (by default it is empty) */ 215b338082bSbellard BlockDriverState *bdrv_new(const char *device_name) 216fc01f7e7Sbellard { 2171b7bdbc1SStefan Hajnoczi BlockDriverState *bs; 218b338082bSbellard 2197267c094SAnthony Liguori bs = g_malloc0(sizeof(BlockDriverState)); 220b338082bSbellard pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 221ea2384d3Sbellard if (device_name[0] != '\0') { 2221b7bdbc1SStefan Hajnoczi QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); 223ea2384d3Sbellard } 22428a7282aSLuiz Capitulino bdrv_iostatus_disable(bs); 225b338082bSbellard return bs; 226b338082bSbellard } 227b338082bSbellard 228ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name) 229ea2384d3Sbellard { 230ea2384d3Sbellard BlockDriver *drv1; 2318a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 2328a22f02aSStefan Hajnoczi if (!strcmp(drv1->format_name, format_name)) { 233ea2384d3Sbellard return drv1; 234ea2384d3Sbellard } 2358a22f02aSStefan Hajnoczi } 236ea2384d3Sbellard return NULL; 237ea2384d3Sbellard } 238ea2384d3Sbellard 239eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv) 240eb852011SMarkus Armbruster { 241eb852011SMarkus Armbruster static const char *whitelist[] = { 242eb852011SMarkus Armbruster CONFIG_BDRV_WHITELIST 243eb852011SMarkus Armbruster }; 244eb852011SMarkus Armbruster const char **p; 245eb852011SMarkus Armbruster 246eb852011SMarkus Armbruster if (!whitelist[0]) 247eb852011SMarkus Armbruster return 1; /* no whitelist, anything goes */ 248eb852011SMarkus Armbruster 249eb852011SMarkus Armbruster for (p = whitelist; *p; p++) { 250eb852011SMarkus Armbruster if (!strcmp(drv->format_name, *p)) { 251eb852011SMarkus Armbruster return 1; 252eb852011SMarkus Armbruster } 253eb852011SMarkus Armbruster } 254eb852011SMarkus Armbruster return 0; 255eb852011SMarkus Armbruster } 256eb852011SMarkus Armbruster 257eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name) 258eb852011SMarkus Armbruster { 259eb852011SMarkus Armbruster BlockDriver *drv = bdrv_find_format(format_name); 260eb852011SMarkus Armbruster return drv && bdrv_is_whitelisted(drv) ? drv : NULL; 261eb852011SMarkus Armbruster } 262eb852011SMarkus Armbruster 2630e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename, 2640e7e1989SKevin Wolf QEMUOptionParameter *options) 265ea2384d3Sbellard { 266ea2384d3Sbellard if (!drv->bdrv_create) 267ea2384d3Sbellard return -ENOTSUP; 2680e7e1989SKevin Wolf 2690e7e1989SKevin Wolf return drv->bdrv_create(filename, options); 270ea2384d3Sbellard } 271ea2384d3Sbellard 27284a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options) 27384a12e66SChristoph Hellwig { 27484a12e66SChristoph Hellwig BlockDriver *drv; 27584a12e66SChristoph Hellwig 276b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 27784a12e66SChristoph Hellwig if (drv == NULL) { 27816905d71SStefan Hajnoczi return -ENOENT; 27984a12e66SChristoph Hellwig } 28084a12e66SChristoph Hellwig 28184a12e66SChristoph Hellwig return bdrv_create(drv, filename, options); 28284a12e66SChristoph Hellwig } 28384a12e66SChristoph Hellwig 284d5249393Sbellard #ifdef _WIN32 28595389c86Sbellard void get_tmp_filename(char *filename, int size) 286d5249393Sbellard { 2873b9f94e1Sbellard char temp_dir[MAX_PATH]; 2883b9f94e1Sbellard 2893b9f94e1Sbellard GetTempPath(MAX_PATH, temp_dir); 2903b9f94e1Sbellard GetTempFileName(temp_dir, "qem", 0, filename); 291d5249393Sbellard } 292d5249393Sbellard #else 29395389c86Sbellard void get_tmp_filename(char *filename, int size) 294ea2384d3Sbellard { 295ea2384d3Sbellard int fd; 2967ccfb2ebSblueswir1 const char *tmpdir; 297d5249393Sbellard /* XXX: race condition possible */ 2980badc1eeSaurel32 tmpdir = getenv("TMPDIR"); 2990badc1eeSaurel32 if (!tmpdir) 3000badc1eeSaurel32 tmpdir = "/tmp"; 3010badc1eeSaurel32 snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 302ea2384d3Sbellard fd = mkstemp(filename); 303ea2384d3Sbellard close(fd); 304ea2384d3Sbellard } 305d5249393Sbellard #endif 306ea2384d3Sbellard 307f3a5d3f8SChristoph Hellwig /* 308f3a5d3f8SChristoph Hellwig * Detect host devices. By convention, /dev/cdrom[N] is always 309f3a5d3f8SChristoph Hellwig * recognized as a host CDROM. 310f3a5d3f8SChristoph Hellwig */ 311f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename) 312f3a5d3f8SChristoph Hellwig { 313508c7cb3SChristoph Hellwig int score_max = 0, score; 314508c7cb3SChristoph Hellwig BlockDriver *drv = NULL, *d; 315f3a5d3f8SChristoph Hellwig 3168a22f02aSStefan Hajnoczi QLIST_FOREACH(d, &bdrv_drivers, list) { 317508c7cb3SChristoph Hellwig if (d->bdrv_probe_device) { 318508c7cb3SChristoph Hellwig score = d->bdrv_probe_device(filename); 319508c7cb3SChristoph Hellwig if (score > score_max) { 320508c7cb3SChristoph Hellwig score_max = score; 321508c7cb3SChristoph Hellwig drv = d; 322f3a5d3f8SChristoph Hellwig } 323508c7cb3SChristoph Hellwig } 324f3a5d3f8SChristoph Hellwig } 325f3a5d3f8SChristoph Hellwig 326508c7cb3SChristoph Hellwig return drv; 327f3a5d3f8SChristoph Hellwig } 328f3a5d3f8SChristoph Hellwig 329b50cbabcSMORITA Kazutaka BlockDriver *bdrv_find_protocol(const char *filename) 33084a12e66SChristoph Hellwig { 33184a12e66SChristoph Hellwig BlockDriver *drv1; 33284a12e66SChristoph Hellwig char protocol[128]; 33384a12e66SChristoph Hellwig int len; 33484a12e66SChristoph Hellwig const char *p; 33584a12e66SChristoph Hellwig 33666f82ceeSKevin Wolf /* TODO Drivers without bdrv_file_open must be specified explicitly */ 33766f82ceeSKevin Wolf 33839508e7aSChristoph Hellwig /* 33939508e7aSChristoph Hellwig * XXX(hch): we really should not let host device detection 34039508e7aSChristoph Hellwig * override an explicit protocol specification, but moving this 34139508e7aSChristoph Hellwig * later breaks access to device names with colons in them. 34239508e7aSChristoph Hellwig * Thanks to the brain-dead persistent naming schemes on udev- 34339508e7aSChristoph Hellwig * based Linux systems those actually are quite common. 34439508e7aSChristoph Hellwig */ 34584a12e66SChristoph Hellwig drv1 = find_hdev_driver(filename); 34639508e7aSChristoph Hellwig if (drv1) { 34784a12e66SChristoph Hellwig return drv1; 34884a12e66SChristoph Hellwig } 34939508e7aSChristoph Hellwig 3509e0b22f4SStefan Hajnoczi if (!path_has_protocol(filename)) { 35139508e7aSChristoph Hellwig return bdrv_find_format("file"); 35239508e7aSChristoph Hellwig } 3539e0b22f4SStefan Hajnoczi p = strchr(filename, ':'); 3549e0b22f4SStefan Hajnoczi assert(p != NULL); 35584a12e66SChristoph Hellwig len = p - filename; 35684a12e66SChristoph Hellwig if (len > sizeof(protocol) - 1) 35784a12e66SChristoph Hellwig len = sizeof(protocol) - 1; 35884a12e66SChristoph Hellwig memcpy(protocol, filename, len); 35984a12e66SChristoph Hellwig protocol[len] = '\0'; 36084a12e66SChristoph Hellwig QLIST_FOREACH(drv1, &bdrv_drivers, list) { 36184a12e66SChristoph Hellwig if (drv1->protocol_name && 36284a12e66SChristoph Hellwig !strcmp(drv1->protocol_name, protocol)) { 36384a12e66SChristoph Hellwig return drv1; 36484a12e66SChristoph Hellwig } 36584a12e66SChristoph Hellwig } 36684a12e66SChristoph Hellwig return NULL; 36784a12e66SChristoph Hellwig } 36884a12e66SChristoph Hellwig 369c98ac35dSStefan Weil static int find_image_format(const char *filename, BlockDriver **pdrv) 370ea2384d3Sbellard { 37183f64091Sbellard int ret, score, score_max; 372ea2384d3Sbellard BlockDriver *drv1, *drv; 37383f64091Sbellard uint8_t buf[2048]; 37483f64091Sbellard BlockDriverState *bs; 375ea2384d3Sbellard 376f5edb014SNaphtali Sprei ret = bdrv_file_open(&bs, filename, 0); 377c98ac35dSStefan Weil if (ret < 0) { 378c98ac35dSStefan Weil *pdrv = NULL; 379c98ac35dSStefan Weil return ret; 380c98ac35dSStefan Weil } 381f8ea0b00SNicholas Bellinger 38208a00559SKevin Wolf /* Return the raw BlockDriver * to scsi-generic devices or empty drives */ 38308a00559SKevin Wolf if (bs->sg || !bdrv_is_inserted(bs)) { 3841a396859SNicholas A. Bellinger bdrv_delete(bs); 385c98ac35dSStefan Weil drv = bdrv_find_format("raw"); 386c98ac35dSStefan Weil if (!drv) { 387c98ac35dSStefan Weil ret = -ENOENT; 388c98ac35dSStefan Weil } 389c98ac35dSStefan Weil *pdrv = drv; 390c98ac35dSStefan Weil return ret; 3911a396859SNicholas A. Bellinger } 392f8ea0b00SNicholas Bellinger 39383f64091Sbellard ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 39483f64091Sbellard bdrv_delete(bs); 395ea2384d3Sbellard if (ret < 0) { 396c98ac35dSStefan Weil *pdrv = NULL; 397c98ac35dSStefan Weil return ret; 398ea2384d3Sbellard } 399ea2384d3Sbellard 400ea2384d3Sbellard score_max = 0; 40184a12e66SChristoph Hellwig drv = NULL; 4028a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 40383f64091Sbellard if (drv1->bdrv_probe) { 404ea2384d3Sbellard score = drv1->bdrv_probe(buf, ret, filename); 405ea2384d3Sbellard if (score > score_max) { 406ea2384d3Sbellard score_max = score; 407ea2384d3Sbellard drv = drv1; 408ea2384d3Sbellard } 409ea2384d3Sbellard } 41083f64091Sbellard } 411c98ac35dSStefan Weil if (!drv) { 412c98ac35dSStefan Weil ret = -ENOENT; 413c98ac35dSStefan Weil } 414c98ac35dSStefan Weil *pdrv = drv; 415c98ac35dSStefan Weil return ret; 416ea2384d3Sbellard } 417ea2384d3Sbellard 41851762288SStefan Hajnoczi /** 41951762288SStefan Hajnoczi * Set the current 'total_sectors' value 42051762288SStefan Hajnoczi */ 42151762288SStefan Hajnoczi static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) 42251762288SStefan Hajnoczi { 42351762288SStefan Hajnoczi BlockDriver *drv = bs->drv; 42451762288SStefan Hajnoczi 425396759adSNicholas Bellinger /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */ 426396759adSNicholas Bellinger if (bs->sg) 427396759adSNicholas Bellinger return 0; 428396759adSNicholas Bellinger 42951762288SStefan Hajnoczi /* query actual device if possible, otherwise just trust the hint */ 43051762288SStefan Hajnoczi if (drv->bdrv_getlength) { 43151762288SStefan Hajnoczi int64_t length = drv->bdrv_getlength(bs); 43251762288SStefan Hajnoczi if (length < 0) { 43351762288SStefan Hajnoczi return length; 43451762288SStefan Hajnoczi } 43551762288SStefan Hajnoczi hint = length >> BDRV_SECTOR_BITS; 43651762288SStefan Hajnoczi } 43751762288SStefan Hajnoczi 43851762288SStefan Hajnoczi bs->total_sectors = hint; 43951762288SStefan Hajnoczi return 0; 44051762288SStefan Hajnoczi } 44151762288SStefan Hajnoczi 442c3993cdcSStefan Hajnoczi /** 443c3993cdcSStefan Hajnoczi * Set open flags for a given cache mode 444c3993cdcSStefan Hajnoczi * 445c3993cdcSStefan Hajnoczi * Return 0 on success, -1 if the cache mode was invalid. 446c3993cdcSStefan Hajnoczi */ 447c3993cdcSStefan Hajnoczi int bdrv_parse_cache_flags(const char *mode, int *flags) 448c3993cdcSStefan Hajnoczi { 449c3993cdcSStefan Hajnoczi *flags &= ~BDRV_O_CACHE_MASK; 450c3993cdcSStefan Hajnoczi 451c3993cdcSStefan Hajnoczi if (!strcmp(mode, "off") || !strcmp(mode, "none")) { 452c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; 45392196b2fSStefan Hajnoczi } else if (!strcmp(mode, "directsync")) { 45492196b2fSStefan Hajnoczi *flags |= BDRV_O_NOCACHE; 455c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writeback")) { 456c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 457c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "unsafe")) { 458c3993cdcSStefan Hajnoczi *flags |= BDRV_O_CACHE_WB; 459c3993cdcSStefan Hajnoczi *flags |= BDRV_O_NO_FLUSH; 460c3993cdcSStefan Hajnoczi } else if (!strcmp(mode, "writethrough")) { 461c3993cdcSStefan Hajnoczi /* this is the default */ 462c3993cdcSStefan Hajnoczi } else { 463c3993cdcSStefan Hajnoczi return -1; 464c3993cdcSStefan Hajnoczi } 465c3993cdcSStefan Hajnoczi 466c3993cdcSStefan Hajnoczi return 0; 467c3993cdcSStefan Hajnoczi } 468c3993cdcSStefan Hajnoczi 469b6ce07aaSKevin Wolf /* 47057915332SKevin Wolf * Common part for opening disk images and files 47157915332SKevin Wolf */ 47257915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename, 47357915332SKevin Wolf int flags, BlockDriver *drv) 47457915332SKevin Wolf { 47557915332SKevin Wolf int ret, open_flags; 47657915332SKevin Wolf 47757915332SKevin Wolf assert(drv != NULL); 47857915332SKevin Wolf 47928dcee10SStefan Hajnoczi trace_bdrv_open_common(bs, filename, flags, drv->format_name); 48028dcee10SStefan Hajnoczi 48166f82ceeSKevin Wolf bs->file = NULL; 48251762288SStefan Hajnoczi bs->total_sectors = 0; 48357915332SKevin Wolf bs->encrypted = 0; 48457915332SKevin Wolf bs->valid_key = 0; 48557915332SKevin Wolf bs->open_flags = flags; 48657915332SKevin Wolf bs->buffer_alignment = 512; 48757915332SKevin Wolf 48857915332SKevin Wolf pstrcpy(bs->filename, sizeof(bs->filename), filename); 48957915332SKevin Wolf 49057915332SKevin Wolf if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { 49157915332SKevin Wolf return -ENOTSUP; 49257915332SKevin Wolf } 49357915332SKevin Wolf 49457915332SKevin Wolf bs->drv = drv; 4957267c094SAnthony Liguori bs->opaque = g_malloc0(drv->instance_size); 49657915332SKevin Wolf 497a6599793SChristoph Hellwig if (flags & BDRV_O_CACHE_WB) 49857915332SKevin Wolf bs->enable_write_cache = 1; 49957915332SKevin Wolf 50057915332SKevin Wolf /* 50157915332SKevin Wolf * Clear flags that are internal to the block layer before opening the 50257915332SKevin Wolf * image. 50357915332SKevin Wolf */ 50457915332SKevin Wolf open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 50557915332SKevin Wolf 50657915332SKevin Wolf /* 507ebabb67aSStefan Weil * Snapshots should be writable. 50857915332SKevin Wolf */ 50957915332SKevin Wolf if (bs->is_temporary) { 51057915332SKevin Wolf open_flags |= BDRV_O_RDWR; 51157915332SKevin Wolf } 51257915332SKevin Wolf 51366f82ceeSKevin Wolf /* Open the image, either directly or using a protocol */ 51466f82ceeSKevin Wolf if (drv->bdrv_file_open) { 51566f82ceeSKevin Wolf ret = drv->bdrv_file_open(bs, filename, open_flags); 51666f82ceeSKevin Wolf } else { 51766f82ceeSKevin Wolf ret = bdrv_file_open(&bs->file, filename, open_flags); 51866f82ceeSKevin Wolf if (ret >= 0) { 51966f82ceeSKevin Wolf ret = drv->bdrv_open(bs, open_flags); 52066f82ceeSKevin Wolf } 52166f82ceeSKevin Wolf } 52266f82ceeSKevin Wolf 52357915332SKevin Wolf if (ret < 0) { 52457915332SKevin Wolf goto free_and_fail; 52557915332SKevin Wolf } 52657915332SKevin Wolf 52757915332SKevin Wolf bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); 52851762288SStefan Hajnoczi 52951762288SStefan Hajnoczi ret = refresh_total_sectors(bs, bs->total_sectors); 53051762288SStefan Hajnoczi if (ret < 0) { 53151762288SStefan Hajnoczi goto free_and_fail; 53257915332SKevin Wolf } 53351762288SStefan Hajnoczi 53457915332SKevin Wolf #ifndef _WIN32 53557915332SKevin Wolf if (bs->is_temporary) { 53657915332SKevin Wolf unlink(filename); 53757915332SKevin Wolf } 53857915332SKevin Wolf #endif 53957915332SKevin Wolf return 0; 54057915332SKevin Wolf 54157915332SKevin Wolf free_and_fail: 54266f82ceeSKevin Wolf if (bs->file) { 54366f82ceeSKevin Wolf bdrv_delete(bs->file); 54466f82ceeSKevin Wolf bs->file = NULL; 54566f82ceeSKevin Wolf } 5467267c094SAnthony Liguori g_free(bs->opaque); 54757915332SKevin Wolf bs->opaque = NULL; 54857915332SKevin Wolf bs->drv = NULL; 54957915332SKevin Wolf return ret; 55057915332SKevin Wolf } 55157915332SKevin Wolf 55257915332SKevin Wolf /* 553b6ce07aaSKevin Wolf * Opens a file using a protocol (file, host_device, nbd, ...) 554b6ce07aaSKevin Wolf */ 55583f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 556b338082bSbellard { 55783f64091Sbellard BlockDriverState *bs; 5586db95603SChristoph Hellwig BlockDriver *drv; 55983f64091Sbellard int ret; 5603b0d4f61Sbellard 561b50cbabcSMORITA Kazutaka drv = bdrv_find_protocol(filename); 5626db95603SChristoph Hellwig if (!drv) { 5636db95603SChristoph Hellwig return -ENOENT; 5646db95603SChristoph Hellwig } 5656db95603SChristoph Hellwig 56683f64091Sbellard bs = bdrv_new(""); 567b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 56883f64091Sbellard if (ret < 0) { 56983f64091Sbellard bdrv_delete(bs); 57083f64091Sbellard return ret; 5713b0d4f61Sbellard } 57271d0770cSaliguori bs->growable = 1; 57383f64091Sbellard *pbs = bs; 57483f64091Sbellard return 0; 5753b0d4f61Sbellard } 5763b0d4f61Sbellard 577b6ce07aaSKevin Wolf /* 578b6ce07aaSKevin Wolf * Opens a disk image (raw, qcow2, vmdk, ...) 579b6ce07aaSKevin Wolf */ 580d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags, 581ea2384d3Sbellard BlockDriver *drv) 582ea2384d3Sbellard { 583b6ce07aaSKevin Wolf int ret; 58433e3963eSbellard 58583f64091Sbellard if (flags & BDRV_O_SNAPSHOT) { 586ea2384d3Sbellard BlockDriverState *bs1; 587ea2384d3Sbellard int64_t total_size; 5887c96d46eSaliguori int is_protocol = 0; 58991a073a9SKevin Wolf BlockDriver *bdrv_qcow2; 59091a073a9SKevin Wolf QEMUOptionParameter *options; 591b6ce07aaSKevin Wolf char tmp_filename[PATH_MAX]; 592b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 59333e3963eSbellard 594ea2384d3Sbellard /* if snapshot, we create a temporary backing file and open it 595ea2384d3Sbellard instead of opening 'filename' directly */ 596ea2384d3Sbellard 597ea2384d3Sbellard /* if there is a backing file, use it */ 598ea2384d3Sbellard bs1 = bdrv_new(""); 599d6e9098eSKevin Wolf ret = bdrv_open(bs1, filename, 0, drv); 60051d7c00cSaliguori if (ret < 0) { 601ea2384d3Sbellard bdrv_delete(bs1); 60251d7c00cSaliguori return ret; 603ea2384d3Sbellard } 6043e82990bSJes Sorensen total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; 6057c96d46eSaliguori 6067c96d46eSaliguori if (bs1->drv && bs1->drv->protocol_name) 6077c96d46eSaliguori is_protocol = 1; 6087c96d46eSaliguori 609ea2384d3Sbellard bdrv_delete(bs1); 610ea2384d3Sbellard 611ea2384d3Sbellard get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 6127c96d46eSaliguori 6137c96d46eSaliguori /* Real path is meaningless for protocols */ 6147c96d46eSaliguori if (is_protocol) 6157c96d46eSaliguori snprintf(backing_filename, sizeof(backing_filename), 6167c96d46eSaliguori "%s", filename); 617114cdfa9SKirill A. Shutemov else if (!realpath(filename, backing_filename)) 618114cdfa9SKirill A. Shutemov return -errno; 6197c96d46eSaliguori 62091a073a9SKevin Wolf bdrv_qcow2 = bdrv_find_format("qcow2"); 62191a073a9SKevin Wolf options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); 62291a073a9SKevin Wolf 6233e82990bSJes Sorensen set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size); 62491a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename); 62591a073a9SKevin Wolf if (drv) { 62691a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FMT, 62791a073a9SKevin Wolf drv->format_name); 62891a073a9SKevin Wolf } 62991a073a9SKevin Wolf 63091a073a9SKevin Wolf ret = bdrv_create(bdrv_qcow2, tmp_filename, options); 631d748768cSJan Kiszka free_option_parameters(options); 63251d7c00cSaliguori if (ret < 0) { 63351d7c00cSaliguori return ret; 634ea2384d3Sbellard } 63591a073a9SKevin Wolf 636ea2384d3Sbellard filename = tmp_filename; 63791a073a9SKevin Wolf drv = bdrv_qcow2; 638ea2384d3Sbellard bs->is_temporary = 1; 639ea2384d3Sbellard } 640ea2384d3Sbellard 641b6ce07aaSKevin Wolf /* Find the right image format driver */ 6426db95603SChristoph Hellwig if (!drv) { 643c98ac35dSStefan Weil ret = find_image_format(filename, &drv); 644ea2384d3Sbellard } 6456987307cSChristoph Hellwig 64651d7c00cSaliguori if (!drv) { 64751d7c00cSaliguori goto unlink_and_fail; 64883f64091Sbellard } 649b6ce07aaSKevin Wolf 650b6ce07aaSKevin Wolf /* Open the image */ 651b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 652b6ce07aaSKevin Wolf if (ret < 0) { 6536987307cSChristoph Hellwig goto unlink_and_fail; 6546987307cSChristoph Hellwig } 6556987307cSChristoph Hellwig 656b6ce07aaSKevin Wolf /* If there is a backing file, use it */ 657b6ce07aaSKevin Wolf if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { 658b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 659b6ce07aaSKevin Wolf int back_flags; 660b6ce07aaSKevin Wolf BlockDriver *back_drv = NULL; 661b6ce07aaSKevin Wolf 662b6ce07aaSKevin Wolf bs->backing_hd = bdrv_new(""); 663df2dbb4aSStefan Hajnoczi 664df2dbb4aSStefan Hajnoczi if (path_has_protocol(bs->backing_file)) { 665df2dbb4aSStefan Hajnoczi pstrcpy(backing_filename, sizeof(backing_filename), 666df2dbb4aSStefan Hajnoczi bs->backing_file); 667df2dbb4aSStefan Hajnoczi } else { 668b6ce07aaSKevin Wolf path_combine(backing_filename, sizeof(backing_filename), 669b6ce07aaSKevin Wolf filename, bs->backing_file); 670df2dbb4aSStefan Hajnoczi } 671df2dbb4aSStefan Hajnoczi 672df2dbb4aSStefan Hajnoczi if (bs->backing_format[0] != '\0') { 673b6ce07aaSKevin Wolf back_drv = bdrv_find_format(bs->backing_format); 674df2dbb4aSStefan Hajnoczi } 675b6ce07aaSKevin Wolf 676b6ce07aaSKevin Wolf /* backing files always opened read-only */ 677b6ce07aaSKevin Wolf back_flags = 678b6ce07aaSKevin Wolf flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 679b6ce07aaSKevin Wolf 680b6ce07aaSKevin Wolf ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv); 681b6ce07aaSKevin Wolf if (ret < 0) { 682b6ce07aaSKevin Wolf bdrv_close(bs); 683b6ce07aaSKevin Wolf return ret; 684b6ce07aaSKevin Wolf } 685b6ce07aaSKevin Wolf if (bs->is_temporary) { 686b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); 687b6ce07aaSKevin Wolf } else { 688b6ce07aaSKevin Wolf /* base image inherits from "parent" */ 689b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = bs->keep_read_only; 690b6ce07aaSKevin Wolf } 691b6ce07aaSKevin Wolf } 692b6ce07aaSKevin Wolf 693b6ce07aaSKevin Wolf if (!bdrv_key_required(bs)) { 6947d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 695b6ce07aaSKevin Wolf } 696b6ce07aaSKevin Wolf 697b6ce07aaSKevin Wolf return 0; 698b6ce07aaSKevin Wolf 699b6ce07aaSKevin Wolf unlink_and_fail: 700b6ce07aaSKevin Wolf if (bs->is_temporary) { 701b6ce07aaSKevin Wolf unlink(filename); 702b6ce07aaSKevin Wolf } 703b6ce07aaSKevin Wolf return ret; 704b6ce07aaSKevin Wolf } 705b6ce07aaSKevin Wolf 706fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs) 707fc01f7e7Sbellard { 70819cb3738Sbellard if (bs->drv) { 709f9092b10SMarkus Armbruster if (bs == bs_snapshots) { 710f9092b10SMarkus Armbruster bs_snapshots = NULL; 711f9092b10SMarkus Armbruster } 712557df6acSStefan Hajnoczi if (bs->backing_hd) { 713ea2384d3Sbellard bdrv_delete(bs->backing_hd); 714557df6acSStefan Hajnoczi bs->backing_hd = NULL; 715557df6acSStefan Hajnoczi } 716ea2384d3Sbellard bs->drv->bdrv_close(bs); 7177267c094SAnthony Liguori g_free(bs->opaque); 718ea2384d3Sbellard #ifdef _WIN32 719ea2384d3Sbellard if (bs->is_temporary) { 720ea2384d3Sbellard unlink(bs->filename); 721ea2384d3Sbellard } 72267b915a5Sbellard #endif 723ea2384d3Sbellard bs->opaque = NULL; 724ea2384d3Sbellard bs->drv = NULL; 725b338082bSbellard 72666f82ceeSKevin Wolf if (bs->file != NULL) { 72766f82ceeSKevin Wolf bdrv_close(bs->file); 72866f82ceeSKevin Wolf } 72966f82ceeSKevin Wolf 7307d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, false); 731b338082bSbellard } 732b338082bSbellard } 733b338082bSbellard 7342bc93fedSMORITA Kazutaka void bdrv_close_all(void) 7352bc93fedSMORITA Kazutaka { 7362bc93fedSMORITA Kazutaka BlockDriverState *bs; 7372bc93fedSMORITA Kazutaka 7382bc93fedSMORITA Kazutaka QTAILQ_FOREACH(bs, &bdrv_states, list) { 7392bc93fedSMORITA Kazutaka bdrv_close(bs); 7402bc93fedSMORITA Kazutaka } 7412bc93fedSMORITA Kazutaka } 7422bc93fedSMORITA Kazutaka 743d22b2f41SRyan Harper /* make a BlockDriverState anonymous by removing from bdrv_state list. 744d22b2f41SRyan Harper Also, NULL terminate the device_name to prevent double remove */ 745d22b2f41SRyan Harper void bdrv_make_anon(BlockDriverState *bs) 746d22b2f41SRyan Harper { 747d22b2f41SRyan Harper if (bs->device_name[0] != '\0') { 748d22b2f41SRyan Harper QTAILQ_REMOVE(&bdrv_states, bs, list); 749d22b2f41SRyan Harper } 750d22b2f41SRyan Harper bs->device_name[0] = '\0'; 751d22b2f41SRyan Harper } 752d22b2f41SRyan Harper 753b338082bSbellard void bdrv_delete(BlockDriverState *bs) 754b338082bSbellard { 755fa879d62SMarkus Armbruster assert(!bs->dev); 75618846deeSMarkus Armbruster 7571b7bdbc1SStefan Hajnoczi /* remove from list, if necessary */ 758d22b2f41SRyan Harper bdrv_make_anon(bs); 75934c6f050Saurel32 760b338082bSbellard bdrv_close(bs); 76166f82ceeSKevin Wolf if (bs->file != NULL) { 76266f82ceeSKevin Wolf bdrv_delete(bs->file); 76366f82ceeSKevin Wolf } 76466f82ceeSKevin Wolf 765f9092b10SMarkus Armbruster assert(bs != bs_snapshots); 7667267c094SAnthony Liguori g_free(bs); 767fc01f7e7Sbellard } 768fc01f7e7Sbellard 769fa879d62SMarkus Armbruster int bdrv_attach_dev(BlockDriverState *bs, void *dev) 770fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 77118846deeSMarkus Armbruster { 772fa879d62SMarkus Armbruster if (bs->dev) { 77318846deeSMarkus Armbruster return -EBUSY; 77418846deeSMarkus Armbruster } 775fa879d62SMarkus Armbruster bs->dev = dev; 77628a7282aSLuiz Capitulino bdrv_iostatus_reset(bs); 77718846deeSMarkus Armbruster return 0; 77818846deeSMarkus Armbruster } 77918846deeSMarkus Armbruster 780fa879d62SMarkus Armbruster /* TODO qdevified devices don't use this, remove when devices are qdevified */ 781fa879d62SMarkus Armbruster void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) 78218846deeSMarkus Armbruster { 783fa879d62SMarkus Armbruster if (bdrv_attach_dev(bs, dev) < 0) { 784fa879d62SMarkus Armbruster abort(); 785fa879d62SMarkus Armbruster } 786fa879d62SMarkus Armbruster } 787fa879d62SMarkus Armbruster 788fa879d62SMarkus Armbruster void bdrv_detach_dev(BlockDriverState *bs, void *dev) 789fa879d62SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 790fa879d62SMarkus Armbruster { 791fa879d62SMarkus Armbruster assert(bs->dev == dev); 792fa879d62SMarkus Armbruster bs->dev = NULL; 7930e49de52SMarkus Armbruster bs->dev_ops = NULL; 7940e49de52SMarkus Armbruster bs->dev_opaque = NULL; 79529e05f20SMarkus Armbruster bs->buffer_alignment = 512; 79618846deeSMarkus Armbruster } 79718846deeSMarkus Armbruster 798fa879d62SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 799fa879d62SMarkus Armbruster void *bdrv_get_attached_dev(BlockDriverState *bs) 80018846deeSMarkus Armbruster { 801fa879d62SMarkus Armbruster return bs->dev; 80218846deeSMarkus Armbruster } 80318846deeSMarkus Armbruster 8040e49de52SMarkus Armbruster void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, 8050e49de52SMarkus Armbruster void *opaque) 8060e49de52SMarkus Armbruster { 8070e49de52SMarkus Armbruster bs->dev_ops = ops; 8080e49de52SMarkus Armbruster bs->dev_opaque = opaque; 8092c6942faSMarkus Armbruster if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) { 8102c6942faSMarkus Armbruster bs_snapshots = NULL; 8112c6942faSMarkus Armbruster } 8120e49de52SMarkus Armbruster } 8130e49de52SMarkus Armbruster 8147d4b4ba5SMarkus Armbruster static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) 8150e49de52SMarkus Armbruster { 816145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->change_media_cb) { 8177d4b4ba5SMarkus Armbruster bs->dev_ops->change_media_cb(bs->dev_opaque, load); 818145feb17SMarkus Armbruster } 819145feb17SMarkus Armbruster } 820145feb17SMarkus Armbruster 8212c6942faSMarkus Armbruster bool bdrv_dev_has_removable_media(BlockDriverState *bs) 8222c6942faSMarkus Armbruster { 8232c6942faSMarkus Armbruster return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); 8242c6942faSMarkus Armbruster } 8252c6942faSMarkus Armbruster 826e4def80bSMarkus Armbruster bool bdrv_dev_is_tray_open(BlockDriverState *bs) 827e4def80bSMarkus Armbruster { 828e4def80bSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_tray_open) { 829e4def80bSMarkus Armbruster return bs->dev_ops->is_tray_open(bs->dev_opaque); 830e4def80bSMarkus Armbruster } 831e4def80bSMarkus Armbruster return false; 832e4def80bSMarkus Armbruster } 833e4def80bSMarkus Armbruster 834145feb17SMarkus Armbruster static void bdrv_dev_resize_cb(BlockDriverState *bs) 835145feb17SMarkus Armbruster { 836145feb17SMarkus Armbruster if (bs->dev_ops && bs->dev_ops->resize_cb) { 837145feb17SMarkus Armbruster bs->dev_ops->resize_cb(bs->dev_opaque); 8380e49de52SMarkus Armbruster } 8390e49de52SMarkus Armbruster } 8400e49de52SMarkus Armbruster 841f107639aSMarkus Armbruster bool bdrv_dev_is_medium_locked(BlockDriverState *bs) 842f107639aSMarkus Armbruster { 843f107639aSMarkus Armbruster if (bs->dev_ops && bs->dev_ops->is_medium_locked) { 844f107639aSMarkus Armbruster return bs->dev_ops->is_medium_locked(bs->dev_opaque); 845f107639aSMarkus Armbruster } 846f107639aSMarkus Armbruster return false; 847f107639aSMarkus Armbruster } 848f107639aSMarkus Armbruster 849e97fc193Saliguori /* 850e97fc193Saliguori * Run consistency checks on an image 851e97fc193Saliguori * 852e076f338SKevin Wolf * Returns 0 if the check could be completed (it doesn't mean that the image is 853a1c7273bSStefan Weil * free of errors) or -errno when an internal error occurred. The results of the 854e076f338SKevin Wolf * check are stored in res. 855e97fc193Saliguori */ 856e076f338SKevin Wolf int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res) 857e97fc193Saliguori { 858e97fc193Saliguori if (bs->drv->bdrv_check == NULL) { 859e97fc193Saliguori return -ENOTSUP; 860e97fc193Saliguori } 861e97fc193Saliguori 862e076f338SKevin Wolf memset(res, 0, sizeof(*res)); 8639ac228e0SKevin Wolf return bs->drv->bdrv_check(bs, res); 864e97fc193Saliguori } 865e97fc193Saliguori 8668a426614SKevin Wolf #define COMMIT_BUF_SECTORS 2048 8678a426614SKevin Wolf 86833e3963eSbellard /* commit COW file into the raw image */ 86933e3963eSbellard int bdrv_commit(BlockDriverState *bs) 87033e3963eSbellard { 87119cb3738Sbellard BlockDriver *drv = bs->drv; 872ee181196SKevin Wolf BlockDriver *backing_drv; 8738a426614SKevin Wolf int64_t sector, total_sectors; 8748a426614SKevin Wolf int n, ro, open_flags; 8754dca4b63SNaphtali Sprei int ret = 0, rw_ret = 0; 8768a426614SKevin Wolf uint8_t *buf; 8774dca4b63SNaphtali Sprei char filename[1024]; 8784dca4b63SNaphtali Sprei BlockDriverState *bs_rw, *bs_ro; 87933e3963eSbellard 88019cb3738Sbellard if (!drv) 88119cb3738Sbellard return -ENOMEDIUM; 88233e3963eSbellard 8834dca4b63SNaphtali Sprei if (!bs->backing_hd) { 8844dca4b63SNaphtali Sprei return -ENOTSUP; 8854dca4b63SNaphtali Sprei } 8864dca4b63SNaphtali Sprei 8874dca4b63SNaphtali Sprei if (bs->backing_hd->keep_read_only) { 888ea2384d3Sbellard return -EACCES; 88933e3963eSbellard } 89033e3963eSbellard 891ee181196SKevin Wolf backing_drv = bs->backing_hd->drv; 8924dca4b63SNaphtali Sprei ro = bs->backing_hd->read_only; 8934dca4b63SNaphtali Sprei strncpy(filename, bs->backing_hd->filename, sizeof(filename)); 8944dca4b63SNaphtali Sprei open_flags = bs->backing_hd->open_flags; 8954dca4b63SNaphtali Sprei 8964dca4b63SNaphtali Sprei if (ro) { 8974dca4b63SNaphtali Sprei /* re-open as RW */ 8984dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 8994dca4b63SNaphtali Sprei bs->backing_hd = NULL; 9004dca4b63SNaphtali Sprei bs_rw = bdrv_new(""); 901ee181196SKevin Wolf rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, 902ee181196SKevin Wolf backing_drv); 9034dca4b63SNaphtali Sprei if (rw_ret < 0) { 9044dca4b63SNaphtali Sprei bdrv_delete(bs_rw); 9054dca4b63SNaphtali Sprei /* try to re-open read-only */ 9064dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 907ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 908ee181196SKevin Wolf backing_drv); 9094dca4b63SNaphtali Sprei if (ret < 0) { 9104dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9114dca4b63SNaphtali Sprei /* drive not functional anymore */ 9124dca4b63SNaphtali Sprei bs->drv = NULL; 9134dca4b63SNaphtali Sprei return ret; 9144dca4b63SNaphtali Sprei } 9154dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9164dca4b63SNaphtali Sprei return rw_ret; 9174dca4b63SNaphtali Sprei } 9184dca4b63SNaphtali Sprei bs->backing_hd = bs_rw; 919ea2384d3Sbellard } 920ea2384d3Sbellard 9216ea44308SJan Kiszka total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; 9227267c094SAnthony Liguori buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); 9238a426614SKevin Wolf 9248a426614SKevin Wolf for (sector = 0; sector < total_sectors; sector += n) { 9258a426614SKevin Wolf if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { 9268a426614SKevin Wolf 9278a426614SKevin Wolf if (bdrv_read(bs, sector, buf, n) != 0) { 9284dca4b63SNaphtali Sprei ret = -EIO; 9294dca4b63SNaphtali Sprei goto ro_cleanup; 93033e3963eSbellard } 93133e3963eSbellard 9328a426614SKevin Wolf if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) { 9334dca4b63SNaphtali Sprei ret = -EIO; 9344dca4b63SNaphtali Sprei goto ro_cleanup; 93533e3963eSbellard } 93633e3963eSbellard } 93733e3963eSbellard } 93895389c86Sbellard 9391d44952fSChristoph Hellwig if (drv->bdrv_make_empty) { 9401d44952fSChristoph Hellwig ret = drv->bdrv_make_empty(bs); 9411d44952fSChristoph Hellwig bdrv_flush(bs); 9421d44952fSChristoph Hellwig } 94395389c86Sbellard 9443f5075aeSChristoph Hellwig /* 9453f5075aeSChristoph Hellwig * Make sure all data we wrote to the backing device is actually 9463f5075aeSChristoph Hellwig * stable on disk. 9473f5075aeSChristoph Hellwig */ 9483f5075aeSChristoph Hellwig if (bs->backing_hd) 9493f5075aeSChristoph Hellwig bdrv_flush(bs->backing_hd); 9504dca4b63SNaphtali Sprei 9514dca4b63SNaphtali Sprei ro_cleanup: 9527267c094SAnthony Liguori g_free(buf); 9534dca4b63SNaphtali Sprei 9544dca4b63SNaphtali Sprei if (ro) { 9554dca4b63SNaphtali Sprei /* re-open as RO */ 9564dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 9574dca4b63SNaphtali Sprei bs->backing_hd = NULL; 9584dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 959ee181196SKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, 960ee181196SKevin Wolf backing_drv); 9614dca4b63SNaphtali Sprei if (ret < 0) { 9624dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 9634dca4b63SNaphtali Sprei /* drive not functional anymore */ 9644dca4b63SNaphtali Sprei bs->drv = NULL; 9654dca4b63SNaphtali Sprei return ret; 9664dca4b63SNaphtali Sprei } 9674dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 9684dca4b63SNaphtali Sprei bs->backing_hd->keep_read_only = 0; 9694dca4b63SNaphtali Sprei } 9704dca4b63SNaphtali Sprei 9711d44952fSChristoph Hellwig return ret; 97233e3963eSbellard } 97333e3963eSbellard 9746ab4b5abSMarkus Armbruster void bdrv_commit_all(void) 9756ab4b5abSMarkus Armbruster { 9766ab4b5abSMarkus Armbruster BlockDriverState *bs; 9776ab4b5abSMarkus Armbruster 9786ab4b5abSMarkus Armbruster QTAILQ_FOREACH(bs, &bdrv_states, list) { 9796ab4b5abSMarkus Armbruster bdrv_commit(bs); 9806ab4b5abSMarkus Armbruster } 9816ab4b5abSMarkus Armbruster } 9826ab4b5abSMarkus Armbruster 983756e6736SKevin Wolf /* 984756e6736SKevin Wolf * Return values: 985756e6736SKevin Wolf * 0 - success 986756e6736SKevin Wolf * -EINVAL - backing format specified, but no file 987756e6736SKevin Wolf * -ENOSPC - can't update the backing file because no space is left in the 988756e6736SKevin Wolf * image file header 989756e6736SKevin Wolf * -ENOTSUP - format driver doesn't support changing the backing file 990756e6736SKevin Wolf */ 991756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs, 992756e6736SKevin Wolf const char *backing_file, const char *backing_fmt) 993756e6736SKevin Wolf { 994756e6736SKevin Wolf BlockDriver *drv = bs->drv; 995756e6736SKevin Wolf 996756e6736SKevin Wolf if (drv->bdrv_change_backing_file != NULL) { 997756e6736SKevin Wolf return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt); 998756e6736SKevin Wolf } else { 999756e6736SKevin Wolf return -ENOTSUP; 1000756e6736SKevin Wolf } 1001756e6736SKevin Wolf } 1002756e6736SKevin Wolf 100371d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, 100471d0770cSaliguori size_t size) 100571d0770cSaliguori { 100671d0770cSaliguori int64_t len; 100771d0770cSaliguori 100871d0770cSaliguori if (!bdrv_is_inserted(bs)) 100971d0770cSaliguori return -ENOMEDIUM; 101071d0770cSaliguori 101171d0770cSaliguori if (bs->growable) 101271d0770cSaliguori return 0; 101371d0770cSaliguori 101471d0770cSaliguori len = bdrv_getlength(bs); 101571d0770cSaliguori 1016fbb7b4e0SKevin Wolf if (offset < 0) 1017fbb7b4e0SKevin Wolf return -EIO; 1018fbb7b4e0SKevin Wolf 1019fbb7b4e0SKevin Wolf if ((offset > len) || (len - offset < size)) 102071d0770cSaliguori return -EIO; 102171d0770cSaliguori 102271d0770cSaliguori return 0; 102371d0770cSaliguori } 102471d0770cSaliguori 102571d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, 102671d0770cSaliguori int nb_sectors) 102771d0770cSaliguori { 1028eb5a3165SJes Sorensen return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE, 1029eb5a3165SJes Sorensen nb_sectors * BDRV_SECTOR_SIZE); 103071d0770cSaliguori } 103171d0770cSaliguori 1032e7a8a783SKevin Wolf static inline bool bdrv_has_async_rw(BlockDriver *drv) 1033e7a8a783SKevin Wolf { 1034e7a8a783SKevin Wolf return drv->bdrv_co_readv != bdrv_co_readv_em 1035e7a8a783SKevin Wolf || drv->bdrv_aio_readv != bdrv_aio_readv_em; 1036e7a8a783SKevin Wolf } 1037e7a8a783SKevin Wolf 1038e7a8a783SKevin Wolf static inline bool bdrv_has_async_flush(BlockDriver *drv) 1039e7a8a783SKevin Wolf { 1040e7a8a783SKevin Wolf return drv->bdrv_aio_flush != bdrv_aio_flush_em; 1041e7a8a783SKevin Wolf } 1042e7a8a783SKevin Wolf 104319cb3738Sbellard /* return < 0 if error. See bdrv_write() for the return codes */ 1044fc01f7e7Sbellard int bdrv_read(BlockDriverState *bs, int64_t sector_num, 1045fc01f7e7Sbellard uint8_t *buf, int nb_sectors) 1046fc01f7e7Sbellard { 1047ea2384d3Sbellard BlockDriver *drv = bs->drv; 1048fc01f7e7Sbellard 104919cb3738Sbellard if (!drv) 105019cb3738Sbellard return -ENOMEDIUM; 1051e7a8a783SKevin Wolf 1052e7a8a783SKevin Wolf if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) { 1053e7a8a783SKevin Wolf QEMUIOVector qiov; 1054e7a8a783SKevin Wolf struct iovec iov = { 1055e7a8a783SKevin Wolf .iov_base = (void *)buf, 1056e7a8a783SKevin Wolf .iov_len = nb_sectors * BDRV_SECTOR_SIZE, 1057e7a8a783SKevin Wolf }; 1058e7a8a783SKevin Wolf 1059e7a8a783SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 1060e7a8a783SKevin Wolf return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov); 1061e7a8a783SKevin Wolf } 1062e7a8a783SKevin Wolf 106371d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 106471d0770cSaliguori return -EIO; 1065b338082bSbellard 106683f64091Sbellard return drv->bdrv_read(bs, sector_num, buf, nb_sectors); 106783f64091Sbellard } 1068fc01f7e7Sbellard 10697cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, 10707cd1e32aSlirans@il.ibm.com int nb_sectors, int dirty) 10717cd1e32aSlirans@il.ibm.com { 10727cd1e32aSlirans@il.ibm.com int64_t start, end; 1073c6d22830SJan Kiszka unsigned long val, idx, bit; 1074a55eb92cSJan Kiszka 10756ea44308SJan Kiszka start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; 1076c6d22830SJan Kiszka end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK; 10777cd1e32aSlirans@il.ibm.com 10787cd1e32aSlirans@il.ibm.com for (; start <= end; start++) { 1079c6d22830SJan Kiszka idx = start / (sizeof(unsigned long) * 8); 1080c6d22830SJan Kiszka bit = start % (sizeof(unsigned long) * 8); 1081c6d22830SJan Kiszka val = bs->dirty_bitmap[idx]; 1082c6d22830SJan Kiszka if (dirty) { 10836d59fec1SMarcelo Tosatti if (!(val & (1UL << bit))) { 1084aaa0eb75SLiran Schour bs->dirty_count++; 10856d59fec1SMarcelo Tosatti val |= 1UL << bit; 1086aaa0eb75SLiran Schour } 1087c6d22830SJan Kiszka } else { 10886d59fec1SMarcelo Tosatti if (val & (1UL << bit)) { 1089aaa0eb75SLiran Schour bs->dirty_count--; 10906d59fec1SMarcelo Tosatti val &= ~(1UL << bit); 1091c6d22830SJan Kiszka } 1092aaa0eb75SLiran Schour } 1093c6d22830SJan Kiszka bs->dirty_bitmap[idx] = val; 10947cd1e32aSlirans@il.ibm.com } 10957cd1e32aSlirans@il.ibm.com } 10967cd1e32aSlirans@il.ibm.com 109719cb3738Sbellard /* Return < 0 if error. Important errors are: 109819cb3738Sbellard -EIO generic I/O error (may happen for all errors) 109919cb3738Sbellard -ENOMEDIUM No media inserted. 110019cb3738Sbellard -EINVAL Invalid sector number or nb_sectors 110119cb3738Sbellard -EACCES Trying to write a read-only device 110219cb3738Sbellard */ 1103fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num, 1104fc01f7e7Sbellard const uint8_t *buf, int nb_sectors) 1105fc01f7e7Sbellard { 110683f64091Sbellard BlockDriver *drv = bs->drv; 1107e7a8a783SKevin Wolf 110819cb3738Sbellard if (!bs->drv) 110919cb3738Sbellard return -ENOMEDIUM; 1110e7a8a783SKevin Wolf 1111e7a8a783SKevin Wolf if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) { 1112e7a8a783SKevin Wolf QEMUIOVector qiov; 1113e7a8a783SKevin Wolf struct iovec iov = { 1114e7a8a783SKevin Wolf .iov_base = (void *)buf, 1115e7a8a783SKevin Wolf .iov_len = nb_sectors * BDRV_SECTOR_SIZE, 1116e7a8a783SKevin Wolf }; 1117e7a8a783SKevin Wolf 1118e7a8a783SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 1119e7a8a783SKevin Wolf return bdrv_co_writev(bs, sector_num, nb_sectors, &qiov); 1120e7a8a783SKevin Wolf } 1121e7a8a783SKevin Wolf 11220849bf08Sbellard if (bs->read_only) 112319cb3738Sbellard return -EACCES; 112471d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 112571d0770cSaliguori return -EIO; 112671d0770cSaliguori 1127c6d22830SJan Kiszka if (bs->dirty_bitmap) { 11287cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 11297cd1e32aSlirans@il.ibm.com } 11307cd1e32aSlirans@il.ibm.com 1131294cc35fSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 1132294cc35fSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 1133294cc35fSKevin Wolf } 1134294cc35fSKevin Wolf 113583f64091Sbellard return drv->bdrv_write(bs, sector_num, buf, nb_sectors); 113683f64091Sbellard } 113783f64091Sbellard 1138eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset, 1139eda578e5Saliguori void *buf, int count1) 114083f64091Sbellard { 11416ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 114283f64091Sbellard int len, nb_sectors, count; 114383f64091Sbellard int64_t sector_num; 11449a8c4cceSKevin Wolf int ret; 114583f64091Sbellard 114683f64091Sbellard count = count1; 114783f64091Sbellard /* first read to align to sector start */ 11486ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 114983f64091Sbellard if (len > count) 115083f64091Sbellard len = count; 11516ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 115283f64091Sbellard if (len > 0) { 11539a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11549a8c4cceSKevin Wolf return ret; 11556ea44308SJan Kiszka memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); 115683f64091Sbellard count -= len; 115783f64091Sbellard if (count == 0) 115883f64091Sbellard return count1; 115983f64091Sbellard sector_num++; 116083f64091Sbellard buf += len; 116183f64091Sbellard } 116283f64091Sbellard 116383f64091Sbellard /* read the sectors "in place" */ 11646ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 116583f64091Sbellard if (nb_sectors > 0) { 11669a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0) 11679a8c4cceSKevin Wolf return ret; 116883f64091Sbellard sector_num += nb_sectors; 11696ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 117083f64091Sbellard buf += len; 117183f64091Sbellard count -= len; 117283f64091Sbellard } 117383f64091Sbellard 117483f64091Sbellard /* add data from the last sector */ 117583f64091Sbellard if (count > 0) { 11769a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11779a8c4cceSKevin Wolf return ret; 117883f64091Sbellard memcpy(buf, tmp_buf, count); 117983f64091Sbellard } 118083f64091Sbellard return count1; 118183f64091Sbellard } 118283f64091Sbellard 1183eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 1184eda578e5Saliguori const void *buf, int count1) 118583f64091Sbellard { 11866ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 118783f64091Sbellard int len, nb_sectors, count; 118883f64091Sbellard int64_t sector_num; 11899a8c4cceSKevin Wolf int ret; 119083f64091Sbellard 119183f64091Sbellard count = count1; 119283f64091Sbellard /* first write to align to sector start */ 11936ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 119483f64091Sbellard if (len > count) 119583f64091Sbellard len = count; 11966ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 119783f64091Sbellard if (len > 0) { 11989a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 11999a8c4cceSKevin Wolf return ret; 12006ea44308SJan Kiszka memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len); 12019a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 12029a8c4cceSKevin Wolf return ret; 120383f64091Sbellard count -= len; 120483f64091Sbellard if (count == 0) 120583f64091Sbellard return count1; 120683f64091Sbellard sector_num++; 120783f64091Sbellard buf += len; 120883f64091Sbellard } 120983f64091Sbellard 121083f64091Sbellard /* write the sectors "in place" */ 12116ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 121283f64091Sbellard if (nb_sectors > 0) { 12139a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0) 12149a8c4cceSKevin Wolf return ret; 121583f64091Sbellard sector_num += nb_sectors; 12166ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 121783f64091Sbellard buf += len; 121883f64091Sbellard count -= len; 121983f64091Sbellard } 122083f64091Sbellard 122183f64091Sbellard /* add data from the last sector */ 122283f64091Sbellard if (count > 0) { 12239a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 12249a8c4cceSKevin Wolf return ret; 122583f64091Sbellard memcpy(tmp_buf, buf, count); 12269a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 12279a8c4cceSKevin Wolf return ret; 122883f64091Sbellard } 122983f64091Sbellard return count1; 123083f64091Sbellard } 123183f64091Sbellard 1232f08145feSKevin Wolf /* 1233f08145feSKevin Wolf * Writes to the file and ensures that no writes are reordered across this 1234f08145feSKevin Wolf * request (acts as a barrier) 1235f08145feSKevin Wolf * 1236f08145feSKevin Wolf * Returns 0 on success, -errno in error cases. 1237f08145feSKevin Wolf */ 1238f08145feSKevin Wolf int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, 1239f08145feSKevin Wolf const void *buf, int count) 1240f08145feSKevin Wolf { 1241f08145feSKevin Wolf int ret; 1242f08145feSKevin Wolf 1243f08145feSKevin Wolf ret = bdrv_pwrite(bs, offset, buf, count); 1244f08145feSKevin Wolf if (ret < 0) { 1245f08145feSKevin Wolf return ret; 1246f08145feSKevin Wolf } 1247f08145feSKevin Wolf 124892196b2fSStefan Hajnoczi /* No flush needed for cache modes that use O_DSYNC */ 124992196b2fSStefan Hajnoczi if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) { 1250f08145feSKevin Wolf bdrv_flush(bs); 1251f08145feSKevin Wolf } 1252f08145feSKevin Wolf 1253f08145feSKevin Wolf return 0; 1254f08145feSKevin Wolf } 1255f08145feSKevin Wolf 1256da1fa91dSKevin Wolf int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, 1257da1fa91dSKevin Wolf int nb_sectors, QEMUIOVector *qiov) 1258da1fa91dSKevin Wolf { 1259da1fa91dSKevin Wolf BlockDriver *drv = bs->drv; 1260da1fa91dSKevin Wolf 1261da1fa91dSKevin Wolf trace_bdrv_co_readv(bs, sector_num, nb_sectors); 1262da1fa91dSKevin Wolf 1263da1fa91dSKevin Wolf if (!drv) { 1264da1fa91dSKevin Wolf return -ENOMEDIUM; 1265da1fa91dSKevin Wolf } 1266da1fa91dSKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) { 1267da1fa91dSKevin Wolf return -EIO; 1268da1fa91dSKevin Wolf } 1269da1fa91dSKevin Wolf 1270da1fa91dSKevin Wolf return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); 1271da1fa91dSKevin Wolf } 1272da1fa91dSKevin Wolf 1273da1fa91dSKevin Wolf int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, 1274da1fa91dSKevin Wolf int nb_sectors, QEMUIOVector *qiov) 1275da1fa91dSKevin Wolf { 1276da1fa91dSKevin Wolf BlockDriver *drv = bs->drv; 1277da1fa91dSKevin Wolf 1278da1fa91dSKevin Wolf trace_bdrv_co_writev(bs, sector_num, nb_sectors); 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 1290da1fa91dSKevin Wolf if (bs->dirty_bitmap) { 1291da1fa91dSKevin Wolf set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 1292da1fa91dSKevin Wolf } 1293da1fa91dSKevin Wolf 1294da1fa91dSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 1295da1fa91dSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 1296da1fa91dSKevin Wolf } 1297da1fa91dSKevin Wolf 1298da1fa91dSKevin Wolf return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); 1299da1fa91dSKevin Wolf } 1300da1fa91dSKevin Wolf 130183f64091Sbellard /** 130283f64091Sbellard * Truncate file to 'offset' bytes (needed only for file protocols) 130383f64091Sbellard */ 130483f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset) 130583f64091Sbellard { 130683f64091Sbellard BlockDriver *drv = bs->drv; 130751762288SStefan Hajnoczi int ret; 130883f64091Sbellard if (!drv) 130919cb3738Sbellard return -ENOMEDIUM; 131083f64091Sbellard if (!drv->bdrv_truncate) 131183f64091Sbellard return -ENOTSUP; 131259f2689dSNaphtali Sprei if (bs->read_only) 131359f2689dSNaphtali Sprei return -EACCES; 13148591675fSMarcelo Tosatti if (bdrv_in_use(bs)) 13158591675fSMarcelo Tosatti return -EBUSY; 131651762288SStefan Hajnoczi ret = drv->bdrv_truncate(bs, offset); 131751762288SStefan Hajnoczi if (ret == 0) { 131851762288SStefan Hajnoczi ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); 1319145feb17SMarkus Armbruster bdrv_dev_resize_cb(bs); 132051762288SStefan Hajnoczi } 132151762288SStefan Hajnoczi return ret; 132283f64091Sbellard } 132383f64091Sbellard 132483f64091Sbellard /** 13254a1d5e1fSFam Zheng * Length of a allocated file in bytes. Sparse files are counted by actual 13264a1d5e1fSFam Zheng * allocated space. Return < 0 if error or unknown. 13274a1d5e1fSFam Zheng */ 13284a1d5e1fSFam Zheng int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) 13294a1d5e1fSFam Zheng { 13304a1d5e1fSFam Zheng BlockDriver *drv = bs->drv; 13314a1d5e1fSFam Zheng if (!drv) { 13324a1d5e1fSFam Zheng return -ENOMEDIUM; 13334a1d5e1fSFam Zheng } 13344a1d5e1fSFam Zheng if (drv->bdrv_get_allocated_file_size) { 13354a1d5e1fSFam Zheng return drv->bdrv_get_allocated_file_size(bs); 13364a1d5e1fSFam Zheng } 13374a1d5e1fSFam Zheng if (bs->file) { 13384a1d5e1fSFam Zheng return bdrv_get_allocated_file_size(bs->file); 13394a1d5e1fSFam Zheng } 13404a1d5e1fSFam Zheng return -ENOTSUP; 13414a1d5e1fSFam Zheng } 13424a1d5e1fSFam Zheng 13434a1d5e1fSFam Zheng /** 134483f64091Sbellard * Length of a file in bytes. Return < 0 if error or unknown. 134583f64091Sbellard */ 134683f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs) 134783f64091Sbellard { 134883f64091Sbellard BlockDriver *drv = bs->drv; 134983f64091Sbellard if (!drv) 135019cb3738Sbellard return -ENOMEDIUM; 135151762288SStefan Hajnoczi 13522c6942faSMarkus Armbruster if (bs->growable || bdrv_dev_has_removable_media(bs)) { 135346a4e4e6SStefan Hajnoczi if (drv->bdrv_getlength) { 135483f64091Sbellard return drv->bdrv_getlength(bs); 1355fc01f7e7Sbellard } 135646a4e4e6SStefan Hajnoczi } 135746a4e4e6SStefan Hajnoczi return bs->total_sectors * BDRV_SECTOR_SIZE; 135846a4e4e6SStefan Hajnoczi } 1359fc01f7e7Sbellard 136019cb3738Sbellard /* return 0 as number of sectors if no device present or error */ 136196b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 1362fc01f7e7Sbellard { 136319cb3738Sbellard int64_t length; 136419cb3738Sbellard length = bdrv_getlength(bs); 136519cb3738Sbellard if (length < 0) 136619cb3738Sbellard length = 0; 136719cb3738Sbellard else 13686ea44308SJan Kiszka length = length >> BDRV_SECTOR_BITS; 136919cb3738Sbellard *nb_sectors_ptr = length; 1370fc01f7e7Sbellard } 1371cf98951bSbellard 1372f3d54fc4Saliguori struct partition { 1373f3d54fc4Saliguori uint8_t boot_ind; /* 0x80 - active */ 1374f3d54fc4Saliguori uint8_t head; /* starting head */ 1375f3d54fc4Saliguori uint8_t sector; /* starting sector */ 1376f3d54fc4Saliguori uint8_t cyl; /* starting cylinder */ 1377f3d54fc4Saliguori uint8_t sys_ind; /* What partition type */ 1378f3d54fc4Saliguori uint8_t end_head; /* end head */ 1379f3d54fc4Saliguori uint8_t end_sector; /* end sector */ 1380f3d54fc4Saliguori uint8_t end_cyl; /* end cylinder */ 1381f3d54fc4Saliguori uint32_t start_sect; /* starting sector counting from 0 */ 1382f3d54fc4Saliguori uint32_t nr_sects; /* nr of sectors in partition */ 1383541dc0d4SStefan Weil } QEMU_PACKED; 1384f3d54fc4Saliguori 1385f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 1386f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs, 1387f3d54fc4Saliguori int *pcylinders, int *pheads, int *psectors) 1388f3d54fc4Saliguori { 1389eb5a3165SJes Sorensen uint8_t buf[BDRV_SECTOR_SIZE]; 1390f3d54fc4Saliguori int ret, i, heads, sectors, cylinders; 1391f3d54fc4Saliguori struct partition *p; 1392f3d54fc4Saliguori uint32_t nr_sects; 1393a38131b6Sblueswir1 uint64_t nb_sectors; 1394f3d54fc4Saliguori 1395f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1396f3d54fc4Saliguori 1397f3d54fc4Saliguori ret = bdrv_read(bs, 0, buf, 1); 1398f3d54fc4Saliguori if (ret < 0) 1399f3d54fc4Saliguori return -1; 1400f3d54fc4Saliguori /* test msdos magic */ 1401f3d54fc4Saliguori if (buf[510] != 0x55 || buf[511] != 0xaa) 1402f3d54fc4Saliguori return -1; 1403f3d54fc4Saliguori for(i = 0; i < 4; i++) { 1404f3d54fc4Saliguori p = ((struct partition *)(buf + 0x1be)) + i; 1405f3d54fc4Saliguori nr_sects = le32_to_cpu(p->nr_sects); 1406f3d54fc4Saliguori if (nr_sects && p->end_head) { 1407f3d54fc4Saliguori /* We make the assumption that the partition terminates on 1408f3d54fc4Saliguori a cylinder boundary */ 1409f3d54fc4Saliguori heads = p->end_head + 1; 1410f3d54fc4Saliguori sectors = p->end_sector & 63; 1411f3d54fc4Saliguori if (sectors == 0) 1412f3d54fc4Saliguori continue; 1413f3d54fc4Saliguori cylinders = nb_sectors / (heads * sectors); 1414f3d54fc4Saliguori if (cylinders < 1 || cylinders > 16383) 1415f3d54fc4Saliguori continue; 1416f3d54fc4Saliguori *pheads = heads; 1417f3d54fc4Saliguori *psectors = sectors; 1418f3d54fc4Saliguori *pcylinders = cylinders; 1419f3d54fc4Saliguori #if 0 1420f3d54fc4Saliguori printf("guessed geometry: LCHS=%d %d %d\n", 1421f3d54fc4Saliguori cylinders, heads, sectors); 1422f3d54fc4Saliguori #endif 1423f3d54fc4Saliguori return 0; 1424f3d54fc4Saliguori } 1425f3d54fc4Saliguori } 1426f3d54fc4Saliguori return -1; 1427f3d54fc4Saliguori } 1428f3d54fc4Saliguori 1429f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 1430f3d54fc4Saliguori { 1431f3d54fc4Saliguori int translation, lba_detected = 0; 1432f3d54fc4Saliguori int cylinders, heads, secs; 1433a38131b6Sblueswir1 uint64_t nb_sectors; 1434f3d54fc4Saliguori 1435f3d54fc4Saliguori /* if a geometry hint is available, use it */ 1436f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1437f3d54fc4Saliguori bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 1438f3d54fc4Saliguori translation = bdrv_get_translation_hint(bs); 1439f3d54fc4Saliguori if (cylinders != 0) { 1440f3d54fc4Saliguori *pcyls = cylinders; 1441f3d54fc4Saliguori *pheads = heads; 1442f3d54fc4Saliguori *psecs = secs; 1443f3d54fc4Saliguori } else { 1444f3d54fc4Saliguori if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 1445f3d54fc4Saliguori if (heads > 16) { 1446f3d54fc4Saliguori /* if heads > 16, it means that a BIOS LBA 1447f3d54fc4Saliguori translation was active, so the default 1448f3d54fc4Saliguori hardware geometry is OK */ 1449f3d54fc4Saliguori lba_detected = 1; 1450f3d54fc4Saliguori goto default_geometry; 1451f3d54fc4Saliguori } else { 1452f3d54fc4Saliguori *pcyls = cylinders; 1453f3d54fc4Saliguori *pheads = heads; 1454f3d54fc4Saliguori *psecs = secs; 1455f3d54fc4Saliguori /* disable any translation to be in sync with 1456f3d54fc4Saliguori the logical geometry */ 1457f3d54fc4Saliguori if (translation == BIOS_ATA_TRANSLATION_AUTO) { 1458f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1459f3d54fc4Saliguori BIOS_ATA_TRANSLATION_NONE); 1460f3d54fc4Saliguori } 1461f3d54fc4Saliguori } 1462f3d54fc4Saliguori } else { 1463f3d54fc4Saliguori default_geometry: 1464f3d54fc4Saliguori /* if no geometry, use a standard physical disk geometry */ 1465f3d54fc4Saliguori cylinders = nb_sectors / (16 * 63); 1466f3d54fc4Saliguori 1467f3d54fc4Saliguori if (cylinders > 16383) 1468f3d54fc4Saliguori cylinders = 16383; 1469f3d54fc4Saliguori else if (cylinders < 2) 1470f3d54fc4Saliguori cylinders = 2; 1471f3d54fc4Saliguori *pcyls = cylinders; 1472f3d54fc4Saliguori *pheads = 16; 1473f3d54fc4Saliguori *psecs = 63; 1474f3d54fc4Saliguori if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 1475f3d54fc4Saliguori if ((*pcyls * *pheads) <= 131072) { 1476f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1477f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LARGE); 1478f3d54fc4Saliguori } else { 1479f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1480f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LBA); 1481f3d54fc4Saliguori } 1482f3d54fc4Saliguori } 1483f3d54fc4Saliguori } 1484f3d54fc4Saliguori bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 1485f3d54fc4Saliguori } 1486f3d54fc4Saliguori } 1487f3d54fc4Saliguori 1488b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs, 1489b338082bSbellard int cyls, int heads, int secs) 1490b338082bSbellard { 1491b338082bSbellard bs->cyls = cyls; 1492b338082bSbellard bs->heads = heads; 1493b338082bSbellard bs->secs = secs; 1494b338082bSbellard } 1495b338082bSbellard 149646d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 149746d4767dSbellard { 149846d4767dSbellard bs->translation = translation; 149946d4767dSbellard } 150046d4767dSbellard 1501b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs, 1502b338082bSbellard int *pcyls, int *pheads, int *psecs) 1503b338082bSbellard { 1504b338082bSbellard *pcyls = bs->cyls; 1505b338082bSbellard *pheads = bs->heads; 1506b338082bSbellard *psecs = bs->secs; 1507b338082bSbellard } 1508b338082bSbellard 15095bbdbb46SBlue Swirl /* Recognize floppy formats */ 15105bbdbb46SBlue Swirl typedef struct FDFormat { 15115bbdbb46SBlue Swirl FDriveType drive; 15125bbdbb46SBlue Swirl uint8_t last_sect; 15135bbdbb46SBlue Swirl uint8_t max_track; 15145bbdbb46SBlue Swirl uint8_t max_head; 15155bbdbb46SBlue Swirl } FDFormat; 15165bbdbb46SBlue Swirl 15175bbdbb46SBlue Swirl static const FDFormat fd_formats[] = { 15185bbdbb46SBlue Swirl /* First entry is default format */ 15195bbdbb46SBlue Swirl /* 1.44 MB 3"1/2 floppy disks */ 15205bbdbb46SBlue Swirl { FDRIVE_DRV_144, 18, 80, 1, }, 15215bbdbb46SBlue Swirl { FDRIVE_DRV_144, 20, 80, 1, }, 15225bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 80, 1, }, 15235bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 82, 1, }, 15245bbdbb46SBlue Swirl { FDRIVE_DRV_144, 21, 83, 1, }, 15255bbdbb46SBlue Swirl { FDRIVE_DRV_144, 22, 80, 1, }, 15265bbdbb46SBlue Swirl { FDRIVE_DRV_144, 23, 80, 1, }, 15275bbdbb46SBlue Swirl { FDRIVE_DRV_144, 24, 80, 1, }, 15285bbdbb46SBlue Swirl /* 2.88 MB 3"1/2 floppy disks */ 15295bbdbb46SBlue Swirl { FDRIVE_DRV_288, 36, 80, 1, }, 15305bbdbb46SBlue Swirl { FDRIVE_DRV_288, 39, 80, 1, }, 15315bbdbb46SBlue Swirl { FDRIVE_DRV_288, 40, 80, 1, }, 15325bbdbb46SBlue Swirl { FDRIVE_DRV_288, 44, 80, 1, }, 15335bbdbb46SBlue Swirl { FDRIVE_DRV_288, 48, 80, 1, }, 15345bbdbb46SBlue Swirl /* 720 kB 3"1/2 floppy disks */ 15355bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 1, }, 15365bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 80, 1, }, 15375bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 82, 1, }, 15385bbdbb46SBlue Swirl { FDRIVE_DRV_144, 10, 83, 1, }, 15395bbdbb46SBlue Swirl { FDRIVE_DRV_144, 13, 80, 1, }, 15405bbdbb46SBlue Swirl { FDRIVE_DRV_144, 14, 80, 1, }, 15415bbdbb46SBlue Swirl /* 1.2 MB 5"1/4 floppy disks */ 15425bbdbb46SBlue Swirl { FDRIVE_DRV_120, 15, 80, 1, }, 15435bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 80, 1, }, 15445bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 82, 1, }, 15455bbdbb46SBlue Swirl { FDRIVE_DRV_120, 18, 83, 1, }, 15465bbdbb46SBlue Swirl { FDRIVE_DRV_120, 20, 80, 1, }, 15475bbdbb46SBlue Swirl /* 720 kB 5"1/4 floppy disks */ 15485bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 80, 1, }, 15495bbdbb46SBlue Swirl { FDRIVE_DRV_120, 11, 80, 1, }, 15505bbdbb46SBlue Swirl /* 360 kB 5"1/4 floppy disks */ 15515bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 1, }, 15525bbdbb46SBlue Swirl { FDRIVE_DRV_120, 9, 40, 0, }, 15535bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 41, 1, }, 15545bbdbb46SBlue Swirl { FDRIVE_DRV_120, 10, 42, 1, }, 15555bbdbb46SBlue Swirl /* 320 kB 5"1/4 floppy disks */ 15565bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 1, }, 15575bbdbb46SBlue Swirl { FDRIVE_DRV_120, 8, 40, 0, }, 15585bbdbb46SBlue Swirl /* 360 kB must match 5"1/4 better than 3"1/2... */ 15595bbdbb46SBlue Swirl { FDRIVE_DRV_144, 9, 80, 0, }, 15605bbdbb46SBlue Swirl /* end */ 15615bbdbb46SBlue Swirl { FDRIVE_DRV_NONE, -1, -1, 0, }, 15625bbdbb46SBlue Swirl }; 15635bbdbb46SBlue Swirl 15645bbdbb46SBlue Swirl void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, 15655bbdbb46SBlue Swirl int *max_track, int *last_sect, 15665bbdbb46SBlue Swirl FDriveType drive_in, FDriveType *drive) 15675bbdbb46SBlue Swirl { 15685bbdbb46SBlue Swirl const FDFormat *parse; 15695bbdbb46SBlue Swirl uint64_t nb_sectors, size; 15705bbdbb46SBlue Swirl int i, first_match, match; 15715bbdbb46SBlue Swirl 15725bbdbb46SBlue Swirl bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect); 15735bbdbb46SBlue Swirl if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) { 15745bbdbb46SBlue Swirl /* User defined disk */ 15755bbdbb46SBlue Swirl } else { 15765bbdbb46SBlue Swirl bdrv_get_geometry(bs, &nb_sectors); 15775bbdbb46SBlue Swirl match = -1; 15785bbdbb46SBlue Swirl first_match = -1; 15795bbdbb46SBlue Swirl for (i = 0; ; i++) { 15805bbdbb46SBlue Swirl parse = &fd_formats[i]; 15815bbdbb46SBlue Swirl if (parse->drive == FDRIVE_DRV_NONE) { 15825bbdbb46SBlue Swirl break; 15835bbdbb46SBlue Swirl } 15845bbdbb46SBlue Swirl if (drive_in == parse->drive || 15855bbdbb46SBlue Swirl drive_in == FDRIVE_DRV_NONE) { 15865bbdbb46SBlue Swirl size = (parse->max_head + 1) * parse->max_track * 15875bbdbb46SBlue Swirl parse->last_sect; 15885bbdbb46SBlue Swirl if (nb_sectors == size) { 15895bbdbb46SBlue Swirl match = i; 15905bbdbb46SBlue Swirl break; 15915bbdbb46SBlue Swirl } 15925bbdbb46SBlue Swirl if (first_match == -1) { 15935bbdbb46SBlue Swirl first_match = i; 15945bbdbb46SBlue Swirl } 15955bbdbb46SBlue Swirl } 15965bbdbb46SBlue Swirl } 15975bbdbb46SBlue Swirl if (match == -1) { 15985bbdbb46SBlue Swirl if (first_match == -1) { 15995bbdbb46SBlue Swirl match = 1; 16005bbdbb46SBlue Swirl } else { 16015bbdbb46SBlue Swirl match = first_match; 16025bbdbb46SBlue Swirl } 16035bbdbb46SBlue Swirl parse = &fd_formats[match]; 16045bbdbb46SBlue Swirl } 16055bbdbb46SBlue Swirl *nb_heads = parse->max_head + 1; 16065bbdbb46SBlue Swirl *max_track = parse->max_track; 16075bbdbb46SBlue Swirl *last_sect = parse->last_sect; 16085bbdbb46SBlue Swirl *drive = parse->drive; 16095bbdbb46SBlue Swirl } 16105bbdbb46SBlue Swirl } 16115bbdbb46SBlue Swirl 161246d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs) 161346d4767dSbellard { 161446d4767dSbellard return bs->translation; 161546d4767dSbellard } 161646d4767dSbellard 1617abd7f68dSMarkus Armbruster void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error, 1618abd7f68dSMarkus Armbruster BlockErrorAction on_write_error) 1619abd7f68dSMarkus Armbruster { 1620abd7f68dSMarkus Armbruster bs->on_read_error = on_read_error; 1621abd7f68dSMarkus Armbruster bs->on_write_error = on_write_error; 1622abd7f68dSMarkus Armbruster } 1623abd7f68dSMarkus Armbruster 1624abd7f68dSMarkus Armbruster BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read) 1625abd7f68dSMarkus Armbruster { 1626abd7f68dSMarkus Armbruster return is_read ? bs->on_read_error : bs->on_write_error; 1627abd7f68dSMarkus Armbruster } 1628abd7f68dSMarkus Armbruster 1629b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs) 1630b338082bSbellard { 1631b338082bSbellard return bs->read_only; 1632b338082bSbellard } 1633b338082bSbellard 1634985a03b0Sths int bdrv_is_sg(BlockDriverState *bs) 1635985a03b0Sths { 1636985a03b0Sths return bs->sg; 1637985a03b0Sths } 1638985a03b0Sths 1639e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs) 1640e900a7b7SChristoph Hellwig { 1641e900a7b7SChristoph Hellwig return bs->enable_write_cache; 1642e900a7b7SChristoph Hellwig } 1643e900a7b7SChristoph Hellwig 1644ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs) 1645ea2384d3Sbellard { 1646ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) 1647ea2384d3Sbellard return 1; 1648ea2384d3Sbellard return bs->encrypted; 1649ea2384d3Sbellard } 1650ea2384d3Sbellard 1651c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs) 1652c0f4ce77Saliguori { 1653c0f4ce77Saliguori BlockDriverState *backing_hd = bs->backing_hd; 1654c0f4ce77Saliguori 1655c0f4ce77Saliguori if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 1656c0f4ce77Saliguori return 1; 1657c0f4ce77Saliguori return (bs->encrypted && !bs->valid_key); 1658c0f4ce77Saliguori } 1659c0f4ce77Saliguori 1660ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key) 1661ea2384d3Sbellard { 1662ea2384d3Sbellard int ret; 1663ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) { 1664ea2384d3Sbellard ret = bdrv_set_key(bs->backing_hd, key); 1665ea2384d3Sbellard if (ret < 0) 1666ea2384d3Sbellard return ret; 1667ea2384d3Sbellard if (!bs->encrypted) 1668ea2384d3Sbellard return 0; 1669ea2384d3Sbellard } 1670fd04a2aeSShahar Havivi if (!bs->encrypted) { 1671fd04a2aeSShahar Havivi return -EINVAL; 1672fd04a2aeSShahar Havivi } else if (!bs->drv || !bs->drv->bdrv_set_key) { 1673fd04a2aeSShahar Havivi return -ENOMEDIUM; 1674fd04a2aeSShahar Havivi } 1675c0f4ce77Saliguori ret = bs->drv->bdrv_set_key(bs, key); 1676bb5fc20fSaliguori if (ret < 0) { 1677bb5fc20fSaliguori bs->valid_key = 0; 1678bb5fc20fSaliguori } else if (!bs->valid_key) { 1679bb5fc20fSaliguori bs->valid_key = 1; 1680bb5fc20fSaliguori /* call the change callback now, we skipped it on open */ 16817d4b4ba5SMarkus Armbruster bdrv_dev_change_media_cb(bs, true); 1682bb5fc20fSaliguori } 1683c0f4ce77Saliguori return ret; 1684ea2384d3Sbellard } 1685ea2384d3Sbellard 1686ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 1687ea2384d3Sbellard { 168819cb3738Sbellard if (!bs->drv) { 1689ea2384d3Sbellard buf[0] = '\0'; 1690ea2384d3Sbellard } else { 1691ea2384d3Sbellard pstrcpy(buf, buf_size, bs->drv->format_name); 1692ea2384d3Sbellard } 1693ea2384d3Sbellard } 1694ea2384d3Sbellard 1695ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 1696ea2384d3Sbellard void *opaque) 1697ea2384d3Sbellard { 1698ea2384d3Sbellard BlockDriver *drv; 1699ea2384d3Sbellard 17008a22f02aSStefan Hajnoczi QLIST_FOREACH(drv, &bdrv_drivers, list) { 1701ea2384d3Sbellard it(opaque, drv->format_name); 1702ea2384d3Sbellard } 1703ea2384d3Sbellard } 1704ea2384d3Sbellard 1705b338082bSbellard BlockDriverState *bdrv_find(const char *name) 1706b338082bSbellard { 1707b338082bSbellard BlockDriverState *bs; 1708b338082bSbellard 17091b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 17101b7bdbc1SStefan Hajnoczi if (!strcmp(name, bs->device_name)) { 1711b338082bSbellard return bs; 1712b338082bSbellard } 17131b7bdbc1SStefan Hajnoczi } 1714b338082bSbellard return NULL; 1715b338082bSbellard } 1716b338082bSbellard 17172f399b0aSMarkus Armbruster BlockDriverState *bdrv_next(BlockDriverState *bs) 17182f399b0aSMarkus Armbruster { 17192f399b0aSMarkus Armbruster if (!bs) { 17202f399b0aSMarkus Armbruster return QTAILQ_FIRST(&bdrv_states); 17212f399b0aSMarkus Armbruster } 17222f399b0aSMarkus Armbruster return QTAILQ_NEXT(bs, list); 17232f399b0aSMarkus Armbruster } 17242f399b0aSMarkus Armbruster 172551de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 172681d0912dSbellard { 172781d0912dSbellard BlockDriverState *bs; 172881d0912dSbellard 17291b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 173051de9760Saliguori it(opaque, bs); 173181d0912dSbellard } 173281d0912dSbellard } 173381d0912dSbellard 1734ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs) 1735ea2384d3Sbellard { 1736ea2384d3Sbellard return bs->device_name; 1737ea2384d3Sbellard } 1738ea2384d3Sbellard 1739205ef796SKevin Wolf int bdrv_flush(BlockDriverState *bs) 17407a6cba61Spbrook { 1741016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 1742205ef796SKevin Wolf return 0; 1743016f5cf6SAlexander Graf } 1744016f5cf6SAlexander Graf 1745e7a8a783SKevin Wolf if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) { 1746e7a8a783SKevin Wolf return bdrv_co_flush_em(bs); 1747e7a8a783SKevin Wolf } 1748e7a8a783SKevin Wolf 1749205ef796SKevin Wolf if (bs->drv && bs->drv->bdrv_flush) { 1750205ef796SKevin Wolf return bs->drv->bdrv_flush(bs); 1751205ef796SKevin Wolf } 1752205ef796SKevin Wolf 1753205ef796SKevin Wolf /* 1754205ef796SKevin Wolf * Some block drivers always operate in either writethrough or unsafe mode 1755205ef796SKevin Wolf * and don't support bdrv_flush therefore. Usually qemu doesn't know how 1756205ef796SKevin Wolf * the server works (because the behaviour is hardcoded or depends on 1757205ef796SKevin Wolf * server-side configuration), so we can't ensure that everything is safe 1758205ef796SKevin Wolf * on disk. Returning an error doesn't work because that would break guests 1759205ef796SKevin Wolf * even if the server operates in writethrough mode. 1760205ef796SKevin Wolf * 1761205ef796SKevin Wolf * Let's hope the user knows what he's doing. 1762205ef796SKevin Wolf */ 1763205ef796SKevin Wolf return 0; 17647a6cba61Spbrook } 17657a6cba61Spbrook 1766c6ca28d6Saliguori void bdrv_flush_all(void) 1767c6ca28d6Saliguori { 1768c6ca28d6Saliguori BlockDriverState *bs; 1769c6ca28d6Saliguori 17701b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1771c602a489SMarkus Armbruster if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) { 1772c6ca28d6Saliguori bdrv_flush(bs); 1773c6ca28d6Saliguori } 17741b7bdbc1SStefan Hajnoczi } 17751b7bdbc1SStefan Hajnoczi } 1776c6ca28d6Saliguori 1777f2feebbdSKevin Wolf int bdrv_has_zero_init(BlockDriverState *bs) 1778f2feebbdSKevin Wolf { 1779f2feebbdSKevin Wolf assert(bs->drv); 1780f2feebbdSKevin Wolf 1781336c1c12SKevin Wolf if (bs->drv->bdrv_has_zero_init) { 1782336c1c12SKevin Wolf return bs->drv->bdrv_has_zero_init(bs); 1783f2feebbdSKevin Wolf } 1784f2feebbdSKevin Wolf 1785f2feebbdSKevin Wolf return 1; 1786f2feebbdSKevin Wolf } 1787f2feebbdSKevin Wolf 1788bb8bf76fSChristoph Hellwig int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) 1789bb8bf76fSChristoph Hellwig { 1790bb8bf76fSChristoph Hellwig if (!bs->drv) { 1791bb8bf76fSChristoph Hellwig return -ENOMEDIUM; 1792bb8bf76fSChristoph Hellwig } 1793bb8bf76fSChristoph Hellwig if (!bs->drv->bdrv_discard) { 1794bb8bf76fSChristoph Hellwig return 0; 1795bb8bf76fSChristoph Hellwig } 1796bb8bf76fSChristoph Hellwig return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); 1797bb8bf76fSChristoph Hellwig } 1798bb8bf76fSChristoph Hellwig 1799f58c7b35Sths /* 1800f58c7b35Sths * Returns true iff the specified sector is present in the disk image. Drivers 1801f58c7b35Sths * not implementing the functionality are assumed to not support backing files, 1802f58c7b35Sths * hence all their sectors are reported as allocated. 1803f58c7b35Sths * 1804f58c7b35Sths * 'pnum' is set to the number of sectors (including and immediately following 1805f58c7b35Sths * the specified sector) that are known to be in the same 1806f58c7b35Sths * allocated/unallocated state. 1807f58c7b35Sths * 1808f58c7b35Sths * 'nb_sectors' is the max value 'pnum' should be set to. 1809f58c7b35Sths */ 1810f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1811f58c7b35Sths int *pnum) 1812f58c7b35Sths { 1813f58c7b35Sths int64_t n; 1814f58c7b35Sths if (!bs->drv->bdrv_is_allocated) { 1815f58c7b35Sths if (sector_num >= bs->total_sectors) { 1816f58c7b35Sths *pnum = 0; 1817f58c7b35Sths return 0; 1818f58c7b35Sths } 1819f58c7b35Sths n = bs->total_sectors - sector_num; 1820f58c7b35Sths *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1821f58c7b35Sths return 1; 1822f58c7b35Sths } 1823f58c7b35Sths return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1824f58c7b35Sths } 1825f58c7b35Sths 18262582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv, 18272582bfedSLuiz Capitulino BlockMonEventAction action, int is_read) 18282582bfedSLuiz Capitulino { 18292582bfedSLuiz Capitulino QObject *data; 18302582bfedSLuiz Capitulino const char *action_str; 18312582bfedSLuiz Capitulino 18322582bfedSLuiz Capitulino switch (action) { 18332582bfedSLuiz Capitulino case BDRV_ACTION_REPORT: 18342582bfedSLuiz Capitulino action_str = "report"; 18352582bfedSLuiz Capitulino break; 18362582bfedSLuiz Capitulino case BDRV_ACTION_IGNORE: 18372582bfedSLuiz Capitulino action_str = "ignore"; 18382582bfedSLuiz Capitulino break; 18392582bfedSLuiz Capitulino case BDRV_ACTION_STOP: 18402582bfedSLuiz Capitulino action_str = "stop"; 18412582bfedSLuiz Capitulino break; 18422582bfedSLuiz Capitulino default: 18432582bfedSLuiz Capitulino abort(); 18442582bfedSLuiz Capitulino } 18452582bfedSLuiz Capitulino 18462582bfedSLuiz Capitulino data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", 18472582bfedSLuiz Capitulino bdrv->device_name, 18482582bfedSLuiz Capitulino action_str, 18492582bfedSLuiz Capitulino is_read ? "read" : "write"); 18502582bfedSLuiz Capitulino monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data); 18512582bfedSLuiz Capitulino 18522582bfedSLuiz Capitulino qobject_decref(data); 18532582bfedSLuiz Capitulino } 18542582bfedSLuiz Capitulino 1855d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque) 1856b338082bSbellard { 1857d15e5465SLuiz Capitulino QDict *bs_dict; 1858d15e5465SLuiz Capitulino Monitor *mon = opaque; 1859b338082bSbellard 1860d15e5465SLuiz Capitulino bs_dict = qobject_to_qdict(obj); 1861d15e5465SLuiz Capitulino 1862d8aeeb31SMarkus Armbruster monitor_printf(mon, "%s: removable=%d", 1863d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "device"), 1864d15e5465SLuiz Capitulino qdict_get_bool(bs_dict, "removable")); 1865d15e5465SLuiz Capitulino 1866d15e5465SLuiz Capitulino if (qdict_get_bool(bs_dict, "removable")) { 1867d15e5465SLuiz Capitulino monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); 1868e4def80bSMarkus Armbruster monitor_printf(mon, " tray-open=%d", 1869e4def80bSMarkus Armbruster qdict_get_bool(bs_dict, "tray-open")); 1870b338082bSbellard } 1871d15e5465SLuiz Capitulino if (qdict_haskey(bs_dict, "inserted")) { 1872d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); 1873d15e5465SLuiz Capitulino 1874376253ecSaliguori monitor_printf(mon, " file="); 1875d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "file")); 1876d15e5465SLuiz Capitulino if (qdict_haskey(qdict, "backing_file")) { 1877376253ecSaliguori monitor_printf(mon, " backing_file="); 1878d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); 1879fef30743Sths } 1880d15e5465SLuiz Capitulino monitor_printf(mon, " ro=%d drv=%s encrypted=%d", 1881d15e5465SLuiz Capitulino qdict_get_bool(qdict, "ro"), 1882d15e5465SLuiz Capitulino qdict_get_str(qdict, "drv"), 1883d15e5465SLuiz Capitulino qdict_get_bool(qdict, "encrypted")); 1884b338082bSbellard } else { 1885376253ecSaliguori monitor_printf(mon, " [not inserted]"); 1886b338082bSbellard } 1887d15e5465SLuiz Capitulino 1888376253ecSaliguori monitor_printf(mon, "\n"); 1889b338082bSbellard } 1890d15e5465SLuiz Capitulino 1891d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data) 1892d15e5465SLuiz Capitulino { 1893d15e5465SLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); 1894d15e5465SLuiz Capitulino } 1895d15e5465SLuiz Capitulino 1896*f04ef601SLuiz Capitulino static const char *const io_status_name[BDRV_IOS_MAX] = { 1897*f04ef601SLuiz Capitulino [BDRV_IOS_OK] = "ok", 1898*f04ef601SLuiz Capitulino [BDRV_IOS_FAILED] = "failed", 1899*f04ef601SLuiz Capitulino [BDRV_IOS_ENOSPC] = "nospace", 1900*f04ef601SLuiz Capitulino }; 1901*f04ef601SLuiz Capitulino 1902d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data) 1903d15e5465SLuiz Capitulino { 1904d15e5465SLuiz Capitulino QList *bs_list; 1905d15e5465SLuiz Capitulino BlockDriverState *bs; 1906d15e5465SLuiz Capitulino 1907d15e5465SLuiz Capitulino bs_list = qlist_new(); 1908d15e5465SLuiz Capitulino 19091b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1910d15e5465SLuiz Capitulino QObject *bs_obj; 1911e4def80bSMarkus Armbruster QDict *bs_dict; 1912d15e5465SLuiz Capitulino 1913d8aeeb31SMarkus Armbruster bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', " 1914d15e5465SLuiz Capitulino "'removable': %i, 'locked': %i }", 19152c6942faSMarkus Armbruster bs->device_name, 19162c6942faSMarkus Armbruster bdrv_dev_has_removable_media(bs), 1917f107639aSMarkus Armbruster bdrv_dev_is_medium_locked(bs)); 1918e4def80bSMarkus Armbruster bs_dict = qobject_to_qdict(bs_obj); 1919d15e5465SLuiz Capitulino 1920e4def80bSMarkus Armbruster if (bdrv_dev_has_removable_media(bs)) { 1921e4def80bSMarkus Armbruster qdict_put(bs_dict, "tray-open", 1922e4def80bSMarkus Armbruster qbool_from_int(bdrv_dev_is_tray_open(bs))); 1923e4def80bSMarkus Armbruster } 1924*f04ef601SLuiz Capitulino 1925*f04ef601SLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 1926*f04ef601SLuiz Capitulino qdict_put(bs_dict, "io-status", 1927*f04ef601SLuiz Capitulino qstring_from_str(io_status_name[bs->iostatus])); 1928*f04ef601SLuiz Capitulino } 1929*f04ef601SLuiz Capitulino 1930d15e5465SLuiz Capitulino if (bs->drv) { 1931d15e5465SLuiz Capitulino QObject *obj; 1932d15e5465SLuiz Capitulino 1933d15e5465SLuiz Capitulino obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " 1934d15e5465SLuiz Capitulino "'encrypted': %i }", 1935d15e5465SLuiz Capitulino bs->filename, bs->read_only, 1936d15e5465SLuiz Capitulino bs->drv->format_name, 1937d15e5465SLuiz Capitulino bdrv_is_encrypted(bs)); 1938d15e5465SLuiz Capitulino if (bs->backing_file[0] != '\0') { 1939d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(obj); 1940d15e5465SLuiz Capitulino qdict_put(qdict, "backing_file", 1941d15e5465SLuiz Capitulino qstring_from_str(bs->backing_file)); 1942d15e5465SLuiz Capitulino } 1943d15e5465SLuiz Capitulino 1944d15e5465SLuiz Capitulino qdict_put_obj(bs_dict, "inserted", obj); 1945d15e5465SLuiz Capitulino } 1946d15e5465SLuiz Capitulino qlist_append_obj(bs_list, bs_obj); 1947d15e5465SLuiz Capitulino } 1948d15e5465SLuiz Capitulino 1949d15e5465SLuiz Capitulino *ret_data = QOBJECT(bs_list); 1950b338082bSbellard } 1951a36e69ddSths 1952218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque) 1953a36e69ddSths { 1954218a536aSLuiz Capitulino QDict *qdict; 1955218a536aSLuiz Capitulino Monitor *mon = opaque; 1956218a536aSLuiz Capitulino 1957218a536aSLuiz Capitulino qdict = qobject_to_qdict(data); 1958218a536aSLuiz Capitulino monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 1959218a536aSLuiz Capitulino 1960218a536aSLuiz Capitulino qdict = qobject_to_qdict(qdict_get(qdict, "stats")); 1961218a536aSLuiz Capitulino monitor_printf(mon, " rd_bytes=%" PRId64 1962218a536aSLuiz Capitulino " wr_bytes=%" PRId64 1963218a536aSLuiz Capitulino " rd_operations=%" PRId64 1964218a536aSLuiz Capitulino " wr_operations=%" PRId64 1965e8045d67SChristoph Hellwig " flush_operations=%" PRId64 1966c488c7f6SChristoph Hellwig " wr_total_time_ns=%" PRId64 1967c488c7f6SChristoph Hellwig " rd_total_time_ns=%" PRId64 1968c488c7f6SChristoph Hellwig " flush_total_time_ns=%" PRId64 1969218a536aSLuiz Capitulino "\n", 1970218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_bytes"), 1971218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_bytes"), 1972218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_operations"), 1973e8045d67SChristoph Hellwig qdict_get_int(qdict, "wr_operations"), 1974c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_operations"), 1975c488c7f6SChristoph Hellwig qdict_get_int(qdict, "wr_total_time_ns"), 1976c488c7f6SChristoph Hellwig qdict_get_int(qdict, "rd_total_time_ns"), 1977c488c7f6SChristoph Hellwig qdict_get_int(qdict, "flush_total_time_ns")); 1978218a536aSLuiz Capitulino } 1979218a536aSLuiz Capitulino 1980218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data) 1981218a536aSLuiz Capitulino { 1982218a536aSLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); 1983218a536aSLuiz Capitulino } 1984218a536aSLuiz Capitulino 1985294cc35fSKevin Wolf static QObject* bdrv_info_stats_bs(BlockDriverState *bs) 1986294cc35fSKevin Wolf { 1987294cc35fSKevin Wolf QObject *res; 1988294cc35fSKevin Wolf QDict *dict; 1989294cc35fSKevin Wolf 1990294cc35fSKevin Wolf res = qobject_from_jsonf("{ 'stats': {" 1991294cc35fSKevin Wolf "'rd_bytes': %" PRId64 "," 1992294cc35fSKevin Wolf "'wr_bytes': %" PRId64 "," 1993294cc35fSKevin Wolf "'rd_operations': %" PRId64 "," 1994294cc35fSKevin Wolf "'wr_operations': %" PRId64 "," 1995e8045d67SChristoph Hellwig "'wr_highest_offset': %" PRId64 "," 1996c488c7f6SChristoph Hellwig "'flush_operations': %" PRId64 "," 1997c488c7f6SChristoph Hellwig "'wr_total_time_ns': %" PRId64 "," 1998c488c7f6SChristoph Hellwig "'rd_total_time_ns': %" PRId64 "," 1999c488c7f6SChristoph Hellwig "'flush_total_time_ns': %" PRId64 2000294cc35fSKevin Wolf "} }", 2001a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_READ], 2002a597e79cSChristoph Hellwig bs->nr_bytes[BDRV_ACCT_WRITE], 2003a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_READ], 2004a597e79cSChristoph Hellwig bs->nr_ops[BDRV_ACCT_WRITE], 20055ffbbc67SBlue Swirl bs->wr_highest_sector * 2006e8045d67SChristoph Hellwig (uint64_t)BDRV_SECTOR_SIZE, 2007c488c7f6SChristoph Hellwig bs->nr_ops[BDRV_ACCT_FLUSH], 2008c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_WRITE], 2009c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_READ], 2010c488c7f6SChristoph Hellwig bs->total_time_ns[BDRV_ACCT_FLUSH]); 2011294cc35fSKevin Wolf dict = qobject_to_qdict(res); 2012294cc35fSKevin Wolf 2013294cc35fSKevin Wolf if (*bs->device_name) { 2014294cc35fSKevin Wolf qdict_put(dict, "device", qstring_from_str(bs->device_name)); 2015294cc35fSKevin Wolf } 2016294cc35fSKevin Wolf 2017294cc35fSKevin Wolf if (bs->file) { 2018294cc35fSKevin Wolf QObject *parent = bdrv_info_stats_bs(bs->file); 2019294cc35fSKevin Wolf qdict_put_obj(dict, "parent", parent); 2020294cc35fSKevin Wolf } 2021294cc35fSKevin Wolf 2022294cc35fSKevin Wolf return res; 2023294cc35fSKevin Wolf } 2024294cc35fSKevin Wolf 2025218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data) 2026218a536aSLuiz Capitulino { 2027218a536aSLuiz Capitulino QObject *obj; 2028218a536aSLuiz Capitulino QList *devices; 2029a36e69ddSths BlockDriverState *bs; 2030a36e69ddSths 2031218a536aSLuiz Capitulino devices = qlist_new(); 2032218a536aSLuiz Capitulino 20331b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 2034294cc35fSKevin Wolf obj = bdrv_info_stats_bs(bs); 2035218a536aSLuiz Capitulino qlist_append_obj(devices, obj); 2036a36e69ddSths } 2037218a536aSLuiz Capitulino 2038218a536aSLuiz Capitulino *ret_data = QOBJECT(devices); 2039a36e69ddSths } 2040ea2384d3Sbellard 2041045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs) 2042045df330Saliguori { 2043045df330Saliguori if (bs->backing_hd && bs->backing_hd->encrypted) 2044045df330Saliguori return bs->backing_file; 2045045df330Saliguori else if (bs->encrypted) 2046045df330Saliguori return bs->filename; 2047045df330Saliguori else 2048045df330Saliguori return NULL; 2049045df330Saliguori } 2050045df330Saliguori 205183f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs, 205283f64091Sbellard char *filename, int filename_size) 205383f64091Sbellard { 2054b783e409SKevin Wolf if (!bs->backing_file) { 205583f64091Sbellard pstrcpy(filename, filename_size, ""); 205683f64091Sbellard } else { 205783f64091Sbellard pstrcpy(filename, filename_size, bs->backing_file); 205883f64091Sbellard } 205983f64091Sbellard } 206083f64091Sbellard 2061faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 2062faea38e7Sbellard const uint8_t *buf, int nb_sectors) 2063faea38e7Sbellard { 2064faea38e7Sbellard BlockDriver *drv = bs->drv; 2065faea38e7Sbellard if (!drv) 206619cb3738Sbellard return -ENOMEDIUM; 2067faea38e7Sbellard if (!drv->bdrv_write_compressed) 2068faea38e7Sbellard return -ENOTSUP; 2069fbb7b4e0SKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) 2070fbb7b4e0SKevin Wolf return -EIO; 20717cd1e32aSlirans@il.ibm.com 2072c6d22830SJan Kiszka if (bs->dirty_bitmap) { 20737cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 20747cd1e32aSlirans@il.ibm.com } 20757cd1e32aSlirans@il.ibm.com 2076faea38e7Sbellard return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 2077faea38e7Sbellard } 2078faea38e7Sbellard 2079faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 2080faea38e7Sbellard { 2081faea38e7Sbellard BlockDriver *drv = bs->drv; 2082faea38e7Sbellard if (!drv) 208319cb3738Sbellard return -ENOMEDIUM; 2084faea38e7Sbellard if (!drv->bdrv_get_info) 2085faea38e7Sbellard return -ENOTSUP; 2086faea38e7Sbellard memset(bdi, 0, sizeof(*bdi)); 2087faea38e7Sbellard return drv->bdrv_get_info(bs, bdi); 2088faea38e7Sbellard } 2089faea38e7Sbellard 209045566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 209145566e9cSChristoph Hellwig int64_t pos, int size) 2092178e08a5Saliguori { 2093178e08a5Saliguori BlockDriver *drv = bs->drv; 2094178e08a5Saliguori if (!drv) 2095178e08a5Saliguori return -ENOMEDIUM; 20967cdb1f6dSMORITA Kazutaka if (drv->bdrv_save_vmstate) 209745566e9cSChristoph Hellwig return drv->bdrv_save_vmstate(bs, buf, pos, size); 20987cdb1f6dSMORITA Kazutaka if (bs->file) 20997cdb1f6dSMORITA Kazutaka return bdrv_save_vmstate(bs->file, buf, pos, size); 21007cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2101178e08a5Saliguori } 2102178e08a5Saliguori 210345566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, 210445566e9cSChristoph Hellwig int64_t pos, int size) 2105178e08a5Saliguori { 2106178e08a5Saliguori BlockDriver *drv = bs->drv; 2107178e08a5Saliguori if (!drv) 2108178e08a5Saliguori return -ENOMEDIUM; 21097cdb1f6dSMORITA Kazutaka if (drv->bdrv_load_vmstate) 211045566e9cSChristoph Hellwig return drv->bdrv_load_vmstate(bs, buf, pos, size); 21117cdb1f6dSMORITA Kazutaka if (bs->file) 21127cdb1f6dSMORITA Kazutaka return bdrv_load_vmstate(bs->file, buf, pos, size); 21137cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2114178e08a5Saliguori } 2115178e08a5Saliguori 21168b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) 21178b9b0cc2SKevin Wolf { 21188b9b0cc2SKevin Wolf BlockDriver *drv = bs->drv; 21198b9b0cc2SKevin Wolf 21208b9b0cc2SKevin Wolf if (!drv || !drv->bdrv_debug_event) { 21218b9b0cc2SKevin Wolf return; 21228b9b0cc2SKevin Wolf } 21238b9b0cc2SKevin Wolf 21248b9b0cc2SKevin Wolf return drv->bdrv_debug_event(bs, event); 21258b9b0cc2SKevin Wolf 21268b9b0cc2SKevin Wolf } 21278b9b0cc2SKevin Wolf 2128faea38e7Sbellard /**************************************************************/ 2129faea38e7Sbellard /* handling of snapshots */ 2130faea38e7Sbellard 2131feeee5acSMiguel Di Ciurcio Filho int bdrv_can_snapshot(BlockDriverState *bs) 2132feeee5acSMiguel Di Ciurcio Filho { 2133feeee5acSMiguel Di Ciurcio Filho BlockDriver *drv = bs->drv; 213407b70bfbSMarkus Armbruster if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { 2135feeee5acSMiguel Di Ciurcio Filho return 0; 2136feeee5acSMiguel Di Ciurcio Filho } 2137feeee5acSMiguel Di Ciurcio Filho 2138feeee5acSMiguel Di Ciurcio Filho if (!drv->bdrv_snapshot_create) { 2139feeee5acSMiguel Di Ciurcio Filho if (bs->file != NULL) { 2140feeee5acSMiguel Di Ciurcio Filho return bdrv_can_snapshot(bs->file); 2141feeee5acSMiguel Di Ciurcio Filho } 2142feeee5acSMiguel Di Ciurcio Filho return 0; 2143feeee5acSMiguel Di Ciurcio Filho } 2144feeee5acSMiguel Di Ciurcio Filho 2145feeee5acSMiguel Di Ciurcio Filho return 1; 2146feeee5acSMiguel Di Ciurcio Filho } 2147feeee5acSMiguel Di Ciurcio Filho 2148199630b6SBlue Swirl int bdrv_is_snapshot(BlockDriverState *bs) 2149199630b6SBlue Swirl { 2150199630b6SBlue Swirl return !!(bs->open_flags & BDRV_O_SNAPSHOT); 2151199630b6SBlue Swirl } 2152199630b6SBlue Swirl 2153f9092b10SMarkus Armbruster BlockDriverState *bdrv_snapshots(void) 2154f9092b10SMarkus Armbruster { 2155f9092b10SMarkus Armbruster BlockDriverState *bs; 2156f9092b10SMarkus Armbruster 21573ac906f7SMarkus Armbruster if (bs_snapshots) { 2158f9092b10SMarkus Armbruster return bs_snapshots; 21593ac906f7SMarkus Armbruster } 2160f9092b10SMarkus Armbruster 2161f9092b10SMarkus Armbruster bs = NULL; 2162f9092b10SMarkus Armbruster while ((bs = bdrv_next(bs))) { 2163f9092b10SMarkus Armbruster if (bdrv_can_snapshot(bs)) { 21643ac906f7SMarkus Armbruster bs_snapshots = bs; 21653ac906f7SMarkus Armbruster return bs; 2166f9092b10SMarkus Armbruster } 2167f9092b10SMarkus Armbruster } 2168f9092b10SMarkus Armbruster return NULL; 2169f9092b10SMarkus Armbruster } 2170f9092b10SMarkus Armbruster 2171faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs, 2172faea38e7Sbellard QEMUSnapshotInfo *sn_info) 2173faea38e7Sbellard { 2174faea38e7Sbellard BlockDriver *drv = bs->drv; 2175faea38e7Sbellard if (!drv) 217619cb3738Sbellard return -ENOMEDIUM; 21777cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_create) 2178faea38e7Sbellard return drv->bdrv_snapshot_create(bs, sn_info); 21797cdb1f6dSMORITA Kazutaka if (bs->file) 21807cdb1f6dSMORITA Kazutaka return bdrv_snapshot_create(bs->file, sn_info); 21817cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2182faea38e7Sbellard } 2183faea38e7Sbellard 2184faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs, 2185faea38e7Sbellard const char *snapshot_id) 2186faea38e7Sbellard { 2187faea38e7Sbellard BlockDriver *drv = bs->drv; 21887cdb1f6dSMORITA Kazutaka int ret, open_ret; 21897cdb1f6dSMORITA Kazutaka 2190faea38e7Sbellard if (!drv) 219119cb3738Sbellard return -ENOMEDIUM; 21927cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_goto) 2193faea38e7Sbellard return drv->bdrv_snapshot_goto(bs, snapshot_id); 21947cdb1f6dSMORITA Kazutaka 21957cdb1f6dSMORITA Kazutaka if (bs->file) { 21967cdb1f6dSMORITA Kazutaka drv->bdrv_close(bs); 21977cdb1f6dSMORITA Kazutaka ret = bdrv_snapshot_goto(bs->file, snapshot_id); 21987cdb1f6dSMORITA Kazutaka open_ret = drv->bdrv_open(bs, bs->open_flags); 21997cdb1f6dSMORITA Kazutaka if (open_ret < 0) { 22007cdb1f6dSMORITA Kazutaka bdrv_delete(bs->file); 22017cdb1f6dSMORITA Kazutaka bs->drv = NULL; 22027cdb1f6dSMORITA Kazutaka return open_ret; 22037cdb1f6dSMORITA Kazutaka } 22047cdb1f6dSMORITA Kazutaka return ret; 22057cdb1f6dSMORITA Kazutaka } 22067cdb1f6dSMORITA Kazutaka 22077cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2208faea38e7Sbellard } 2209faea38e7Sbellard 2210faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 2211faea38e7Sbellard { 2212faea38e7Sbellard BlockDriver *drv = bs->drv; 2213faea38e7Sbellard if (!drv) 221419cb3738Sbellard return -ENOMEDIUM; 22157cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_delete) 2216faea38e7Sbellard return drv->bdrv_snapshot_delete(bs, snapshot_id); 22177cdb1f6dSMORITA Kazutaka if (bs->file) 22187cdb1f6dSMORITA Kazutaka return bdrv_snapshot_delete(bs->file, snapshot_id); 22197cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2220faea38e7Sbellard } 2221faea38e7Sbellard 2222faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs, 2223faea38e7Sbellard QEMUSnapshotInfo **psn_info) 2224faea38e7Sbellard { 2225faea38e7Sbellard BlockDriver *drv = bs->drv; 2226faea38e7Sbellard if (!drv) 222719cb3738Sbellard return -ENOMEDIUM; 22287cdb1f6dSMORITA Kazutaka if (drv->bdrv_snapshot_list) 2229faea38e7Sbellard return drv->bdrv_snapshot_list(bs, psn_info); 22307cdb1f6dSMORITA Kazutaka if (bs->file) 22317cdb1f6dSMORITA Kazutaka return bdrv_snapshot_list(bs->file, psn_info); 22327cdb1f6dSMORITA Kazutaka return -ENOTSUP; 2233faea38e7Sbellard } 2234faea38e7Sbellard 223551ef6727Sedison int bdrv_snapshot_load_tmp(BlockDriverState *bs, 223651ef6727Sedison const char *snapshot_name) 223751ef6727Sedison { 223851ef6727Sedison BlockDriver *drv = bs->drv; 223951ef6727Sedison if (!drv) { 224051ef6727Sedison return -ENOMEDIUM; 224151ef6727Sedison } 224251ef6727Sedison if (!bs->read_only) { 224351ef6727Sedison return -EINVAL; 224451ef6727Sedison } 224551ef6727Sedison if (drv->bdrv_snapshot_load_tmp) { 224651ef6727Sedison return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); 224751ef6727Sedison } 224851ef6727Sedison return -ENOTSUP; 224951ef6727Sedison } 225051ef6727Sedison 2251faea38e7Sbellard #define NB_SUFFIXES 4 2252faea38e7Sbellard 2253faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size) 2254faea38e7Sbellard { 2255faea38e7Sbellard static const char suffixes[NB_SUFFIXES] = "KMGT"; 2256faea38e7Sbellard int64_t base; 2257faea38e7Sbellard int i; 2258faea38e7Sbellard 2259faea38e7Sbellard if (size <= 999) { 2260faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64, size); 2261faea38e7Sbellard } else { 2262faea38e7Sbellard base = 1024; 2263faea38e7Sbellard for(i = 0; i < NB_SUFFIXES; i++) { 2264faea38e7Sbellard if (size < (10 * base)) { 2265faea38e7Sbellard snprintf(buf, buf_size, "%0.1f%c", 2266faea38e7Sbellard (double)size / base, 2267faea38e7Sbellard suffixes[i]); 2268faea38e7Sbellard break; 2269faea38e7Sbellard } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 2270faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64 "%c", 2271faea38e7Sbellard ((size + (base >> 1)) / base), 2272faea38e7Sbellard suffixes[i]); 2273faea38e7Sbellard break; 2274faea38e7Sbellard } 2275faea38e7Sbellard base = base * 1024; 2276faea38e7Sbellard } 2277faea38e7Sbellard } 2278faea38e7Sbellard return buf; 2279faea38e7Sbellard } 2280faea38e7Sbellard 2281faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 2282faea38e7Sbellard { 2283faea38e7Sbellard char buf1[128], date_buf[128], clock_buf[128]; 22843b9f94e1Sbellard #ifdef _WIN32 22853b9f94e1Sbellard struct tm *ptm; 22863b9f94e1Sbellard #else 2287faea38e7Sbellard struct tm tm; 22883b9f94e1Sbellard #endif 2289faea38e7Sbellard time_t ti; 2290faea38e7Sbellard int64_t secs; 2291faea38e7Sbellard 2292faea38e7Sbellard if (!sn) { 2293faea38e7Sbellard snprintf(buf, buf_size, 2294faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2295faea38e7Sbellard "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 2296faea38e7Sbellard } else { 2297faea38e7Sbellard ti = sn->date_sec; 22983b9f94e1Sbellard #ifdef _WIN32 22993b9f94e1Sbellard ptm = localtime(&ti); 23003b9f94e1Sbellard strftime(date_buf, sizeof(date_buf), 23013b9f94e1Sbellard "%Y-%m-%d %H:%M:%S", ptm); 23023b9f94e1Sbellard #else 2303faea38e7Sbellard localtime_r(&ti, &tm); 2304faea38e7Sbellard strftime(date_buf, sizeof(date_buf), 2305faea38e7Sbellard "%Y-%m-%d %H:%M:%S", &tm); 23063b9f94e1Sbellard #endif 2307faea38e7Sbellard secs = sn->vm_clock_nsec / 1000000000; 2308faea38e7Sbellard snprintf(clock_buf, sizeof(clock_buf), 2309faea38e7Sbellard "%02d:%02d:%02d.%03d", 2310faea38e7Sbellard (int)(secs / 3600), 2311faea38e7Sbellard (int)((secs / 60) % 60), 2312faea38e7Sbellard (int)(secs % 60), 2313faea38e7Sbellard (int)((sn->vm_clock_nsec / 1000000) % 1000)); 2314faea38e7Sbellard snprintf(buf, buf_size, 2315faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 2316faea38e7Sbellard sn->id_str, sn->name, 2317faea38e7Sbellard get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 2318faea38e7Sbellard date_buf, 2319faea38e7Sbellard clock_buf); 2320faea38e7Sbellard } 2321faea38e7Sbellard return buf; 2322faea38e7Sbellard } 2323faea38e7Sbellard 2324ea2384d3Sbellard /**************************************************************/ 232583f64091Sbellard /* async I/Os */ 2326ea2384d3Sbellard 23273b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 2328f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 232983f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 2330ea2384d3Sbellard { 233183f64091Sbellard BlockDriver *drv = bs->drv; 2332ea2384d3Sbellard 2333bbf0a440SStefan Hajnoczi trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); 2334bbf0a440SStefan Hajnoczi 233519cb3738Sbellard if (!drv) 2336ce1a14dcSpbrook return NULL; 233771d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 233871d0770cSaliguori return NULL; 233983f64091Sbellard 2340a597e79cSChristoph Hellwig return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, 2341f141eafeSaliguori cb, opaque); 234283f64091Sbellard } 234383f64091Sbellard 23444dcafbb1SMarcelo Tosatti typedef struct BlockCompleteData { 23454dcafbb1SMarcelo Tosatti BlockDriverCompletionFunc *cb; 23464dcafbb1SMarcelo Tosatti void *opaque; 23474dcafbb1SMarcelo Tosatti BlockDriverState *bs; 23484dcafbb1SMarcelo Tosatti int64_t sector_num; 23494dcafbb1SMarcelo Tosatti int nb_sectors; 23504dcafbb1SMarcelo Tosatti } BlockCompleteData; 23514dcafbb1SMarcelo Tosatti 23524dcafbb1SMarcelo Tosatti static void block_complete_cb(void *opaque, int ret) 23534dcafbb1SMarcelo Tosatti { 23544dcafbb1SMarcelo Tosatti BlockCompleteData *b = opaque; 23554dcafbb1SMarcelo Tosatti 23564dcafbb1SMarcelo Tosatti if (b->bs->dirty_bitmap) { 23574dcafbb1SMarcelo Tosatti set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1); 23584dcafbb1SMarcelo Tosatti } 23594dcafbb1SMarcelo Tosatti b->cb(b->opaque, ret); 23607267c094SAnthony Liguori g_free(b); 23614dcafbb1SMarcelo Tosatti } 23624dcafbb1SMarcelo Tosatti 23634dcafbb1SMarcelo Tosatti static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs, 23644dcafbb1SMarcelo Tosatti int64_t sector_num, 23654dcafbb1SMarcelo Tosatti int nb_sectors, 23664dcafbb1SMarcelo Tosatti BlockDriverCompletionFunc *cb, 23674dcafbb1SMarcelo Tosatti void *opaque) 23684dcafbb1SMarcelo Tosatti { 23697267c094SAnthony Liguori BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData)); 23704dcafbb1SMarcelo Tosatti 23714dcafbb1SMarcelo Tosatti blkdata->bs = bs; 23724dcafbb1SMarcelo Tosatti blkdata->cb = cb; 23734dcafbb1SMarcelo Tosatti blkdata->opaque = opaque; 23744dcafbb1SMarcelo Tosatti blkdata->sector_num = sector_num; 23754dcafbb1SMarcelo Tosatti blkdata->nb_sectors = nb_sectors; 23764dcafbb1SMarcelo Tosatti 23774dcafbb1SMarcelo Tosatti return blkdata; 23784dcafbb1SMarcelo Tosatti } 23794dcafbb1SMarcelo Tosatti 2380f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 2381f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 238283f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 23837674e7bfSbellard { 238483f64091Sbellard BlockDriver *drv = bs->drv; 2385a36e69ddSths BlockDriverAIOCB *ret; 23864dcafbb1SMarcelo Tosatti BlockCompleteData *blk_cb_data; 238783f64091Sbellard 2388bbf0a440SStefan Hajnoczi trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); 2389bbf0a440SStefan Hajnoczi 239019cb3738Sbellard if (!drv) 2391ce1a14dcSpbrook return NULL; 239283f64091Sbellard if (bs->read_only) 2393ce1a14dcSpbrook return NULL; 239471d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 239571d0770cSaliguori return NULL; 239683f64091Sbellard 2397c6d22830SJan Kiszka if (bs->dirty_bitmap) { 23984dcafbb1SMarcelo Tosatti blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb, 23994dcafbb1SMarcelo Tosatti opaque); 24004dcafbb1SMarcelo Tosatti cb = &block_complete_cb; 24014dcafbb1SMarcelo Tosatti opaque = blk_cb_data; 24027cd1e32aSlirans@il.ibm.com } 24037cd1e32aSlirans@il.ibm.com 2404f141eafeSaliguori ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, 2405f141eafeSaliguori cb, opaque); 2406a36e69ddSths 2407a36e69ddSths if (ret) { 2408294cc35fSKevin Wolf if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { 2409294cc35fSKevin Wolf bs->wr_highest_sector = sector_num + nb_sectors - 1; 2410294cc35fSKevin Wolf } 2411a36e69ddSths } 2412a36e69ddSths 2413a36e69ddSths return ret; 241483f64091Sbellard } 241583f64091Sbellard 241640b4f539SKevin Wolf 241740b4f539SKevin Wolf typedef struct MultiwriteCB { 241840b4f539SKevin Wolf int error; 241940b4f539SKevin Wolf int num_requests; 242040b4f539SKevin Wolf int num_callbacks; 242140b4f539SKevin Wolf struct { 242240b4f539SKevin Wolf BlockDriverCompletionFunc *cb; 242340b4f539SKevin Wolf void *opaque; 242440b4f539SKevin Wolf QEMUIOVector *free_qiov; 242540b4f539SKevin Wolf void *free_buf; 242640b4f539SKevin Wolf } callbacks[]; 242740b4f539SKevin Wolf } MultiwriteCB; 242840b4f539SKevin Wolf 242940b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb) 243040b4f539SKevin Wolf { 243140b4f539SKevin Wolf int i; 243240b4f539SKevin Wolf 243340b4f539SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 243440b4f539SKevin Wolf mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); 24351e1ea48dSStefan Hajnoczi if (mcb->callbacks[i].free_qiov) { 24361e1ea48dSStefan Hajnoczi qemu_iovec_destroy(mcb->callbacks[i].free_qiov); 24371e1ea48dSStefan Hajnoczi } 24387267c094SAnthony Liguori g_free(mcb->callbacks[i].free_qiov); 2439f8a83245SHerve Poussineau qemu_vfree(mcb->callbacks[i].free_buf); 244040b4f539SKevin Wolf } 244140b4f539SKevin Wolf } 244240b4f539SKevin Wolf 244340b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret) 244440b4f539SKevin Wolf { 244540b4f539SKevin Wolf MultiwriteCB *mcb = opaque; 244640b4f539SKevin Wolf 24476d519a5fSStefan Hajnoczi trace_multiwrite_cb(mcb, ret); 24486d519a5fSStefan Hajnoczi 2449cb6d3ca0SKevin Wolf if (ret < 0 && !mcb->error) { 245040b4f539SKevin Wolf mcb->error = ret; 245140b4f539SKevin Wolf } 245240b4f539SKevin Wolf 245340b4f539SKevin Wolf mcb->num_requests--; 245440b4f539SKevin Wolf if (mcb->num_requests == 0) { 245540b4f539SKevin Wolf multiwrite_user_cb(mcb); 24567267c094SAnthony Liguori g_free(mcb); 245740b4f539SKevin Wolf } 245840b4f539SKevin Wolf } 245940b4f539SKevin Wolf 246040b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b) 246140b4f539SKevin Wolf { 246277be4366SChristoph Hellwig const BlockRequest *req1 = a, *req2 = b; 246377be4366SChristoph Hellwig 246477be4366SChristoph Hellwig /* 246577be4366SChristoph Hellwig * Note that we can't simply subtract req2->sector from req1->sector 246677be4366SChristoph Hellwig * here as that could overflow the return value. 246777be4366SChristoph Hellwig */ 246877be4366SChristoph Hellwig if (req1->sector > req2->sector) { 246977be4366SChristoph Hellwig return 1; 247077be4366SChristoph Hellwig } else if (req1->sector < req2->sector) { 247177be4366SChristoph Hellwig return -1; 247277be4366SChristoph Hellwig } else { 247377be4366SChristoph Hellwig return 0; 247477be4366SChristoph Hellwig } 247540b4f539SKevin Wolf } 247640b4f539SKevin Wolf 247740b4f539SKevin Wolf /* 247840b4f539SKevin Wolf * Takes a bunch of requests and tries to merge them. Returns the number of 247940b4f539SKevin Wolf * requests that remain after merging. 248040b4f539SKevin Wolf */ 248140b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, 248240b4f539SKevin Wolf int num_reqs, MultiwriteCB *mcb) 248340b4f539SKevin Wolf { 248440b4f539SKevin Wolf int i, outidx; 248540b4f539SKevin Wolf 248640b4f539SKevin Wolf // Sort requests by start sector 248740b4f539SKevin Wolf qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); 248840b4f539SKevin Wolf 248940b4f539SKevin Wolf // Check if adjacent requests touch the same clusters. If so, combine them, 249040b4f539SKevin Wolf // filling up gaps with zero sectors. 249140b4f539SKevin Wolf outidx = 0; 249240b4f539SKevin Wolf for (i = 1; i < num_reqs; i++) { 249340b4f539SKevin Wolf int merge = 0; 249440b4f539SKevin Wolf int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; 249540b4f539SKevin Wolf 249640b4f539SKevin Wolf // This handles the cases that are valid for all block drivers, namely 249740b4f539SKevin Wolf // exactly sequential writes and overlapping writes. 249840b4f539SKevin Wolf if (reqs[i].sector <= oldreq_last) { 249940b4f539SKevin Wolf merge = 1; 250040b4f539SKevin Wolf } 250140b4f539SKevin Wolf 250240b4f539SKevin Wolf // The block driver may decide that it makes sense to combine requests 250340b4f539SKevin Wolf // even if there is a gap of some sectors between them. In this case, 250440b4f539SKevin Wolf // the gap is filled with zeros (therefore only applicable for yet 250540b4f539SKevin Wolf // unused space in format like qcow2). 250640b4f539SKevin Wolf if (!merge && bs->drv->bdrv_merge_requests) { 250740b4f539SKevin Wolf merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); 250840b4f539SKevin Wolf } 250940b4f539SKevin Wolf 2510e2a305fbSChristoph Hellwig if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { 2511e2a305fbSChristoph Hellwig merge = 0; 2512e2a305fbSChristoph Hellwig } 2513e2a305fbSChristoph Hellwig 251440b4f539SKevin Wolf if (merge) { 251540b4f539SKevin Wolf size_t size; 25167267c094SAnthony Liguori QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); 251740b4f539SKevin Wolf qemu_iovec_init(qiov, 251840b4f539SKevin Wolf reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); 251940b4f539SKevin Wolf 252040b4f539SKevin Wolf // Add the first request to the merged one. If the requests are 252140b4f539SKevin Wolf // overlapping, drop the last sectors of the first request. 252240b4f539SKevin Wolf size = (reqs[i].sector - reqs[outidx].sector) << 9; 252340b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[outidx].qiov, size); 252440b4f539SKevin Wolf 252540b4f539SKevin Wolf // We might need to add some zeros between the two requests 252640b4f539SKevin Wolf if (reqs[i].sector > oldreq_last) { 252740b4f539SKevin Wolf size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9; 252840b4f539SKevin Wolf uint8_t *buf = qemu_blockalign(bs, zero_bytes); 252940b4f539SKevin Wolf memset(buf, 0, zero_bytes); 253040b4f539SKevin Wolf qemu_iovec_add(qiov, buf, zero_bytes); 253140b4f539SKevin Wolf mcb->callbacks[i].free_buf = buf; 253240b4f539SKevin Wolf } 253340b4f539SKevin Wolf 253440b4f539SKevin Wolf // Add the second request 253540b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size); 253640b4f539SKevin Wolf 2537cbf1dff2SKevin Wolf reqs[outidx].nb_sectors = qiov->size >> 9; 253840b4f539SKevin Wolf reqs[outidx].qiov = qiov; 253940b4f539SKevin Wolf 254040b4f539SKevin Wolf mcb->callbacks[i].free_qiov = reqs[outidx].qiov; 254140b4f539SKevin Wolf } else { 254240b4f539SKevin Wolf outidx++; 254340b4f539SKevin Wolf reqs[outidx].sector = reqs[i].sector; 254440b4f539SKevin Wolf reqs[outidx].nb_sectors = reqs[i].nb_sectors; 254540b4f539SKevin Wolf reqs[outidx].qiov = reqs[i].qiov; 254640b4f539SKevin Wolf } 254740b4f539SKevin Wolf } 254840b4f539SKevin Wolf 254940b4f539SKevin Wolf return outidx + 1; 255040b4f539SKevin Wolf } 255140b4f539SKevin Wolf 255240b4f539SKevin Wolf /* 255340b4f539SKevin Wolf * Submit multiple AIO write requests at once. 255440b4f539SKevin Wolf * 255540b4f539SKevin Wolf * On success, the function returns 0 and all requests in the reqs array have 255640b4f539SKevin Wolf * been submitted. In error case this function returns -1, and any of the 255740b4f539SKevin Wolf * requests may or may not be submitted yet. In particular, this means that the 255840b4f539SKevin Wolf * callback will be called for some of the requests, for others it won't. The 255940b4f539SKevin Wolf * caller must check the error field of the BlockRequest to wait for the right 256040b4f539SKevin Wolf * callbacks (if error != 0, no callback will be called). 256140b4f539SKevin Wolf * 256240b4f539SKevin Wolf * The implementation may modify the contents of the reqs array, e.g. to merge 256340b4f539SKevin Wolf * requests. However, the fields opaque and error are left unmodified as they 256440b4f539SKevin Wolf * are used to signal failure for a single request to the caller. 256540b4f539SKevin Wolf */ 256640b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) 256740b4f539SKevin Wolf { 256840b4f539SKevin Wolf BlockDriverAIOCB *acb; 256940b4f539SKevin Wolf MultiwriteCB *mcb; 257040b4f539SKevin Wolf int i; 257140b4f539SKevin Wolf 2572301db7c2SRyan Harper /* don't submit writes if we don't have a medium */ 2573301db7c2SRyan Harper if (bs->drv == NULL) { 2574301db7c2SRyan Harper for (i = 0; i < num_reqs; i++) { 2575301db7c2SRyan Harper reqs[i].error = -ENOMEDIUM; 2576301db7c2SRyan Harper } 2577301db7c2SRyan Harper return -1; 2578301db7c2SRyan Harper } 2579301db7c2SRyan Harper 258040b4f539SKevin Wolf if (num_reqs == 0) { 258140b4f539SKevin Wolf return 0; 258240b4f539SKevin Wolf } 258340b4f539SKevin Wolf 258440b4f539SKevin Wolf // Create MultiwriteCB structure 25857267c094SAnthony Liguori mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); 258640b4f539SKevin Wolf mcb->num_requests = 0; 258740b4f539SKevin Wolf mcb->num_callbacks = num_reqs; 258840b4f539SKevin Wolf 258940b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 259040b4f539SKevin Wolf mcb->callbacks[i].cb = reqs[i].cb; 259140b4f539SKevin Wolf mcb->callbacks[i].opaque = reqs[i].opaque; 259240b4f539SKevin Wolf } 259340b4f539SKevin Wolf 259440b4f539SKevin Wolf // Check for mergable requests 259540b4f539SKevin Wolf num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); 259640b4f539SKevin Wolf 25976d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); 25986d519a5fSStefan Hajnoczi 2599453f9a16SKevin Wolf /* 2600453f9a16SKevin Wolf * Run the aio requests. As soon as one request can't be submitted 2601453f9a16SKevin Wolf * successfully, fail all requests that are not yet submitted (we must 2602453f9a16SKevin Wolf * return failure for all requests anyway) 2603453f9a16SKevin Wolf * 2604453f9a16SKevin Wolf * num_requests cannot be set to the right value immediately: If 2605453f9a16SKevin Wolf * bdrv_aio_writev fails for some request, num_requests would be too high 2606453f9a16SKevin Wolf * and therefore multiwrite_cb() would never recognize the multiwrite 2607453f9a16SKevin Wolf * request as completed. We also cannot use the loop variable i to set it 2608453f9a16SKevin Wolf * when the first request fails because the callback may already have been 2609453f9a16SKevin Wolf * called for previously submitted requests. Thus, num_requests must be 2610453f9a16SKevin Wolf * incremented for each request that is submitted. 2611453f9a16SKevin Wolf * 2612453f9a16SKevin Wolf * The problem that callbacks may be called early also means that we need 2613453f9a16SKevin Wolf * to take care that num_requests doesn't become 0 before all requests are 2614453f9a16SKevin Wolf * submitted - multiwrite_cb() would consider the multiwrite request 2615453f9a16SKevin Wolf * completed. A dummy request that is "completed" by a manual call to 2616453f9a16SKevin Wolf * multiwrite_cb() takes care of this. 2617453f9a16SKevin Wolf */ 2618453f9a16SKevin Wolf mcb->num_requests = 1; 2619453f9a16SKevin Wolf 26206d519a5fSStefan Hajnoczi // Run the aio requests 262140b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 2622453f9a16SKevin Wolf mcb->num_requests++; 262340b4f539SKevin Wolf acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, 262440b4f539SKevin Wolf reqs[i].nb_sectors, multiwrite_cb, mcb); 262540b4f539SKevin Wolf 262640b4f539SKevin Wolf if (acb == NULL) { 262740b4f539SKevin Wolf // We can only fail the whole thing if no request has been 262840b4f539SKevin Wolf // submitted yet. Otherwise we'll wait for the submitted AIOs to 262940b4f539SKevin Wolf // complete and report the error in the callback. 2630453f9a16SKevin Wolf if (i == 0) { 26316d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_earlyfail(mcb); 263240b4f539SKevin Wolf goto fail; 263340b4f539SKevin Wolf } else { 26346d519a5fSStefan Hajnoczi trace_bdrv_aio_multiwrite_latefail(mcb, i); 26357eb58a6cSKevin Wolf multiwrite_cb(mcb, -EIO); 263640b4f539SKevin Wolf break; 263740b4f539SKevin Wolf } 263840b4f539SKevin Wolf } 263940b4f539SKevin Wolf } 264040b4f539SKevin Wolf 2641453f9a16SKevin Wolf /* Complete the dummy request */ 2642453f9a16SKevin Wolf multiwrite_cb(mcb, 0); 2643453f9a16SKevin Wolf 264440b4f539SKevin Wolf return 0; 264540b4f539SKevin Wolf 264640b4f539SKevin Wolf fail: 2647453f9a16SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 2648453f9a16SKevin Wolf reqs[i].error = -EIO; 2649453f9a16SKevin Wolf } 26507267c094SAnthony Liguori g_free(mcb); 265140b4f539SKevin Wolf return -1; 265240b4f539SKevin Wolf } 265340b4f539SKevin Wolf 2654b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 2655b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2656b2e12bc6SChristoph Hellwig { 2657b2e12bc6SChristoph Hellwig BlockDriver *drv = bs->drv; 2658b2e12bc6SChristoph Hellwig 2659a13aac04SStefan Hajnoczi trace_bdrv_aio_flush(bs, opaque); 2660a13aac04SStefan Hajnoczi 2661016f5cf6SAlexander Graf if (bs->open_flags & BDRV_O_NO_FLUSH) { 2662016f5cf6SAlexander Graf return bdrv_aio_noop_em(bs, cb, opaque); 2663016f5cf6SAlexander Graf } 2664016f5cf6SAlexander Graf 2665b2e12bc6SChristoph Hellwig if (!drv) 2666b2e12bc6SChristoph Hellwig return NULL; 2667b2e12bc6SChristoph Hellwig return drv->bdrv_aio_flush(bs, cb, opaque); 2668b2e12bc6SChristoph Hellwig } 2669b2e12bc6SChristoph Hellwig 267083f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb) 267183f64091Sbellard { 26726bbff9a0Saliguori acb->pool->cancel(acb); 267383f64091Sbellard } 267483f64091Sbellard 267583f64091Sbellard 267683f64091Sbellard /**************************************************************/ 267783f64091Sbellard /* async block device emulation */ 267883f64091Sbellard 2679c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync { 2680c16b5a2cSChristoph Hellwig BlockDriverAIOCB common; 2681c16b5a2cSChristoph Hellwig QEMUBH *bh; 2682c16b5a2cSChristoph Hellwig int ret; 2683c16b5a2cSChristoph Hellwig /* vector translation state */ 2684c16b5a2cSChristoph Hellwig QEMUIOVector *qiov; 2685c16b5a2cSChristoph Hellwig uint8_t *bounce; 2686c16b5a2cSChristoph Hellwig int is_write; 2687c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync; 2688c16b5a2cSChristoph Hellwig 2689c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 2690c16b5a2cSChristoph Hellwig { 2691b666d239SKevin Wolf BlockDriverAIOCBSync *acb = 2692b666d239SKevin Wolf container_of(blockacb, BlockDriverAIOCBSync, common); 26936a7ad299SDor Laor qemu_bh_delete(acb->bh); 269436afc451SAvi Kivity acb->bh = NULL; 2695c16b5a2cSChristoph Hellwig qemu_aio_release(acb); 2696c16b5a2cSChristoph Hellwig } 2697c16b5a2cSChristoph Hellwig 2698c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = { 2699c16b5a2cSChristoph Hellwig .aiocb_size = sizeof(BlockDriverAIOCBSync), 2700c16b5a2cSChristoph Hellwig .cancel = bdrv_aio_cancel_em, 2701c16b5a2cSChristoph Hellwig }; 2702c16b5a2cSChristoph Hellwig 270383f64091Sbellard static void bdrv_aio_bh_cb(void *opaque) 2704beac80cdSbellard { 2705ce1a14dcSpbrook BlockDriverAIOCBSync *acb = opaque; 2706f141eafeSaliguori 2707f141eafeSaliguori if (!acb->is_write) 2708f141eafeSaliguori qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 2709ceb42de8Saliguori qemu_vfree(acb->bounce); 2710ce1a14dcSpbrook acb->common.cb(acb->common.opaque, acb->ret); 27116a7ad299SDor Laor qemu_bh_delete(acb->bh); 271236afc451SAvi Kivity acb->bh = NULL; 2713ce1a14dcSpbrook qemu_aio_release(acb); 2714beac80cdSbellard } 2715beac80cdSbellard 2716f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 2717f141eafeSaliguori int64_t sector_num, 2718f141eafeSaliguori QEMUIOVector *qiov, 2719f141eafeSaliguori int nb_sectors, 2720f141eafeSaliguori BlockDriverCompletionFunc *cb, 2721f141eafeSaliguori void *opaque, 2722f141eafeSaliguori int is_write) 2723f141eafeSaliguori 2724ea2384d3Sbellard { 2725ce1a14dcSpbrook BlockDriverAIOCBSync *acb; 272683f64091Sbellard 2727c16b5a2cSChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2728f141eafeSaliguori acb->is_write = is_write; 2729f141eafeSaliguori acb->qiov = qiov; 2730e268ca52Saliguori acb->bounce = qemu_blockalign(bs, qiov->size); 2731f141eafeSaliguori 2732ce1a14dcSpbrook if (!acb->bh) 2733ce1a14dcSpbrook acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2734f141eafeSaliguori 2735f141eafeSaliguori if (is_write) { 2736f141eafeSaliguori qemu_iovec_to_buffer(acb->qiov, acb->bounce); 2737f141eafeSaliguori acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 2738f141eafeSaliguori } else { 2739f141eafeSaliguori acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 2740f141eafeSaliguori } 2741f141eafeSaliguori 2742ce1a14dcSpbrook qemu_bh_schedule(acb->bh); 2743f141eafeSaliguori 2744ce1a14dcSpbrook return &acb->common; 27457a6cba61Spbrook } 27467a6cba61Spbrook 2747f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 2748f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2749ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque) 275083f64091Sbellard { 2751f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 275283f64091Sbellard } 275383f64091Sbellard 2754f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 2755f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2756f141eafeSaliguori BlockDriverCompletionFunc *cb, void *opaque) 2757f141eafeSaliguori { 2758f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 2759f141eafeSaliguori } 2760f141eafeSaliguori 276168485420SKevin Wolf 276268485420SKevin Wolf typedef struct BlockDriverAIOCBCoroutine { 276368485420SKevin Wolf BlockDriverAIOCB common; 276468485420SKevin Wolf BlockRequest req; 276568485420SKevin Wolf bool is_write; 276668485420SKevin Wolf QEMUBH* bh; 276768485420SKevin Wolf } BlockDriverAIOCBCoroutine; 276868485420SKevin Wolf 276968485420SKevin Wolf static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) 277068485420SKevin Wolf { 277168485420SKevin Wolf qemu_aio_flush(); 277268485420SKevin Wolf } 277368485420SKevin Wolf 277468485420SKevin Wolf static AIOPool bdrv_em_co_aio_pool = { 277568485420SKevin Wolf .aiocb_size = sizeof(BlockDriverAIOCBCoroutine), 277668485420SKevin Wolf .cancel = bdrv_aio_co_cancel_em, 277768485420SKevin Wolf }; 277868485420SKevin Wolf 277968485420SKevin Wolf static void bdrv_co_rw_bh(void *opaque) 278068485420SKevin Wolf { 278168485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 278268485420SKevin Wolf 278368485420SKevin Wolf acb->common.cb(acb->common.opaque, acb->req.error); 278468485420SKevin Wolf qemu_bh_delete(acb->bh); 278568485420SKevin Wolf qemu_aio_release(acb); 278668485420SKevin Wolf } 278768485420SKevin Wolf 278868485420SKevin Wolf static void coroutine_fn bdrv_co_rw(void *opaque) 278968485420SKevin Wolf { 279068485420SKevin Wolf BlockDriverAIOCBCoroutine *acb = opaque; 279168485420SKevin Wolf BlockDriverState *bs = acb->common.bs; 279268485420SKevin Wolf 279368485420SKevin Wolf if (!acb->is_write) { 279468485420SKevin Wolf acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector, 279568485420SKevin Wolf acb->req.nb_sectors, acb->req.qiov); 279668485420SKevin Wolf } else { 279768485420SKevin Wolf acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector, 279868485420SKevin Wolf acb->req.nb_sectors, acb->req.qiov); 279968485420SKevin Wolf } 280068485420SKevin Wolf 280168485420SKevin Wolf acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb); 280268485420SKevin Wolf qemu_bh_schedule(acb->bh); 280368485420SKevin Wolf } 280468485420SKevin Wolf 280568485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, 280668485420SKevin Wolf int64_t sector_num, 280768485420SKevin Wolf QEMUIOVector *qiov, 280868485420SKevin Wolf int nb_sectors, 280968485420SKevin Wolf BlockDriverCompletionFunc *cb, 281068485420SKevin Wolf void *opaque, 281168485420SKevin Wolf bool is_write) 281268485420SKevin Wolf { 281368485420SKevin Wolf Coroutine *co; 281468485420SKevin Wolf BlockDriverAIOCBCoroutine *acb; 281568485420SKevin Wolf 281668485420SKevin Wolf acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); 281768485420SKevin Wolf acb->req.sector = sector_num; 281868485420SKevin Wolf acb->req.nb_sectors = nb_sectors; 281968485420SKevin Wolf acb->req.qiov = qiov; 282068485420SKevin Wolf acb->is_write = is_write; 282168485420SKevin Wolf 282268485420SKevin Wolf co = qemu_coroutine_create(bdrv_co_rw); 282368485420SKevin Wolf qemu_coroutine_enter(co, acb); 282468485420SKevin Wolf 282568485420SKevin Wolf return &acb->common; 282668485420SKevin Wolf } 282768485420SKevin Wolf 282868485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs, 282968485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 283068485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque) 283168485420SKevin Wolf { 283268485420SKevin Wolf return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 283368485420SKevin Wolf false); 283468485420SKevin Wolf } 283568485420SKevin Wolf 283668485420SKevin Wolf static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs, 283768485420SKevin Wolf int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 283868485420SKevin Wolf BlockDriverCompletionFunc *cb, void *opaque) 283968485420SKevin Wolf { 284068485420SKevin Wolf return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 284168485420SKevin Wolf true); 284268485420SKevin Wolf } 284368485420SKevin Wolf 2844b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 2845b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2846b2e12bc6SChristoph Hellwig { 2847b2e12bc6SChristoph Hellwig BlockDriverAIOCBSync *acb; 2848b2e12bc6SChristoph Hellwig 2849b2e12bc6SChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2850b2e12bc6SChristoph Hellwig acb->is_write = 1; /* don't bounce in the completion hadler */ 2851b2e12bc6SChristoph Hellwig acb->qiov = NULL; 2852b2e12bc6SChristoph Hellwig acb->bounce = NULL; 2853b2e12bc6SChristoph Hellwig acb->ret = 0; 2854b2e12bc6SChristoph Hellwig 2855b2e12bc6SChristoph Hellwig if (!acb->bh) 2856b2e12bc6SChristoph Hellwig acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2857b2e12bc6SChristoph Hellwig 2858b2e12bc6SChristoph Hellwig bdrv_flush(bs); 2859b2e12bc6SChristoph Hellwig qemu_bh_schedule(acb->bh); 2860b2e12bc6SChristoph Hellwig return &acb->common; 2861b2e12bc6SChristoph Hellwig } 2862b2e12bc6SChristoph Hellwig 2863016f5cf6SAlexander Graf static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, 2864016f5cf6SAlexander Graf BlockDriverCompletionFunc *cb, void *opaque) 2865016f5cf6SAlexander Graf { 2866016f5cf6SAlexander Graf BlockDriverAIOCBSync *acb; 2867016f5cf6SAlexander Graf 2868016f5cf6SAlexander Graf acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2869016f5cf6SAlexander Graf acb->is_write = 1; /* don't bounce in the completion handler */ 2870016f5cf6SAlexander Graf acb->qiov = NULL; 2871016f5cf6SAlexander Graf acb->bounce = NULL; 2872016f5cf6SAlexander Graf acb->ret = 0; 2873016f5cf6SAlexander Graf 2874016f5cf6SAlexander Graf if (!acb->bh) { 2875016f5cf6SAlexander Graf acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2876016f5cf6SAlexander Graf } 2877016f5cf6SAlexander Graf 2878016f5cf6SAlexander Graf qemu_bh_schedule(acb->bh); 2879016f5cf6SAlexander Graf return &acb->common; 2880016f5cf6SAlexander Graf } 2881016f5cf6SAlexander Graf 288283f64091Sbellard /**************************************************************/ 288383f64091Sbellard /* sync block device emulation */ 288483f64091Sbellard 288583f64091Sbellard static void bdrv_rw_em_cb(void *opaque, int ret) 288683f64091Sbellard { 288783f64091Sbellard *(int *)opaque = ret; 288883f64091Sbellard } 288983f64091Sbellard 289083f64091Sbellard #define NOT_DONE 0x7fffffff 289183f64091Sbellard 289283f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 289383f64091Sbellard uint8_t *buf, int nb_sectors) 289483f64091Sbellard { 2895ce1a14dcSpbrook int async_ret; 2896ce1a14dcSpbrook BlockDriverAIOCB *acb; 2897f141eafeSaliguori struct iovec iov; 2898f141eafeSaliguori QEMUIOVector qiov; 289983f64091Sbellard 290083f64091Sbellard async_ret = NOT_DONE; 29013f4cb3d3Sblueswir1 iov.iov_base = (void *)buf; 2902eb5a3165SJes Sorensen iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; 2903f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 2904f141eafeSaliguori acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors, 290583f64091Sbellard bdrv_rw_em_cb, &async_ret); 290665d6b3d8SKevin Wolf if (acb == NULL) { 290765d6b3d8SKevin Wolf async_ret = -1; 290865d6b3d8SKevin Wolf goto fail; 290965d6b3d8SKevin Wolf } 2910baf35cb9Saliguori 291183f64091Sbellard while (async_ret == NOT_DONE) { 291283f64091Sbellard qemu_aio_wait(); 291383f64091Sbellard } 2914baf35cb9Saliguori 291565d6b3d8SKevin Wolf 291665d6b3d8SKevin Wolf fail: 291783f64091Sbellard return async_ret; 291883f64091Sbellard } 291983f64091Sbellard 292083f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 292183f64091Sbellard const uint8_t *buf, int nb_sectors) 292283f64091Sbellard { 2923ce1a14dcSpbrook int async_ret; 2924ce1a14dcSpbrook BlockDriverAIOCB *acb; 2925f141eafeSaliguori struct iovec iov; 2926f141eafeSaliguori QEMUIOVector qiov; 292783f64091Sbellard 292883f64091Sbellard async_ret = NOT_DONE; 2929f141eafeSaliguori iov.iov_base = (void *)buf; 2930eb5a3165SJes Sorensen iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; 2931f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 2932f141eafeSaliguori acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors, 293383f64091Sbellard bdrv_rw_em_cb, &async_ret); 293465d6b3d8SKevin Wolf if (acb == NULL) { 293565d6b3d8SKevin Wolf async_ret = -1; 293665d6b3d8SKevin Wolf goto fail; 293765d6b3d8SKevin Wolf } 293883f64091Sbellard while (async_ret == NOT_DONE) { 293983f64091Sbellard qemu_aio_wait(); 294083f64091Sbellard } 294165d6b3d8SKevin Wolf 294265d6b3d8SKevin Wolf fail: 294383f64091Sbellard return async_ret; 294483f64091Sbellard } 2945ea2384d3Sbellard 2946ea2384d3Sbellard void bdrv_init(void) 2947ea2384d3Sbellard { 29485efa9d5aSAnthony Liguori module_call_init(MODULE_INIT_BLOCK); 2949ea2384d3Sbellard } 2950ce1a14dcSpbrook 2951eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void) 2952eb852011SMarkus Armbruster { 2953eb852011SMarkus Armbruster use_bdrv_whitelist = 1; 2954eb852011SMarkus Armbruster bdrv_init(); 2955eb852011SMarkus Armbruster } 2956eb852011SMarkus Armbruster 2957c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 29586bbff9a0Saliguori BlockDriverCompletionFunc *cb, void *opaque) 29596bbff9a0Saliguori { 2960ce1a14dcSpbrook BlockDriverAIOCB *acb; 2961ce1a14dcSpbrook 29626bbff9a0Saliguori if (pool->free_aiocb) { 29636bbff9a0Saliguori acb = pool->free_aiocb; 29646bbff9a0Saliguori pool->free_aiocb = acb->next; 2965ce1a14dcSpbrook } else { 29667267c094SAnthony Liguori acb = g_malloc0(pool->aiocb_size); 29676bbff9a0Saliguori acb->pool = pool; 2968ce1a14dcSpbrook } 2969ce1a14dcSpbrook acb->bs = bs; 2970ce1a14dcSpbrook acb->cb = cb; 2971ce1a14dcSpbrook acb->opaque = opaque; 2972ce1a14dcSpbrook return acb; 2973ce1a14dcSpbrook } 2974ce1a14dcSpbrook 2975ce1a14dcSpbrook void qemu_aio_release(void *p) 2976ce1a14dcSpbrook { 29776bbff9a0Saliguori BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 29786bbff9a0Saliguori AIOPool *pool = acb->pool; 29796bbff9a0Saliguori acb->next = pool->free_aiocb; 29806bbff9a0Saliguori pool->free_aiocb = acb; 2981ce1a14dcSpbrook } 298219cb3738Sbellard 298319cb3738Sbellard /**************************************************************/ 2984f9f05dc5SKevin Wolf /* Coroutine block device emulation */ 2985f9f05dc5SKevin Wolf 2986f9f05dc5SKevin Wolf typedef struct CoroutineIOCompletion { 2987f9f05dc5SKevin Wolf Coroutine *coroutine; 2988f9f05dc5SKevin Wolf int ret; 2989f9f05dc5SKevin Wolf } CoroutineIOCompletion; 2990f9f05dc5SKevin Wolf 2991f9f05dc5SKevin Wolf static void bdrv_co_io_em_complete(void *opaque, int ret) 2992f9f05dc5SKevin Wolf { 2993f9f05dc5SKevin Wolf CoroutineIOCompletion *co = opaque; 2994f9f05dc5SKevin Wolf 2995f9f05dc5SKevin Wolf co->ret = ret; 2996f9f05dc5SKevin Wolf qemu_coroutine_enter(co->coroutine, NULL); 2997f9f05dc5SKevin Wolf } 2998f9f05dc5SKevin Wolf 2999f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, 3000f9f05dc5SKevin Wolf int nb_sectors, QEMUIOVector *iov, 3001f9f05dc5SKevin Wolf bool is_write) 3002f9f05dc5SKevin Wolf { 3003f9f05dc5SKevin Wolf CoroutineIOCompletion co = { 3004f9f05dc5SKevin Wolf .coroutine = qemu_coroutine_self(), 3005f9f05dc5SKevin Wolf }; 3006f9f05dc5SKevin Wolf BlockDriverAIOCB *acb; 3007f9f05dc5SKevin Wolf 3008f9f05dc5SKevin Wolf if (is_write) { 3009f9f05dc5SKevin Wolf acb = bdrv_aio_writev(bs, sector_num, iov, nb_sectors, 3010f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 3011f9f05dc5SKevin Wolf } else { 3012f9f05dc5SKevin Wolf acb = bdrv_aio_readv(bs, sector_num, iov, nb_sectors, 3013f9f05dc5SKevin Wolf bdrv_co_io_em_complete, &co); 3014f9f05dc5SKevin Wolf } 3015f9f05dc5SKevin Wolf 301659370aaaSStefan Hajnoczi trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); 3017f9f05dc5SKevin Wolf if (!acb) { 3018f9f05dc5SKevin Wolf return -EIO; 3019f9f05dc5SKevin Wolf } 3020f9f05dc5SKevin Wolf qemu_coroutine_yield(); 3021f9f05dc5SKevin Wolf 3022f9f05dc5SKevin Wolf return co.ret; 3023f9f05dc5SKevin Wolf } 3024f9f05dc5SKevin Wolf 3025f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, 3026f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 3027f9f05dc5SKevin Wolf QEMUIOVector *iov) 3028f9f05dc5SKevin Wolf { 3029f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); 3030f9f05dc5SKevin Wolf } 3031f9f05dc5SKevin Wolf 3032f9f05dc5SKevin Wolf static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, 3033f9f05dc5SKevin Wolf int64_t sector_num, int nb_sectors, 3034f9f05dc5SKevin Wolf QEMUIOVector *iov) 3035f9f05dc5SKevin Wolf { 3036f9f05dc5SKevin Wolf return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); 3037f9f05dc5SKevin Wolf } 3038f9f05dc5SKevin Wolf 3039e7a8a783SKevin Wolf static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs) 3040e7a8a783SKevin Wolf { 3041e7a8a783SKevin Wolf CoroutineIOCompletion co = { 3042e7a8a783SKevin Wolf .coroutine = qemu_coroutine_self(), 3043e7a8a783SKevin Wolf }; 3044e7a8a783SKevin Wolf BlockDriverAIOCB *acb; 3045e7a8a783SKevin Wolf 3046e7a8a783SKevin Wolf acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); 3047e7a8a783SKevin Wolf if (!acb) { 3048e7a8a783SKevin Wolf return -EIO; 3049e7a8a783SKevin Wolf } 3050e7a8a783SKevin Wolf qemu_coroutine_yield(); 3051e7a8a783SKevin Wolf return co.ret; 3052e7a8a783SKevin Wolf } 3053e7a8a783SKevin Wolf 3054f9f05dc5SKevin Wolf /**************************************************************/ 305519cb3738Sbellard /* removable device support */ 305619cb3738Sbellard 305719cb3738Sbellard /** 305819cb3738Sbellard * Return TRUE if the media is present 305919cb3738Sbellard */ 306019cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs) 306119cb3738Sbellard { 306219cb3738Sbellard BlockDriver *drv = bs->drv; 3063a1aff5bfSMarkus Armbruster 306419cb3738Sbellard if (!drv) 306519cb3738Sbellard return 0; 306619cb3738Sbellard if (!drv->bdrv_is_inserted) 3067a1aff5bfSMarkus Armbruster return 1; 3068a1aff5bfSMarkus Armbruster return drv->bdrv_is_inserted(bs); 306919cb3738Sbellard } 307019cb3738Sbellard 307119cb3738Sbellard /** 30728e49ca46SMarkus Armbruster * Return whether the media changed since the last call to this 30738e49ca46SMarkus Armbruster * function, or -ENOTSUP if we don't know. Most drivers don't know. 307419cb3738Sbellard */ 307519cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs) 307619cb3738Sbellard { 307719cb3738Sbellard BlockDriver *drv = bs->drv; 307819cb3738Sbellard 30798e49ca46SMarkus Armbruster if (drv && drv->bdrv_media_changed) { 30808e49ca46SMarkus Armbruster return drv->bdrv_media_changed(bs); 30818e49ca46SMarkus Armbruster } 30828e49ca46SMarkus Armbruster return -ENOTSUP; 308319cb3738Sbellard } 308419cb3738Sbellard 308519cb3738Sbellard /** 308619cb3738Sbellard * If eject_flag is TRUE, eject the media. Otherwise, close the tray 308719cb3738Sbellard */ 3088fdec4404SMarkus Armbruster void bdrv_eject(BlockDriverState *bs, int eject_flag) 308919cb3738Sbellard { 309019cb3738Sbellard BlockDriver *drv = bs->drv; 309119cb3738Sbellard 3092822e1cd1SMarkus Armbruster if (drv && drv->bdrv_eject) { 3093822e1cd1SMarkus Armbruster drv->bdrv_eject(bs, eject_flag); 309419cb3738Sbellard } 309519cb3738Sbellard } 309619cb3738Sbellard 309719cb3738Sbellard /** 309819cb3738Sbellard * Lock or unlock the media (if it is locked, the user won't be able 309919cb3738Sbellard * to eject it manually). 310019cb3738Sbellard */ 3101025e849aSMarkus Armbruster void bdrv_lock_medium(BlockDriverState *bs, bool locked) 310219cb3738Sbellard { 310319cb3738Sbellard BlockDriver *drv = bs->drv; 310419cb3738Sbellard 3105025e849aSMarkus Armbruster trace_bdrv_lock_medium(bs, locked); 3106b8c6d095SStefan Hajnoczi 3107025e849aSMarkus Armbruster if (drv && drv->bdrv_lock_medium) { 3108025e849aSMarkus Armbruster drv->bdrv_lock_medium(bs, locked); 310919cb3738Sbellard } 311019cb3738Sbellard } 3111985a03b0Sths 3112985a03b0Sths /* needed for generic scsi interface */ 3113985a03b0Sths 3114985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 3115985a03b0Sths { 3116985a03b0Sths BlockDriver *drv = bs->drv; 3117985a03b0Sths 3118985a03b0Sths if (drv && drv->bdrv_ioctl) 3119985a03b0Sths return drv->bdrv_ioctl(bs, req, buf); 3120985a03b0Sths return -ENOTSUP; 3121985a03b0Sths } 31227d780669Saliguori 3123221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 3124221f715dSaliguori unsigned long int req, void *buf, 31257d780669Saliguori BlockDriverCompletionFunc *cb, void *opaque) 31267d780669Saliguori { 3127221f715dSaliguori BlockDriver *drv = bs->drv; 31287d780669Saliguori 3129221f715dSaliguori if (drv && drv->bdrv_aio_ioctl) 3130221f715dSaliguori return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 3131221f715dSaliguori return NULL; 31327d780669Saliguori } 3133e268ca52Saliguori 31347b6f9300SMarkus Armbruster void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) 31357b6f9300SMarkus Armbruster { 31367b6f9300SMarkus Armbruster bs->buffer_alignment = align; 31377b6f9300SMarkus Armbruster } 31387cd1e32aSlirans@il.ibm.com 3139e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size) 3140e268ca52Saliguori { 3141e268ca52Saliguori return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 3142e268ca52Saliguori } 31437cd1e32aSlirans@il.ibm.com 31447cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) 31457cd1e32aSlirans@il.ibm.com { 31467cd1e32aSlirans@il.ibm.com int64_t bitmap_size; 3147a55eb92cSJan Kiszka 3148aaa0eb75SLiran Schour bs->dirty_count = 0; 31497cd1e32aSlirans@il.ibm.com if (enable) { 3150c6d22830SJan Kiszka if (!bs->dirty_bitmap) { 3151c6d22830SJan Kiszka bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + 3152c6d22830SJan Kiszka BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; 3153c6d22830SJan Kiszka bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; 31547cd1e32aSlirans@il.ibm.com 31557267c094SAnthony Liguori bs->dirty_bitmap = g_malloc0(bitmap_size); 31567cd1e32aSlirans@il.ibm.com } 31577cd1e32aSlirans@il.ibm.com } else { 3158c6d22830SJan Kiszka if (bs->dirty_bitmap) { 31597267c094SAnthony Liguori g_free(bs->dirty_bitmap); 3160c6d22830SJan Kiszka bs->dirty_bitmap = NULL; 31617cd1e32aSlirans@il.ibm.com } 31627cd1e32aSlirans@il.ibm.com } 31637cd1e32aSlirans@il.ibm.com } 31647cd1e32aSlirans@il.ibm.com 31657cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) 31667cd1e32aSlirans@il.ibm.com { 31676ea44308SJan Kiszka int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; 31687cd1e32aSlirans@il.ibm.com 3169c6d22830SJan Kiszka if (bs->dirty_bitmap && 3170c6d22830SJan Kiszka (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { 31716d59fec1SMarcelo Tosatti return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & 31726d59fec1SMarcelo Tosatti (1UL << (chunk % (sizeof(unsigned long) * 8)))); 31737cd1e32aSlirans@il.ibm.com } else { 31747cd1e32aSlirans@il.ibm.com return 0; 31757cd1e32aSlirans@il.ibm.com } 31767cd1e32aSlirans@il.ibm.com } 31777cd1e32aSlirans@il.ibm.com 31787cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, 31797cd1e32aSlirans@il.ibm.com int nr_sectors) 31807cd1e32aSlirans@il.ibm.com { 31817cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); 31827cd1e32aSlirans@il.ibm.com } 3183aaa0eb75SLiran Schour 3184aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs) 3185aaa0eb75SLiran Schour { 3186aaa0eb75SLiran Schour return bs->dirty_count; 3187aaa0eb75SLiran Schour } 3188f88e1a42SJes Sorensen 3189db593f25SMarcelo Tosatti void bdrv_set_in_use(BlockDriverState *bs, int in_use) 3190db593f25SMarcelo Tosatti { 3191db593f25SMarcelo Tosatti assert(bs->in_use != in_use); 3192db593f25SMarcelo Tosatti bs->in_use = in_use; 3193db593f25SMarcelo Tosatti } 3194db593f25SMarcelo Tosatti 3195db593f25SMarcelo Tosatti int bdrv_in_use(BlockDriverState *bs) 3196db593f25SMarcelo Tosatti { 3197db593f25SMarcelo Tosatti return bs->in_use; 3198db593f25SMarcelo Tosatti } 3199db593f25SMarcelo Tosatti 320028a7282aSLuiz Capitulino void bdrv_iostatus_enable(BlockDriverState *bs) 320128a7282aSLuiz Capitulino { 320228a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 320328a7282aSLuiz Capitulino } 320428a7282aSLuiz Capitulino 320528a7282aSLuiz Capitulino /* The I/O status is only enabled if the drive explicitly 320628a7282aSLuiz Capitulino * enables it _and_ the VM is configured to stop on errors */ 320728a7282aSLuiz Capitulino bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) 320828a7282aSLuiz Capitulino { 320928a7282aSLuiz Capitulino return (bs->iostatus != BDRV_IOS_INVAL && 321028a7282aSLuiz Capitulino (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || 321128a7282aSLuiz Capitulino bs->on_write_error == BLOCK_ERR_STOP_ANY || 321228a7282aSLuiz Capitulino bs->on_read_error == BLOCK_ERR_STOP_ANY)); 321328a7282aSLuiz Capitulino } 321428a7282aSLuiz Capitulino 321528a7282aSLuiz Capitulino void bdrv_iostatus_disable(BlockDriverState *bs) 321628a7282aSLuiz Capitulino { 321728a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_INVAL; 321828a7282aSLuiz Capitulino } 321928a7282aSLuiz Capitulino 322028a7282aSLuiz Capitulino void bdrv_iostatus_reset(BlockDriverState *bs) 322128a7282aSLuiz Capitulino { 322228a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs)) { 322328a7282aSLuiz Capitulino bs->iostatus = BDRV_IOS_OK; 322428a7282aSLuiz Capitulino } 322528a7282aSLuiz Capitulino } 322628a7282aSLuiz Capitulino 322728a7282aSLuiz Capitulino /* XXX: Today this is set by device models because it makes the implementation 322828a7282aSLuiz Capitulino quite simple. However, the block layer knows about the error, so it's 322928a7282aSLuiz Capitulino possible to implement this without device models being involved */ 323028a7282aSLuiz Capitulino void bdrv_iostatus_set_err(BlockDriverState *bs, int error) 323128a7282aSLuiz Capitulino { 323228a7282aSLuiz Capitulino if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) { 323328a7282aSLuiz Capitulino assert(error >= 0); 323428a7282aSLuiz Capitulino bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; 323528a7282aSLuiz Capitulino } 323628a7282aSLuiz Capitulino } 323728a7282aSLuiz Capitulino 3238a597e79cSChristoph Hellwig void 3239a597e79cSChristoph Hellwig bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, 3240a597e79cSChristoph Hellwig enum BlockAcctType type) 3241a597e79cSChristoph Hellwig { 3242a597e79cSChristoph Hellwig assert(type < BDRV_MAX_IOTYPE); 3243a597e79cSChristoph Hellwig 3244a597e79cSChristoph Hellwig cookie->bytes = bytes; 3245c488c7f6SChristoph Hellwig cookie->start_time_ns = get_clock(); 3246a597e79cSChristoph Hellwig cookie->type = type; 3247a597e79cSChristoph Hellwig } 3248a597e79cSChristoph Hellwig 3249a597e79cSChristoph Hellwig void 3250a597e79cSChristoph Hellwig bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) 3251a597e79cSChristoph Hellwig { 3252a597e79cSChristoph Hellwig assert(cookie->type < BDRV_MAX_IOTYPE); 3253a597e79cSChristoph Hellwig 3254a597e79cSChristoph Hellwig bs->nr_bytes[cookie->type] += cookie->bytes; 3255a597e79cSChristoph Hellwig bs->nr_ops[cookie->type]++; 3256c488c7f6SChristoph Hellwig bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; 3257a597e79cSChristoph Hellwig } 3258a597e79cSChristoph Hellwig 3259f88e1a42SJes Sorensen int bdrv_img_create(const char *filename, const char *fmt, 3260f88e1a42SJes Sorensen const char *base_filename, const char *base_fmt, 3261f88e1a42SJes Sorensen char *options, uint64_t img_size, int flags) 3262f88e1a42SJes Sorensen { 3263f88e1a42SJes Sorensen QEMUOptionParameter *param = NULL, *create_options = NULL; 3264d220894eSKevin Wolf QEMUOptionParameter *backing_fmt, *backing_file, *size; 3265f88e1a42SJes Sorensen BlockDriverState *bs = NULL; 3266f88e1a42SJes Sorensen BlockDriver *drv, *proto_drv; 326796df67d1SStefan Hajnoczi BlockDriver *backing_drv = NULL; 3268f88e1a42SJes Sorensen int ret = 0; 3269f88e1a42SJes Sorensen 3270f88e1a42SJes Sorensen /* Find driver and parse its options */ 3271f88e1a42SJes Sorensen drv = bdrv_find_format(fmt); 3272f88e1a42SJes Sorensen if (!drv) { 3273f88e1a42SJes Sorensen error_report("Unknown file format '%s'", fmt); 32744f70f249SJes Sorensen ret = -EINVAL; 3275f88e1a42SJes Sorensen goto out; 3276f88e1a42SJes Sorensen } 3277f88e1a42SJes Sorensen 3278f88e1a42SJes Sorensen proto_drv = bdrv_find_protocol(filename); 3279f88e1a42SJes Sorensen if (!proto_drv) { 3280f88e1a42SJes Sorensen error_report("Unknown protocol '%s'", filename); 32814f70f249SJes Sorensen ret = -EINVAL; 3282f88e1a42SJes Sorensen goto out; 3283f88e1a42SJes Sorensen } 3284f88e1a42SJes Sorensen 3285f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3286f88e1a42SJes Sorensen drv->create_options); 3287f88e1a42SJes Sorensen create_options = append_option_parameters(create_options, 3288f88e1a42SJes Sorensen proto_drv->create_options); 3289f88e1a42SJes Sorensen 3290f88e1a42SJes Sorensen /* Create parameter list with default values */ 3291f88e1a42SJes Sorensen param = parse_option_parameters("", create_options, param); 3292f88e1a42SJes Sorensen 3293f88e1a42SJes Sorensen set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); 3294f88e1a42SJes Sorensen 3295f88e1a42SJes Sorensen /* Parse -o options */ 3296f88e1a42SJes Sorensen if (options) { 3297f88e1a42SJes Sorensen param = parse_option_parameters(options, create_options, param); 3298f88e1a42SJes Sorensen if (param == NULL) { 3299f88e1a42SJes Sorensen error_report("Invalid options for file format '%s'.", fmt); 33004f70f249SJes Sorensen ret = -EINVAL; 3301f88e1a42SJes Sorensen goto out; 3302f88e1a42SJes Sorensen } 3303f88e1a42SJes Sorensen } 3304f88e1a42SJes Sorensen 3305f88e1a42SJes Sorensen if (base_filename) { 3306f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, 3307f88e1a42SJes Sorensen base_filename)) { 3308f88e1a42SJes Sorensen error_report("Backing file not supported for file format '%s'", 3309f88e1a42SJes Sorensen fmt); 33104f70f249SJes Sorensen ret = -EINVAL; 3311f88e1a42SJes Sorensen goto out; 3312f88e1a42SJes Sorensen } 3313f88e1a42SJes Sorensen } 3314f88e1a42SJes Sorensen 3315f88e1a42SJes Sorensen if (base_fmt) { 3316f88e1a42SJes Sorensen if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { 3317f88e1a42SJes Sorensen error_report("Backing file format not supported for file " 3318f88e1a42SJes Sorensen "format '%s'", fmt); 33194f70f249SJes Sorensen ret = -EINVAL; 3320f88e1a42SJes Sorensen goto out; 3321f88e1a42SJes Sorensen } 3322f88e1a42SJes Sorensen } 3323f88e1a42SJes Sorensen 3324792da93aSJes Sorensen backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); 3325792da93aSJes Sorensen if (backing_file && backing_file->value.s) { 3326792da93aSJes Sorensen if (!strcmp(filename, backing_file->value.s)) { 3327792da93aSJes Sorensen error_report("Error: Trying to create an image with the " 3328792da93aSJes Sorensen "same filename as the backing file"); 33294f70f249SJes Sorensen ret = -EINVAL; 3330792da93aSJes Sorensen goto out; 3331792da93aSJes Sorensen } 3332792da93aSJes Sorensen } 3333792da93aSJes Sorensen 3334f88e1a42SJes Sorensen backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); 3335f88e1a42SJes Sorensen if (backing_fmt && backing_fmt->value.s) { 333696df67d1SStefan Hajnoczi backing_drv = bdrv_find_format(backing_fmt->value.s); 333796df67d1SStefan Hajnoczi if (!backing_drv) { 3338f88e1a42SJes Sorensen error_report("Unknown backing file format '%s'", 3339f88e1a42SJes Sorensen backing_fmt->value.s); 33404f70f249SJes Sorensen ret = -EINVAL; 3341f88e1a42SJes Sorensen goto out; 3342f88e1a42SJes Sorensen } 3343f88e1a42SJes Sorensen } 3344f88e1a42SJes Sorensen 3345f88e1a42SJes Sorensen // The size for the image must always be specified, with one exception: 3346f88e1a42SJes Sorensen // If we are using a backing file, we can obtain the size from there 3347d220894eSKevin Wolf size = get_option_parameter(param, BLOCK_OPT_SIZE); 3348d220894eSKevin Wolf if (size && size->value.n == -1) { 3349f88e1a42SJes Sorensen if (backing_file && backing_file->value.s) { 3350f88e1a42SJes Sorensen uint64_t size; 3351f88e1a42SJes Sorensen char buf[32]; 3352f88e1a42SJes Sorensen 3353f88e1a42SJes Sorensen bs = bdrv_new(""); 3354f88e1a42SJes Sorensen 335596df67d1SStefan Hajnoczi ret = bdrv_open(bs, backing_file->value.s, flags, backing_drv); 3356f88e1a42SJes Sorensen if (ret < 0) { 335796df67d1SStefan Hajnoczi error_report("Could not open '%s'", backing_file->value.s); 3358f88e1a42SJes Sorensen goto out; 3359f88e1a42SJes Sorensen } 3360f88e1a42SJes Sorensen bdrv_get_geometry(bs, &size); 3361f88e1a42SJes Sorensen size *= 512; 3362f88e1a42SJes Sorensen 3363f88e1a42SJes Sorensen snprintf(buf, sizeof(buf), "%" PRId64, size); 3364f88e1a42SJes Sorensen set_option_parameter(param, BLOCK_OPT_SIZE, buf); 3365f88e1a42SJes Sorensen } else { 3366f88e1a42SJes Sorensen error_report("Image creation needs a size parameter"); 33674f70f249SJes Sorensen ret = -EINVAL; 3368f88e1a42SJes Sorensen goto out; 3369f88e1a42SJes Sorensen } 3370f88e1a42SJes Sorensen } 3371f88e1a42SJes Sorensen 3372f88e1a42SJes Sorensen printf("Formatting '%s', fmt=%s ", filename, fmt); 3373f88e1a42SJes Sorensen print_option_parameters(param); 3374f88e1a42SJes Sorensen puts(""); 3375f88e1a42SJes Sorensen 3376f88e1a42SJes Sorensen ret = bdrv_create(drv, filename, param); 3377f88e1a42SJes Sorensen 3378f88e1a42SJes Sorensen if (ret < 0) { 3379f88e1a42SJes Sorensen if (ret == -ENOTSUP) { 3380f88e1a42SJes Sorensen error_report("Formatting or formatting option not supported for " 3381f88e1a42SJes Sorensen "file format '%s'", fmt); 3382f88e1a42SJes Sorensen } else if (ret == -EFBIG) { 3383f88e1a42SJes Sorensen error_report("The image size is too large for file format '%s'", 3384f88e1a42SJes Sorensen fmt); 3385f88e1a42SJes Sorensen } else { 3386f88e1a42SJes Sorensen error_report("%s: error while creating %s: %s", filename, fmt, 3387f88e1a42SJes Sorensen strerror(-ret)); 3388f88e1a42SJes Sorensen } 3389f88e1a42SJes Sorensen } 3390f88e1a42SJes Sorensen 3391f88e1a42SJes Sorensen out: 3392f88e1a42SJes Sorensen free_option_parameters(create_options); 3393f88e1a42SJes Sorensen free_option_parameters(param); 3394f88e1a42SJes Sorensen 3395f88e1a42SJes Sorensen if (bs) { 3396f88e1a42SJes Sorensen bdrv_delete(bs); 3397f88e1a42SJes Sorensen } 33984f70f249SJes Sorensen 33994f70f249SJes Sorensen return ret; 3400f88e1a42SJes Sorensen } 3401