block.c revision 2c538c86c15d597cc875dc926e4e39285c5625df
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 */ 245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config-host.h" 252c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_BSD 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* include native header before sys-queue.h */ 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/queue.h> 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h" 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "block_int.h" 335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "module.h" 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 352c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_BSD 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h> 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/stat.h> 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/ioctl.h> 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef __DragonFly__ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/disk.h> 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <windows.h> 465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SECTOR_BITS 9 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SECTOR_SIZE (1 << SECTOR_BITS) 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque); 545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque); 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors); 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors); 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockDriverState *bdrv_first; 635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *first_drv; 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint _path_is_absolute(const char *path) 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* specific case for names like: "\\.\d:" */ 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*path == '/' || *path == '\\') 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(path, ':'); 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p) 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = path; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (*p == '/' || *p == '\\'); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (*p == '/'); 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if filename is absolute, just copy it to dest. Otherwise, build a 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path to it by considering it is relative to base_path. URL are 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project supported. */ 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid path_combine(char *dest, int dest_size, 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *base_path, 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *filename) 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p, *p1; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dest_size <= 0) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (_path_is_absolute(filename)) { 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(dest, dest_size, filename); 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(base_path, ':'); 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p) 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p++; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = base_path; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = strrchr(base_path, '/'); 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p2; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p2 = strrchr(base_path, '\\'); 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p1 || p2 > p1) 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = p2; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p1) 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1++; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = base_path; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p1 > p) 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = p1; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = p - base_path; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > dest_size - 1) 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = dest_size - 1; 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(dest, base_path, len); 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dest[len] = '\0'; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcat(dest, dest_size, filename); 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_register(BlockDriver *bdrv) 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!bdrv->bdrv_aio_readv) { 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add AIO emulation layer */ 1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv->bdrv_aio_readv = bdrv_aio_readv_em; 1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv->bdrv_aio_writev = bdrv_aio_writev_em; 1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!bdrv->bdrv_read) { 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add synchronous IO emulation layer */ 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_read = bdrv_read_em; 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->bdrv_write = bdrv_write_em; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv->next = first_drv; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first_drv = bdrv; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* create a new block device (by default it is empty) */ 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverState *bdrv_new(const char *device_name) 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState **pbs, *bs; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs = qemu_mallocz(sizeof(BlockDriverState)); 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (device_name[0] != '\0') { 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* insert at the end */ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &bdrv_first; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*pbs != NULL) 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &(*pbs)->next; 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriver *bdrv_find_format(const char *format_name) 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!strcmp(drv1->format_name, format_name)) 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv1; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_create(BlockDriver *drv, const char* filename, 1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUOptionParameter *options) 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_create) 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_create(filename, options); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid get_tmp_filename(char *filename, int size) 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp_dir[MAX_PATH]; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GetTempPath(MAX_PATH, temp_dir); 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project GetTempFileName(temp_dir, "qem", 0, filename); 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid get_tmp_filename(char *filename, int size) 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *tmpdir; 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: race condition possible */ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpdir = getenv("TMPDIR"); 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tmpdir) 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpdir = "/tmp"; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fd = mkstemp(filename); 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project close(fd); 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int is_windows_drive_prefix(const char *filename) 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (((filename[0] >= 'a' && filename[0] <= 'z') || 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (filename[0] >= 'A' && filename[0] <= 'Z')) && 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename[1] == ':'); 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint is_windows_drive(const char *filename) 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_windows_drive_prefix(filename) && 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename[2] == '\0') 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strstart(filename, "\\\\.\\", NULL) || 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strstart(filename, "//./", NULL)) 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *find_protocol(const char *filename) 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1; 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char protocol[128]; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *p; 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_windows_drive(filename) || 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_windows_drive_prefix(filename)) 2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bdrv_find_format("raw"); 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = strchr(filename, ':'); 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) 2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bdrv_find_format("raw"); 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = p - filename; 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > sizeof(protocol) - 1) 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof(protocol) - 1; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(protocol, filename, len); 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project protocol[len] = '\0'; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv1->protocol_name && 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !strcmp(drv1->protocol_name, protocol)) 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv1; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Detect host devices. By convention, /dev/cdrom[N] is always 2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * recognized as a host CDROM. 2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriver *find_hdev_driver(const char *filename) 2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int score_max = 0, score; 2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *drv = NULL, *d; 2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (d = first_drv; d; d = d->next) { 2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (d->bdrv_probe_device) { 2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner score = d->bdrv_probe_device(filename); 2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (score > score_max) { 2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner score_max = score; 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner drv = d; 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv; 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic BlockDriver *find_image_format(const char *filename) 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, score, score_max; 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv1, *drv; 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t buf[2048]; 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_protocol(filename); 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* no need to test disk image formats for vvfat */ 2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (drv && strcmp(drv->format_name, "vvfat") == 0) 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY); 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs); 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score_max = 0; 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv1->bdrv_probe) { 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score = drv1->bdrv_probe(buf, ret, filename); 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (score > score_max) { 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project score_max = score; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = drv1; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs = bdrv_new(""); 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs); 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->growable = 1; 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_open(BlockDriverState *bs, const char *filename, int flags) 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bdrv_open2(bs, filename, flags, NULL); 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_open2(BlockDriverState *bs, const char *filename, int flags, 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv) 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, open_flags; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char tmp_filename[PATH_MAX]; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char backing_filename[PATH_MAX]; 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->read_only = 0; 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->is_temporary = 0; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->encrypted = 0; 3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->valid_key = 0; 3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* buffer_alignment defaulted to 512, drivers can change this value */ 3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->buffer_alignment = 512; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & BDRV_O_SNAPSHOT) { 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs1; 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t total_size; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_protocol = 0; 3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *bdrv_qcow2; 3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUOptionParameter *options; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if snapshot, we create a temporary backing file and open it 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project instead of opening 'filename' directly */ 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if there is a backing file, use it */ 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs1 = bdrv_new(""); 3555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = bdrv_open2(bs1, filename, 0, drv); 3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs1); 3585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_size = bdrv_getlength(bs1) >> SECTOR_BITS; 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs1->drv && bs1->drv->protocol_name) 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_protocol = 1; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs1); 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Real path is meaningless for protocols */ 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_protocol) 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(backing_filename, sizeof(backing_filename), 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%s", filename); 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project realpath(filename, backing_filename); 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_qcow2 = bdrv_find_format("qcow2"); 3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); 3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size * 512); 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename); 3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (drv) { 3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_option_parameter(options, BLOCK_OPT_BACKING_FMT, 3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner drv->format_name); 3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = bdrv_create(bdrv_qcow2, tmp_filename, options); 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename = tmp_filename; 3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner drv = bdrv_qcow2; 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->is_temporary = 1; 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(bs->filename, sizeof(bs->filename), filename); 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & BDRV_O_FILE) { 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_protocol(filename); 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!drv) { 4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner drv = find_hdev_driver(filename); 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) { 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv = find_image_format(filename); 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!drv) { 4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = -ENOENT; 4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto unlink_and_fail; 4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = drv; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = qemu_mallocz(drv->instance_size); 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Note: for compatibility, we open disk image files as RDWR, and 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RDONLY as fallback */ 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(flags & BDRV_O_FILE)) 4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK); 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_open(bs, filename, open_flags); 4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) { 4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR); 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->read_only = 1; 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs->opaque); 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = NULL; 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = NULL; 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unlink_and_fail: 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->is_temporary) 4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unlink(filename); 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_getlength) { 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->is_temporary) { 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unlink(filename); 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_file[0] != '\0') { 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if there is a backing file, use it */ 4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *back_drv = NULL; 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->backing_hd = bdrv_new(""); 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path_combine(backing_filename, sizeof(backing_filename), 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filename, bs->backing_file); 4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->backing_format[0] != '\0') 4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner back_drv = bdrv_find_format(bs->backing_format); 4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags, 4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner back_drv); 4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_close(bs); 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!bdrv_key_required(bs)) { 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* call the change callback */ 4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->media_changed = 1; 4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->change_cb) 4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->change_cb(bs->change_opaque); 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_close(BlockDriverState *bs) 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv) { 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd) 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_delete(bs->backing_hd); 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv->bdrv_close(bs); 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs->opaque); 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->is_temporary) { 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unlink(bs->filename); 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->opaque = NULL; 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv = NULL; 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* call the change callback */ 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->media_changed = 1; 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->change_cb) 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_cb(bs->change_opaque); 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_delete(BlockDriverState *bs) 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState **pbs; 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &bdrv_first; 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*pbs != bs && *pbs != NULL) 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pbs = &(*pbs)->next; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*pbs == bs) 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pbs = bs->next; 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_close(bs); 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free(bs); 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Run consistency checks on an image 5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Returns the number of errors or -errno when an internal error occurs 5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_check(BlockDriverState *bs) 5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->drv->bdrv_check == NULL) { 5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOTSUP; 5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bs->drv->bdrv_check(bs); 5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* commit COW file into the raw image */ 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_commit(BlockDriverState *bs) 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t i, total_sectors; 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, j; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char sector[512]; 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) { 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EACCES; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->backing_hd) { 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < total_sectors;) { 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_is_allocated(bs, i, 65536, &n)) { 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(j = 0; j < n; j++) { 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, i, sector, 1) != 0) { 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) { 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++; 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += n; 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv->bdrv_make_empty) 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_make_empty(bs); 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, 5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size_t size) 5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t len; 5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!bdrv_is_inserted(bs)) 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOMEDIUM; 5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->growable) 5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner len = bdrv_getlength(bs); 5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (offset < 0) 5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((offset > len) || (len - offset < size)) 5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, 5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_sectors) 5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bdrv_check_byte_request(bs, sector_num * 512, nb_sectors * 512); 5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return < 0 if error. See bdrv_write() for the return codes */ 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_read(BlockDriverState *bs, int64_t sector_num, 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors) 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bdrv_check_request(bs, sector_num, nb_sectors)) 5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_read(bs, sector_num, buf, nb_sectors); 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return < 0 if error. Important errors are: 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EIO generic I/O error (may happen for all errors) 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -ENOMEDIUM No media inserted. 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EINVAL Invalid sector number or nb_sectors 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project -EACCES Trying to write a read-only device 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_write(BlockDriverState *bs, int64_t sector_num, 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv) 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EACCES; 6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bdrv_check_request(bs, sector_num, nb_sectors)) 6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_write(bs, sector_num, buf, nb_sectors); 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_pread(BlockDriverState *bs, int64_t offset, 6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner void *buf, int count1) 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t tmp_buf[SECTOR_SIZE]; 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, nb_sectors, count; 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num; 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = count1; 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first read to align to sector start */ 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > count) 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = count; 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num = offset >> SECTOR_BITS; 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > 0) { 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len); 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count == 0) 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read the sectors "in place" */ 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors = count >> SECTOR_BITS; 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_sectors > 0) { 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0) 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num += nb_sectors; 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors << SECTOR_BITS; 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add data from the last sector */ 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count > 0) { 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(buf, tmp_buf, count); 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_pwrite(BlockDriverState *bs, int64_t offset, 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const void *buf, int count1) 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t tmp_buf[SECTOR_SIZE]; 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len, nb_sectors, count; 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t sector_num; 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count = count1; 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first write to align to sector start */ 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > count) 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = count; 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num = offset >> SECTOR_BITS; 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > 0) { 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len); 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count == 0) 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count1; 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num++; 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the sectors "in place" */ 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_sectors = count >> SECTOR_BITS; 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_sectors > 0) { 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0) 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sector_num += nb_sectors; 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = nb_sectors << SECTOR_BITS; 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project count -= len; 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add data from the last sector */ 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (count > 0) { 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(tmp_buf, buf, count); 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -EIO; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 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 7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct partition { 7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t boot_ind; /* 0x80 - active */ 7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t head; /* starting head */ 7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t sector; /* starting sector */ 7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t cyl; /* starting cylinder */ 7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t sys_ind; /* What partition type */ 7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t end_head; /* end head */ 7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t end_sector; /* end sector */ 7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t end_cyl; /* end cylinder */ 7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t start_sect; /* starting sector counting from 0 */ 7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t nr_sects; /* nr of sectors in partition */ 7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} __attribute__((packed)); 7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int guess_disk_lchs(BlockDriverState *bs, 7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int *pcylinders, int *pheads, int *psectors) 7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t buf[512]; 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret, i, heads, sectors, cylinders; 7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct partition *p; 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t nr_sects; 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t nb_sectors; 7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_get_geometry(bs, &nb_sectors); 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = bdrv_read(bs, 0, buf, 1); 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* test msdos magic */ 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (buf[510] != 0x55 || buf[511] != 0xaa) 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < 4; i++) { 7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner p = ((struct partition *)(buf + 0x1be)) + i; 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nr_sects = le32_to_cpu(p->nr_sects); 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (nr_sects && p->end_head) { 7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* We make the assumption that the partition terminates on 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner a cylinder boundary */ 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner heads = p->end_head + 1; 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sectors = p->end_sector & 63; 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sectors == 0) 7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner continue; 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cylinders = nb_sectors / (heads * sectors); 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (cylinders < 1 || cylinders > 16383) 7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner continue; 7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pheads = heads; 7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *psectors = sectors; 7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pcylinders = cylinders; 7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner printf("guessed geometry: LCHS=%d %d %d\n", 8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cylinders, heads, sectors); 8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int translation, lba_detected = 0; 8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int cylinders, heads, secs; 8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint64_t nb_sectors; 8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* if a geometry hint is available, use it */ 8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_get_geometry(bs, &nb_sectors); 8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner translation = bdrv_get_translation_hint(bs); 8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (cylinders != 0) { 8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pcyls = cylinders; 8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pheads = heads; 8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *psecs = secs; 8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (heads > 16) { 8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* if heads > 16, it means that a BIOS LBA 8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner translation was active, so the default 8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner hardware geometry is OK */ 8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lba_detected = 1; 8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto default_geometry; 8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pcyls = cylinders; 8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pheads = heads; 8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *psecs = secs; 8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* disable any translation to be in sync with 8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner the logical geometry */ 8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (translation == BIOS_ATA_TRANSLATION_AUTO) { 8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_set_translation_hint(bs, 8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BIOS_ATA_TRANSLATION_NONE); 8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default_geometry: 8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* if no geometry, use a standard physical disk geometry */ 8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cylinders = nb_sectors / (16 * 63); 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (cylinders > 16383) 8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cylinders = 16383; 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (cylinders < 2) 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cylinders = 2; 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pcyls = cylinders; 8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *pheads = 16; 8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *psecs = 63; 8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((*pcyls * *pheads) <= 131072) { 8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_set_translation_hint(bs, 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BIOS_ATA_TRANSLATION_LARGE); 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_set_translation_hint(bs, 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BIOS_ATA_TRANSLATION_LBA); 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_geometry_hint(BlockDriverState *bs, 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cyls, int heads, int secs) 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->cyls = cyls; 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->heads = heads; 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->secs = secs; 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_type_hint(BlockDriverState *bs, int type) 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->type = type; 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->removable = ((type == BDRV_TYPE_CDROM || 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project type == BDRV_TYPE_FLOPPY)); 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_translation_hint(BlockDriverState *bs, int translation) 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->translation = translation; 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_geometry_hint(BlockDriverState *bs, 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *pcyls, int *pheads, int *psecs) 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pcyls = bs->cyls; 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pheads = bs->heads; 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *psecs = bs->secs; 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_type_hint(BlockDriverState *bs) 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->type; 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_translation_hint(BlockDriverState *bs) 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->translation; 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_removable(BlockDriverState *bs) 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->removable; 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_read_only(BlockDriverState *bs) 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->read_only; 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_sg(BlockDriverState *bs) 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->sg; 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: no longer used */ 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_change_cb(BlockDriverState *bs, 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void (*change_cb)(void *opaque), void *opaque) 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_cb = change_cb; 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->change_opaque = opaque; 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_encrypted(BlockDriverState *bs) 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd && bs->backing_hd->encrypted) 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->encrypted; 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_key_required(BlockDriverState *bs) 9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverState *backing_hd = bs->backing_hd; 9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) 9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 1; 9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (bs->encrypted && !bs->valid_key); 9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_set_key(BlockDriverState *bs, const char *key) 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd && bs->backing_hd->encrypted) { 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bdrv_set_key(bs->backing_hd, key); 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->encrypted) 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = bs->drv->bdrv_set_key(bs, key); 9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) { 9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->valid_key = 0; 9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (!bs->valid_key) { 9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->valid_key = 1; 9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* call the change callback now, we skipped it on open */ 9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->media_changed = 1; 9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->change_cb) 9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->change_cb(bs->change_opaque); 9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv) { 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = '\0'; 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(buf, buf_size, bs->drv->format_name); 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_iterate_format(void (*it)(void *opaque, const char *name), 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *opaque) 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv; 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (drv = first_drv; drv != NULL; drv = drv->next) { 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project it(opaque, drv->format_name); 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBlockDriverState *bdrv_find(const char *name) 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!strcmp(name, bs->device_name)) 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs; 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner it(opaque, bs); 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *bdrv_get_device_name(BlockDriverState *bs) 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->device_name; 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_flush(BlockDriverState *bs) 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!bs->drv) 10165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv->bdrv_flush) 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->drv->bdrv_flush(bs); 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_hd) 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_flush(bs->backing_hd); 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_flush_all(void) 10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverState *bs; 10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (bs = bdrv_first; bs != NULL; bs = bs->next) 10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->drv && !bdrv_is_read_only(bs) && 10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (!bdrv_is_removable(bs) || bdrv_is_inserted(bs))) 10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_flush(bs); 10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Returns true iff the specified sector is present in the disk image. Drivers 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * not implementing the functionality are assumed to not support backing files, 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * hence all their sectors are reported as allocated. 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'pnum' is set to the number of sectors (including and immediately following 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the specified sector) that are known to be in the same 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * allocated/unallocated state. 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'nb_sectors' is the max value 'pnum' should be set to. 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *pnum) 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t n; 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->drv->bdrv_is_allocated) { 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sector_num >= bs->total_sectors) { 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnum = 0; 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = bs->total_sectors - sector_num; 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_info(Monitor *mon) 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "%s:", bs->device_name); 10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " type="); 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(bs->type) { 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_HD: 10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "hd"); 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_CDROM: 10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "cdrom"); 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BDRV_TYPE_FLOPPY: 10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "floppy"); 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " removable=%d", bs->removable); 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->removable) { 10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " locked=%d", bs->locked); 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->drv) { 10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " file="); 10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_print_filename(mon, bs->filename); 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->backing_file[0] != '\0') { 10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " backing_file="); 10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_print_filename(mon, bs->backing_file); 10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " ro=%d", bs->read_only); 10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " drv=%s", bs->drv->format_name); 10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " encrypted=%d", bdrv_is_encrypted(bs)); 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, " [not inserted]"); 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "\n"); 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* The "info blockstats" command. */ 11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid bdrv_info_stats(Monitor *mon) 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverState *bs; 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (bs = bdrv_first; bs != NULL; bs = bs->next) { 11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_printf(mon, "%s:" 11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " rd_bytes=%" PRIu64 11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " wr_bytes=%" PRIu64 11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " rd_operations=%" PRIu64 11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner " wr_operations=%" PRIu64 11105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "\n", 11115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->device_name, 11125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->rd_bytes, bs->wr_bytes, 11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bs->rd_ops, bs->wr_ops); 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *bdrv_get_encrypted_filename(BlockDriverState *bs) 11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->backing_hd && bs->backing_hd->encrypted) 11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bs->backing_file; 11215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (bs->encrypted) 11225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bs->filename; 11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_get_backing_filename(BlockDriverState *bs, 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *filename, int filename_size) 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!bs->backing_hd) { 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(filename, filename_size, ""); 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(filename, filename_size, bs->backing_file); 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_write_compressed) 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bdrv_check_request(bs, sector_num, nb_sectors)) 11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EIO; 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_get_info) 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(bdi, 0, sizeof(*bdi)); 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_get_info(bs, bdi); 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size) 11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *drv = bs->drv; 11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!drv) 11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOMEDIUM; 11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!drv->bdrv_put_buffer) 11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOTSUP; 11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_put_buffer(bs, buf, pos, size); 11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size) 11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *drv = bs->drv; 11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!drv) 11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOMEDIUM; 11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!drv->bdrv_get_buffer) 11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -ENOTSUP; 11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_get_buffer(bs, buf, pos, size); 11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* handling of snapshots */ 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_create(BlockDriverState *bs, 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUSnapshotInfo *sn_info) 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_create) 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_create(bs, sn_info); 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_goto(BlockDriverState *bs, 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *snapshot_id) 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_goto) 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_goto(bs, snapshot_id); 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_delete) 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_delete(bs, snapshot_id); 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_snapshot_list(BlockDriverState *bs, 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUSnapshotInfo **psn_info) 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOMEDIUM; 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_snapshot_list) 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_snapshot_list(bs, psn_info); 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NB_SUFFIXES 4 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar *get_human_readable_size(char *buf, int buf_size, int64_t size) 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char suffixes[NB_SUFFIXES] = "KMGT"; 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t base; 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size <= 999) { 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%" PRId64, size); 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project base = 1024; 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < NB_SUFFIXES; i++) { 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size < (10 * base)) { 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%0.1f%c", 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)size / base, 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project suffixes[i]); 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "%" PRId64 "%c", 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((size + (base >> 1)) / base), 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project suffixes[i]); 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project base = base * 1024; 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf1[128], date_buf[128], clock_buf[128]; 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm *ptm; 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tm tm; 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project time_t ti; 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t secs; 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sn) { 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%-10s%-20s%7s%20s%15s", 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti = sn->date_sec; 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ptm = localtime(&ti); 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strftime(date_buf, sizeof(date_buf), 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%Y-%m-%d %H:%M:%S", ptm); 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project localtime_r(&ti, &tm); 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strftime(date_buf, sizeof(date_buf), 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%Y-%m-%d %H:%M:%S", &tm); 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project secs = sn->vm_clock_nsec / 1000000000; 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(clock_buf, sizeof(clock_buf), 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%02d:%02d:%02d.%03d", 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)(secs / 3600), 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)((secs / 60) % 60), 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)(secs % 60), 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (int)((sn->vm_clock_nsec / 1000000) % 1000)); 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%-10s%-20s%7s%20s%15s", 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sn->id_str, sn->name, 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project date_buf, 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clock_buf); 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* async I/Os */ 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, 13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector *qiov, int nb_sectors, 13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *ret; 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bdrv_check_request(bs, sector_num, nb_sectors)) 13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, 13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cb, opaque); 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update stats even though technically transfer has not happened. */ 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->rd_ops ++; 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, 13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector *qiov, int nb_sectors, 13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *ret; 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bs->read_only) 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bdrv_check_request(bs, sector_num, nb_sectors)) 13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, 13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cb, opaque); 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update stats even though technically transfer has not happened. */ 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->wr_ops ++; 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_aio_cancel(BlockDriverAIOCB *acb) 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->pool->cancel(acb); 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* async block device emulation */ 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct BlockDriverAIOCBSync { 13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverAIOCB common; 13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUBH *bh; 13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* vector translation state */ 13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector *qiov; 13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint8_t *bounce; 13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int is_write; 13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} BlockDriverAIOCBSync; 13725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 13745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; 13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_bh_delete(acb->bh); 13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_aio_release(acb); 13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic AIOPool bdrv_em_aio_pool = { 13815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .aiocb_size = sizeof(BlockDriverAIOCBSync), 13825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner .cancel = bdrv_aio_cancel_em, 13835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}; 13845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_aio_bh_cb(void *opaque) 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb = opaque; 13885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 13895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!acb->is_write) 13905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); 13915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_vfree(acb->bounce); 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->common.cb(acb->common.opaque, acb->ret); 13935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_bh_delete(acb->bh); 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_release(acb); 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, 13985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, 13995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector *qiov, 14005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_sectors, 14015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, 14025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner void *opaque, 14035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int is_write) 14045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCBSync *acb; 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); 14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->is_write = is_write; 14105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->qiov = qiov; 14115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->bounce = qemu_blockalign(bs, qiov->size); 14125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!acb->bh) 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 14155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 14165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (is_write) { 14175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_to_buffer(acb->qiov, acb->bounce); 14185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors); 14195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 14205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors); 14215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 14225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_bh_schedule(acb->bh); 14245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &acb->common; 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, 14295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverCompletionFunc *cb, void *opaque) 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, 14365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 14375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sync block device emulation */ 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void bdrv_rw_em_cb(void *opaque, int ret) 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(int *)opaque = ret; 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NOT_DONE 0x7fffffff 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *buf, int nb_sectors) 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int async_ret; 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 14575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct iovec iov; 14585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector qiov; 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project async_ret = NOT_DONE; 14615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iov.iov_base = (void *)buf; 14625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iov.iov_len = nb_sectors * 512; 14635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_init_external(&qiov, &iov, 1); 14645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors, 14655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_rw_em_cb, &async_ret); 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (acb == NULL) 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (async_ret == NOT_DONE) { 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_wait(); 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return async_ret; 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t *buf, int nb_sectors) 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int async_ret; 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 14815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct iovec iov; 14825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner QEMUIOVector qiov; 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project async_ret = NOT_DONE; 14855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iov.iov_base = (void *)buf; 14865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iov.iov_len = nb_sectors * 512; 14875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_iovec_init_external(&qiov, &iov, 1); 14885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors, 14895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bdrv_rw_em_cb, &async_ret); 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (acb == NULL) 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (async_ret == NOT_DONE) { 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_aio_wait(); 14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return async_ret; 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_init(void) 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner module_call_init(MODULE_INIT_BLOCK); 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, 15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriverAIOCB *acb; 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (pool->free_aiocb) { 15095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = pool->free_aiocb; 15105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner pool->free_aiocb = acb->next; 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb = qemu_mallocz(pool->aiocb_size); 15135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->pool = pool; 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->bs = bs; 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->cb = cb; 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project acb->opaque = opaque; 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return acb; 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid qemu_aio_release(void *p) 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; 15245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AIOPool *pool = acb->pool; 15255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner acb->next = pool->free_aiocb; 15265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner pool->free_aiocb = acb; 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**************************************************************/ 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* removable device support */ 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TRUE if the media is present 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_inserted(BlockDriverState *bs) 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv) 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv->bdrv_is_inserted) 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_is_inserted(bs); 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TRUE if the media changed since the last call to this 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * function. It is currently only used for floppy disks 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_media_changed(BlockDriverState *bs) 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv || !drv->bdrv_media_changed) 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = -ENOTSUP; 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_media_changed(bs); 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == -ENOTSUP) 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = bs->media_changed; 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->media_changed = 0; 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If eject_flag is TRUE, eject the media. Otherwise, close the tray 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint bdrv_eject(BlockDriverState *bs, int eject_flag) 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (bs->locked) { 15755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -EBUSY; 15765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 15775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!drv || !drv->bdrv_eject) { 15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = -ENOTSUP; 15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = drv->bdrv_eject(bs, eject_flag); 15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == -ENOTSUP) { 15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (eject_flag) 15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bdrv_close(bs); 15865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = 0; 15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 15895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_is_locked(BlockDriverState *bs) 15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bs->locked; 15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** 15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lock or unlock the media (if it is locked, the user won't be able 15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to eject it manually). 16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid bdrv_set_locked(BlockDriverState *bs, int locked) 16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bs->locked = locked; 16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv && drv->bdrv_set_locked) { 16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->bdrv_set_locked(bs, locked); 16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* needed for generic scsi interface */ 16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BlockDriver *drv = bs->drv; 16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (drv && drv->bdrv_ioctl) 16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return drv->bdrv_ioctl(bs, req, buf); 16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -ENOTSUP; 16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, 16235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unsigned long int req, void *buf, 16245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriverCompletionFunc *cb, void *opaque) 16255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 16265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BlockDriver *drv = bs->drv; 16275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (drv && drv->bdrv_aio_ioctl) 16295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); 16305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 16315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 16325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid *qemu_blockalign(BlockDriverState *bs, size_t size) 16345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 16355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); 16365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1637