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" 26376253ecSaliguori #include "monitor.h" 27ea2384d3Sbellard #include "block_int.h" 285efa9d5aSAnthony Liguori #include "module.h" 29d15e5465SLuiz Capitulino #include "qemu-objects.h" 30fc01f7e7Sbellard 3171e72a19SJuan Quintela #ifdef CONFIG_BSD 327674e7bfSbellard #include <sys/types.h> 337674e7bfSbellard #include <sys/stat.h> 347674e7bfSbellard #include <sys/ioctl.h> 3572cf2d4fSBlue Swirl #include <sys/queue.h> 36c5e97233Sblueswir1 #ifndef __DragonFly__ 377674e7bfSbellard #include <sys/disk.h> 387674e7bfSbellard #endif 39c5e97233Sblueswir1 #endif 407674e7bfSbellard 4149dc768dSaliguori #ifdef _WIN32 4249dc768dSaliguori #include <windows.h> 4349dc768dSaliguori #endif 4449dc768dSaliguori 45f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 46f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 47c87c0672Saliguori BlockDriverCompletionFunc *cb, void *opaque); 48f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 49f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 50ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque); 51b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 52b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque); 5383f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 5483f64091Sbellard uint8_t *buf, int nb_sectors); 5583f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 5683f64091Sbellard const uint8_t *buf, int nb_sectors); 5784a12e66SChristoph Hellwig static BlockDriver *find_protocol(const char *filename); 58ec530c81Sbellard 591b7bdbc1SStefan Hajnoczi static QTAILQ_HEAD(, BlockDriverState) bdrv_states = 601b7bdbc1SStefan Hajnoczi QTAILQ_HEAD_INITIALIZER(bdrv_states); 617ee930d0Sblueswir1 628a22f02aSStefan Hajnoczi static QLIST_HEAD(, BlockDriver) bdrv_drivers = 638a22f02aSStefan Hajnoczi QLIST_HEAD_INITIALIZER(bdrv_drivers); 64ea2384d3Sbellard 65eb852011SMarkus Armbruster /* If non-zero, use only whitelisted block drivers */ 66eb852011SMarkus Armbruster static int use_bdrv_whitelist; 67eb852011SMarkus Armbruster 6883f64091Sbellard int path_is_absolute(const char *path) 6983f64091Sbellard { 7083f64091Sbellard const char *p; 7121664424Sbellard #ifdef _WIN32 7221664424Sbellard /* specific case for names like: "\\.\d:" */ 7321664424Sbellard if (*path == '/' || *path == '\\') 7421664424Sbellard return 1; 7521664424Sbellard #endif 7683f64091Sbellard p = strchr(path, ':'); 7783f64091Sbellard if (p) 7883f64091Sbellard p++; 7983f64091Sbellard else 8083f64091Sbellard p = path; 813b9f94e1Sbellard #ifdef _WIN32 823b9f94e1Sbellard return (*p == '/' || *p == '\\'); 833b9f94e1Sbellard #else 843b9f94e1Sbellard return (*p == '/'); 853b9f94e1Sbellard #endif 8683f64091Sbellard } 8783f64091Sbellard 8883f64091Sbellard /* if filename is absolute, just copy it to dest. Otherwise, build a 8983f64091Sbellard path to it by considering it is relative to base_path. URL are 9083f64091Sbellard supported. */ 9183f64091Sbellard void path_combine(char *dest, int dest_size, 9283f64091Sbellard const char *base_path, 9383f64091Sbellard const char *filename) 9483f64091Sbellard { 9583f64091Sbellard const char *p, *p1; 9683f64091Sbellard int len; 9783f64091Sbellard 9883f64091Sbellard if (dest_size <= 0) 9983f64091Sbellard return; 10083f64091Sbellard if (path_is_absolute(filename)) { 10183f64091Sbellard pstrcpy(dest, dest_size, filename); 10283f64091Sbellard } else { 10383f64091Sbellard p = strchr(base_path, ':'); 10483f64091Sbellard if (p) 10583f64091Sbellard p++; 10683f64091Sbellard else 10783f64091Sbellard p = base_path; 1083b9f94e1Sbellard p1 = strrchr(base_path, '/'); 1093b9f94e1Sbellard #ifdef _WIN32 1103b9f94e1Sbellard { 1113b9f94e1Sbellard const char *p2; 1123b9f94e1Sbellard p2 = strrchr(base_path, '\\'); 1133b9f94e1Sbellard if (!p1 || p2 > p1) 1143b9f94e1Sbellard p1 = p2; 1153b9f94e1Sbellard } 1163b9f94e1Sbellard #endif 11783f64091Sbellard if (p1) 11883f64091Sbellard p1++; 11983f64091Sbellard else 12083f64091Sbellard p1 = base_path; 12183f64091Sbellard if (p1 > p) 12283f64091Sbellard p = p1; 12383f64091Sbellard len = p - base_path; 12483f64091Sbellard if (len > dest_size - 1) 12583f64091Sbellard len = dest_size - 1; 12683f64091Sbellard memcpy(dest, base_path, len); 12783f64091Sbellard dest[len] = '\0'; 12883f64091Sbellard pstrcat(dest, dest_size, filename); 12983f64091Sbellard } 13083f64091Sbellard } 13183f64091Sbellard 1325efa9d5aSAnthony Liguori void bdrv_register(BlockDriver *bdrv) 133ea2384d3Sbellard { 134f141eafeSaliguori if (!bdrv->bdrv_aio_readv) { 13583f64091Sbellard /* add AIO emulation layer */ 136f141eafeSaliguori bdrv->bdrv_aio_readv = bdrv_aio_readv_em; 137f141eafeSaliguori bdrv->bdrv_aio_writev = bdrv_aio_writev_em; 138eda578e5Saliguori } else if (!bdrv->bdrv_read) { 13983f64091Sbellard /* add synchronous IO emulation layer */ 14083f64091Sbellard bdrv->bdrv_read = bdrv_read_em; 14183f64091Sbellard bdrv->bdrv_write = bdrv_write_em; 14283f64091Sbellard } 143b2e12bc6SChristoph Hellwig 144b2e12bc6SChristoph Hellwig if (!bdrv->bdrv_aio_flush) 145b2e12bc6SChristoph Hellwig bdrv->bdrv_aio_flush = bdrv_aio_flush_em; 146b2e12bc6SChristoph Hellwig 1478a22f02aSStefan Hajnoczi QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); 148ea2384d3Sbellard } 149b338082bSbellard 150b338082bSbellard /* create a new block device (by default it is empty) */ 151b338082bSbellard BlockDriverState *bdrv_new(const char *device_name) 152fc01f7e7Sbellard { 1531b7bdbc1SStefan Hajnoczi BlockDriverState *bs; 154b338082bSbellard 155b338082bSbellard bs = qemu_mallocz(sizeof(BlockDriverState)); 156b338082bSbellard pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 157ea2384d3Sbellard if (device_name[0] != '\0') { 1581b7bdbc1SStefan Hajnoczi QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); 159ea2384d3Sbellard } 160b338082bSbellard return bs; 161b338082bSbellard } 162b338082bSbellard 163ea2384d3Sbellard BlockDriver *bdrv_find_format(const char *format_name) 164ea2384d3Sbellard { 165ea2384d3Sbellard BlockDriver *drv1; 1668a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 1678a22f02aSStefan Hajnoczi if (!strcmp(drv1->format_name, format_name)) { 168ea2384d3Sbellard return drv1; 169ea2384d3Sbellard } 1708a22f02aSStefan Hajnoczi } 171ea2384d3Sbellard return NULL; 172ea2384d3Sbellard } 173ea2384d3Sbellard 174eb852011SMarkus Armbruster static int bdrv_is_whitelisted(BlockDriver *drv) 175eb852011SMarkus Armbruster { 176eb852011SMarkus Armbruster static const char *whitelist[] = { 177eb852011SMarkus Armbruster CONFIG_BDRV_WHITELIST 178eb852011SMarkus Armbruster }; 179eb852011SMarkus Armbruster const char **p; 180eb852011SMarkus Armbruster 181eb852011SMarkus Armbruster if (!whitelist[0]) 182eb852011SMarkus Armbruster return 1; /* no whitelist, anything goes */ 183eb852011SMarkus Armbruster 184eb852011SMarkus Armbruster for (p = whitelist; *p; p++) { 185eb852011SMarkus Armbruster if (!strcmp(drv->format_name, *p)) { 186eb852011SMarkus Armbruster return 1; 187eb852011SMarkus Armbruster } 188eb852011SMarkus Armbruster } 189eb852011SMarkus Armbruster return 0; 190eb852011SMarkus Armbruster } 191eb852011SMarkus Armbruster 192eb852011SMarkus Armbruster BlockDriver *bdrv_find_whitelisted_format(const char *format_name) 193eb852011SMarkus Armbruster { 194eb852011SMarkus Armbruster BlockDriver *drv = bdrv_find_format(format_name); 195eb852011SMarkus Armbruster return drv && bdrv_is_whitelisted(drv) ? drv : NULL; 196eb852011SMarkus Armbruster } 197eb852011SMarkus Armbruster 1980e7e1989SKevin Wolf int bdrv_create(BlockDriver *drv, const char* filename, 1990e7e1989SKevin Wolf QEMUOptionParameter *options) 200ea2384d3Sbellard { 201ea2384d3Sbellard if (!drv->bdrv_create) 202ea2384d3Sbellard return -ENOTSUP; 2030e7e1989SKevin Wolf 2040e7e1989SKevin Wolf return drv->bdrv_create(filename, options); 205ea2384d3Sbellard } 206ea2384d3Sbellard 20784a12e66SChristoph Hellwig int bdrv_create_file(const char* filename, QEMUOptionParameter *options) 20884a12e66SChristoph Hellwig { 20984a12e66SChristoph Hellwig BlockDriver *drv; 21084a12e66SChristoph Hellwig 21184a12e66SChristoph Hellwig drv = find_protocol(filename); 21284a12e66SChristoph Hellwig if (drv == NULL) { 21384a12e66SChristoph Hellwig drv = bdrv_find_format("file"); 21484a12e66SChristoph Hellwig } 21584a12e66SChristoph Hellwig 21684a12e66SChristoph Hellwig return bdrv_create(drv, filename, options); 21784a12e66SChristoph Hellwig } 21884a12e66SChristoph Hellwig 219d5249393Sbellard #ifdef _WIN32 22095389c86Sbellard void get_tmp_filename(char *filename, int size) 221d5249393Sbellard { 2223b9f94e1Sbellard char temp_dir[MAX_PATH]; 2233b9f94e1Sbellard 2243b9f94e1Sbellard GetTempPath(MAX_PATH, temp_dir); 2253b9f94e1Sbellard GetTempFileName(temp_dir, "qem", 0, filename); 226d5249393Sbellard } 227d5249393Sbellard #else 22895389c86Sbellard void get_tmp_filename(char *filename, int size) 229ea2384d3Sbellard { 230ea2384d3Sbellard int fd; 2317ccfb2ebSblueswir1 const char *tmpdir; 232d5249393Sbellard /* XXX: race condition possible */ 2330badc1eeSaurel32 tmpdir = getenv("TMPDIR"); 2340badc1eeSaurel32 if (!tmpdir) 2350badc1eeSaurel32 tmpdir = "/tmp"; 2360badc1eeSaurel32 snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 237ea2384d3Sbellard fd = mkstemp(filename); 238ea2384d3Sbellard close(fd); 239ea2384d3Sbellard } 240d5249393Sbellard #endif 241ea2384d3Sbellard 24219cb3738Sbellard #ifdef _WIN32 243f45512feSbellard static int is_windows_drive_prefix(const char *filename) 244f45512feSbellard { 245f45512feSbellard return (((filename[0] >= 'a' && filename[0] <= 'z') || 246f45512feSbellard (filename[0] >= 'A' && filename[0] <= 'Z')) && 247f45512feSbellard filename[1] == ':'); 248f45512feSbellard } 249f45512feSbellard 250508c7cb3SChristoph Hellwig int is_windows_drive(const char *filename) 25119cb3738Sbellard { 252f45512feSbellard if (is_windows_drive_prefix(filename) && 253f45512feSbellard filename[2] == '\0') 25419cb3738Sbellard return 1; 25519cb3738Sbellard if (strstart(filename, "\\\\.\\", NULL) || 25619cb3738Sbellard strstart(filename, "//./", NULL)) 25719cb3738Sbellard return 1; 25819cb3738Sbellard return 0; 25919cb3738Sbellard } 26019cb3738Sbellard #endif 26119cb3738Sbellard 262f3a5d3f8SChristoph Hellwig /* 263f3a5d3f8SChristoph Hellwig * Detect host devices. By convention, /dev/cdrom[N] is always 264f3a5d3f8SChristoph Hellwig * recognized as a host CDROM. 265f3a5d3f8SChristoph Hellwig */ 266f3a5d3f8SChristoph Hellwig static BlockDriver *find_hdev_driver(const char *filename) 267f3a5d3f8SChristoph Hellwig { 268508c7cb3SChristoph Hellwig int score_max = 0, score; 269508c7cb3SChristoph Hellwig BlockDriver *drv = NULL, *d; 270f3a5d3f8SChristoph Hellwig 2718a22f02aSStefan Hajnoczi QLIST_FOREACH(d, &bdrv_drivers, list) { 272508c7cb3SChristoph Hellwig if (d->bdrv_probe_device) { 273508c7cb3SChristoph Hellwig score = d->bdrv_probe_device(filename); 274508c7cb3SChristoph Hellwig if (score > score_max) { 275508c7cb3SChristoph Hellwig score_max = score; 276508c7cb3SChristoph Hellwig drv = d; 277f3a5d3f8SChristoph Hellwig } 278508c7cb3SChristoph Hellwig } 279f3a5d3f8SChristoph Hellwig } 280f3a5d3f8SChristoph Hellwig 281508c7cb3SChristoph Hellwig return drv; 282f3a5d3f8SChristoph Hellwig } 283f3a5d3f8SChristoph Hellwig 28484a12e66SChristoph Hellwig static BlockDriver *find_protocol(const char *filename) 28584a12e66SChristoph Hellwig { 28684a12e66SChristoph Hellwig BlockDriver *drv1; 28784a12e66SChristoph Hellwig char protocol[128]; 28884a12e66SChristoph Hellwig int len; 28984a12e66SChristoph Hellwig const char *p; 29084a12e66SChristoph Hellwig 29184a12e66SChristoph Hellwig #ifdef _WIN32 29284a12e66SChristoph Hellwig if (is_windows_drive(filename) || 29384a12e66SChristoph Hellwig is_windows_drive_prefix(filename)) 29484a12e66SChristoph Hellwig return bdrv_find_format("file"); 29584a12e66SChristoph Hellwig #endif 29684a12e66SChristoph Hellwig p = strchr(filename, ':'); 29784a12e66SChristoph Hellwig if (!p) { 29884a12e66SChristoph Hellwig drv1 = find_hdev_driver(filename); 29984a12e66SChristoph Hellwig if (!drv1) { 30084a12e66SChristoph Hellwig drv1 = bdrv_find_format("file"); 30184a12e66SChristoph Hellwig } 30284a12e66SChristoph Hellwig return drv1; 30384a12e66SChristoph Hellwig } 30484a12e66SChristoph Hellwig len = p - filename; 30584a12e66SChristoph Hellwig if (len > sizeof(protocol) - 1) 30684a12e66SChristoph Hellwig len = sizeof(protocol) - 1; 30784a12e66SChristoph Hellwig memcpy(protocol, filename, len); 30884a12e66SChristoph Hellwig protocol[len] = '\0'; 30984a12e66SChristoph Hellwig QLIST_FOREACH(drv1, &bdrv_drivers, list) { 31084a12e66SChristoph Hellwig if (drv1->protocol_name && 31184a12e66SChristoph Hellwig !strcmp(drv1->protocol_name, protocol)) { 31284a12e66SChristoph Hellwig return drv1; 31384a12e66SChristoph Hellwig } 31484a12e66SChristoph Hellwig } 31584a12e66SChristoph Hellwig return NULL; 31684a12e66SChristoph Hellwig } 31784a12e66SChristoph Hellwig 318ea2384d3Sbellard static BlockDriver *find_image_format(const char *filename) 319ea2384d3Sbellard { 32083f64091Sbellard int ret, score, score_max; 321ea2384d3Sbellard BlockDriver *drv1, *drv; 32283f64091Sbellard uint8_t buf[2048]; 32383f64091Sbellard BlockDriverState *bs; 324ea2384d3Sbellard 32583f64091Sbellard drv = find_protocol(filename); 32619cb3738Sbellard /* no need to test disk image formats for vvfat */ 327c833ab73SAnthony Liguori if (drv && strcmp(drv->format_name, "vvfat") == 0) 32883f64091Sbellard return drv; 32983f64091Sbellard 330f5edb014SNaphtali Sprei ret = bdrv_file_open(&bs, filename, 0); 33183f64091Sbellard if (ret < 0) 3327674e7bfSbellard return NULL; 33383f64091Sbellard ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 33483f64091Sbellard bdrv_delete(bs); 335ea2384d3Sbellard if (ret < 0) { 336ea2384d3Sbellard return NULL; 337ea2384d3Sbellard } 338ea2384d3Sbellard 339ea2384d3Sbellard score_max = 0; 34084a12e66SChristoph Hellwig drv = NULL; 3418a22f02aSStefan Hajnoczi QLIST_FOREACH(drv1, &bdrv_drivers, list) { 34283f64091Sbellard if (drv1->bdrv_probe) { 343ea2384d3Sbellard score = drv1->bdrv_probe(buf, ret, filename); 344ea2384d3Sbellard if (score > score_max) { 345ea2384d3Sbellard score_max = score; 346ea2384d3Sbellard drv = drv1; 347ea2384d3Sbellard } 348ea2384d3Sbellard } 34983f64091Sbellard } 350ea2384d3Sbellard return drv; 351ea2384d3Sbellard } 352ea2384d3Sbellard 353b6ce07aaSKevin Wolf /* 354*57915332SKevin Wolf * Common part for opening disk images and files 355*57915332SKevin Wolf */ 356*57915332SKevin Wolf static int bdrv_open_common(BlockDriverState *bs, const char *filename, 357*57915332SKevin Wolf int flags, BlockDriver *drv) 358*57915332SKevin Wolf { 359*57915332SKevin Wolf int ret, open_flags; 360*57915332SKevin Wolf 361*57915332SKevin Wolf assert(drv != NULL); 362*57915332SKevin Wolf 363*57915332SKevin Wolf bs->is_temporary = 0; 364*57915332SKevin Wolf bs->encrypted = 0; 365*57915332SKevin Wolf bs->valid_key = 0; 366*57915332SKevin Wolf bs->open_flags = flags; 367*57915332SKevin Wolf /* buffer_alignment defaulted to 512, drivers can change this value */ 368*57915332SKevin Wolf bs->buffer_alignment = 512; 369*57915332SKevin Wolf 370*57915332SKevin Wolf pstrcpy(bs->filename, sizeof(bs->filename), filename); 371*57915332SKevin Wolf 372*57915332SKevin Wolf if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { 373*57915332SKevin Wolf return -ENOTSUP; 374*57915332SKevin Wolf } 375*57915332SKevin Wolf 376*57915332SKevin Wolf bs->drv = drv; 377*57915332SKevin Wolf bs->opaque = qemu_mallocz(drv->instance_size); 378*57915332SKevin Wolf 379*57915332SKevin Wolf /* 380*57915332SKevin Wolf * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a 381*57915332SKevin Wolf * write cache to the guest. We do need the fdatasync to flush 382*57915332SKevin Wolf * out transactions for block allocations, and we maybe have a 383*57915332SKevin Wolf * volatile write cache in our backing device to deal with. 384*57915332SKevin Wolf */ 385*57915332SKevin Wolf if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE)) 386*57915332SKevin Wolf bs->enable_write_cache = 1; 387*57915332SKevin Wolf 388*57915332SKevin Wolf /* 389*57915332SKevin Wolf * Clear flags that are internal to the block layer before opening the 390*57915332SKevin Wolf * image. 391*57915332SKevin Wolf */ 392*57915332SKevin Wolf open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 393*57915332SKevin Wolf 394*57915332SKevin Wolf /* 395*57915332SKevin Wolf * Snapshots should be writeable. 396*57915332SKevin Wolf */ 397*57915332SKevin Wolf if (bs->is_temporary) { 398*57915332SKevin Wolf open_flags |= BDRV_O_RDWR; 399*57915332SKevin Wolf } 400*57915332SKevin Wolf 401*57915332SKevin Wolf ret = drv->bdrv_open(bs, filename, open_flags); 402*57915332SKevin Wolf if (ret < 0) { 403*57915332SKevin Wolf goto free_and_fail; 404*57915332SKevin Wolf } 405*57915332SKevin Wolf 406*57915332SKevin Wolf bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); 407*57915332SKevin Wolf if (drv->bdrv_getlength) { 408*57915332SKevin Wolf bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; 409*57915332SKevin Wolf } 410*57915332SKevin Wolf #ifndef _WIN32 411*57915332SKevin Wolf if (bs->is_temporary) { 412*57915332SKevin Wolf unlink(filename); 413*57915332SKevin Wolf } 414*57915332SKevin Wolf #endif 415*57915332SKevin Wolf return 0; 416*57915332SKevin Wolf 417*57915332SKevin Wolf free_and_fail: 418*57915332SKevin Wolf qemu_free(bs->opaque); 419*57915332SKevin Wolf bs->opaque = NULL; 420*57915332SKevin Wolf bs->drv = NULL; 421*57915332SKevin Wolf return ret; 422*57915332SKevin Wolf } 423*57915332SKevin Wolf 424*57915332SKevin Wolf /* 425b6ce07aaSKevin Wolf * Opens a file using a protocol (file, host_device, nbd, ...) 426b6ce07aaSKevin Wolf */ 42783f64091Sbellard int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 428b338082bSbellard { 42983f64091Sbellard BlockDriverState *bs; 4306db95603SChristoph Hellwig BlockDriver *drv; 43183f64091Sbellard int ret; 4323b0d4f61Sbellard 4336db95603SChristoph Hellwig drv = find_protocol(filename); 4346db95603SChristoph Hellwig if (!drv) { 4356db95603SChristoph Hellwig return -ENOENT; 4366db95603SChristoph Hellwig } 4376db95603SChristoph Hellwig 43883f64091Sbellard bs = bdrv_new(""); 439b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 44083f64091Sbellard if (ret < 0) { 44183f64091Sbellard bdrv_delete(bs); 44283f64091Sbellard return ret; 4433b0d4f61Sbellard } 44471d0770cSaliguori bs->growable = 1; 44583f64091Sbellard *pbs = bs; 44683f64091Sbellard return 0; 4473b0d4f61Sbellard } 4483b0d4f61Sbellard 449b6ce07aaSKevin Wolf /* 450b6ce07aaSKevin Wolf * Opens a disk image (raw, qcow2, vmdk, ...) 451b6ce07aaSKevin Wolf */ 452d6e9098eSKevin Wolf int bdrv_open(BlockDriverState *bs, const char *filename, int flags, 453ea2384d3Sbellard BlockDriver *drv) 454ea2384d3Sbellard { 455b6ce07aaSKevin Wolf int ret; 45633e3963eSbellard 45783f64091Sbellard if (flags & BDRV_O_SNAPSHOT) { 458ea2384d3Sbellard BlockDriverState *bs1; 459ea2384d3Sbellard int64_t total_size; 4607c96d46eSaliguori int is_protocol = 0; 46191a073a9SKevin Wolf BlockDriver *bdrv_qcow2; 46291a073a9SKevin Wolf QEMUOptionParameter *options; 463b6ce07aaSKevin Wolf char tmp_filename[PATH_MAX]; 464b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 46533e3963eSbellard 466ea2384d3Sbellard /* if snapshot, we create a temporary backing file and open it 467ea2384d3Sbellard instead of opening 'filename' directly */ 468ea2384d3Sbellard 469ea2384d3Sbellard /* if there is a backing file, use it */ 470ea2384d3Sbellard bs1 = bdrv_new(""); 471d6e9098eSKevin Wolf ret = bdrv_open(bs1, filename, 0, drv); 47251d7c00cSaliguori if (ret < 0) { 473ea2384d3Sbellard bdrv_delete(bs1); 47451d7c00cSaliguori return ret; 475ea2384d3Sbellard } 4766ea44308SJan Kiszka total_size = bdrv_getlength(bs1) >> BDRV_SECTOR_BITS; 4777c96d46eSaliguori 4787c96d46eSaliguori if (bs1->drv && bs1->drv->protocol_name) 4797c96d46eSaliguori is_protocol = 1; 4807c96d46eSaliguori 481ea2384d3Sbellard bdrv_delete(bs1); 482ea2384d3Sbellard 483ea2384d3Sbellard get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 4847c96d46eSaliguori 4857c96d46eSaliguori /* Real path is meaningless for protocols */ 4867c96d46eSaliguori if (is_protocol) 4877c96d46eSaliguori snprintf(backing_filename, sizeof(backing_filename), 4887c96d46eSaliguori "%s", filename); 489114cdfa9SKirill A. Shutemov else if (!realpath(filename, backing_filename)) 490114cdfa9SKirill A. Shutemov return -errno; 4917c96d46eSaliguori 49291a073a9SKevin Wolf bdrv_qcow2 = bdrv_find_format("qcow2"); 49391a073a9SKevin Wolf options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); 49491a073a9SKevin Wolf 49591a073a9SKevin Wolf set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size * 512); 49691a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename); 49791a073a9SKevin Wolf if (drv) { 49891a073a9SKevin Wolf set_option_parameter(options, BLOCK_OPT_BACKING_FMT, 49991a073a9SKevin Wolf drv->format_name); 50091a073a9SKevin Wolf } 50191a073a9SKevin Wolf 50291a073a9SKevin Wolf ret = bdrv_create(bdrv_qcow2, tmp_filename, options); 50351d7c00cSaliguori if (ret < 0) { 50451d7c00cSaliguori return ret; 505ea2384d3Sbellard } 50691a073a9SKevin Wolf 507ea2384d3Sbellard filename = tmp_filename; 50891a073a9SKevin Wolf drv = bdrv_qcow2; 509ea2384d3Sbellard bs->is_temporary = 1; 510ea2384d3Sbellard } 511ea2384d3Sbellard 512b6ce07aaSKevin Wolf /* Find the right image format driver */ 5136db95603SChristoph Hellwig if (!drv) { 514ea2384d3Sbellard drv = find_image_format(filename); 515ea2384d3Sbellard } 5166987307cSChristoph Hellwig 51751d7c00cSaliguori if (!drv) { 51851d7c00cSaliguori ret = -ENOENT; 51951d7c00cSaliguori goto unlink_and_fail; 52083f64091Sbellard } 521b6ce07aaSKevin Wolf 522b6ce07aaSKevin Wolf /* Open the image */ 523b6ce07aaSKevin Wolf ret = bdrv_open_common(bs, filename, flags, drv); 524b6ce07aaSKevin Wolf if (ret < 0) { 5256987307cSChristoph Hellwig goto unlink_and_fail; 5266987307cSChristoph Hellwig } 5276987307cSChristoph Hellwig 528b6ce07aaSKevin Wolf /* If there is a backing file, use it */ 529b6ce07aaSKevin Wolf if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { 530b6ce07aaSKevin Wolf char backing_filename[PATH_MAX]; 531b6ce07aaSKevin Wolf int back_flags; 532b6ce07aaSKevin Wolf BlockDriver *back_drv = NULL; 533b6ce07aaSKevin Wolf 534b6ce07aaSKevin Wolf bs->backing_hd = bdrv_new(""); 535b6ce07aaSKevin Wolf path_combine(backing_filename, sizeof(backing_filename), 536b6ce07aaSKevin Wolf filename, bs->backing_file); 537b6ce07aaSKevin Wolf if (bs->backing_format[0] != '\0') 538b6ce07aaSKevin Wolf back_drv = bdrv_find_format(bs->backing_format); 539b6ce07aaSKevin Wolf 540b6ce07aaSKevin Wolf /* backing files always opened read-only */ 541b6ce07aaSKevin Wolf back_flags = 542b6ce07aaSKevin Wolf flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 543b6ce07aaSKevin Wolf 544b6ce07aaSKevin Wolf ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv); 545b6ce07aaSKevin Wolf if (ret < 0) { 546b6ce07aaSKevin Wolf bdrv_close(bs); 547b6ce07aaSKevin Wolf return ret; 548b6ce07aaSKevin Wolf } 549b6ce07aaSKevin Wolf if (bs->is_temporary) { 550b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); 551b6ce07aaSKevin Wolf } else { 552b6ce07aaSKevin Wolf /* base image inherits from "parent" */ 553b6ce07aaSKevin Wolf bs->backing_hd->keep_read_only = bs->keep_read_only; 554b6ce07aaSKevin Wolf } 555b6ce07aaSKevin Wolf } 556b6ce07aaSKevin Wolf 557b6ce07aaSKevin Wolf if (!bdrv_key_required(bs)) { 558b6ce07aaSKevin Wolf /* call the change callback */ 559b6ce07aaSKevin Wolf bs->media_changed = 1; 560b6ce07aaSKevin Wolf if (bs->change_cb) 561b6ce07aaSKevin Wolf bs->change_cb(bs->change_opaque); 562b6ce07aaSKevin Wolf } 563b6ce07aaSKevin Wolf 564b6ce07aaSKevin Wolf return 0; 565b6ce07aaSKevin Wolf 566b6ce07aaSKevin Wolf unlink_and_fail: 567b6ce07aaSKevin Wolf if (bs->is_temporary) { 568b6ce07aaSKevin Wolf unlink(filename); 569b6ce07aaSKevin Wolf } 570b6ce07aaSKevin Wolf return ret; 571b6ce07aaSKevin Wolf } 572b6ce07aaSKevin Wolf 573fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs) 574fc01f7e7Sbellard { 57519cb3738Sbellard if (bs->drv) { 576ea2384d3Sbellard if (bs->backing_hd) 577ea2384d3Sbellard bdrv_delete(bs->backing_hd); 578ea2384d3Sbellard bs->drv->bdrv_close(bs); 579ea2384d3Sbellard qemu_free(bs->opaque); 580ea2384d3Sbellard #ifdef _WIN32 581ea2384d3Sbellard if (bs->is_temporary) { 582ea2384d3Sbellard unlink(bs->filename); 583ea2384d3Sbellard } 58467b915a5Sbellard #endif 585ea2384d3Sbellard bs->opaque = NULL; 586ea2384d3Sbellard bs->drv = NULL; 587b338082bSbellard 588b338082bSbellard /* call the change callback */ 58919cb3738Sbellard bs->media_changed = 1; 590b338082bSbellard if (bs->change_cb) 591b338082bSbellard bs->change_cb(bs->change_opaque); 592b338082bSbellard } 593b338082bSbellard } 594b338082bSbellard 595b338082bSbellard void bdrv_delete(BlockDriverState *bs) 596b338082bSbellard { 5971b7bdbc1SStefan Hajnoczi /* remove from list, if necessary */ 5981b7bdbc1SStefan Hajnoczi if (bs->device_name[0] != '\0') { 5991b7bdbc1SStefan Hajnoczi QTAILQ_REMOVE(&bdrv_states, bs, list); 6001b7bdbc1SStefan Hajnoczi } 60134c6f050Saurel32 602b338082bSbellard bdrv_close(bs); 603b338082bSbellard qemu_free(bs); 604fc01f7e7Sbellard } 605fc01f7e7Sbellard 606e97fc193Saliguori /* 607e97fc193Saliguori * Run consistency checks on an image 608e97fc193Saliguori * 609e97fc193Saliguori * Returns the number of errors or -errno when an internal error occurs 610e97fc193Saliguori */ 611e97fc193Saliguori int bdrv_check(BlockDriverState *bs) 612e97fc193Saliguori { 613e97fc193Saliguori if (bs->drv->bdrv_check == NULL) { 614e97fc193Saliguori return -ENOTSUP; 615e97fc193Saliguori } 616e97fc193Saliguori 617e97fc193Saliguori return bs->drv->bdrv_check(bs); 618e97fc193Saliguori } 619e97fc193Saliguori 62033e3963eSbellard /* commit COW file into the raw image */ 62133e3963eSbellard int bdrv_commit(BlockDriverState *bs) 62233e3963eSbellard { 62319cb3738Sbellard BlockDriver *drv = bs->drv; 62483f64091Sbellard int64_t i, total_sectors; 6254dca4b63SNaphtali Sprei int n, j, ro, open_flags; 6264dca4b63SNaphtali Sprei int ret = 0, rw_ret = 0; 627ea2384d3Sbellard unsigned char sector[512]; 6284dca4b63SNaphtali Sprei char filename[1024]; 6294dca4b63SNaphtali Sprei BlockDriverState *bs_rw, *bs_ro; 63033e3963eSbellard 63119cb3738Sbellard if (!drv) 63219cb3738Sbellard return -ENOMEDIUM; 63333e3963eSbellard 6344dca4b63SNaphtali Sprei if (!bs->backing_hd) { 6354dca4b63SNaphtali Sprei return -ENOTSUP; 6364dca4b63SNaphtali Sprei } 6374dca4b63SNaphtali Sprei 6384dca4b63SNaphtali Sprei if (bs->backing_hd->keep_read_only) { 639ea2384d3Sbellard return -EACCES; 64033e3963eSbellard } 64133e3963eSbellard 6424dca4b63SNaphtali Sprei ro = bs->backing_hd->read_only; 6434dca4b63SNaphtali Sprei strncpy(filename, bs->backing_hd->filename, sizeof(filename)); 6444dca4b63SNaphtali Sprei open_flags = bs->backing_hd->open_flags; 6454dca4b63SNaphtali Sprei 6464dca4b63SNaphtali Sprei if (ro) { 6474dca4b63SNaphtali Sprei /* re-open as RW */ 6484dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 6494dca4b63SNaphtali Sprei bs->backing_hd = NULL; 6504dca4b63SNaphtali Sprei bs_rw = bdrv_new(""); 651d6e9098eSKevin Wolf rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL); 6524dca4b63SNaphtali Sprei if (rw_ret < 0) { 6534dca4b63SNaphtali Sprei bdrv_delete(bs_rw); 6544dca4b63SNaphtali Sprei /* try to re-open read-only */ 6554dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 656d6e9098eSKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL); 6574dca4b63SNaphtali Sprei if (ret < 0) { 6584dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 6594dca4b63SNaphtali Sprei /* drive not functional anymore */ 6604dca4b63SNaphtali Sprei bs->drv = NULL; 6614dca4b63SNaphtali Sprei return ret; 6624dca4b63SNaphtali Sprei } 6634dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 6644dca4b63SNaphtali Sprei return rw_ret; 6654dca4b63SNaphtali Sprei } 6664dca4b63SNaphtali Sprei bs->backing_hd = bs_rw; 667ea2384d3Sbellard } 668ea2384d3Sbellard 6696ea44308SJan Kiszka total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; 67083f64091Sbellard for (i = 0; i < total_sectors;) { 67119cb3738Sbellard if (drv->bdrv_is_allocated(bs, i, 65536, &n)) { 672ea2384d3Sbellard for(j = 0; j < n; j++) { 67333e3963eSbellard if (bdrv_read(bs, i, sector, 1) != 0) { 6744dca4b63SNaphtali Sprei ret = -EIO; 6754dca4b63SNaphtali Sprei goto ro_cleanup; 67633e3963eSbellard } 67733e3963eSbellard 678ea2384d3Sbellard if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) { 6794dca4b63SNaphtali Sprei ret = -EIO; 6804dca4b63SNaphtali Sprei goto ro_cleanup; 68133e3963eSbellard } 682ea2384d3Sbellard i++; 683ea2384d3Sbellard } 684ea2384d3Sbellard } else { 685ea2384d3Sbellard i += n; 68633e3963eSbellard } 68733e3963eSbellard } 68895389c86Sbellard 6891d44952fSChristoph Hellwig if (drv->bdrv_make_empty) { 6901d44952fSChristoph Hellwig ret = drv->bdrv_make_empty(bs); 6911d44952fSChristoph Hellwig bdrv_flush(bs); 6921d44952fSChristoph Hellwig } 69395389c86Sbellard 6943f5075aeSChristoph Hellwig /* 6953f5075aeSChristoph Hellwig * Make sure all data we wrote to the backing device is actually 6963f5075aeSChristoph Hellwig * stable on disk. 6973f5075aeSChristoph Hellwig */ 6983f5075aeSChristoph Hellwig if (bs->backing_hd) 6993f5075aeSChristoph Hellwig bdrv_flush(bs->backing_hd); 7004dca4b63SNaphtali Sprei 7014dca4b63SNaphtali Sprei ro_cleanup: 7024dca4b63SNaphtali Sprei 7034dca4b63SNaphtali Sprei if (ro) { 7044dca4b63SNaphtali Sprei /* re-open as RO */ 7054dca4b63SNaphtali Sprei bdrv_delete(bs->backing_hd); 7064dca4b63SNaphtali Sprei bs->backing_hd = NULL; 7074dca4b63SNaphtali Sprei bs_ro = bdrv_new(""); 708d6e9098eSKevin Wolf ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL); 7094dca4b63SNaphtali Sprei if (ret < 0) { 7104dca4b63SNaphtali Sprei bdrv_delete(bs_ro); 7114dca4b63SNaphtali Sprei /* drive not functional anymore */ 7124dca4b63SNaphtali Sprei bs->drv = NULL; 7134dca4b63SNaphtali Sprei return ret; 7144dca4b63SNaphtali Sprei } 7154dca4b63SNaphtali Sprei bs->backing_hd = bs_ro; 7164dca4b63SNaphtali Sprei bs->backing_hd->keep_read_only = 0; 7174dca4b63SNaphtali Sprei } 7184dca4b63SNaphtali Sprei 7191d44952fSChristoph Hellwig return ret; 72033e3963eSbellard } 72133e3963eSbellard 722756e6736SKevin Wolf /* 723756e6736SKevin Wolf * Return values: 724756e6736SKevin Wolf * 0 - success 725756e6736SKevin Wolf * -EINVAL - backing format specified, but no file 726756e6736SKevin Wolf * -ENOSPC - can't update the backing file because no space is left in the 727756e6736SKevin Wolf * image file header 728756e6736SKevin Wolf * -ENOTSUP - format driver doesn't support changing the backing file 729756e6736SKevin Wolf */ 730756e6736SKevin Wolf int bdrv_change_backing_file(BlockDriverState *bs, 731756e6736SKevin Wolf const char *backing_file, const char *backing_fmt) 732756e6736SKevin Wolf { 733756e6736SKevin Wolf BlockDriver *drv = bs->drv; 734756e6736SKevin Wolf 735756e6736SKevin Wolf if (drv->bdrv_change_backing_file != NULL) { 736756e6736SKevin Wolf return drv->bdrv_change_backing_file(bs, backing_file, backing_fmt); 737756e6736SKevin Wolf } else { 738756e6736SKevin Wolf return -ENOTSUP; 739756e6736SKevin Wolf } 740756e6736SKevin Wolf } 741756e6736SKevin Wolf 74271d0770cSaliguori static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, 74371d0770cSaliguori size_t size) 74471d0770cSaliguori { 74571d0770cSaliguori int64_t len; 74671d0770cSaliguori 74771d0770cSaliguori if (!bdrv_is_inserted(bs)) 74871d0770cSaliguori return -ENOMEDIUM; 74971d0770cSaliguori 75071d0770cSaliguori if (bs->growable) 75171d0770cSaliguori return 0; 75271d0770cSaliguori 75371d0770cSaliguori len = bdrv_getlength(bs); 75471d0770cSaliguori 755fbb7b4e0SKevin Wolf if (offset < 0) 756fbb7b4e0SKevin Wolf return -EIO; 757fbb7b4e0SKevin Wolf 758fbb7b4e0SKevin Wolf if ((offset > len) || (len - offset < size)) 75971d0770cSaliguori return -EIO; 76071d0770cSaliguori 76171d0770cSaliguori return 0; 76271d0770cSaliguori } 76371d0770cSaliguori 76471d0770cSaliguori static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, 76571d0770cSaliguori int nb_sectors) 76671d0770cSaliguori { 767999dec57Saliguori return bdrv_check_byte_request(bs, sector_num * 512, nb_sectors * 512); 76871d0770cSaliguori } 76971d0770cSaliguori 77019cb3738Sbellard /* return < 0 if error. See bdrv_write() for the return codes */ 771fc01f7e7Sbellard int bdrv_read(BlockDriverState *bs, int64_t sector_num, 772fc01f7e7Sbellard uint8_t *buf, int nb_sectors) 773fc01f7e7Sbellard { 774ea2384d3Sbellard BlockDriver *drv = bs->drv; 775fc01f7e7Sbellard 77619cb3738Sbellard if (!drv) 77719cb3738Sbellard return -ENOMEDIUM; 77871d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 77971d0770cSaliguori return -EIO; 780b338082bSbellard 78183f64091Sbellard return drv->bdrv_read(bs, sector_num, buf, nb_sectors); 78283f64091Sbellard } 783fc01f7e7Sbellard 7847cd1e32aSlirans@il.ibm.com static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, 7857cd1e32aSlirans@il.ibm.com int nb_sectors, int dirty) 7867cd1e32aSlirans@il.ibm.com { 7877cd1e32aSlirans@il.ibm.com int64_t start, end; 788c6d22830SJan Kiszka unsigned long val, idx, bit; 789a55eb92cSJan Kiszka 7906ea44308SJan Kiszka start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; 791c6d22830SJan Kiszka end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK; 7927cd1e32aSlirans@il.ibm.com 7937cd1e32aSlirans@il.ibm.com for (; start <= end; start++) { 794c6d22830SJan Kiszka idx = start / (sizeof(unsigned long) * 8); 795c6d22830SJan Kiszka bit = start % (sizeof(unsigned long) * 8); 796c6d22830SJan Kiszka val = bs->dirty_bitmap[idx]; 797c6d22830SJan Kiszka if (dirty) { 798aaa0eb75SLiran Schour if (!(val & (1 << bit))) { 799aaa0eb75SLiran Schour bs->dirty_count++; 800c6d22830SJan Kiszka val |= 1 << bit; 801aaa0eb75SLiran Schour } 802c6d22830SJan Kiszka } else { 803aaa0eb75SLiran Schour if (val & (1 << bit)) { 804aaa0eb75SLiran Schour bs->dirty_count--; 805c6d22830SJan Kiszka val &= ~(1 << bit); 806c6d22830SJan Kiszka } 807aaa0eb75SLiran Schour } 808c6d22830SJan Kiszka bs->dirty_bitmap[idx] = val; 8097cd1e32aSlirans@il.ibm.com } 8107cd1e32aSlirans@il.ibm.com } 8117cd1e32aSlirans@il.ibm.com 81219cb3738Sbellard /* Return < 0 if error. Important errors are: 81319cb3738Sbellard -EIO generic I/O error (may happen for all errors) 81419cb3738Sbellard -ENOMEDIUM No media inserted. 81519cb3738Sbellard -EINVAL Invalid sector number or nb_sectors 81619cb3738Sbellard -EACCES Trying to write a read-only device 81719cb3738Sbellard */ 818fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num, 819fc01f7e7Sbellard const uint8_t *buf, int nb_sectors) 820fc01f7e7Sbellard { 82183f64091Sbellard BlockDriver *drv = bs->drv; 82219cb3738Sbellard if (!bs->drv) 82319cb3738Sbellard return -ENOMEDIUM; 8240849bf08Sbellard if (bs->read_only) 82519cb3738Sbellard return -EACCES; 82671d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 82771d0770cSaliguori return -EIO; 82871d0770cSaliguori 829c6d22830SJan Kiszka if (bs->dirty_bitmap) { 8307cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 8317cd1e32aSlirans@il.ibm.com } 8327cd1e32aSlirans@il.ibm.com 83383f64091Sbellard return drv->bdrv_write(bs, sector_num, buf, nb_sectors); 83483f64091Sbellard } 83583f64091Sbellard 836eda578e5Saliguori int bdrv_pread(BlockDriverState *bs, int64_t offset, 837eda578e5Saliguori void *buf, int count1) 83883f64091Sbellard { 8396ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 84083f64091Sbellard int len, nb_sectors, count; 84183f64091Sbellard int64_t sector_num; 8429a8c4cceSKevin Wolf int ret; 84383f64091Sbellard 84483f64091Sbellard count = count1; 84583f64091Sbellard /* first read to align to sector start */ 8466ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 84783f64091Sbellard if (len > count) 84883f64091Sbellard len = count; 8496ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 85083f64091Sbellard if (len > 0) { 8519a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 8529a8c4cceSKevin Wolf return ret; 8536ea44308SJan Kiszka memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); 85483f64091Sbellard count -= len; 85583f64091Sbellard if (count == 0) 85683f64091Sbellard return count1; 85783f64091Sbellard sector_num++; 85883f64091Sbellard buf += len; 85983f64091Sbellard } 86083f64091Sbellard 86183f64091Sbellard /* read the sectors "in place" */ 8626ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 86383f64091Sbellard if (nb_sectors > 0) { 8649a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0) 8659a8c4cceSKevin Wolf return ret; 86683f64091Sbellard sector_num += nb_sectors; 8676ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 86883f64091Sbellard buf += len; 86983f64091Sbellard count -= len; 87083f64091Sbellard } 87183f64091Sbellard 87283f64091Sbellard /* add data from the last sector */ 87383f64091Sbellard if (count > 0) { 8749a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 8759a8c4cceSKevin Wolf return ret; 87683f64091Sbellard memcpy(buf, tmp_buf, count); 87783f64091Sbellard } 87883f64091Sbellard return count1; 87983f64091Sbellard } 88083f64091Sbellard 881eda578e5Saliguori int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 882eda578e5Saliguori const void *buf, int count1) 88383f64091Sbellard { 8846ea44308SJan Kiszka uint8_t tmp_buf[BDRV_SECTOR_SIZE]; 88583f64091Sbellard int len, nb_sectors, count; 88683f64091Sbellard int64_t sector_num; 8879a8c4cceSKevin Wolf int ret; 88883f64091Sbellard 88983f64091Sbellard count = count1; 89083f64091Sbellard /* first write to align to sector start */ 8916ea44308SJan Kiszka len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); 89283f64091Sbellard if (len > count) 89383f64091Sbellard len = count; 8946ea44308SJan Kiszka sector_num = offset >> BDRV_SECTOR_BITS; 89583f64091Sbellard if (len > 0) { 8969a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 8979a8c4cceSKevin Wolf return ret; 8986ea44308SJan Kiszka memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len); 8999a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 9009a8c4cceSKevin Wolf return ret; 90183f64091Sbellard count -= len; 90283f64091Sbellard if (count == 0) 90383f64091Sbellard return count1; 90483f64091Sbellard sector_num++; 90583f64091Sbellard buf += len; 90683f64091Sbellard } 90783f64091Sbellard 90883f64091Sbellard /* write the sectors "in place" */ 9096ea44308SJan Kiszka nb_sectors = count >> BDRV_SECTOR_BITS; 91083f64091Sbellard if (nb_sectors > 0) { 9119a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0) 9129a8c4cceSKevin Wolf return ret; 91383f64091Sbellard sector_num += nb_sectors; 9146ea44308SJan Kiszka len = nb_sectors << BDRV_SECTOR_BITS; 91583f64091Sbellard buf += len; 91683f64091Sbellard count -= len; 91783f64091Sbellard } 91883f64091Sbellard 91983f64091Sbellard /* add data from the last sector */ 92083f64091Sbellard if (count > 0) { 9219a8c4cceSKevin Wolf if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) 9229a8c4cceSKevin Wolf return ret; 92383f64091Sbellard memcpy(tmp_buf, buf, count); 9249a8c4cceSKevin Wolf if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) 9259a8c4cceSKevin Wolf return ret; 92683f64091Sbellard } 92783f64091Sbellard return count1; 92883f64091Sbellard } 92983f64091Sbellard 93083f64091Sbellard /** 93183f64091Sbellard * Truncate file to 'offset' bytes (needed only for file protocols) 93283f64091Sbellard */ 93383f64091Sbellard int bdrv_truncate(BlockDriverState *bs, int64_t offset) 93483f64091Sbellard { 93583f64091Sbellard BlockDriver *drv = bs->drv; 93683f64091Sbellard if (!drv) 93719cb3738Sbellard return -ENOMEDIUM; 93883f64091Sbellard if (!drv->bdrv_truncate) 93983f64091Sbellard return -ENOTSUP; 94059f2689dSNaphtali Sprei if (bs->read_only) 94159f2689dSNaphtali Sprei return -EACCES; 94283f64091Sbellard return drv->bdrv_truncate(bs, offset); 94383f64091Sbellard } 94483f64091Sbellard 94583f64091Sbellard /** 94683f64091Sbellard * Length of a file in bytes. Return < 0 if error or unknown. 94783f64091Sbellard */ 94883f64091Sbellard int64_t bdrv_getlength(BlockDriverState *bs) 94983f64091Sbellard { 95083f64091Sbellard BlockDriver *drv = bs->drv; 95183f64091Sbellard if (!drv) 95219cb3738Sbellard return -ENOMEDIUM; 95383f64091Sbellard if (!drv->bdrv_getlength) { 95483f64091Sbellard /* legacy mode */ 9556ea44308SJan Kiszka return bs->total_sectors * BDRV_SECTOR_SIZE; 95683f64091Sbellard } 95783f64091Sbellard return drv->bdrv_getlength(bs); 958fc01f7e7Sbellard } 959fc01f7e7Sbellard 96019cb3738Sbellard /* return 0 as number of sectors if no device present or error */ 96196b8f136Sths void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 962fc01f7e7Sbellard { 96319cb3738Sbellard int64_t length; 96419cb3738Sbellard length = bdrv_getlength(bs); 96519cb3738Sbellard if (length < 0) 96619cb3738Sbellard length = 0; 96719cb3738Sbellard else 9686ea44308SJan Kiszka length = length >> BDRV_SECTOR_BITS; 96919cb3738Sbellard *nb_sectors_ptr = length; 970fc01f7e7Sbellard } 971cf98951bSbellard 972f3d54fc4Saliguori struct partition { 973f3d54fc4Saliguori uint8_t boot_ind; /* 0x80 - active */ 974f3d54fc4Saliguori uint8_t head; /* starting head */ 975f3d54fc4Saliguori uint8_t sector; /* starting sector */ 976f3d54fc4Saliguori uint8_t cyl; /* starting cylinder */ 977f3d54fc4Saliguori uint8_t sys_ind; /* What partition type */ 978f3d54fc4Saliguori uint8_t end_head; /* end head */ 979f3d54fc4Saliguori uint8_t end_sector; /* end sector */ 980f3d54fc4Saliguori uint8_t end_cyl; /* end cylinder */ 981f3d54fc4Saliguori uint32_t start_sect; /* starting sector counting from 0 */ 982f3d54fc4Saliguori uint32_t nr_sects; /* nr of sectors in partition */ 983f3d54fc4Saliguori } __attribute__((packed)); 984f3d54fc4Saliguori 985f3d54fc4Saliguori /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 986f3d54fc4Saliguori static int guess_disk_lchs(BlockDriverState *bs, 987f3d54fc4Saliguori int *pcylinders, int *pheads, int *psectors) 988f3d54fc4Saliguori { 989f3d54fc4Saliguori uint8_t buf[512]; 990f3d54fc4Saliguori int ret, i, heads, sectors, cylinders; 991f3d54fc4Saliguori struct partition *p; 992f3d54fc4Saliguori uint32_t nr_sects; 993a38131b6Sblueswir1 uint64_t nb_sectors; 994f3d54fc4Saliguori 995f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 996f3d54fc4Saliguori 997f3d54fc4Saliguori ret = bdrv_read(bs, 0, buf, 1); 998f3d54fc4Saliguori if (ret < 0) 999f3d54fc4Saliguori return -1; 1000f3d54fc4Saliguori /* test msdos magic */ 1001f3d54fc4Saliguori if (buf[510] != 0x55 || buf[511] != 0xaa) 1002f3d54fc4Saliguori return -1; 1003f3d54fc4Saliguori for(i = 0; i < 4; i++) { 1004f3d54fc4Saliguori p = ((struct partition *)(buf + 0x1be)) + i; 1005f3d54fc4Saliguori nr_sects = le32_to_cpu(p->nr_sects); 1006f3d54fc4Saliguori if (nr_sects && p->end_head) { 1007f3d54fc4Saliguori /* We make the assumption that the partition terminates on 1008f3d54fc4Saliguori a cylinder boundary */ 1009f3d54fc4Saliguori heads = p->end_head + 1; 1010f3d54fc4Saliguori sectors = p->end_sector & 63; 1011f3d54fc4Saliguori if (sectors == 0) 1012f3d54fc4Saliguori continue; 1013f3d54fc4Saliguori cylinders = nb_sectors / (heads * sectors); 1014f3d54fc4Saliguori if (cylinders < 1 || cylinders > 16383) 1015f3d54fc4Saliguori continue; 1016f3d54fc4Saliguori *pheads = heads; 1017f3d54fc4Saliguori *psectors = sectors; 1018f3d54fc4Saliguori *pcylinders = cylinders; 1019f3d54fc4Saliguori #if 0 1020f3d54fc4Saliguori printf("guessed geometry: LCHS=%d %d %d\n", 1021f3d54fc4Saliguori cylinders, heads, sectors); 1022f3d54fc4Saliguori #endif 1023f3d54fc4Saliguori return 0; 1024f3d54fc4Saliguori } 1025f3d54fc4Saliguori } 1026f3d54fc4Saliguori return -1; 1027f3d54fc4Saliguori } 1028f3d54fc4Saliguori 1029f3d54fc4Saliguori void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 1030f3d54fc4Saliguori { 1031f3d54fc4Saliguori int translation, lba_detected = 0; 1032f3d54fc4Saliguori int cylinders, heads, secs; 1033a38131b6Sblueswir1 uint64_t nb_sectors; 1034f3d54fc4Saliguori 1035f3d54fc4Saliguori /* if a geometry hint is available, use it */ 1036f3d54fc4Saliguori bdrv_get_geometry(bs, &nb_sectors); 1037f3d54fc4Saliguori bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 1038f3d54fc4Saliguori translation = bdrv_get_translation_hint(bs); 1039f3d54fc4Saliguori if (cylinders != 0) { 1040f3d54fc4Saliguori *pcyls = cylinders; 1041f3d54fc4Saliguori *pheads = heads; 1042f3d54fc4Saliguori *psecs = secs; 1043f3d54fc4Saliguori } else { 1044f3d54fc4Saliguori if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 1045f3d54fc4Saliguori if (heads > 16) { 1046f3d54fc4Saliguori /* if heads > 16, it means that a BIOS LBA 1047f3d54fc4Saliguori translation was active, so the default 1048f3d54fc4Saliguori hardware geometry is OK */ 1049f3d54fc4Saliguori lba_detected = 1; 1050f3d54fc4Saliguori goto default_geometry; 1051f3d54fc4Saliguori } else { 1052f3d54fc4Saliguori *pcyls = cylinders; 1053f3d54fc4Saliguori *pheads = heads; 1054f3d54fc4Saliguori *psecs = secs; 1055f3d54fc4Saliguori /* disable any translation to be in sync with 1056f3d54fc4Saliguori the logical geometry */ 1057f3d54fc4Saliguori if (translation == BIOS_ATA_TRANSLATION_AUTO) { 1058f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1059f3d54fc4Saliguori BIOS_ATA_TRANSLATION_NONE); 1060f3d54fc4Saliguori } 1061f3d54fc4Saliguori } 1062f3d54fc4Saliguori } else { 1063f3d54fc4Saliguori default_geometry: 1064f3d54fc4Saliguori /* if no geometry, use a standard physical disk geometry */ 1065f3d54fc4Saliguori cylinders = nb_sectors / (16 * 63); 1066f3d54fc4Saliguori 1067f3d54fc4Saliguori if (cylinders > 16383) 1068f3d54fc4Saliguori cylinders = 16383; 1069f3d54fc4Saliguori else if (cylinders < 2) 1070f3d54fc4Saliguori cylinders = 2; 1071f3d54fc4Saliguori *pcyls = cylinders; 1072f3d54fc4Saliguori *pheads = 16; 1073f3d54fc4Saliguori *psecs = 63; 1074f3d54fc4Saliguori if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 1075f3d54fc4Saliguori if ((*pcyls * *pheads) <= 131072) { 1076f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1077f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LARGE); 1078f3d54fc4Saliguori } else { 1079f3d54fc4Saliguori bdrv_set_translation_hint(bs, 1080f3d54fc4Saliguori BIOS_ATA_TRANSLATION_LBA); 1081f3d54fc4Saliguori } 1082f3d54fc4Saliguori } 1083f3d54fc4Saliguori } 1084f3d54fc4Saliguori bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 1085f3d54fc4Saliguori } 1086f3d54fc4Saliguori } 1087f3d54fc4Saliguori 1088b338082bSbellard void bdrv_set_geometry_hint(BlockDriverState *bs, 1089b338082bSbellard int cyls, int heads, int secs) 1090b338082bSbellard { 1091b338082bSbellard bs->cyls = cyls; 1092b338082bSbellard bs->heads = heads; 1093b338082bSbellard bs->secs = secs; 1094b338082bSbellard } 1095b338082bSbellard 1096b338082bSbellard void bdrv_set_type_hint(BlockDriverState *bs, int type) 1097b338082bSbellard { 1098b338082bSbellard bs->type = type; 1099b338082bSbellard bs->removable = ((type == BDRV_TYPE_CDROM || 1100b338082bSbellard type == BDRV_TYPE_FLOPPY)); 1101b338082bSbellard } 1102b338082bSbellard 110346d4767dSbellard void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 110446d4767dSbellard { 110546d4767dSbellard bs->translation = translation; 110646d4767dSbellard } 110746d4767dSbellard 1108b338082bSbellard void bdrv_get_geometry_hint(BlockDriverState *bs, 1109b338082bSbellard int *pcyls, int *pheads, int *psecs) 1110b338082bSbellard { 1111b338082bSbellard *pcyls = bs->cyls; 1112b338082bSbellard *pheads = bs->heads; 1113b338082bSbellard *psecs = bs->secs; 1114b338082bSbellard } 1115b338082bSbellard 1116b338082bSbellard int bdrv_get_type_hint(BlockDriverState *bs) 1117b338082bSbellard { 1118b338082bSbellard return bs->type; 1119b338082bSbellard } 1120b338082bSbellard 112146d4767dSbellard int bdrv_get_translation_hint(BlockDriverState *bs) 112246d4767dSbellard { 112346d4767dSbellard return bs->translation; 112446d4767dSbellard } 112546d4767dSbellard 1126b338082bSbellard int bdrv_is_removable(BlockDriverState *bs) 1127b338082bSbellard { 1128b338082bSbellard return bs->removable; 1129b338082bSbellard } 1130b338082bSbellard 1131b338082bSbellard int bdrv_is_read_only(BlockDriverState *bs) 1132b338082bSbellard { 1133b338082bSbellard return bs->read_only; 1134b338082bSbellard } 1135b338082bSbellard 1136985a03b0Sths int bdrv_is_sg(BlockDriverState *bs) 1137985a03b0Sths { 1138985a03b0Sths return bs->sg; 1139985a03b0Sths } 1140985a03b0Sths 1141e900a7b7SChristoph Hellwig int bdrv_enable_write_cache(BlockDriverState *bs) 1142e900a7b7SChristoph Hellwig { 1143e900a7b7SChristoph Hellwig return bs->enable_write_cache; 1144e900a7b7SChristoph Hellwig } 1145e900a7b7SChristoph Hellwig 114619cb3738Sbellard /* XXX: no longer used */ 1147b338082bSbellard void bdrv_set_change_cb(BlockDriverState *bs, 1148b338082bSbellard void (*change_cb)(void *opaque), void *opaque) 1149b338082bSbellard { 1150b338082bSbellard bs->change_cb = change_cb; 1151b338082bSbellard bs->change_opaque = opaque; 1152b338082bSbellard } 1153b338082bSbellard 1154ea2384d3Sbellard int bdrv_is_encrypted(BlockDriverState *bs) 1155ea2384d3Sbellard { 1156ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) 1157ea2384d3Sbellard return 1; 1158ea2384d3Sbellard return bs->encrypted; 1159ea2384d3Sbellard } 1160ea2384d3Sbellard 1161c0f4ce77Saliguori int bdrv_key_required(BlockDriverState *bs) 1162c0f4ce77Saliguori { 1163c0f4ce77Saliguori BlockDriverState *backing_hd = bs->backing_hd; 1164c0f4ce77Saliguori 1165c0f4ce77Saliguori if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 1166c0f4ce77Saliguori return 1; 1167c0f4ce77Saliguori return (bs->encrypted && !bs->valid_key); 1168c0f4ce77Saliguori } 1169c0f4ce77Saliguori 1170ea2384d3Sbellard int bdrv_set_key(BlockDriverState *bs, const char *key) 1171ea2384d3Sbellard { 1172ea2384d3Sbellard int ret; 1173ea2384d3Sbellard if (bs->backing_hd && bs->backing_hd->encrypted) { 1174ea2384d3Sbellard ret = bdrv_set_key(bs->backing_hd, key); 1175ea2384d3Sbellard if (ret < 0) 1176ea2384d3Sbellard return ret; 1177ea2384d3Sbellard if (!bs->encrypted) 1178ea2384d3Sbellard return 0; 1179ea2384d3Sbellard } 1180fd04a2aeSShahar Havivi if (!bs->encrypted) { 1181fd04a2aeSShahar Havivi return -EINVAL; 1182fd04a2aeSShahar Havivi } else if (!bs->drv || !bs->drv->bdrv_set_key) { 1183fd04a2aeSShahar Havivi return -ENOMEDIUM; 1184fd04a2aeSShahar Havivi } 1185c0f4ce77Saliguori ret = bs->drv->bdrv_set_key(bs, key); 1186bb5fc20fSaliguori if (ret < 0) { 1187bb5fc20fSaliguori bs->valid_key = 0; 1188bb5fc20fSaliguori } else if (!bs->valid_key) { 1189bb5fc20fSaliguori bs->valid_key = 1; 1190bb5fc20fSaliguori /* call the change callback now, we skipped it on open */ 1191bb5fc20fSaliguori bs->media_changed = 1; 1192bb5fc20fSaliguori if (bs->change_cb) 1193bb5fc20fSaliguori bs->change_cb(bs->change_opaque); 1194bb5fc20fSaliguori } 1195c0f4ce77Saliguori return ret; 1196ea2384d3Sbellard } 1197ea2384d3Sbellard 1198ea2384d3Sbellard void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 1199ea2384d3Sbellard { 120019cb3738Sbellard if (!bs->drv) { 1201ea2384d3Sbellard buf[0] = '\0'; 1202ea2384d3Sbellard } else { 1203ea2384d3Sbellard pstrcpy(buf, buf_size, bs->drv->format_name); 1204ea2384d3Sbellard } 1205ea2384d3Sbellard } 1206ea2384d3Sbellard 1207ea2384d3Sbellard void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 1208ea2384d3Sbellard void *opaque) 1209ea2384d3Sbellard { 1210ea2384d3Sbellard BlockDriver *drv; 1211ea2384d3Sbellard 12128a22f02aSStefan Hajnoczi QLIST_FOREACH(drv, &bdrv_drivers, list) { 1213ea2384d3Sbellard it(opaque, drv->format_name); 1214ea2384d3Sbellard } 1215ea2384d3Sbellard } 1216ea2384d3Sbellard 1217b338082bSbellard BlockDriverState *bdrv_find(const char *name) 1218b338082bSbellard { 1219b338082bSbellard BlockDriverState *bs; 1220b338082bSbellard 12211b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 12221b7bdbc1SStefan Hajnoczi if (!strcmp(name, bs->device_name)) { 1223b338082bSbellard return bs; 1224b338082bSbellard } 12251b7bdbc1SStefan Hajnoczi } 1226b338082bSbellard return NULL; 1227b338082bSbellard } 1228b338082bSbellard 122951de9760Saliguori void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 123081d0912dSbellard { 123181d0912dSbellard BlockDriverState *bs; 123281d0912dSbellard 12331b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 123451de9760Saliguori it(opaque, bs); 123581d0912dSbellard } 123681d0912dSbellard } 123781d0912dSbellard 1238ea2384d3Sbellard const char *bdrv_get_device_name(BlockDriverState *bs) 1239ea2384d3Sbellard { 1240ea2384d3Sbellard return bs->device_name; 1241ea2384d3Sbellard } 1242ea2384d3Sbellard 12437a6cba61Spbrook void bdrv_flush(BlockDriverState *bs) 12447a6cba61Spbrook { 12453f5075aeSChristoph Hellwig if (bs->drv && bs->drv->bdrv_flush) 12467a6cba61Spbrook bs->drv->bdrv_flush(bs); 12477a6cba61Spbrook } 12487a6cba61Spbrook 1249c6ca28d6Saliguori void bdrv_flush_all(void) 1250c6ca28d6Saliguori { 1251c6ca28d6Saliguori BlockDriverState *bs; 1252c6ca28d6Saliguori 12531b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1254c6ca28d6Saliguori if (bs->drv && !bdrv_is_read_only(bs) && 12551b7bdbc1SStefan Hajnoczi (!bdrv_is_removable(bs) || bdrv_is_inserted(bs))) { 1256c6ca28d6Saliguori bdrv_flush(bs); 1257c6ca28d6Saliguori } 12581b7bdbc1SStefan Hajnoczi } 12591b7bdbc1SStefan Hajnoczi } 1260c6ca28d6Saliguori 1261f58c7b35Sths /* 1262f58c7b35Sths * Returns true iff the specified sector is present in the disk image. Drivers 1263f58c7b35Sths * not implementing the functionality are assumed to not support backing files, 1264f58c7b35Sths * hence all their sectors are reported as allocated. 1265f58c7b35Sths * 1266f58c7b35Sths * 'pnum' is set to the number of sectors (including and immediately following 1267f58c7b35Sths * the specified sector) that are known to be in the same 1268f58c7b35Sths * allocated/unallocated state. 1269f58c7b35Sths * 1270f58c7b35Sths * 'nb_sectors' is the max value 'pnum' should be set to. 1271f58c7b35Sths */ 1272f58c7b35Sths int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1273f58c7b35Sths int *pnum) 1274f58c7b35Sths { 1275f58c7b35Sths int64_t n; 1276f58c7b35Sths if (!bs->drv->bdrv_is_allocated) { 1277f58c7b35Sths if (sector_num >= bs->total_sectors) { 1278f58c7b35Sths *pnum = 0; 1279f58c7b35Sths return 0; 1280f58c7b35Sths } 1281f58c7b35Sths n = bs->total_sectors - sector_num; 1282f58c7b35Sths *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1283f58c7b35Sths return 1; 1284f58c7b35Sths } 1285f58c7b35Sths return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1286f58c7b35Sths } 1287f58c7b35Sths 12882582bfedSLuiz Capitulino void bdrv_mon_event(const BlockDriverState *bdrv, 12892582bfedSLuiz Capitulino BlockMonEventAction action, int is_read) 12902582bfedSLuiz Capitulino { 12912582bfedSLuiz Capitulino QObject *data; 12922582bfedSLuiz Capitulino const char *action_str; 12932582bfedSLuiz Capitulino 12942582bfedSLuiz Capitulino switch (action) { 12952582bfedSLuiz Capitulino case BDRV_ACTION_REPORT: 12962582bfedSLuiz Capitulino action_str = "report"; 12972582bfedSLuiz Capitulino break; 12982582bfedSLuiz Capitulino case BDRV_ACTION_IGNORE: 12992582bfedSLuiz Capitulino action_str = "ignore"; 13002582bfedSLuiz Capitulino break; 13012582bfedSLuiz Capitulino case BDRV_ACTION_STOP: 13022582bfedSLuiz Capitulino action_str = "stop"; 13032582bfedSLuiz Capitulino break; 13042582bfedSLuiz Capitulino default: 13052582bfedSLuiz Capitulino abort(); 13062582bfedSLuiz Capitulino } 13072582bfedSLuiz Capitulino 13082582bfedSLuiz Capitulino data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", 13092582bfedSLuiz Capitulino bdrv->device_name, 13102582bfedSLuiz Capitulino action_str, 13112582bfedSLuiz Capitulino is_read ? "read" : "write"); 13122582bfedSLuiz Capitulino monitor_protocol_event(QEVENT_BLOCK_IO_ERROR, data); 13132582bfedSLuiz Capitulino 13142582bfedSLuiz Capitulino qobject_decref(data); 13152582bfedSLuiz Capitulino } 13162582bfedSLuiz Capitulino 1317d15e5465SLuiz Capitulino static void bdrv_print_dict(QObject *obj, void *opaque) 1318b338082bSbellard { 1319d15e5465SLuiz Capitulino QDict *bs_dict; 1320d15e5465SLuiz Capitulino Monitor *mon = opaque; 1321b338082bSbellard 1322d15e5465SLuiz Capitulino bs_dict = qobject_to_qdict(obj); 1323d15e5465SLuiz Capitulino 1324d15e5465SLuiz Capitulino monitor_printf(mon, "%s: type=%s removable=%d", 1325d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "device"), 1326d15e5465SLuiz Capitulino qdict_get_str(bs_dict, "type"), 1327d15e5465SLuiz Capitulino qdict_get_bool(bs_dict, "removable")); 1328d15e5465SLuiz Capitulino 1329d15e5465SLuiz Capitulino if (qdict_get_bool(bs_dict, "removable")) { 1330d15e5465SLuiz Capitulino monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); 1331b338082bSbellard } 1332d15e5465SLuiz Capitulino 1333d15e5465SLuiz Capitulino if (qdict_haskey(bs_dict, "inserted")) { 1334d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); 1335d15e5465SLuiz Capitulino 1336376253ecSaliguori monitor_printf(mon, " file="); 1337d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "file")); 1338d15e5465SLuiz Capitulino if (qdict_haskey(qdict, "backing_file")) { 1339376253ecSaliguori monitor_printf(mon, " backing_file="); 1340d15e5465SLuiz Capitulino monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); 1341fef30743Sths } 1342d15e5465SLuiz Capitulino monitor_printf(mon, " ro=%d drv=%s encrypted=%d", 1343d15e5465SLuiz Capitulino qdict_get_bool(qdict, "ro"), 1344d15e5465SLuiz Capitulino qdict_get_str(qdict, "drv"), 1345d15e5465SLuiz Capitulino qdict_get_bool(qdict, "encrypted")); 1346b338082bSbellard } else { 1347376253ecSaliguori monitor_printf(mon, " [not inserted]"); 1348b338082bSbellard } 1349d15e5465SLuiz Capitulino 1350376253ecSaliguori monitor_printf(mon, "\n"); 1351b338082bSbellard } 1352d15e5465SLuiz Capitulino 1353d15e5465SLuiz Capitulino void bdrv_info_print(Monitor *mon, const QObject *data) 1354d15e5465SLuiz Capitulino { 1355d15e5465SLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); 1356d15e5465SLuiz Capitulino } 1357d15e5465SLuiz Capitulino 1358d15e5465SLuiz Capitulino /** 1359d15e5465SLuiz Capitulino * bdrv_info(): Block devices information 1360d15e5465SLuiz Capitulino * 1361d15e5465SLuiz Capitulino * Each block device information is stored in a QDict and the 1362d15e5465SLuiz Capitulino * returned QObject is a QList of all devices. 1363d15e5465SLuiz Capitulino * 1364d15e5465SLuiz Capitulino * The QDict contains the following: 1365d15e5465SLuiz Capitulino * 1366d15e5465SLuiz Capitulino * - "device": device name 1367d15e5465SLuiz Capitulino * - "type": device type 1368d15e5465SLuiz Capitulino * - "removable": true if the device is removable, false otherwise 1369d15e5465SLuiz Capitulino * - "locked": true if the device is locked, false otherwise 1370d15e5465SLuiz Capitulino * - "inserted": only present if the device is inserted, it is a QDict 1371d15e5465SLuiz Capitulino * containing the following: 1372d15e5465SLuiz Capitulino * - "file": device file name 1373d15e5465SLuiz Capitulino * - "ro": true if read-only, false otherwise 1374d15e5465SLuiz Capitulino * - "drv": driver format name 1375d15e5465SLuiz Capitulino * - "backing_file": backing file name if one is used 1376d15e5465SLuiz Capitulino * - "encrypted": true if encrypted, false otherwise 1377d15e5465SLuiz Capitulino * 1378d15e5465SLuiz Capitulino * Example: 1379d15e5465SLuiz Capitulino * 1380d15e5465SLuiz Capitulino * [ { "device": "ide0-hd0", "type": "hd", "removable": false, "locked": false, 1381d15e5465SLuiz Capitulino * "inserted": { "file": "/tmp/foobar", "ro": false, "drv": "qcow2" } }, 1382d15e5465SLuiz Capitulino * { "device": "floppy0", "type": "floppy", "removable": true, 1383d15e5465SLuiz Capitulino * "locked": false } ] 1384d15e5465SLuiz Capitulino */ 1385d15e5465SLuiz Capitulino void bdrv_info(Monitor *mon, QObject **ret_data) 1386d15e5465SLuiz Capitulino { 1387d15e5465SLuiz Capitulino QList *bs_list; 1388d15e5465SLuiz Capitulino BlockDriverState *bs; 1389d15e5465SLuiz Capitulino 1390d15e5465SLuiz Capitulino bs_list = qlist_new(); 1391d15e5465SLuiz Capitulino 13921b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1393d15e5465SLuiz Capitulino QObject *bs_obj; 1394d15e5465SLuiz Capitulino const char *type = "unknown"; 1395d15e5465SLuiz Capitulino 1396d15e5465SLuiz Capitulino switch(bs->type) { 1397d15e5465SLuiz Capitulino case BDRV_TYPE_HD: 1398d15e5465SLuiz Capitulino type = "hd"; 1399d15e5465SLuiz Capitulino break; 1400d15e5465SLuiz Capitulino case BDRV_TYPE_CDROM: 1401d15e5465SLuiz Capitulino type = "cdrom"; 1402d15e5465SLuiz Capitulino break; 1403d15e5465SLuiz Capitulino case BDRV_TYPE_FLOPPY: 1404d15e5465SLuiz Capitulino type = "floppy"; 1405d15e5465SLuiz Capitulino break; 1406d15e5465SLuiz Capitulino } 1407d15e5465SLuiz Capitulino 1408d15e5465SLuiz Capitulino bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, " 1409d15e5465SLuiz Capitulino "'removable': %i, 'locked': %i }", 1410d15e5465SLuiz Capitulino bs->device_name, type, bs->removable, 1411d15e5465SLuiz Capitulino bs->locked); 1412d15e5465SLuiz Capitulino 1413d15e5465SLuiz Capitulino if (bs->drv) { 1414d15e5465SLuiz Capitulino QObject *obj; 1415d15e5465SLuiz Capitulino QDict *bs_dict = qobject_to_qdict(bs_obj); 1416d15e5465SLuiz Capitulino 1417d15e5465SLuiz Capitulino obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " 1418d15e5465SLuiz Capitulino "'encrypted': %i }", 1419d15e5465SLuiz Capitulino bs->filename, bs->read_only, 1420d15e5465SLuiz Capitulino bs->drv->format_name, 1421d15e5465SLuiz Capitulino bdrv_is_encrypted(bs)); 1422d15e5465SLuiz Capitulino if (bs->backing_file[0] != '\0') { 1423d15e5465SLuiz Capitulino QDict *qdict = qobject_to_qdict(obj); 1424d15e5465SLuiz Capitulino qdict_put(qdict, "backing_file", 1425d15e5465SLuiz Capitulino qstring_from_str(bs->backing_file)); 1426d15e5465SLuiz Capitulino } 1427d15e5465SLuiz Capitulino 1428d15e5465SLuiz Capitulino qdict_put_obj(bs_dict, "inserted", obj); 1429d15e5465SLuiz Capitulino } 1430d15e5465SLuiz Capitulino qlist_append_obj(bs_list, bs_obj); 1431d15e5465SLuiz Capitulino } 1432d15e5465SLuiz Capitulino 1433d15e5465SLuiz Capitulino *ret_data = QOBJECT(bs_list); 1434b338082bSbellard } 1435a36e69ddSths 1436218a536aSLuiz Capitulino static void bdrv_stats_iter(QObject *data, void *opaque) 1437a36e69ddSths { 1438218a536aSLuiz Capitulino QDict *qdict; 1439218a536aSLuiz Capitulino Monitor *mon = opaque; 1440218a536aSLuiz Capitulino 1441218a536aSLuiz Capitulino qdict = qobject_to_qdict(data); 1442218a536aSLuiz Capitulino monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 1443218a536aSLuiz Capitulino 1444218a536aSLuiz Capitulino qdict = qobject_to_qdict(qdict_get(qdict, "stats")); 1445218a536aSLuiz Capitulino monitor_printf(mon, " rd_bytes=%" PRId64 1446218a536aSLuiz Capitulino " wr_bytes=%" PRId64 1447218a536aSLuiz Capitulino " rd_operations=%" PRId64 1448218a536aSLuiz Capitulino " wr_operations=%" PRId64 1449218a536aSLuiz Capitulino "\n", 1450218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_bytes"), 1451218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_bytes"), 1452218a536aSLuiz Capitulino qdict_get_int(qdict, "rd_operations"), 1453218a536aSLuiz Capitulino qdict_get_int(qdict, "wr_operations")); 1454218a536aSLuiz Capitulino } 1455218a536aSLuiz Capitulino 1456218a536aSLuiz Capitulino void bdrv_stats_print(Monitor *mon, const QObject *data) 1457218a536aSLuiz Capitulino { 1458218a536aSLuiz Capitulino qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); 1459218a536aSLuiz Capitulino } 1460218a536aSLuiz Capitulino 1461218a536aSLuiz Capitulino /** 1462218a536aSLuiz Capitulino * bdrv_info_stats(): show block device statistics 1463218a536aSLuiz Capitulino * 1464218a536aSLuiz Capitulino * Each device statistic information is stored in a QDict and 1465218a536aSLuiz Capitulino * the returned QObject is a QList of all devices. 1466218a536aSLuiz Capitulino * 1467218a536aSLuiz Capitulino * The QDict contains the following: 1468218a536aSLuiz Capitulino * 1469218a536aSLuiz Capitulino * - "device": device name 1470218a536aSLuiz Capitulino * - "stats": A QDict with the statistics information, it contains: 1471218a536aSLuiz Capitulino * - "rd_bytes": bytes read 1472218a536aSLuiz Capitulino * - "wr_bytes": bytes written 1473218a536aSLuiz Capitulino * - "rd_operations": read operations 1474218a536aSLuiz Capitulino * - "wr_operations": write operations 1475218a536aSLuiz Capitulino * 1476218a536aSLuiz Capitulino * Example: 1477218a536aSLuiz Capitulino * 1478218a536aSLuiz Capitulino * [ { "device": "ide0-hd0", 1479218a536aSLuiz Capitulino * "stats": { "rd_bytes": 512, 1480218a536aSLuiz Capitulino * "wr_bytes": 0, 1481218a536aSLuiz Capitulino * "rd_operations": 1, 1482218a536aSLuiz Capitulino * "wr_operations": 0 } }, 1483218a536aSLuiz Capitulino * { "device": "ide1-cd0", 1484218a536aSLuiz Capitulino * "stats": { "rd_bytes": 0, 1485218a536aSLuiz Capitulino * "wr_bytes": 0, 1486218a536aSLuiz Capitulino * "rd_operations": 0, 1487218a536aSLuiz Capitulino * "wr_operations": 0 } } ] 1488218a536aSLuiz Capitulino */ 1489218a536aSLuiz Capitulino void bdrv_info_stats(Monitor *mon, QObject **ret_data) 1490218a536aSLuiz Capitulino { 1491218a536aSLuiz Capitulino QObject *obj; 1492218a536aSLuiz Capitulino QList *devices; 1493a36e69ddSths BlockDriverState *bs; 1494a36e69ddSths 1495218a536aSLuiz Capitulino devices = qlist_new(); 1496218a536aSLuiz Capitulino 14971b7bdbc1SStefan Hajnoczi QTAILQ_FOREACH(bs, &bdrv_states, list) { 1498218a536aSLuiz Capitulino obj = qobject_from_jsonf("{ 'device': %s, 'stats': {" 1499218a536aSLuiz Capitulino "'rd_bytes': %" PRId64 "," 1500218a536aSLuiz Capitulino "'wr_bytes': %" PRId64 "," 1501218a536aSLuiz Capitulino "'rd_operations': %" PRId64 "," 1502218a536aSLuiz Capitulino "'wr_operations': %" PRId64 1503218a536aSLuiz Capitulino "} }", 1504a36e69ddSths bs->device_name, 1505a36e69ddSths bs->rd_bytes, bs->wr_bytes, 1506a36e69ddSths bs->rd_ops, bs->wr_ops); 1507218a536aSLuiz Capitulino qlist_append_obj(devices, obj); 1508a36e69ddSths } 1509218a536aSLuiz Capitulino 1510218a536aSLuiz Capitulino *ret_data = QOBJECT(devices); 1511a36e69ddSths } 1512ea2384d3Sbellard 1513045df330Saliguori const char *bdrv_get_encrypted_filename(BlockDriverState *bs) 1514045df330Saliguori { 1515045df330Saliguori if (bs->backing_hd && bs->backing_hd->encrypted) 1516045df330Saliguori return bs->backing_file; 1517045df330Saliguori else if (bs->encrypted) 1518045df330Saliguori return bs->filename; 1519045df330Saliguori else 1520045df330Saliguori return NULL; 1521045df330Saliguori } 1522045df330Saliguori 152383f64091Sbellard void bdrv_get_backing_filename(BlockDriverState *bs, 152483f64091Sbellard char *filename, int filename_size) 152583f64091Sbellard { 1526b783e409SKevin Wolf if (!bs->backing_file) { 152783f64091Sbellard pstrcpy(filename, filename_size, ""); 152883f64091Sbellard } else { 152983f64091Sbellard pstrcpy(filename, filename_size, bs->backing_file); 153083f64091Sbellard } 153183f64091Sbellard } 153283f64091Sbellard 1533faea38e7Sbellard int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 1534faea38e7Sbellard const uint8_t *buf, int nb_sectors) 1535faea38e7Sbellard { 1536faea38e7Sbellard BlockDriver *drv = bs->drv; 1537faea38e7Sbellard if (!drv) 153819cb3738Sbellard return -ENOMEDIUM; 1539faea38e7Sbellard if (!drv->bdrv_write_compressed) 1540faea38e7Sbellard return -ENOTSUP; 1541fbb7b4e0SKevin Wolf if (bdrv_check_request(bs, sector_num, nb_sectors)) 1542fbb7b4e0SKevin Wolf return -EIO; 15437cd1e32aSlirans@il.ibm.com 1544c6d22830SJan Kiszka if (bs->dirty_bitmap) { 15457cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 15467cd1e32aSlirans@il.ibm.com } 15477cd1e32aSlirans@il.ibm.com 1548faea38e7Sbellard return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 1549faea38e7Sbellard } 1550faea38e7Sbellard 1551faea38e7Sbellard int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 1552faea38e7Sbellard { 1553faea38e7Sbellard BlockDriver *drv = bs->drv; 1554faea38e7Sbellard if (!drv) 155519cb3738Sbellard return -ENOMEDIUM; 1556faea38e7Sbellard if (!drv->bdrv_get_info) 1557faea38e7Sbellard return -ENOTSUP; 1558faea38e7Sbellard memset(bdi, 0, sizeof(*bdi)); 1559faea38e7Sbellard return drv->bdrv_get_info(bs, bdi); 1560faea38e7Sbellard } 1561faea38e7Sbellard 156245566e9cSChristoph Hellwig int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, 156345566e9cSChristoph Hellwig int64_t pos, int size) 1564178e08a5Saliguori { 1565178e08a5Saliguori BlockDriver *drv = bs->drv; 1566178e08a5Saliguori if (!drv) 1567178e08a5Saliguori return -ENOMEDIUM; 156845566e9cSChristoph Hellwig if (!drv->bdrv_save_vmstate) 1569178e08a5Saliguori return -ENOTSUP; 157045566e9cSChristoph Hellwig return drv->bdrv_save_vmstate(bs, buf, pos, size); 1571178e08a5Saliguori } 1572178e08a5Saliguori 157345566e9cSChristoph Hellwig int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, 157445566e9cSChristoph Hellwig int64_t pos, int size) 1575178e08a5Saliguori { 1576178e08a5Saliguori BlockDriver *drv = bs->drv; 1577178e08a5Saliguori if (!drv) 1578178e08a5Saliguori return -ENOMEDIUM; 157945566e9cSChristoph Hellwig if (!drv->bdrv_load_vmstate) 1580178e08a5Saliguori return -ENOTSUP; 158145566e9cSChristoph Hellwig return drv->bdrv_load_vmstate(bs, buf, pos, size); 1582178e08a5Saliguori } 1583178e08a5Saliguori 15848b9b0cc2SKevin Wolf void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) 15858b9b0cc2SKevin Wolf { 15868b9b0cc2SKevin Wolf BlockDriver *drv = bs->drv; 15878b9b0cc2SKevin Wolf 15888b9b0cc2SKevin Wolf if (!drv || !drv->bdrv_debug_event) { 15898b9b0cc2SKevin Wolf return; 15908b9b0cc2SKevin Wolf } 15918b9b0cc2SKevin Wolf 15928b9b0cc2SKevin Wolf return drv->bdrv_debug_event(bs, event); 15938b9b0cc2SKevin Wolf 15948b9b0cc2SKevin Wolf } 15958b9b0cc2SKevin Wolf 1596faea38e7Sbellard /**************************************************************/ 1597faea38e7Sbellard /* handling of snapshots */ 1598faea38e7Sbellard 1599faea38e7Sbellard int bdrv_snapshot_create(BlockDriverState *bs, 1600faea38e7Sbellard QEMUSnapshotInfo *sn_info) 1601faea38e7Sbellard { 1602faea38e7Sbellard BlockDriver *drv = bs->drv; 1603faea38e7Sbellard if (!drv) 160419cb3738Sbellard return -ENOMEDIUM; 1605faea38e7Sbellard if (!drv->bdrv_snapshot_create) 1606faea38e7Sbellard return -ENOTSUP; 1607faea38e7Sbellard return drv->bdrv_snapshot_create(bs, sn_info); 1608faea38e7Sbellard } 1609faea38e7Sbellard 1610faea38e7Sbellard int bdrv_snapshot_goto(BlockDriverState *bs, 1611faea38e7Sbellard const char *snapshot_id) 1612faea38e7Sbellard { 1613faea38e7Sbellard BlockDriver *drv = bs->drv; 1614faea38e7Sbellard if (!drv) 161519cb3738Sbellard return -ENOMEDIUM; 1616faea38e7Sbellard if (!drv->bdrv_snapshot_goto) 1617faea38e7Sbellard return -ENOTSUP; 1618faea38e7Sbellard return drv->bdrv_snapshot_goto(bs, snapshot_id); 1619faea38e7Sbellard } 1620faea38e7Sbellard 1621faea38e7Sbellard int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 1622faea38e7Sbellard { 1623faea38e7Sbellard BlockDriver *drv = bs->drv; 1624faea38e7Sbellard if (!drv) 162519cb3738Sbellard return -ENOMEDIUM; 1626faea38e7Sbellard if (!drv->bdrv_snapshot_delete) 1627faea38e7Sbellard return -ENOTSUP; 1628faea38e7Sbellard return drv->bdrv_snapshot_delete(bs, snapshot_id); 1629faea38e7Sbellard } 1630faea38e7Sbellard 1631faea38e7Sbellard int bdrv_snapshot_list(BlockDriverState *bs, 1632faea38e7Sbellard QEMUSnapshotInfo **psn_info) 1633faea38e7Sbellard { 1634faea38e7Sbellard BlockDriver *drv = bs->drv; 1635faea38e7Sbellard if (!drv) 163619cb3738Sbellard return -ENOMEDIUM; 1637faea38e7Sbellard if (!drv->bdrv_snapshot_list) 1638faea38e7Sbellard return -ENOTSUP; 1639faea38e7Sbellard return drv->bdrv_snapshot_list(bs, psn_info); 1640faea38e7Sbellard } 1641faea38e7Sbellard 1642faea38e7Sbellard #define NB_SUFFIXES 4 1643faea38e7Sbellard 1644faea38e7Sbellard char *get_human_readable_size(char *buf, int buf_size, int64_t size) 1645faea38e7Sbellard { 1646faea38e7Sbellard static const char suffixes[NB_SUFFIXES] = "KMGT"; 1647faea38e7Sbellard int64_t base; 1648faea38e7Sbellard int i; 1649faea38e7Sbellard 1650faea38e7Sbellard if (size <= 999) { 1651faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64, size); 1652faea38e7Sbellard } else { 1653faea38e7Sbellard base = 1024; 1654faea38e7Sbellard for(i = 0; i < NB_SUFFIXES; i++) { 1655faea38e7Sbellard if (size < (10 * base)) { 1656faea38e7Sbellard snprintf(buf, buf_size, "%0.1f%c", 1657faea38e7Sbellard (double)size / base, 1658faea38e7Sbellard suffixes[i]); 1659faea38e7Sbellard break; 1660faea38e7Sbellard } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 1661faea38e7Sbellard snprintf(buf, buf_size, "%" PRId64 "%c", 1662faea38e7Sbellard ((size + (base >> 1)) / base), 1663faea38e7Sbellard suffixes[i]); 1664faea38e7Sbellard break; 1665faea38e7Sbellard } 1666faea38e7Sbellard base = base * 1024; 1667faea38e7Sbellard } 1668faea38e7Sbellard } 1669faea38e7Sbellard return buf; 1670faea38e7Sbellard } 1671faea38e7Sbellard 1672faea38e7Sbellard char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 1673faea38e7Sbellard { 1674faea38e7Sbellard char buf1[128], date_buf[128], clock_buf[128]; 16753b9f94e1Sbellard #ifdef _WIN32 16763b9f94e1Sbellard struct tm *ptm; 16773b9f94e1Sbellard #else 1678faea38e7Sbellard struct tm tm; 16793b9f94e1Sbellard #endif 1680faea38e7Sbellard time_t ti; 1681faea38e7Sbellard int64_t secs; 1682faea38e7Sbellard 1683faea38e7Sbellard if (!sn) { 1684faea38e7Sbellard snprintf(buf, buf_size, 1685faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 1686faea38e7Sbellard "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 1687faea38e7Sbellard } else { 1688faea38e7Sbellard ti = sn->date_sec; 16893b9f94e1Sbellard #ifdef _WIN32 16903b9f94e1Sbellard ptm = localtime(&ti); 16913b9f94e1Sbellard strftime(date_buf, sizeof(date_buf), 16923b9f94e1Sbellard "%Y-%m-%d %H:%M:%S", ptm); 16933b9f94e1Sbellard #else 1694faea38e7Sbellard localtime_r(&ti, &tm); 1695faea38e7Sbellard strftime(date_buf, sizeof(date_buf), 1696faea38e7Sbellard "%Y-%m-%d %H:%M:%S", &tm); 16973b9f94e1Sbellard #endif 1698faea38e7Sbellard secs = sn->vm_clock_nsec / 1000000000; 1699faea38e7Sbellard snprintf(clock_buf, sizeof(clock_buf), 1700faea38e7Sbellard "%02d:%02d:%02d.%03d", 1701faea38e7Sbellard (int)(secs / 3600), 1702faea38e7Sbellard (int)((secs / 60) % 60), 1703faea38e7Sbellard (int)(secs % 60), 1704faea38e7Sbellard (int)((sn->vm_clock_nsec / 1000000) % 1000)); 1705faea38e7Sbellard snprintf(buf, buf_size, 1706faea38e7Sbellard "%-10s%-20s%7s%20s%15s", 1707faea38e7Sbellard sn->id_str, sn->name, 1708faea38e7Sbellard get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 1709faea38e7Sbellard date_buf, 1710faea38e7Sbellard clock_buf); 1711faea38e7Sbellard } 1712faea38e7Sbellard return buf; 1713faea38e7Sbellard } 1714faea38e7Sbellard 171583f64091Sbellard 1716ea2384d3Sbellard /**************************************************************/ 171783f64091Sbellard /* async I/Os */ 1718ea2384d3Sbellard 17193b69e4b9Saliguori BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 1720f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 172183f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 1722ea2384d3Sbellard { 172383f64091Sbellard BlockDriver *drv = bs->drv; 1724a36e69ddSths BlockDriverAIOCB *ret; 1725ea2384d3Sbellard 172619cb3738Sbellard if (!drv) 1727ce1a14dcSpbrook return NULL; 172871d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 172971d0770cSaliguori return NULL; 173083f64091Sbellard 1731f141eafeSaliguori ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, 1732f141eafeSaliguori cb, opaque); 1733a36e69ddSths 1734a36e69ddSths if (ret) { 1735a36e69ddSths /* Update stats even though technically transfer has not happened. */ 17366ea44308SJan Kiszka bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; 1737a36e69ddSths bs->rd_ops ++; 1738a36e69ddSths } 1739a36e69ddSths 1740a36e69ddSths return ret; 174183f64091Sbellard } 174283f64091Sbellard 1743f141eafeSaliguori BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 1744f141eafeSaliguori QEMUIOVector *qiov, int nb_sectors, 174583f64091Sbellard BlockDriverCompletionFunc *cb, void *opaque) 17467674e7bfSbellard { 174783f64091Sbellard BlockDriver *drv = bs->drv; 1748a36e69ddSths BlockDriverAIOCB *ret; 174983f64091Sbellard 175019cb3738Sbellard if (!drv) 1751ce1a14dcSpbrook return NULL; 175283f64091Sbellard if (bs->read_only) 1753ce1a14dcSpbrook return NULL; 175471d0770cSaliguori if (bdrv_check_request(bs, sector_num, nb_sectors)) 175571d0770cSaliguori return NULL; 175683f64091Sbellard 1757c6d22830SJan Kiszka if (bs->dirty_bitmap) { 17587cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, sector_num, nb_sectors, 1); 17597cd1e32aSlirans@il.ibm.com } 17607cd1e32aSlirans@il.ibm.com 1761f141eafeSaliguori ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, 1762f141eafeSaliguori cb, opaque); 1763a36e69ddSths 1764a36e69ddSths if (ret) { 1765a36e69ddSths /* Update stats even though technically transfer has not happened. */ 17666ea44308SJan Kiszka bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; 1767a36e69ddSths bs->wr_ops ++; 1768a36e69ddSths } 1769a36e69ddSths 1770a36e69ddSths return ret; 177183f64091Sbellard } 177283f64091Sbellard 177340b4f539SKevin Wolf 177440b4f539SKevin Wolf typedef struct MultiwriteCB { 177540b4f539SKevin Wolf int error; 177640b4f539SKevin Wolf int num_requests; 177740b4f539SKevin Wolf int num_callbacks; 177840b4f539SKevin Wolf struct { 177940b4f539SKevin Wolf BlockDriverCompletionFunc *cb; 178040b4f539SKevin Wolf void *opaque; 178140b4f539SKevin Wolf QEMUIOVector *free_qiov; 178240b4f539SKevin Wolf void *free_buf; 178340b4f539SKevin Wolf } callbacks[]; 178440b4f539SKevin Wolf } MultiwriteCB; 178540b4f539SKevin Wolf 178640b4f539SKevin Wolf static void multiwrite_user_cb(MultiwriteCB *mcb) 178740b4f539SKevin Wolf { 178840b4f539SKevin Wolf int i; 178940b4f539SKevin Wolf 179040b4f539SKevin Wolf for (i = 0; i < mcb->num_callbacks; i++) { 179140b4f539SKevin Wolf mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); 17921e1ea48dSStefan Hajnoczi if (mcb->callbacks[i].free_qiov) { 17931e1ea48dSStefan Hajnoczi qemu_iovec_destroy(mcb->callbacks[i].free_qiov); 17941e1ea48dSStefan Hajnoczi } 179540b4f539SKevin Wolf qemu_free(mcb->callbacks[i].free_qiov); 1796f8a83245SHerve Poussineau qemu_vfree(mcb->callbacks[i].free_buf); 179740b4f539SKevin Wolf } 179840b4f539SKevin Wolf } 179940b4f539SKevin Wolf 180040b4f539SKevin Wolf static void multiwrite_cb(void *opaque, int ret) 180140b4f539SKevin Wolf { 180240b4f539SKevin Wolf MultiwriteCB *mcb = opaque; 180340b4f539SKevin Wolf 1804cb6d3ca0SKevin Wolf if (ret < 0 && !mcb->error) { 180540b4f539SKevin Wolf mcb->error = ret; 180640b4f539SKevin Wolf multiwrite_user_cb(mcb); 180740b4f539SKevin Wolf } 180840b4f539SKevin Wolf 180940b4f539SKevin Wolf mcb->num_requests--; 181040b4f539SKevin Wolf if (mcb->num_requests == 0) { 181140b4f539SKevin Wolf if (mcb->error == 0) { 181240b4f539SKevin Wolf multiwrite_user_cb(mcb); 181340b4f539SKevin Wolf } 181440b4f539SKevin Wolf qemu_free(mcb); 181540b4f539SKevin Wolf } 181640b4f539SKevin Wolf } 181740b4f539SKevin Wolf 181840b4f539SKevin Wolf static int multiwrite_req_compare(const void *a, const void *b) 181940b4f539SKevin Wolf { 182040b4f539SKevin Wolf return (((BlockRequest*) a)->sector - ((BlockRequest*) b)->sector); 182140b4f539SKevin Wolf } 182240b4f539SKevin Wolf 182340b4f539SKevin Wolf /* 182440b4f539SKevin Wolf * Takes a bunch of requests and tries to merge them. Returns the number of 182540b4f539SKevin Wolf * requests that remain after merging. 182640b4f539SKevin Wolf */ 182740b4f539SKevin Wolf static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, 182840b4f539SKevin Wolf int num_reqs, MultiwriteCB *mcb) 182940b4f539SKevin Wolf { 183040b4f539SKevin Wolf int i, outidx; 183140b4f539SKevin Wolf 183240b4f539SKevin Wolf // Sort requests by start sector 183340b4f539SKevin Wolf qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); 183440b4f539SKevin Wolf 183540b4f539SKevin Wolf // Check if adjacent requests touch the same clusters. If so, combine them, 183640b4f539SKevin Wolf // filling up gaps with zero sectors. 183740b4f539SKevin Wolf outidx = 0; 183840b4f539SKevin Wolf for (i = 1; i < num_reqs; i++) { 183940b4f539SKevin Wolf int merge = 0; 184040b4f539SKevin Wolf int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; 184140b4f539SKevin Wolf 184240b4f539SKevin Wolf // This handles the cases that are valid for all block drivers, namely 184340b4f539SKevin Wolf // exactly sequential writes and overlapping writes. 184440b4f539SKevin Wolf if (reqs[i].sector <= oldreq_last) { 184540b4f539SKevin Wolf merge = 1; 184640b4f539SKevin Wolf } 184740b4f539SKevin Wolf 184840b4f539SKevin Wolf // The block driver may decide that it makes sense to combine requests 184940b4f539SKevin Wolf // even if there is a gap of some sectors between them. In this case, 185040b4f539SKevin Wolf // the gap is filled with zeros (therefore only applicable for yet 185140b4f539SKevin Wolf // unused space in format like qcow2). 185240b4f539SKevin Wolf if (!merge && bs->drv->bdrv_merge_requests) { 185340b4f539SKevin Wolf merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); 185440b4f539SKevin Wolf } 185540b4f539SKevin Wolf 1856e2a305fbSChristoph Hellwig if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { 1857e2a305fbSChristoph Hellwig merge = 0; 1858e2a305fbSChristoph Hellwig } 1859e2a305fbSChristoph Hellwig 186040b4f539SKevin Wolf if (merge) { 186140b4f539SKevin Wolf size_t size; 186240b4f539SKevin Wolf QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov)); 186340b4f539SKevin Wolf qemu_iovec_init(qiov, 186440b4f539SKevin Wolf reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); 186540b4f539SKevin Wolf 186640b4f539SKevin Wolf // Add the first request to the merged one. If the requests are 186740b4f539SKevin Wolf // overlapping, drop the last sectors of the first request. 186840b4f539SKevin Wolf size = (reqs[i].sector - reqs[outidx].sector) << 9; 186940b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[outidx].qiov, size); 187040b4f539SKevin Wolf 187140b4f539SKevin Wolf // We might need to add some zeros between the two requests 187240b4f539SKevin Wolf if (reqs[i].sector > oldreq_last) { 187340b4f539SKevin Wolf size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9; 187440b4f539SKevin Wolf uint8_t *buf = qemu_blockalign(bs, zero_bytes); 187540b4f539SKevin Wolf memset(buf, 0, zero_bytes); 187640b4f539SKevin Wolf qemu_iovec_add(qiov, buf, zero_bytes); 187740b4f539SKevin Wolf mcb->callbacks[i].free_buf = buf; 187840b4f539SKevin Wolf } 187940b4f539SKevin Wolf 188040b4f539SKevin Wolf // Add the second request 188140b4f539SKevin Wolf qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size); 188240b4f539SKevin Wolf 188340b4f539SKevin Wolf reqs[outidx].nb_sectors += reqs[i].nb_sectors; 188440b4f539SKevin Wolf reqs[outidx].qiov = qiov; 188540b4f539SKevin Wolf 188640b4f539SKevin Wolf mcb->callbacks[i].free_qiov = reqs[outidx].qiov; 188740b4f539SKevin Wolf } else { 188840b4f539SKevin Wolf outidx++; 188940b4f539SKevin Wolf reqs[outidx].sector = reqs[i].sector; 189040b4f539SKevin Wolf reqs[outidx].nb_sectors = reqs[i].nb_sectors; 189140b4f539SKevin Wolf reqs[outidx].qiov = reqs[i].qiov; 189240b4f539SKevin Wolf } 189340b4f539SKevin Wolf } 189440b4f539SKevin Wolf 189540b4f539SKevin Wolf return outidx + 1; 189640b4f539SKevin Wolf } 189740b4f539SKevin Wolf 189840b4f539SKevin Wolf /* 189940b4f539SKevin Wolf * Submit multiple AIO write requests at once. 190040b4f539SKevin Wolf * 190140b4f539SKevin Wolf * On success, the function returns 0 and all requests in the reqs array have 190240b4f539SKevin Wolf * been submitted. In error case this function returns -1, and any of the 190340b4f539SKevin Wolf * requests may or may not be submitted yet. In particular, this means that the 190440b4f539SKevin Wolf * callback will be called for some of the requests, for others it won't. The 190540b4f539SKevin Wolf * caller must check the error field of the BlockRequest to wait for the right 190640b4f539SKevin Wolf * callbacks (if error != 0, no callback will be called). 190740b4f539SKevin Wolf * 190840b4f539SKevin Wolf * The implementation may modify the contents of the reqs array, e.g. to merge 190940b4f539SKevin Wolf * requests. However, the fields opaque and error are left unmodified as they 191040b4f539SKevin Wolf * are used to signal failure for a single request to the caller. 191140b4f539SKevin Wolf */ 191240b4f539SKevin Wolf int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) 191340b4f539SKevin Wolf { 191440b4f539SKevin Wolf BlockDriverAIOCB *acb; 191540b4f539SKevin Wolf MultiwriteCB *mcb; 191640b4f539SKevin Wolf int i; 191740b4f539SKevin Wolf 191840b4f539SKevin Wolf if (num_reqs == 0) { 191940b4f539SKevin Wolf return 0; 192040b4f539SKevin Wolf } 192140b4f539SKevin Wolf 192240b4f539SKevin Wolf // Create MultiwriteCB structure 192340b4f539SKevin Wolf mcb = qemu_mallocz(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); 192440b4f539SKevin Wolf mcb->num_requests = 0; 192540b4f539SKevin Wolf mcb->num_callbacks = num_reqs; 192640b4f539SKevin Wolf 192740b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 192840b4f539SKevin Wolf mcb->callbacks[i].cb = reqs[i].cb; 192940b4f539SKevin Wolf mcb->callbacks[i].opaque = reqs[i].opaque; 193040b4f539SKevin Wolf } 193140b4f539SKevin Wolf 193240b4f539SKevin Wolf // Check for mergable requests 193340b4f539SKevin Wolf num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); 193440b4f539SKevin Wolf 193540b4f539SKevin Wolf // Run the aio requests 193640b4f539SKevin Wolf for (i = 0; i < num_reqs; i++) { 193740b4f539SKevin Wolf acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, 193840b4f539SKevin Wolf reqs[i].nb_sectors, multiwrite_cb, mcb); 193940b4f539SKevin Wolf 194040b4f539SKevin Wolf if (acb == NULL) { 194140b4f539SKevin Wolf // We can only fail the whole thing if no request has been 194240b4f539SKevin Wolf // submitted yet. Otherwise we'll wait for the submitted AIOs to 194340b4f539SKevin Wolf // complete and report the error in the callback. 194440b4f539SKevin Wolf if (mcb->num_requests == 0) { 19450f0b604bSKevin Wolf reqs[i].error = -EIO; 194640b4f539SKevin Wolf goto fail; 194740b4f539SKevin Wolf } else { 19487eb58a6cSKevin Wolf mcb->num_requests++; 19497eb58a6cSKevin Wolf multiwrite_cb(mcb, -EIO); 195040b4f539SKevin Wolf break; 195140b4f539SKevin Wolf } 195240b4f539SKevin Wolf } else { 195340b4f539SKevin Wolf mcb->num_requests++; 195440b4f539SKevin Wolf } 195540b4f539SKevin Wolf } 195640b4f539SKevin Wolf 195740b4f539SKevin Wolf return 0; 195840b4f539SKevin Wolf 195940b4f539SKevin Wolf fail: 196040b4f539SKevin Wolf free(mcb); 196140b4f539SKevin Wolf return -1; 196240b4f539SKevin Wolf } 196340b4f539SKevin Wolf 1964b2e12bc6SChristoph Hellwig BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 1965b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 1966b2e12bc6SChristoph Hellwig { 1967b2e12bc6SChristoph Hellwig BlockDriver *drv = bs->drv; 1968b2e12bc6SChristoph Hellwig 1969b2e12bc6SChristoph Hellwig if (!drv) 1970b2e12bc6SChristoph Hellwig return NULL; 1971b2e12bc6SChristoph Hellwig return drv->bdrv_aio_flush(bs, cb, opaque); 1972b2e12bc6SChristoph Hellwig } 1973b2e12bc6SChristoph Hellwig 197483f64091Sbellard void bdrv_aio_cancel(BlockDriverAIOCB *acb) 197583f64091Sbellard { 19766bbff9a0Saliguori acb->pool->cancel(acb); 197783f64091Sbellard } 197883f64091Sbellard 197983f64091Sbellard 198083f64091Sbellard /**************************************************************/ 198183f64091Sbellard /* async block device emulation */ 198283f64091Sbellard 1983c16b5a2cSChristoph Hellwig typedef struct BlockDriverAIOCBSync { 1984c16b5a2cSChristoph Hellwig BlockDriverAIOCB common; 1985c16b5a2cSChristoph Hellwig QEMUBH *bh; 1986c16b5a2cSChristoph Hellwig int ret; 1987c16b5a2cSChristoph Hellwig /* vector translation state */ 1988c16b5a2cSChristoph Hellwig QEMUIOVector *qiov; 1989c16b5a2cSChristoph Hellwig uint8_t *bounce; 1990c16b5a2cSChristoph Hellwig int is_write; 1991c16b5a2cSChristoph Hellwig } BlockDriverAIOCBSync; 1992c16b5a2cSChristoph Hellwig 1993c16b5a2cSChristoph Hellwig static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 1994c16b5a2cSChristoph Hellwig { 1995c16b5a2cSChristoph Hellwig BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; 19966a7ad299SDor Laor qemu_bh_delete(acb->bh); 199736afc451SAvi Kivity acb->bh = NULL; 1998c16b5a2cSChristoph Hellwig qemu_aio_release(acb); 1999c16b5a2cSChristoph Hellwig } 2000c16b5a2cSChristoph Hellwig 2001c16b5a2cSChristoph Hellwig static AIOPool bdrv_em_aio_pool = { 2002c16b5a2cSChristoph Hellwig .aiocb_size = sizeof(BlockDriverAIOCBSync), 2003c16b5a2cSChristoph Hellwig .cancel = bdrv_aio_cancel_em, 2004c16b5a2cSChristoph Hellwig }; 2005c16b5a2cSChristoph Hellwig 200683f64091Sbellard static void bdrv_aio_bh_cb(void *opaque) 2007beac80cdSbellard { 2008ce1a14dcSpbrook BlockDriverAIOCBSync *acb = opaque; 2009f141eafeSaliguori 2010f141eafeSaliguori if (!acb->is_write) 2011f141eafeSaliguori qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 2012ceb42de8Saliguori qemu_vfree(acb->bounce); 2013ce1a14dcSpbrook acb->common.cb(acb->common.opaque, acb->ret); 20146a7ad299SDor Laor qemu_bh_delete(acb->bh); 201536afc451SAvi Kivity acb->bh = NULL; 2016ce1a14dcSpbrook qemu_aio_release(acb); 2017beac80cdSbellard } 2018beac80cdSbellard 2019f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 2020f141eafeSaliguori int64_t sector_num, 2021f141eafeSaliguori QEMUIOVector *qiov, 2022f141eafeSaliguori int nb_sectors, 2023f141eafeSaliguori BlockDriverCompletionFunc *cb, 2024f141eafeSaliguori void *opaque, 2025f141eafeSaliguori int is_write) 2026f141eafeSaliguori 2027ea2384d3Sbellard { 2028ce1a14dcSpbrook BlockDriverAIOCBSync *acb; 202983f64091Sbellard 2030c16b5a2cSChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2031f141eafeSaliguori acb->is_write = is_write; 2032f141eafeSaliguori acb->qiov = qiov; 2033e268ca52Saliguori acb->bounce = qemu_blockalign(bs, qiov->size); 2034f141eafeSaliguori 2035ce1a14dcSpbrook if (!acb->bh) 2036ce1a14dcSpbrook acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2037f141eafeSaliguori 2038f141eafeSaliguori if (is_write) { 2039f141eafeSaliguori qemu_iovec_to_buffer(acb->qiov, acb->bounce); 2040f141eafeSaliguori acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 2041f141eafeSaliguori } else { 2042f141eafeSaliguori acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 2043f141eafeSaliguori } 2044f141eafeSaliguori 2045ce1a14dcSpbrook qemu_bh_schedule(acb->bh); 2046f141eafeSaliguori 2047ce1a14dcSpbrook return &acb->common; 20487a6cba61Spbrook } 20497a6cba61Spbrook 2050f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 2051f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2052ce1a14dcSpbrook BlockDriverCompletionFunc *cb, void *opaque) 205383f64091Sbellard { 2054f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 205583f64091Sbellard } 205683f64091Sbellard 2057f141eafeSaliguori static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 2058f141eafeSaliguori int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 2059f141eafeSaliguori BlockDriverCompletionFunc *cb, void *opaque) 2060f141eafeSaliguori { 2061f141eafeSaliguori return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 2062f141eafeSaliguori } 2063f141eafeSaliguori 2064b2e12bc6SChristoph Hellwig static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, 2065b2e12bc6SChristoph Hellwig BlockDriverCompletionFunc *cb, void *opaque) 2066b2e12bc6SChristoph Hellwig { 2067b2e12bc6SChristoph Hellwig BlockDriverAIOCBSync *acb; 2068b2e12bc6SChristoph Hellwig 2069b2e12bc6SChristoph Hellwig acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 2070b2e12bc6SChristoph Hellwig acb->is_write = 1; /* don't bounce in the completion hadler */ 2071b2e12bc6SChristoph Hellwig acb->qiov = NULL; 2072b2e12bc6SChristoph Hellwig acb->bounce = NULL; 2073b2e12bc6SChristoph Hellwig acb->ret = 0; 2074b2e12bc6SChristoph Hellwig 2075b2e12bc6SChristoph Hellwig if (!acb->bh) 2076b2e12bc6SChristoph Hellwig acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 2077b2e12bc6SChristoph Hellwig 2078b2e12bc6SChristoph Hellwig bdrv_flush(bs); 2079b2e12bc6SChristoph Hellwig qemu_bh_schedule(acb->bh); 2080b2e12bc6SChristoph Hellwig return &acb->common; 2081b2e12bc6SChristoph Hellwig } 2082b2e12bc6SChristoph Hellwig 208383f64091Sbellard /**************************************************************/ 208483f64091Sbellard /* sync block device emulation */ 208583f64091Sbellard 208683f64091Sbellard static void bdrv_rw_em_cb(void *opaque, int ret) 208783f64091Sbellard { 208883f64091Sbellard *(int *)opaque = ret; 208983f64091Sbellard } 209083f64091Sbellard 209183f64091Sbellard #define NOT_DONE 0x7fffffff 209283f64091Sbellard 209383f64091Sbellard static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 209483f64091Sbellard uint8_t *buf, int nb_sectors) 209583f64091Sbellard { 2096ce1a14dcSpbrook int async_ret; 2097ce1a14dcSpbrook BlockDriverAIOCB *acb; 2098f141eafeSaliguori struct iovec iov; 2099f141eafeSaliguori QEMUIOVector qiov; 210083f64091Sbellard 210165d6b3d8SKevin Wolf async_context_push(); 210265d6b3d8SKevin Wolf 210383f64091Sbellard async_ret = NOT_DONE; 21043f4cb3d3Sblueswir1 iov.iov_base = (void *)buf; 2105f141eafeSaliguori iov.iov_len = nb_sectors * 512; 2106f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 2107f141eafeSaliguori acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors, 210883f64091Sbellard bdrv_rw_em_cb, &async_ret); 210965d6b3d8SKevin Wolf if (acb == NULL) { 211065d6b3d8SKevin Wolf async_ret = -1; 211165d6b3d8SKevin Wolf goto fail; 211265d6b3d8SKevin Wolf } 2113baf35cb9Saliguori 211483f64091Sbellard while (async_ret == NOT_DONE) { 211583f64091Sbellard qemu_aio_wait(); 211683f64091Sbellard } 2117baf35cb9Saliguori 211865d6b3d8SKevin Wolf 211965d6b3d8SKevin Wolf fail: 212065d6b3d8SKevin Wolf async_context_pop(); 212183f64091Sbellard return async_ret; 212283f64091Sbellard } 212383f64091Sbellard 212483f64091Sbellard static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 212583f64091Sbellard const uint8_t *buf, int nb_sectors) 212683f64091Sbellard { 2127ce1a14dcSpbrook int async_ret; 2128ce1a14dcSpbrook BlockDriverAIOCB *acb; 2129f141eafeSaliguori struct iovec iov; 2130f141eafeSaliguori QEMUIOVector qiov; 213183f64091Sbellard 213265d6b3d8SKevin Wolf async_context_push(); 213365d6b3d8SKevin Wolf 213483f64091Sbellard async_ret = NOT_DONE; 2135f141eafeSaliguori iov.iov_base = (void *)buf; 2136f141eafeSaliguori iov.iov_len = nb_sectors * 512; 2137f141eafeSaliguori qemu_iovec_init_external(&qiov, &iov, 1); 2138f141eafeSaliguori acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors, 213983f64091Sbellard bdrv_rw_em_cb, &async_ret); 214065d6b3d8SKevin Wolf if (acb == NULL) { 214165d6b3d8SKevin Wolf async_ret = -1; 214265d6b3d8SKevin Wolf goto fail; 214365d6b3d8SKevin Wolf } 214483f64091Sbellard while (async_ret == NOT_DONE) { 214583f64091Sbellard qemu_aio_wait(); 214683f64091Sbellard } 214765d6b3d8SKevin Wolf 214865d6b3d8SKevin Wolf fail: 214965d6b3d8SKevin Wolf async_context_pop(); 215083f64091Sbellard return async_ret; 215183f64091Sbellard } 2152ea2384d3Sbellard 2153ea2384d3Sbellard void bdrv_init(void) 2154ea2384d3Sbellard { 21555efa9d5aSAnthony Liguori module_call_init(MODULE_INIT_BLOCK); 2156ea2384d3Sbellard } 2157ce1a14dcSpbrook 2158eb852011SMarkus Armbruster void bdrv_init_with_whitelist(void) 2159eb852011SMarkus Armbruster { 2160eb852011SMarkus Armbruster use_bdrv_whitelist = 1; 2161eb852011SMarkus Armbruster bdrv_init(); 2162eb852011SMarkus Armbruster } 2163eb852011SMarkus Armbruster 2164c16b5a2cSChristoph Hellwig void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 21656bbff9a0Saliguori BlockDriverCompletionFunc *cb, void *opaque) 21666bbff9a0Saliguori { 2167ce1a14dcSpbrook BlockDriverAIOCB *acb; 2168ce1a14dcSpbrook 21696bbff9a0Saliguori if (pool->free_aiocb) { 21706bbff9a0Saliguori acb = pool->free_aiocb; 21716bbff9a0Saliguori pool->free_aiocb = acb->next; 2172ce1a14dcSpbrook } else { 21736bbff9a0Saliguori acb = qemu_mallocz(pool->aiocb_size); 21746bbff9a0Saliguori acb->pool = pool; 2175ce1a14dcSpbrook } 2176ce1a14dcSpbrook acb->bs = bs; 2177ce1a14dcSpbrook acb->cb = cb; 2178ce1a14dcSpbrook acb->opaque = opaque; 2179ce1a14dcSpbrook return acb; 2180ce1a14dcSpbrook } 2181ce1a14dcSpbrook 2182ce1a14dcSpbrook void qemu_aio_release(void *p) 2183ce1a14dcSpbrook { 21846bbff9a0Saliguori BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 21856bbff9a0Saliguori AIOPool *pool = acb->pool; 21866bbff9a0Saliguori acb->next = pool->free_aiocb; 21876bbff9a0Saliguori pool->free_aiocb = acb; 2188ce1a14dcSpbrook } 218919cb3738Sbellard 219019cb3738Sbellard /**************************************************************/ 219119cb3738Sbellard /* removable device support */ 219219cb3738Sbellard 219319cb3738Sbellard /** 219419cb3738Sbellard * Return TRUE if the media is present 219519cb3738Sbellard */ 219619cb3738Sbellard int bdrv_is_inserted(BlockDriverState *bs) 219719cb3738Sbellard { 219819cb3738Sbellard BlockDriver *drv = bs->drv; 219919cb3738Sbellard int ret; 220019cb3738Sbellard if (!drv) 220119cb3738Sbellard return 0; 220219cb3738Sbellard if (!drv->bdrv_is_inserted) 220319cb3738Sbellard return 1; 220419cb3738Sbellard ret = drv->bdrv_is_inserted(bs); 220519cb3738Sbellard return ret; 220619cb3738Sbellard } 220719cb3738Sbellard 220819cb3738Sbellard /** 220919cb3738Sbellard * Return TRUE if the media changed since the last call to this 221019cb3738Sbellard * function. It is currently only used for floppy disks 221119cb3738Sbellard */ 221219cb3738Sbellard int bdrv_media_changed(BlockDriverState *bs) 221319cb3738Sbellard { 221419cb3738Sbellard BlockDriver *drv = bs->drv; 221519cb3738Sbellard int ret; 221619cb3738Sbellard 221719cb3738Sbellard if (!drv || !drv->bdrv_media_changed) 221819cb3738Sbellard ret = -ENOTSUP; 221919cb3738Sbellard else 222019cb3738Sbellard ret = drv->bdrv_media_changed(bs); 222119cb3738Sbellard if (ret == -ENOTSUP) 222219cb3738Sbellard ret = bs->media_changed; 222319cb3738Sbellard bs->media_changed = 0; 222419cb3738Sbellard return ret; 222519cb3738Sbellard } 222619cb3738Sbellard 222719cb3738Sbellard /** 222819cb3738Sbellard * If eject_flag is TRUE, eject the media. Otherwise, close the tray 222919cb3738Sbellard */ 2230aea2a33cSMark McLoughlin int bdrv_eject(BlockDriverState *bs, int eject_flag) 223119cb3738Sbellard { 223219cb3738Sbellard BlockDriver *drv = bs->drv; 223319cb3738Sbellard int ret; 223419cb3738Sbellard 2235aea2a33cSMark McLoughlin if (bs->locked) { 2236aea2a33cSMark McLoughlin return -EBUSY; 2237aea2a33cSMark McLoughlin } 2238aea2a33cSMark McLoughlin 223919cb3738Sbellard if (!drv || !drv->bdrv_eject) { 224019cb3738Sbellard ret = -ENOTSUP; 224119cb3738Sbellard } else { 224219cb3738Sbellard ret = drv->bdrv_eject(bs, eject_flag); 224319cb3738Sbellard } 224419cb3738Sbellard if (ret == -ENOTSUP) { 224519cb3738Sbellard if (eject_flag) 224619cb3738Sbellard bdrv_close(bs); 2247aea2a33cSMark McLoughlin ret = 0; 224819cb3738Sbellard } 2249aea2a33cSMark McLoughlin 2250aea2a33cSMark McLoughlin return ret; 225119cb3738Sbellard } 225219cb3738Sbellard 225319cb3738Sbellard int bdrv_is_locked(BlockDriverState *bs) 225419cb3738Sbellard { 225519cb3738Sbellard return bs->locked; 225619cb3738Sbellard } 225719cb3738Sbellard 225819cb3738Sbellard /** 225919cb3738Sbellard * Lock or unlock the media (if it is locked, the user won't be able 226019cb3738Sbellard * to eject it manually). 226119cb3738Sbellard */ 226219cb3738Sbellard void bdrv_set_locked(BlockDriverState *bs, int locked) 226319cb3738Sbellard { 226419cb3738Sbellard BlockDriver *drv = bs->drv; 226519cb3738Sbellard 226619cb3738Sbellard bs->locked = locked; 226719cb3738Sbellard if (drv && drv->bdrv_set_locked) { 226819cb3738Sbellard drv->bdrv_set_locked(bs, locked); 226919cb3738Sbellard } 227019cb3738Sbellard } 2271985a03b0Sths 2272985a03b0Sths /* needed for generic scsi interface */ 2273985a03b0Sths 2274985a03b0Sths int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 2275985a03b0Sths { 2276985a03b0Sths BlockDriver *drv = bs->drv; 2277985a03b0Sths 2278985a03b0Sths if (drv && drv->bdrv_ioctl) 2279985a03b0Sths return drv->bdrv_ioctl(bs, req, buf); 2280985a03b0Sths return -ENOTSUP; 2281985a03b0Sths } 22827d780669Saliguori 2283221f715dSaliguori BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 2284221f715dSaliguori unsigned long int req, void *buf, 22857d780669Saliguori BlockDriverCompletionFunc *cb, void *opaque) 22867d780669Saliguori { 2287221f715dSaliguori BlockDriver *drv = bs->drv; 22887d780669Saliguori 2289221f715dSaliguori if (drv && drv->bdrv_aio_ioctl) 2290221f715dSaliguori return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 2291221f715dSaliguori return NULL; 22927d780669Saliguori } 2293e268ca52Saliguori 22947cd1e32aSlirans@il.ibm.com 22957cd1e32aSlirans@il.ibm.com 2296e268ca52Saliguori void *qemu_blockalign(BlockDriverState *bs, size_t size) 2297e268ca52Saliguori { 2298e268ca52Saliguori return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 2299e268ca52Saliguori } 23007cd1e32aSlirans@il.ibm.com 23017cd1e32aSlirans@il.ibm.com void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) 23027cd1e32aSlirans@il.ibm.com { 23037cd1e32aSlirans@il.ibm.com int64_t bitmap_size; 2304a55eb92cSJan Kiszka 2305aaa0eb75SLiran Schour bs->dirty_count = 0; 23067cd1e32aSlirans@il.ibm.com if (enable) { 2307c6d22830SJan Kiszka if (!bs->dirty_bitmap) { 2308c6d22830SJan Kiszka bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + 2309c6d22830SJan Kiszka BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; 2310c6d22830SJan Kiszka bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; 23117cd1e32aSlirans@il.ibm.com 23127cd1e32aSlirans@il.ibm.com bs->dirty_bitmap = qemu_mallocz(bitmap_size); 23137cd1e32aSlirans@il.ibm.com } 23147cd1e32aSlirans@il.ibm.com } else { 2315c6d22830SJan Kiszka if (bs->dirty_bitmap) { 23167cd1e32aSlirans@il.ibm.com qemu_free(bs->dirty_bitmap); 2317c6d22830SJan Kiszka bs->dirty_bitmap = NULL; 23187cd1e32aSlirans@il.ibm.com } 23197cd1e32aSlirans@il.ibm.com } 23207cd1e32aSlirans@il.ibm.com } 23217cd1e32aSlirans@il.ibm.com 23227cd1e32aSlirans@il.ibm.com int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) 23237cd1e32aSlirans@il.ibm.com { 23246ea44308SJan Kiszka int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; 23257cd1e32aSlirans@il.ibm.com 2326c6d22830SJan Kiszka if (bs->dirty_bitmap && 2327c6d22830SJan Kiszka (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { 2328c6d22830SJan Kiszka return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & 2329c6d22830SJan Kiszka (1 << (chunk % (sizeof(unsigned long) * 8))); 23307cd1e32aSlirans@il.ibm.com } else { 23317cd1e32aSlirans@il.ibm.com return 0; 23327cd1e32aSlirans@il.ibm.com } 23337cd1e32aSlirans@il.ibm.com } 23347cd1e32aSlirans@il.ibm.com 23357cd1e32aSlirans@il.ibm.com void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, 23367cd1e32aSlirans@il.ibm.com int nr_sectors) 23377cd1e32aSlirans@il.ibm.com { 23387cd1e32aSlirans@il.ibm.com set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); 23397cd1e32aSlirans@il.ibm.com } 2340aaa0eb75SLiran Schour 2341aaa0eb75SLiran Schour int64_t bdrv_get_dirty_count(BlockDriverState *bs) 2342aaa0eb75SLiran Schour { 2343aaa0eb75SLiran Schour return bs->dirty_count; 2344aaa0eb75SLiran Schour } 2345