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