block.c revision 8b23a6c7e1aee255004dd19098d4c2462b61b849
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU System Emulator block driver 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2003 Fabrice Bellard 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "console.h" 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "block_int.h" 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _BSD 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h> 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/stat.h> 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/ioctl.h> 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/queue.h> 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/disk.h> 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SECTOR_BITS 9 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SECTOR_SIZE (1 << SECTOR_BITS) 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct BlockDriverAIOCBSync { 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB common; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUBH *bh; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} BlockDriverAIOCBSync; 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num, uint8_t *buf, int nb_sectors, 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque); 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num, const uint8_t *buf, int nb_sectors, 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque); 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_aio_cancel_em(BlockDriverAIOCB *acb); 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors); 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors); 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *first_drv; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int path_is_absolute(const char *path) 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* specific case for names like: "\\.\d:" */ 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*path == '/' || *path == '\\') 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(path, ':'); 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p) 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = path; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (*p == '/' || *p == '\\'); 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (*p == '/'); 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if filename is absolute, just copy it to dest. Otherwise, build a 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path to it by considering it is relative to base_path. URL are 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project supported. */ 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid path_combine(char *dest, int dest_size, 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *base_path, 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *filename) 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p, *p1; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dest_size <= 0) 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (path_is_absolute(filename)) { 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(dest, dest_size, filename); 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(base_path, ':'); 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p) 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = base_path; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = strrchr(base_path, '/'); 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p2; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p2 = strrchr(base_path, '\\'); 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p1 || p2 > p1) 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = p2; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p1) 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1++; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = base_path; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p1 > p) 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = p1; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = p - base_path; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > dest_size - 1) 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = dest_size - 1; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(dest, base_path, len); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dest[len] = '\0'; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcat(dest, dest_size, filename); 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_register(BlockDriver *bdrv) 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bdrv->bdrv_aio_read) { 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add AIO emulation layer */ 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_aio_read = bdrv_aio_read_em; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_aio_write = bdrv_aio_write_em; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync); 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) { 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add synchronous IO emulation layer */ 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_read = bdrv_read_em; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_write = bdrv_write_em; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->next = first_drv; 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first_drv = bdrv; 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* create a new block device (by default it is empty) */ 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverState *bdrv_new(const char *device_name) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState **pbs, *bs; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs = qemu_mallocz(sizeof(BlockDriverState)); 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(!bs) 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (device_name[0] != '\0') { 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* insert at the end */ 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &bdrv_first; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*pbs != NULL) 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &(*pbs)->next; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs; 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriver *bdrv_find_format(const char *format_name) 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!strcmp(drv1->format_name, format_name)) 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv1; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_create(BlockDriver *drv, 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *filename, int64_t size_in_sectors, 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *backing_file, int flags) 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_create) 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_create(filename, size_in_sectors, backing_file, flags); 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid get_tmp_filename(char *filename, int size) 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp_dir[MAX_PATH]; 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GetTempPath(MAX_PATH, temp_dir); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GetTempFileName(temp_dir, "qem", 0, filename); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid get_tmp_filename(char *filename, int size) 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *tmpdir; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: race condition possible */ 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpdir = getenv("TMPDIR"); 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tmpdir) 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpdir = "/tmp"; 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fd = mkstemp(filename); 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project close(fd); 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int is_windows_drive_prefix(const char *filename) 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (((filename[0] >= 'a' && filename[0] <= 'z') || 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (filename[0] >= 'A' && filename[0] <= 'Z')) && 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename[1] == ':'); 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int is_windows_drive(const char *filename) 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_windows_drive_prefix(filename) && 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename[2] == '\0') 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strstart(filename, "\\\\.\\", NULL) || 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strstart(filename, "//./", NULL)) 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *find_protocol(const char *filename) 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char protocol[128]; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_windows_drive(filename) || 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_windows_drive_prefix(filename)) 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &bdrv_raw; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(filename, ':'); 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &bdrv_raw; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = p - filename; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > sizeof(protocol) - 1) 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof(protocol) - 1; 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(protocol, filename, len); 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project protocol[len] = '\0'; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv1->protocol_name && 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !strcmp(drv1->protocol_name, protocol)) 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv1; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: force raw format if block or character device ? It would 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project simplify the BSD case */ 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *find_image_format(const char *filename) 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, score, score_max; 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1, *drv; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t buf[2048]; 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* detect host devices. By convention, /dev/cdrom[N] is always 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project recognized as a host CDROM */ 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strstart(filename, "/dev/cdrom", NULL)) 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &bdrv_host_device; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_windows_drive(filename)) 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &bdrv_host_device; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct stat st; 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (stat(filename, &st) >= 0 && 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &bdrv_host_device; 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_protocol(filename); 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* no need to test disk image formats for vvfat */ 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv == &bdrv_vvfat) 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY); 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs); 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score_max = 0; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv1->bdrv_probe) { 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score = drv1->bdrv_probe(buf, ret, filename); 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (score > score_max) { 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score_max = score; 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = drv1; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs = bdrv_new(""); 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs) 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEM; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs); 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_open(BlockDriverState *bs, const char *filename, int flags) 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bdrv_open2(bs, filename, flags, NULL); 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_open2(BlockDriverState *bs, const char *filename, int flags, 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv) 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, open_flags; 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char tmp_filename[PATH_MAX]; 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char backing_filename[PATH_MAX]; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->read_only = 0; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->is_temporary = 0; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->encrypted = 0; 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & BDRV_O_SNAPSHOT) { 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs1; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t total_size; 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_protocol = 0; 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if snapshot, we create a temporary backing file and open it 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project instead of opening 'filename' directly */ 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if there is a backing file, use it */ 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs1 = bdrv_new(""); 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs1) { 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEM; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_open(bs1, filename, 0) < 0) { 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs1); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_size = bdrv_getlength(bs1) >> SECTOR_BITS; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs1->drv && bs1->drv->protocol_name) 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_protocol = 1; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs1); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Real path is meaningless for protocols */ 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_protocol) 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(backing_filename, sizeof(backing_filename), 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%s", filename); 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project realpath(filename, backing_filename); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_create(&bdrv_qcow2, tmp_filename, 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_size, backing_filename, 0) < 0) { 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename = tmp_filename; 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->is_temporary = 1; 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(bs->filename, sizeof(bs->filename), filename); 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & BDRV_O_FILE) { 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_protocol(filename); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOENT; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) { 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_image_format(filename); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = drv; 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = qemu_mallocz(drv->instance_size); 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->opaque == NULL && drv->instance_size > 0) 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Note: for compatibility, we open disk image files as RDWR, and 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RDONLY as fallback */ 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(flags & BDRV_O_FILE)) 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT); 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_open(bs, filename, open_flags); 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == -EACCES && !(flags & BDRV_O_FILE)) { 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY); 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->read_only = 1; 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs->opaque); 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = NULL; 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = NULL; 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_getlength) { 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->is_temporary) { 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unlink(filename); 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_file[0] != '\0') { 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if there is a backing file, use it */ 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->backing_hd = bdrv_new(""); 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->backing_hd) { 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fail: 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_close(bs); 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEM; 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path_combine(backing_filename, sizeof(backing_filename), 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename, bs->backing_file); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0) 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* call the change callback */ 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->media_changed = 1; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->change_cb) 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_cb(bs->change_opaque); 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_close(BlockDriverState *bs) 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv) { 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd) 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs->backing_hd); 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv->bdrv_close(bs); 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs->opaque); 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->is_temporary) { 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unlink(bs->filename); 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = NULL; 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = NULL; 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* call the change callback */ 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->media_changed = 1; 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->change_cb) 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_cb(bs->change_opaque); 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_delete(BlockDriverState *bs) 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState **pbs; 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &bdrv_first; 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*pbs != bs && *pbs != NULL) 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &(*pbs)->next; 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*pbs == bs) 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs->next; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_close(bs); 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs); 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* commit COW file into the raw image */ 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_commit(BlockDriverState *bs) 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t i, total_sectors; 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, j; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char sector[512]; 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) { 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EACCES; 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->backing_hd) { 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < total_sectors;) { 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_is_allocated(bs, i, 65536, &n)) { 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(j = 0; j < n; j++) { 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, i, sector, 1) != 0) { 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) { 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++; 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += n; 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_make_empty) 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_make_empty(bs); 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return < 0 if error. See bdrv_write() for the return codes */ 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_read(BlockDriverState *bs, int64_t sector_num, 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors) 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, bs->boot_sector_data, 512); 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors--; 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += 512; 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_sectors == 0) 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_pread) { 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, len; 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors * 512; 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_pread(bs, sector_num * 512, buf, len); 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (ret != len) 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EINVAL; 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_bytes += (unsigned) len; 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_ops ++; 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_read(bs, sector_num, buf, nb_sectors); 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return < 0 if error. Important errors are: 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EIO generic I/O error (may happen for all errors) 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -ENOMEDIUM No media inserted. 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EINVAL Invalid sector number or nb_sectors 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EACCES Trying to write a read-only device 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_write(BlockDriverState *bs, int64_t sector_num, 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv) 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EACCES; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(bs->boot_sector_data, buf, 512); 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_pwrite) { 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, len; 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors * 512; 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len); 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (ret != len) 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_bytes += (unsigned) len; 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_ops ++; 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_write(bs, sector_num, buf, nb_sectors); 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_pread_em(BlockDriverState *bs, int64_t offset, 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int count1) 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t tmp_buf[SECTOR_SIZE]; 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, nb_sectors, count; 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num; 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = count1; 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first read to align to sector start */ 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > count) 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = count; 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num = offset >> SECTOR_BITS; 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > 0) { 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len); 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count == 0) 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read the sectors "in place" */ 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors = count >> SECTOR_BITS; 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_sectors > 0) { 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0) 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num += nb_sectors; 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors << SECTOR_BITS; 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add data from the last sector */ 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count > 0) { 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, tmp_buf, count); 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset, 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int count1) 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t tmp_buf[SECTOR_SIZE]; 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, nb_sectors, count; 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num; 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = count1; 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first write to align to sector start */ 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > count) 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = count; 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num = offset >> SECTOR_BITS; 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > 0) { 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len); 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count == 0) 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the sectors "in place" */ 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors = count >> SECTOR_BITS; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_sectors > 0) { 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0) 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num += nb_sectors; 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors << SECTOR_BITS; 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add data from the last sector */ 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count > 0) { 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(tmp_buf, buf, count); 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Read with byte offsets (needed only for file protocols) 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_pread(BlockDriverState *bs, int64_t offset, 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *buf1, int count1) 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_pread) 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bdrv_pread_em(bs, offset, buf1, count1); 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_pread(bs, offset, buf1, count1); 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Write with byte offsets (needed only for file protocols) 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_pwrite(BlockDriverState *bs, int64_t offset, 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const void *buf1, int count1) 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_pwrite) 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bdrv_pwrite_em(bs, offset, buf1, count1); 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_pwrite(bs, offset, buf1, count1); 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Truncate file to 'offset' bytes (needed only for file protocols) 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_truncate(BlockDriverState *bs, int64_t offset) 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_truncate) 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_truncate(bs, offset); 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Length of a file in bytes. Return < 0 if error or unknown. 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64_t bdrv_getlength(BlockDriverState *bs) 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_getlength) { 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* legacy mode */ 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->total_sectors * SECTOR_SIZE; 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_getlength(bs); 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return 0 as number of sectors if no device present or error */ 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t length; 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project length = bdrv_getlength(bs); 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (length < 0) 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project length = 0; 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project length = length >> SECTOR_BITS; 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *nb_sectors_ptr = length; 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* force a given boot sector. */ 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size) 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->boot_sector_enabled = 1; 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size > 512) 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = 512; 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(bs->boot_sector_data, data, size); 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(bs->boot_sector_data + size, 0, 512 - size); 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_geometry_hint(BlockDriverState *bs, 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cyls, int heads, int secs) 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->cyls = cyls; 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->heads = heads; 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->secs = secs; 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_type_hint(BlockDriverState *bs, int type) 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->type = type; 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->removable = ((type == BDRV_TYPE_CDROM || 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project type == BDRV_TYPE_FLOPPY)); 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_translation_hint(BlockDriverState *bs, int translation) 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->translation = translation; 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_geometry_hint(BlockDriverState *bs, 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *pcyls, int *pheads, int *psecs) 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcyls = bs->cyls; 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pheads = bs->heads; 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *psecs = bs->secs; 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_type_hint(BlockDriverState *bs) 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->type; 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_translation_hint(BlockDriverState *bs) 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->translation; 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_removable(BlockDriverState *bs) 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->removable; 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_read_only(BlockDriverState *bs) 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->read_only; 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_sg(BlockDriverState *bs) 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->sg; 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: no longer used */ 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_change_cb(BlockDriverState *bs, 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void (*change_cb)(void *opaque), void *opaque) 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_cb = change_cb; 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_opaque = opaque; 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_encrypted(BlockDriverState *bs) 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd && bs->backing_hd->encrypted) 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->encrypted; 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_set_key(BlockDriverState *bs, const char *key) 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd && bs->backing_hd->encrypted) { 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_set_key(bs->backing_hd, key); 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->encrypted) 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->drv->bdrv_set_key(bs, key); 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv) { 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = '\0'; 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(buf, buf_size, bs->drv->format_name); 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_iterate_format(void (*it)(void *opaque, const char *name), 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *opaque) 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv; 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (drv = first_drv; drv != NULL; drv = drv->next) { 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project it(opaque, drv->format_name); 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverState *bdrv_find(const char *name) 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!strcmp(name, bs->device_name)) 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs; 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project it(opaque, bs->device_name); 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *bdrv_get_device_name(BlockDriverState *bs) 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->device_name; 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_flush(BlockDriverState *bs) 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv->bdrv_flush) 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv->bdrv_flush(bs); 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd) 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_flush(bs->backing_hd); 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Returns true iff the specified sector is present in the disk image. Drivers 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * not implementing the functionality are assumed to not support backing files, 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * hence all their sectors are reported as allocated. 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'pnum' is set to the number of sectors (including and immediately following 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the specified sector) that are known to be in the same 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * allocated/unallocated state. 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'nb_sectors' is the max value 'pnum' should be set to. 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *pnum) 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t n; 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv->bdrv_is_allocated) { 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num >= bs->total_sectors) { 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnum = 0; 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = bs->total_sectors - sector_num; 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_info(void) 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf("%s:", bs->device_name); 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" type="); 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(bs->type) { 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_HD: 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf("hd"); 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_CDROM: 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf("cdrom"); 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_FLOPPY: 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf("floppy"); 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" removable=%d", bs->removable); 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->removable) { 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" locked=%d", bs->locked); 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv) { 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" file="); 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_print_filename(bs->filename); 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_file[0] != '\0') { 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" backing_file="); 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_print_filename(bs->backing_file); 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" ro=%d", bs->read_only); 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" drv=%s", bs->drv->format_name); 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->encrypted) 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" encrypted"); 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf(" [not inserted]"); 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf("\n"); 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* The "info blockstats" command. */ 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_info_stats (void) 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project term_printf ("%s:" 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project " rd_bytes=%" PRIu64 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project " wr_bytes=%" PRIu64 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project " rd_operations=%" PRIu64 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project " wr_operations=%" PRIu64 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "\n", 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->device_name, 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_bytes, bs->wr_bytes, 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_ops, bs->wr_ops); 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_backing_filename(BlockDriverState *bs, 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *filename, int filename_size) 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->backing_hd) { 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(filename, filename_size, ""); 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(filename, filename_size, bs->backing_file); 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_write_compressed) 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_get_info) 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(bdi, 0, sizeof(*bdi)); 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_get_info(bs, bdi); 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* handling of snapshots */ 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_create(BlockDriverState *bs, 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUSnapshotInfo *sn_info) 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_create) 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_create(bs, sn_info); 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_goto(BlockDriverState *bs, 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *snapshot_id) 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_goto) 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_goto(bs, snapshot_id); 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_delete) 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_delete(bs, snapshot_id); 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_list(BlockDriverState *bs, 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUSnapshotInfo **psn_info) 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_list) 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_list(bs, psn_info); 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NB_SUFFIXES 4 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar *get_human_readable_size(char *buf, int buf_size, int64_t size) 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char suffixes[NB_SUFFIXES] = "KMGT"; 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t base; 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size <= 999) { 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%" PRId64, size); 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project base = 1024; 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < NB_SUFFIXES; i++) { 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size < (10 * base)) { 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%0.1f%c", 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)size / base, 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project suffixes[i]); 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%" PRId64 "%c", 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((size + (base >> 1)) / base), 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project suffixes[i]); 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project base = base * 1024; 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf1[128], date_buf[128], clock_buf[128]; 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm *ptm; 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm tm; 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project time_t ti; 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t secs; 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sn) { 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%-10s%-20s%7s%20s%15s", 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti = sn->date_sec; 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ptm = localtime(&ti); 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strftime(date_buf, sizeof(date_buf), 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%Y-%m-%d %H:%M:%S", ptm); 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project localtime_r(&ti, &tm); 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strftime(date_buf, sizeof(date_buf), 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%Y-%m-%d %H:%M:%S", &tm); 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project secs = sn->vm_clock_nsec / 1000000000; 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(clock_buf, sizeof(clock_buf), 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%02d:%02d:%02d.%03d", 11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)(secs / 3600), 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)((secs / 60) % 60), 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)(secs % 60), 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)((sn->vm_clock_nsec / 1000000) % 1000)); 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%-10s%-20s%7s%20s%15s", 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sn->id_str, sn->name, 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project date_buf, 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clock_buf); 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* async I/Os */ 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num, 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors, 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque) 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *ret; 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: we assume that nb_sectors == 0 is suppored by the async read */ 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, bs->boot_sector_data, 512); 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors--; 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += 512; 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque); 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update stats even though technically transfer has not happened. */ 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_ops ++; 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors, 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque) 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *ret; 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(bs->boot_sector_data, buf, 512); 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque); 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update stats even though technically transfer has not happened. */ 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_ops ++; 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_aio_cancel(BlockDriverAIOCB *acb) 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = acb->bs->drv; 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->bdrv_aio_cancel(acb); 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* async block device emulation */ 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_aio_bh_cb(void *opaque) 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb = opaque; 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->common.cb(acb->common.opaque, acb->ret); 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_release(acb); 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num, uint8_t *buf, int nb_sectors, 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque) 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb; 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = qemu_aio_get(bs, cb, opaque); 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!acb->bh) 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_read(bs, sector_num, buf, nb_sectors); 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->ret = ret; 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_bh_schedule(acb->bh); 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &acb->common; 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num, const uint8_t *buf, int nb_sectors, 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque) 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb; 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = qemu_aio_get(bs, cb, opaque); 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!acb->bh) 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_write(bs, sector_num, buf, nb_sectors); 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->ret = ret; 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_bh_schedule(acb->bh); 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &acb->common; 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_bh_cancel(acb->bh); 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_release(acb); 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sync block device emulation */ 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_rw_em_cb(void *opaque, int ret) 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(int *)opaque = ret; 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NOT_DONE 0x7fffffff 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors) 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int async_ret; 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project async_ret = NOT_DONE; 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors, 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_rw_em_cb, &async_ret); 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (acb == NULL) 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (async_ret == NOT_DONE) { 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_wait(); 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return async_ret; 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int async_ret; 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project async_ret = NOT_DONE; 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors, 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_rw_em_cb, &async_ret); 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (acb == NULL) 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (async_ret == NOT_DONE) { 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_wait(); 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return async_ret; 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_init(void) 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_raw); 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_host_device); 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_cow); 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_qcow); 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_vmdk); 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_cloop); 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_dmg); 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_bochs); 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_vpc); 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_vvfat); 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_qcow2); 13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_parallels); 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_register(&bdrv_nbd); 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_init(); 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *opaque) 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv; 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = bs->drv; 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->free_aiocb) { 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = drv->free_aiocb; 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->free_aiocb = acb->next; 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb = qemu_mallocz(drv->aiocb_size); 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!acb) 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->bs = bs; 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->cb = cb; 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->opaque = opaque; 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return acb; 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid qemu_aio_release(void *p) 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb = p; 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = acb->bs->drv; 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->next = drv->free_aiocb; 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->free_aiocb = acb; 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* removable device support */ 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TRUE if the media is present 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_inserted(BlockDriverState *bs) 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_is_inserted) 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_is_inserted(bs); 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TRUE if the media changed since the last call to this 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * function. It is currently only used for floppy disks 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_media_changed(BlockDriverState *bs) 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv || !drv->bdrv_media_changed) 13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = -ENOTSUP; 13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_media_changed(bs); 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == -ENOTSUP) 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bs->media_changed; 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->media_changed = 0; 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If eject_flag is TRUE, eject the media. Otherwise, close the tray 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_eject(BlockDriverState *bs, int eject_flag) 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv || !drv->bdrv_eject) { 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = -ENOTSUP; 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_eject(bs, eject_flag); 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == -ENOTSUP) { 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (eject_flag) 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_close(bs); 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_locked(BlockDriverState *bs) 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->locked; 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lock or unlock the media (if it is locked, the user won't be able 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to eject it manually). 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_locked(BlockDriverState *bs, int locked) 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->locked = locked; 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv && drv->bdrv_set_locked) { 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->bdrv_set_locked(bs, locked); 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* needed for generic scsi interface */ 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv && drv->bdrv_ioctl) 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_ioctl(bs, req, buf); 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1434