Annotation of qemu/block.c, revision 1.1.1.13

1.1       root        1: /*
                      2:  * QEMU System Emulator block driver
1.1.1.6   root        3:  *
1.1       root        4:  * Copyright (c) 2003 Fabrice Bellard
1.1.1.6   root        5:  *
1.1       root        6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
1.1.1.7   root       24: #include "config-host.h"
1.1.1.13! root       25: #ifdef HOST_BSD
1.1.1.7   root       26: /* include native header before sys-queue.h */
                     27: #include <sys/queue.h>
                     28: #endif
                     29: 
1.1.1.6   root       30: #include "qemu-common.h"
1.1.1.13! root       31: #include "monitor.h"
1.1       root       32: #include "block_int.h"
1.1.1.13! root       33: #include "module.h"
1.1       root       34: 
1.1.1.13! root       35: #ifdef HOST_BSD
1.1       root       36: #include <sys/types.h>
                     37: #include <sys/stat.h>
                     38: #include <sys/ioctl.h>
1.1.1.13! root       39: #ifndef __DragonFly__
1.1       root       40: #include <sys/disk.h>
                     41: #endif
1.1.1.13! root       42: #endif
        !            43: 
        !            44: #ifdef _WIN32
        !            45: #include <windows.h>
        !            46: #endif
1.1       root       47: 
1.1.1.5   root       48: #define SECTOR_BITS 9
                     49: #define SECTOR_SIZE (1 << SECTOR_BITS)
1.1.1.2   root       50: 
1.1.1.13! root       51: static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
        !            52:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root       53:         BlockDriverCompletionFunc *cb, void *opaque);
1.1.1.13! root       54: static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
        !            55:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root       56:         BlockDriverCompletionFunc *cb, void *opaque);
1.1.1.6   root       57: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root       58:                         uint8_t *buf, int nb_sectors);
                     59: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                     60:                          const uint8_t *buf, int nb_sectors);
1.1.1.3   root       61: 
1.1.1.6   root       62: BlockDriverState *bdrv_first;
1.1.1.7   root       63: 
1.1       root       64: static BlockDriver *first_drv;
                     65: 
1.1.1.5   root       66: int path_is_absolute(const char *path)
                     67: {
                     68:     const char *p;
                     69: #ifdef _WIN32
                     70:     /* specific case for names like: "\\.\d:" */
                     71:     if (*path == '/' || *path == '\\')
                     72:         return 1;
                     73: #endif
                     74:     p = strchr(path, ':');
                     75:     if (p)
                     76:         p++;
                     77:     else
                     78:         p = path;
                     79: #ifdef _WIN32
                     80:     return (*p == '/' || *p == '\\');
                     81: #else
                     82:     return (*p == '/');
                     83: #endif
1.1.1.2   root       84: }
                     85: 
1.1.1.5   root       86: /* if filename is absolute, just copy it to dest. Otherwise, build a
                     87:    path to it by considering it is relative to base_path. URL are
                     88:    supported. */
                     89: void path_combine(char *dest, int dest_size,
                     90:                   const char *base_path,
                     91:                   const char *filename)
                     92: {
                     93:     const char *p, *p1;
                     94:     int len;
                     95: 
                     96:     if (dest_size <= 0)
                     97:         return;
                     98:     if (path_is_absolute(filename)) {
                     99:         pstrcpy(dest, dest_size, filename);
                    100:     } else {
                    101:         p = strchr(base_path, ':');
                    102:         if (p)
                    103:             p++;
                    104:         else
                    105:             p = base_path;
                    106:         p1 = strrchr(base_path, '/');
                    107: #ifdef _WIN32
                    108:         {
                    109:             const char *p2;
                    110:             p2 = strrchr(base_path, '\\');
                    111:             if (!p1 || p2 > p1)
                    112:                 p1 = p2;
1.1.1.2   root      113:         }
1.1.1.5   root      114: #endif
                    115:         if (p1)
                    116:             p1++;
                    117:         else
                    118:             p1 = base_path;
                    119:         if (p1 > p)
                    120:             p = p1;
                    121:         len = p - base_path;
                    122:         if (len > dest_size - 1)
                    123:             len = dest_size - 1;
                    124:         memcpy(dest, base_path, len);
                    125:         dest[len] = '\0';
                    126:         pstrcat(dest, dest_size, filename);
1.1.1.2   root      127:     }
                    128: }
                    129: 
1.1.1.13! root      130: void bdrv_register(BlockDriver *bdrv)
1.1       root      131: {
1.1.1.13! root      132:     if (!bdrv->bdrv_aio_readv) {
1.1.1.5   root      133:         /* add AIO emulation layer */
1.1.1.13! root      134:         bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
        !           135:         bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
        !           136:     } else if (!bdrv->bdrv_read) {
1.1.1.5   root      137:         /* add synchronous IO emulation layer */
                    138:         bdrv->bdrv_read = bdrv_read_em;
                    139:         bdrv->bdrv_write = bdrv_write_em;
                    140:     }
1.1       root      141:     bdrv->next = first_drv;
                    142:     first_drv = bdrv;
                    143: }
                    144: 
                    145: /* create a new block device (by default it is empty) */
                    146: BlockDriverState *bdrv_new(const char *device_name)
                    147: {
                    148:     BlockDriverState **pbs, *bs;
                    149: 
                    150:     bs = qemu_mallocz(sizeof(BlockDriverState));
                    151:     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
                    152:     if (device_name[0] != '\0') {
                    153:         /* insert at the end */
                    154:         pbs = &bdrv_first;
                    155:         while (*pbs != NULL)
                    156:             pbs = &(*pbs)->next;
                    157:         *pbs = bs;
                    158:     }
                    159:     return bs;
                    160: }
                    161: 
                    162: BlockDriver *bdrv_find_format(const char *format_name)
                    163: {
                    164:     BlockDriver *drv1;
                    165:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
                    166:         if (!strcmp(drv1->format_name, format_name))
                    167:             return drv1;
                    168:     }
                    169:     return NULL;
                    170: }
                    171: 
1.1.1.13! root      172: int bdrv_create(BlockDriver *drv, const char* filename,
        !           173:     QEMUOptionParameter *options)
1.1       root      174: {
                    175:     if (!drv->bdrv_create)
                    176:         return -ENOTSUP;
1.1.1.13! root      177: 
        !           178:     return drv->bdrv_create(filename, options);
1.1       root      179: }
                    180: 
                    181: #ifdef _WIN32
1.1.1.2   root      182: void get_tmp_filename(char *filename, int size)
1.1       root      183: {
1.1.1.5   root      184:     char temp_dir[MAX_PATH];
1.1.1.6   root      185: 
1.1.1.5   root      186:     GetTempPath(MAX_PATH, temp_dir);
                    187:     GetTempFileName(temp_dir, "qem", 0, filename);
1.1       root      188: }
                    189: #else
1.1.1.2   root      190: void get_tmp_filename(char *filename, int size)
1.1       root      191: {
                    192:     int fd;
1.1.1.7   root      193:     const char *tmpdir;
1.1       root      194:     /* XXX: race condition possible */
1.1.1.7   root      195:     tmpdir = getenv("TMPDIR");
                    196:     if (!tmpdir)
                    197:         tmpdir = "/tmp";
                    198:     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
1.1       root      199:     fd = mkstemp(filename);
                    200:     close(fd);
                    201: }
                    202: #endif
                    203: 
1.1.1.5   root      204: #ifdef _WIN32
                    205: static int is_windows_drive_prefix(const char *filename)
                    206: {
                    207:     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
                    208:              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
                    209:             filename[1] == ':');
                    210: }
1.1.1.6   root      211: 
1.1.1.13! root      212: int is_windows_drive(const char *filename)
1.1.1.5   root      213: {
1.1.1.6   root      214:     if (is_windows_drive_prefix(filename) &&
1.1.1.5   root      215:         filename[2] == '\0')
                    216:         return 1;
                    217:     if (strstart(filename, "\\\\.\\", NULL) ||
                    218:         strstart(filename, "//./", NULL))
                    219:         return 1;
                    220:     return 0;
                    221: }
                    222: #endif
                    223: 
                    224: static BlockDriver *find_protocol(const char *filename)
                    225: {
                    226:     BlockDriver *drv1;
                    227:     char protocol[128];
                    228:     int len;
                    229:     const char *p;
                    230: 
                    231: #ifdef _WIN32
                    232:     if (is_windows_drive(filename) ||
                    233:         is_windows_drive_prefix(filename))
1.1.1.13! root      234:         return bdrv_find_format("raw");
1.1.1.5   root      235: #endif
                    236:     p = strchr(filename, ':');
                    237:     if (!p)
1.1.1.13! root      238:         return bdrv_find_format("raw");
1.1.1.5   root      239:     len = p - filename;
                    240:     if (len > sizeof(protocol) - 1)
                    241:         len = sizeof(protocol) - 1;
                    242:     memcpy(protocol, filename, len);
                    243:     protocol[len] = '\0';
                    244:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.6   root      245:         if (drv1->protocol_name &&
1.1.1.5   root      246:             !strcmp(drv1->protocol_name, protocol))
                    247:             return drv1;
                    248:     }
                    249:     return NULL;
                    250: }
                    251: 
1.1.1.13! root      252: /*
        !           253:  * Detect host devices. By convention, /dev/cdrom[N] is always
        !           254:  * recognized as a host CDROM.
        !           255:  */
        !           256: static BlockDriver *find_hdev_driver(const char *filename)
        !           257: {
        !           258:     int score_max = 0, score;
        !           259:     BlockDriver *drv = NULL, *d;
        !           260: 
        !           261:     for (d = first_drv; d; d = d->next) {
        !           262:         if (d->bdrv_probe_device) {
        !           263:             score = d->bdrv_probe_device(filename);
        !           264:             if (score > score_max) {
        !           265:                 score_max = score;
        !           266:                 drv = d;
        !           267:             }
        !           268:         }
        !           269:     }
        !           270: 
        !           271:     return drv;
        !           272: }
        !           273: 
1.1       root      274: static BlockDriver *find_image_format(const char *filename)
                    275: {
1.1.1.5   root      276:     int ret, score, score_max;
1.1       root      277:     BlockDriver *drv1, *drv;
1.1.1.5   root      278:     uint8_t buf[2048];
                    279:     BlockDriverState *bs;
1.1.1.6   root      280: 
1.1.1.5   root      281:     drv = find_protocol(filename);
                    282:     /* no need to test disk image formats for vvfat */
1.1.1.13! root      283:     if (drv && strcmp(drv->format_name, "vvfat") == 0)
1.1.1.5   root      284:         return drv;
                    285: 
                    286:     ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
                    287:     if (ret < 0)
                    288:         return NULL;
                    289:     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
                    290:     bdrv_delete(bs);
                    291:     if (ret < 0) {
                    292:         return NULL;
                    293:     }
                    294: 
1.1       root      295:     score_max = 0;
                    296:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.5   root      297:         if (drv1->bdrv_probe) {
                    298:             score = drv1->bdrv_probe(buf, ret, filename);
                    299:             if (score > score_max) {
                    300:                 score_max = score;
                    301:                 drv = drv1;
                    302:             }
1.1       root      303:         }
                    304:     }
                    305:     return drv;
                    306: }
                    307: 
1.1.1.5   root      308: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
1.1       root      309: {
1.1.1.5   root      310:     BlockDriverState *bs;
                    311:     int ret;
                    312: 
                    313:     bs = bdrv_new("");
                    314:     ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
                    315:     if (ret < 0) {
                    316:         bdrv_delete(bs);
                    317:         return ret;
1.1.1.2   root      318:     }
1.1.1.7   root      319:     bs->growable = 1;
1.1.1.5   root      320:     *pbs = bs;
                    321:     return 0;
                    322: }
                    323: 
                    324: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
                    325: {
                    326:     return bdrv_open2(bs, filename, flags, NULL);
1.1       root      327: }
                    328: 
1.1.1.5   root      329: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
1.1       root      330:                BlockDriver *drv)
                    331: {
1.1.1.5   root      332:     int ret, open_flags;
1.1.1.6   root      333:     char tmp_filename[PATH_MAX];
                    334:     char backing_filename[PATH_MAX];
                    335: 
1.1       root      336:     bs->read_only = 0;
                    337:     bs->is_temporary = 0;
                    338:     bs->encrypted = 0;
1.1.1.8   root      339:     bs->valid_key = 0;
1.1.1.13! root      340:     /* buffer_alignment defaulted to 512, drivers can change this value */
        !           341:     bs->buffer_alignment = 512;
1.1       root      342: 
1.1.1.5   root      343:     if (flags & BDRV_O_SNAPSHOT) {
1.1       root      344:         BlockDriverState *bs1;
                    345:         int64_t total_size;
1.1.1.7   root      346:         int is_protocol = 0;
1.1.1.13! root      347:         BlockDriver *bdrv_qcow2;
        !           348:         QEMUOptionParameter *options;
1.1.1.6   root      349: 
1.1       root      350:         /* if snapshot, we create a temporary backing file and open it
                    351:            instead of opening 'filename' directly */
                    352: 
                    353:         /* if there is a backing file, use it */
                    354:         bs1 = bdrv_new("");
1.1.1.13! root      355:         ret = bdrv_open2(bs1, filename, 0, drv);
1.1.1.8   root      356:         if (ret < 0) {
1.1       root      357:             bdrv_delete(bs1);
1.1.1.8   root      358:             return ret;
1.1       root      359:         }
1.1.1.5   root      360:         total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
1.1.1.7   root      361: 
                    362:         if (bs1->drv && bs1->drv->protocol_name)
                    363:             is_protocol = 1;
                    364: 
1.1       root      365:         bdrv_delete(bs1);
1.1.1.6   root      366: 
1.1       root      367:         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
1.1.1.7   root      368: 
                    369:         /* Real path is meaningless for protocols */
                    370:         if (is_protocol)
                    371:             snprintf(backing_filename, sizeof(backing_filename),
                    372:                      "%s", filename);
                    373:         else
                    374:             realpath(filename, backing_filename);
                    375: 
1.1.1.13! root      376:         bdrv_qcow2 = bdrv_find_format("qcow2");
        !           377:         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
        !           378: 
        !           379:         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size * 512);
        !           380:         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
        !           381:         if (drv) {
        !           382:             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
        !           383:                 drv->format_name);
        !           384:         }
        !           385: 
        !           386:         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
1.1.1.8   root      387:         if (ret < 0) {
                    388:             return ret;
1.1       root      389:         }
1.1.1.13! root      390: 
1.1       root      391:         filename = tmp_filename;
1.1.1.13! root      392:         drv = bdrv_qcow2;
1.1       root      393:         bs->is_temporary = 1;
                    394:     }
                    395: 
                    396:     pstrcpy(bs->filename, sizeof(bs->filename), filename);
1.1.1.5   root      397:     if (flags & BDRV_O_FILE) {
                    398:         drv = find_protocol(filename);
1.1.1.8   root      399:     } else if (!drv) {
1.1.1.13! root      400:         drv = find_hdev_driver(filename);
        !           401:         if (!drv) {
        !           402:             drv = find_image_format(filename);
        !           403:         }
1.1.1.8   root      404:     }
                    405:     if (!drv) {
                    406:         ret = -ENOENT;
                    407:         goto unlink_and_fail;
1.1       root      408:     }
                    409:     bs->drv = drv;
                    410:     bs->opaque = qemu_mallocz(drv->instance_size);
1.1.1.5   root      411:     /* Note: for compatibility, we open disk image files as RDWR, and
                    412:        RDONLY as fallback */
                    413:     if (!(flags & BDRV_O_FILE))
1.1.1.7   root      414:         open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
1.1.1.5   root      415:     else
                    416:         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
                    417:     ret = drv->bdrv_open(bs, filename, open_flags);
1.1.1.7   root      418:     if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
                    419:         ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
1.1.1.5   root      420:         bs->read_only = 1;
                    421:     }
1.1       root      422:     if (ret < 0) {
                    423:         qemu_free(bs->opaque);
1.1.1.5   root      424:         bs->opaque = NULL;
                    425:         bs->drv = NULL;
1.1.1.8   root      426:     unlink_and_fail:
                    427:         if (bs->is_temporary)
                    428:             unlink(filename);
1.1.1.5   root      429:         return ret;
                    430:     }
                    431:     if (drv->bdrv_getlength) {
                    432:         bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
1.1       root      433:     }
                    434: #ifndef _WIN32
                    435:     if (bs->is_temporary) {
                    436:         unlink(filename);
                    437:     }
                    438: #endif
1.1.1.5   root      439:     if (bs->backing_file[0] != '\0') {
1.1       root      440:         /* if there is a backing file, use it */
1.1.1.13! root      441:         BlockDriver *back_drv = NULL;
1.1       root      442:         bs->backing_hd = bdrv_new("");
1.1.1.5   root      443:         path_combine(backing_filename, sizeof(backing_filename),
                    444:                      filename, bs->backing_file);
1.1.1.13! root      445:         if (bs->backing_format[0] != '\0')
        !           446:             back_drv = bdrv_find_format(bs->backing_format);
        !           447:         ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
        !           448:                          back_drv);
1.1.1.8   root      449:         if (ret < 0) {
                    450:             bdrv_close(bs);
                    451:             return ret;
                    452:         }
1.1       root      453:     }
                    454: 
1.1.1.13! root      455:     if (!bdrv_key_required(bs)) {
        !           456:         /* call the change callback */
        !           457:         bs->media_changed = 1;
        !           458:         if (bs->change_cb)
        !           459:             bs->change_cb(bs->change_opaque);
        !           460:     }
1.1       root      461:     return 0;
                    462: }
                    463: 
                    464: void bdrv_close(BlockDriverState *bs)
                    465: {
1.1.1.5   root      466:     if (bs->drv) {
1.1       root      467:         if (bs->backing_hd)
                    468:             bdrv_delete(bs->backing_hd);
                    469:         bs->drv->bdrv_close(bs);
                    470:         qemu_free(bs->opaque);
                    471: #ifdef _WIN32
                    472:         if (bs->is_temporary) {
                    473:             unlink(bs->filename);
                    474:         }
                    475: #endif
                    476:         bs->opaque = NULL;
                    477:         bs->drv = NULL;
                    478: 
                    479:         /* call the change callback */
1.1.1.5   root      480:         bs->media_changed = 1;
1.1       root      481:         if (bs->change_cb)
                    482:             bs->change_cb(bs->change_opaque);
                    483:     }
                    484: }
                    485: 
                    486: void bdrv_delete(BlockDriverState *bs)
                    487: {
1.1.1.7   root      488:     BlockDriverState **pbs;
                    489: 
                    490:     pbs = &bdrv_first;
                    491:     while (*pbs != bs && *pbs != NULL)
                    492:         pbs = &(*pbs)->next;
                    493:     if (*pbs == bs)
                    494:         *pbs = bs->next;
                    495: 
1.1       root      496:     bdrv_close(bs);
                    497:     qemu_free(bs);
                    498: }
                    499: 
1.1.1.13! root      500: /*
        !           501:  * Run consistency checks on an image
        !           502:  *
        !           503:  * Returns the number of errors or -errno when an internal error occurs
        !           504:  */
        !           505: int bdrv_check(BlockDriverState *bs)
        !           506: {
        !           507:     if (bs->drv->bdrv_check == NULL) {
        !           508:         return -ENOTSUP;
        !           509:     }
        !           510: 
        !           511:     return bs->drv->bdrv_check(bs);
        !           512: }
        !           513: 
1.1       root      514: /* commit COW file into the raw image */
                    515: int bdrv_commit(BlockDriverState *bs)
                    516: {
1.1.1.5   root      517:     BlockDriver *drv = bs->drv;
                    518:     int64_t i, total_sectors;
1.1       root      519:     int n, j;
                    520:     unsigned char sector[512];
                    521: 
1.1.1.5   root      522:     if (!drv)
                    523:         return -ENOMEDIUM;
1.1       root      524: 
                    525:     if (bs->read_only) {
                    526:        return -EACCES;
                    527:     }
                    528: 
                    529:     if (!bs->backing_hd) {
                    530:        return -ENOTSUP;
                    531:     }
                    532: 
1.1.1.5   root      533:     total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
                    534:     for (i = 0; i < total_sectors;) {
                    535:         if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
1.1       root      536:             for(j = 0; j < n; j++) {
                    537:                 if (bdrv_read(bs, i, sector, 1) != 0) {
                    538:                     return -EIO;
                    539:                 }
                    540: 
                    541:                 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
                    542:                     return -EIO;
                    543:                 }
                    544:                 i++;
                    545:            }
                    546:        } else {
                    547:             i += n;
                    548:         }
                    549:     }
1.1.1.2   root      550: 
1.1.1.5   root      551:     if (drv->bdrv_make_empty)
                    552:        return drv->bdrv_make_empty(bs);
1.1.1.2   root      553: 
1.1       root      554:     return 0;
                    555: }
                    556: 
1.1.1.7   root      557: static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
                    558:                                    size_t size)
                    559: {
                    560:     int64_t len;
                    561: 
                    562:     if (!bdrv_is_inserted(bs))
                    563:         return -ENOMEDIUM;
                    564: 
                    565:     if (bs->growable)
                    566:         return 0;
                    567: 
                    568:     len = bdrv_getlength(bs);
                    569: 
1.1.1.11  root      570:     if (offset < 0)
                    571:         return -EIO;
                    572: 
                    573:     if ((offset > len) || (len - offset < size))
1.1.1.7   root      574:         return -EIO;
                    575: 
                    576:     return 0;
                    577: }
                    578: 
                    579: static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                    580:                               int nb_sectors)
                    581: {
1.1.1.13! root      582:     return bdrv_check_byte_request(bs, sector_num * 512, nb_sectors * 512);
1.1.1.7   root      583: }
                    584: 
1.1.1.5   root      585: /* return < 0 if error. See bdrv_write() for the return codes */
1.1.1.6   root      586: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1.1       root      587:               uint8_t *buf, int nb_sectors)
                    588: {
                    589:     BlockDriver *drv = bs->drv;
                    590: 
1.1.1.5   root      591:     if (!drv)
                    592:         return -ENOMEDIUM;
1.1.1.7   root      593:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    594:         return -EIO;
1.1       root      595: 
1.1.1.13! root      596:     return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
1.1       root      597: }
                    598: 
1.1.1.6   root      599: /* Return < 0 if error. Important errors are:
1.1.1.5   root      600:   -EIO         generic I/O error (may happen for all errors)
                    601:   -ENOMEDIUM   No media inserted.
                    602:   -EINVAL      Invalid sector number or nb_sectors
                    603:   -EACCES      Trying to write a read-only device
                    604: */
1.1.1.6   root      605: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1.1       root      606:                const uint8_t *buf, int nb_sectors)
                    607: {
1.1.1.5   root      608:     BlockDriver *drv = bs->drv;
                    609:     if (!bs->drv)
                    610:         return -ENOMEDIUM;
1.1       root      611:     if (bs->read_only)
1.1.1.5   root      612:         return -EACCES;
1.1.1.7   root      613:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    614:         return -EIO;
                    615: 
                    616:     return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
1.1       root      617: }
                    618: 
1.1.1.13! root      619: int bdrv_pread(BlockDriverState *bs, int64_t offset,
        !           620:                void *buf, int count1)
1.1.1.5   root      621: {
                    622:     uint8_t tmp_buf[SECTOR_SIZE];
                    623:     int len, nb_sectors, count;
                    624:     int64_t sector_num;
                    625: 
                    626:     count = count1;
                    627:     /* first read to align to sector start */
                    628:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    629:     if (len > count)
                    630:         len = count;
                    631:     sector_num = offset >> SECTOR_BITS;
                    632:     if (len > 0) {
                    633:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    634:             return -EIO;
                    635:         memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
                    636:         count -= len;
                    637:         if (count == 0)
                    638:             return count1;
                    639:         sector_num++;
                    640:         buf += len;
                    641:     }
                    642: 
                    643:     /* read the sectors "in place" */
                    644:     nb_sectors = count >> SECTOR_BITS;
                    645:     if (nb_sectors > 0) {
                    646:         if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
                    647:             return -EIO;
                    648:         sector_num += nb_sectors;
                    649:         len = nb_sectors << SECTOR_BITS;
                    650:         buf += len;
                    651:         count -= len;
                    652:     }
                    653: 
                    654:     /* add data from the last sector */
                    655:     if (count > 0) {
                    656:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    657:             return -EIO;
                    658:         memcpy(buf, tmp_buf, count);
                    659:     }
                    660:     return count1;
                    661: }
                    662: 
1.1.1.13! root      663: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
        !           664:                 const void *buf, int count1)
1.1.1.5   root      665: {
                    666:     uint8_t tmp_buf[SECTOR_SIZE];
                    667:     int len, nb_sectors, count;
                    668:     int64_t sector_num;
                    669: 
                    670:     count = count1;
                    671:     /* first write to align to sector start */
                    672:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    673:     if (len > count)
                    674:         len = count;
                    675:     sector_num = offset >> SECTOR_BITS;
                    676:     if (len > 0) {
                    677:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    678:             return -EIO;
                    679:         memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
                    680:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    681:             return -EIO;
                    682:         count -= len;
                    683:         if (count == 0)
                    684:             return count1;
                    685:         sector_num++;
                    686:         buf += len;
                    687:     }
                    688: 
                    689:     /* write the sectors "in place" */
                    690:     nb_sectors = count >> SECTOR_BITS;
                    691:     if (nb_sectors > 0) {
                    692:         if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
                    693:             return -EIO;
                    694:         sector_num += nb_sectors;
                    695:         len = nb_sectors << SECTOR_BITS;
                    696:         buf += len;
                    697:         count -= len;
                    698:     }
                    699: 
                    700:     /* add data from the last sector */
                    701:     if (count > 0) {
                    702:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    703:             return -EIO;
                    704:         memcpy(tmp_buf, buf, count);
                    705:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    706:             return -EIO;
                    707:     }
                    708:     return count1;
                    709: }
                    710: 
                    711: /**
                    712:  * Truncate file to 'offset' bytes (needed only for file protocols)
                    713:  */
                    714: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
                    715: {
                    716:     BlockDriver *drv = bs->drv;
                    717:     if (!drv)
                    718:         return -ENOMEDIUM;
                    719:     if (!drv->bdrv_truncate)
                    720:         return -ENOTSUP;
                    721:     return drv->bdrv_truncate(bs, offset);
                    722: }
                    723: 
                    724: /**
                    725:  * Length of a file in bytes. Return < 0 if error or unknown.
                    726:  */
                    727: int64_t bdrv_getlength(BlockDriverState *bs)
                    728: {
                    729:     BlockDriver *drv = bs->drv;
                    730:     if (!drv)
                    731:         return -ENOMEDIUM;
                    732:     if (!drv->bdrv_getlength) {
                    733:         /* legacy mode */
                    734:         return bs->total_sectors * SECTOR_SIZE;
                    735:     }
                    736:     return drv->bdrv_getlength(bs);
                    737: }
                    738: 
                    739: /* return 0 as number of sectors if no device present or error */
1.1.1.6   root      740: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1.1       root      741: {
1.1.1.5   root      742:     int64_t length;
                    743:     length = bdrv_getlength(bs);
                    744:     if (length < 0)
                    745:         length = 0;
                    746:     else
                    747:         length = length >> SECTOR_BITS;
                    748:     *nb_sectors_ptr = length;
1.1       root      749: }
                    750: 
1.1.1.7   root      751: struct partition {
                    752:         uint8_t boot_ind;           /* 0x80 - active */
                    753:         uint8_t head;               /* starting head */
                    754:         uint8_t sector;             /* starting sector */
                    755:         uint8_t cyl;                /* starting cylinder */
                    756:         uint8_t sys_ind;            /* What partition type */
                    757:         uint8_t end_head;           /* end head */
                    758:         uint8_t end_sector;         /* end sector */
                    759:         uint8_t end_cyl;            /* end cylinder */
                    760:         uint32_t start_sect;        /* starting sector counting from 0 */
                    761:         uint32_t nr_sects;          /* nr of sectors in partition */
                    762: } __attribute__((packed));
                    763: 
                    764: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
                    765: static int guess_disk_lchs(BlockDriverState *bs,
                    766:                            int *pcylinders, int *pheads, int *psectors)
                    767: {
                    768:     uint8_t buf[512];
                    769:     int ret, i, heads, sectors, cylinders;
                    770:     struct partition *p;
                    771:     uint32_t nr_sects;
                    772:     uint64_t nb_sectors;
                    773: 
                    774:     bdrv_get_geometry(bs, &nb_sectors);
                    775: 
                    776:     ret = bdrv_read(bs, 0, buf, 1);
                    777:     if (ret < 0)
                    778:         return -1;
                    779:     /* test msdos magic */
                    780:     if (buf[510] != 0x55 || buf[511] != 0xaa)
                    781:         return -1;
                    782:     for(i = 0; i < 4; i++) {
                    783:         p = ((struct partition *)(buf + 0x1be)) + i;
                    784:         nr_sects = le32_to_cpu(p->nr_sects);
                    785:         if (nr_sects && p->end_head) {
                    786:             /* We make the assumption that the partition terminates on
                    787:                a cylinder boundary */
                    788:             heads = p->end_head + 1;
                    789:             sectors = p->end_sector & 63;
                    790:             if (sectors == 0)
                    791:                 continue;
                    792:             cylinders = nb_sectors / (heads * sectors);
                    793:             if (cylinders < 1 || cylinders > 16383)
                    794:                 continue;
                    795:             *pheads = heads;
                    796:             *psectors = sectors;
                    797:             *pcylinders = cylinders;
                    798: #if 0
                    799:             printf("guessed geometry: LCHS=%d %d %d\n",
                    800:                    cylinders, heads, sectors);
                    801: #endif
                    802:             return 0;
                    803:         }
                    804:     }
                    805:     return -1;
                    806: }
                    807: 
                    808: void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1.1       root      809: {
1.1.1.7   root      810:     int translation, lba_detected = 0;
                    811:     int cylinders, heads, secs;
                    812:     uint64_t nb_sectors;
                    813: 
                    814:     /* if a geometry hint is available, use it */
                    815:     bdrv_get_geometry(bs, &nb_sectors);
                    816:     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
                    817:     translation = bdrv_get_translation_hint(bs);
                    818:     if (cylinders != 0) {
                    819:         *pcyls = cylinders;
                    820:         *pheads = heads;
                    821:         *psecs = secs;
                    822:     } else {
                    823:         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
                    824:             if (heads > 16) {
                    825:                 /* if heads > 16, it means that a BIOS LBA
                    826:                    translation was active, so the default
                    827:                    hardware geometry is OK */
                    828:                 lba_detected = 1;
                    829:                 goto default_geometry;
                    830:             } else {
                    831:                 *pcyls = cylinders;
                    832:                 *pheads = heads;
                    833:                 *psecs = secs;
                    834:                 /* disable any translation to be in sync with
                    835:                    the logical geometry */
                    836:                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
                    837:                     bdrv_set_translation_hint(bs,
                    838:                                               BIOS_ATA_TRANSLATION_NONE);
                    839:                 }
                    840:             }
                    841:         } else {
                    842:         default_geometry:
                    843:             /* if no geometry, use a standard physical disk geometry */
                    844:             cylinders = nb_sectors / (16 * 63);
                    845: 
                    846:             if (cylinders > 16383)
                    847:                 cylinders = 16383;
                    848:             else if (cylinders < 2)
                    849:                 cylinders = 2;
                    850:             *pcyls = cylinders;
                    851:             *pheads = 16;
                    852:             *psecs = 63;
                    853:             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
                    854:                 if ((*pcyls * *pheads) <= 131072) {
                    855:                     bdrv_set_translation_hint(bs,
                    856:                                               BIOS_ATA_TRANSLATION_LARGE);
                    857:                 } else {
                    858:                     bdrv_set_translation_hint(bs,
                    859:                                               BIOS_ATA_TRANSLATION_LBA);
                    860:                 }
                    861:             }
                    862:         }
                    863:         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
                    864:     }
1.1       root      865: }
                    866: 
1.1.1.6   root      867: void bdrv_set_geometry_hint(BlockDriverState *bs,
1.1       root      868:                             int cyls, int heads, int secs)
                    869: {
                    870:     bs->cyls = cyls;
                    871:     bs->heads = heads;
                    872:     bs->secs = secs;
                    873: }
                    874: 
                    875: void bdrv_set_type_hint(BlockDriverState *bs, int type)
                    876: {
                    877:     bs->type = type;
                    878:     bs->removable = ((type == BDRV_TYPE_CDROM ||
                    879:                       type == BDRV_TYPE_FLOPPY));
                    880: }
                    881: 
                    882: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
                    883: {
                    884:     bs->translation = translation;
                    885: }
                    886: 
1.1.1.6   root      887: void bdrv_get_geometry_hint(BlockDriverState *bs,
1.1       root      888:                             int *pcyls, int *pheads, int *psecs)
                    889: {
                    890:     *pcyls = bs->cyls;
                    891:     *pheads = bs->heads;
                    892:     *psecs = bs->secs;
                    893: }
                    894: 
                    895: int bdrv_get_type_hint(BlockDriverState *bs)
                    896: {
                    897:     return bs->type;
                    898: }
                    899: 
                    900: int bdrv_get_translation_hint(BlockDriverState *bs)
                    901: {
                    902:     return bs->translation;
                    903: }
                    904: 
                    905: int bdrv_is_removable(BlockDriverState *bs)
                    906: {
                    907:     return bs->removable;
                    908: }
                    909: 
                    910: int bdrv_is_read_only(BlockDriverState *bs)
                    911: {
                    912:     return bs->read_only;
                    913: }
                    914: 
1.1.1.6   root      915: int bdrv_is_sg(BlockDriverState *bs)
                    916: {
                    917:     return bs->sg;
                    918: }
                    919: 
1.1.1.5   root      920: /* XXX: no longer used */
1.1.1.6   root      921: void bdrv_set_change_cb(BlockDriverState *bs,
1.1       root      922:                         void (*change_cb)(void *opaque), void *opaque)
                    923: {
                    924:     bs->change_cb = change_cb;
                    925:     bs->change_opaque = opaque;
                    926: }
                    927: 
                    928: int bdrv_is_encrypted(BlockDriverState *bs)
                    929: {
                    930:     if (bs->backing_hd && bs->backing_hd->encrypted)
                    931:         return 1;
                    932:     return bs->encrypted;
                    933: }
                    934: 
1.1.1.8   root      935: int bdrv_key_required(BlockDriverState *bs)
                    936: {
                    937:     BlockDriverState *backing_hd = bs->backing_hd;
                    938: 
                    939:     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
                    940:         return 1;
                    941:     return (bs->encrypted && !bs->valid_key);
                    942: }
                    943: 
1.1       root      944: int bdrv_set_key(BlockDriverState *bs, const char *key)
                    945: {
                    946:     int ret;
                    947:     if (bs->backing_hd && bs->backing_hd->encrypted) {
                    948:         ret = bdrv_set_key(bs->backing_hd, key);
                    949:         if (ret < 0)
                    950:             return ret;
                    951:         if (!bs->encrypted)
                    952:             return 0;
                    953:     }
                    954:     if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
                    955:         return -1;
1.1.1.8   root      956:     ret = bs->drv->bdrv_set_key(bs, key);
1.1.1.13! root      957:     if (ret < 0) {
        !           958:         bs->valid_key = 0;
        !           959:     } else if (!bs->valid_key) {
        !           960:         bs->valid_key = 1;
        !           961:         /* call the change callback now, we skipped it on open */
        !           962:         bs->media_changed = 1;
        !           963:         if (bs->change_cb)
        !           964:             bs->change_cb(bs->change_opaque);
        !           965:     }
1.1.1.8   root      966:     return ret;
1.1       root      967: }
                    968: 
                    969: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
                    970: {
1.1.1.5   root      971:     if (!bs->drv) {
1.1       root      972:         buf[0] = '\0';
                    973:     } else {
                    974:         pstrcpy(buf, buf_size, bs->drv->format_name);
                    975:     }
                    976: }
                    977: 
1.1.1.6   root      978: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1.1       root      979:                          void *opaque)
                    980: {
                    981:     BlockDriver *drv;
                    982: 
                    983:     for (drv = first_drv; drv != NULL; drv = drv->next) {
                    984:         it(opaque, drv->format_name);
                    985:     }
                    986: }
                    987: 
                    988: BlockDriverState *bdrv_find(const char *name)
                    989: {
                    990:     BlockDriverState *bs;
                    991: 
                    992:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                    993:         if (!strcmp(name, bs->device_name))
                    994:             return bs;
                    995:     }
                    996:     return NULL;
                    997: }
                    998: 
1.1.1.8   root      999: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1.1       root     1000: {
                   1001:     BlockDriverState *bs;
                   1002: 
                   1003:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.8   root     1004:         it(opaque, bs);
1.1       root     1005:     }
                   1006: }
                   1007: 
                   1008: const char *bdrv_get_device_name(BlockDriverState *bs)
                   1009: {
                   1010:     return bs->device_name;
                   1011: }
                   1012: 
1.1.1.4   root     1013: void bdrv_flush(BlockDriverState *bs)
                   1014: {
1.1.1.13! root     1015:     if (!bs->drv)
        !          1016:         return;
1.1.1.4   root     1017:     if (bs->drv->bdrv_flush)
                   1018:         bs->drv->bdrv_flush(bs);
                   1019:     if (bs->backing_hd)
                   1020:         bdrv_flush(bs->backing_hd);
                   1021: }
                   1022: 
1.1.1.7   root     1023: void bdrv_flush_all(void)
                   1024: {
                   1025:     BlockDriverState *bs;
                   1026: 
                   1027:     for (bs = bdrv_first; bs != NULL; bs = bs->next)
                   1028:         if (bs->drv && !bdrv_is_read_only(bs) && 
                   1029:             (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
                   1030:             bdrv_flush(bs);
                   1031: }
                   1032: 
                   1033: /*
                   1034:  * Returns true iff the specified sector is present in the disk image. Drivers
                   1035:  * not implementing the functionality are assumed to not support backing files,
                   1036:  * hence all their sectors are reported as allocated.
                   1037:  *
                   1038:  * 'pnum' is set to the number of sectors (including and immediately following
                   1039:  * the specified sector) that are known to be in the same
                   1040:  * allocated/unallocated state.
                   1041:  *
                   1042:  * 'nb_sectors' is the max value 'pnum' should be set to.
                   1043:  */
                   1044: int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                   1045:        int *pnum)
                   1046: {
                   1047:     int64_t n;
                   1048:     if (!bs->drv->bdrv_is_allocated) {
                   1049:         if (sector_num >= bs->total_sectors) {
                   1050:             *pnum = 0;
                   1051:             return 0;
                   1052:         }
                   1053:         n = bs->total_sectors - sector_num;
                   1054:         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
                   1055:         return 1;
                   1056:     }
                   1057:     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
                   1058: }
                   1059: 
1.1.1.13! root     1060: void bdrv_info(Monitor *mon)
1.1       root     1061: {
                   1062:     BlockDriverState *bs;
                   1063: 
                   1064:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.13! root     1065:         monitor_printf(mon, "%s:", bs->device_name);
        !          1066:         monitor_printf(mon, " type=");
1.1       root     1067:         switch(bs->type) {
                   1068:         case BDRV_TYPE_HD:
1.1.1.13! root     1069:             monitor_printf(mon, "hd");
1.1       root     1070:             break;
                   1071:         case BDRV_TYPE_CDROM:
1.1.1.13! root     1072:             monitor_printf(mon, "cdrom");
1.1       root     1073:             break;
                   1074:         case BDRV_TYPE_FLOPPY:
1.1.1.13! root     1075:             monitor_printf(mon, "floppy");
1.1       root     1076:             break;
                   1077:         }
1.1.1.13! root     1078:         monitor_printf(mon, " removable=%d", bs->removable);
1.1       root     1079:         if (bs->removable) {
1.1.1.13! root     1080:             monitor_printf(mon, " locked=%d", bs->locked);
1.1       root     1081:         }
1.1.1.5   root     1082:         if (bs->drv) {
1.1.1.13! root     1083:             monitor_printf(mon, " file=");
        !          1084:             monitor_print_filename(mon, bs->filename);
1.1.1.5   root     1085:             if (bs->backing_file[0] != '\0') {
1.1.1.13! root     1086:                 monitor_printf(mon, " backing_file=");
        !          1087:                 monitor_print_filename(mon, bs->backing_file);
        !          1088:             }
        !          1089:             monitor_printf(mon, " ro=%d", bs->read_only);
        !          1090:             monitor_printf(mon, " drv=%s", bs->drv->format_name);
        !          1091:             monitor_printf(mon, " encrypted=%d", bdrv_is_encrypted(bs));
1.1       root     1092:         } else {
1.1.1.13! root     1093:             monitor_printf(mon, " [not inserted]");
1.1       root     1094:         }
1.1.1.13! root     1095:         monitor_printf(mon, "\n");
1.1       root     1096:     }
                   1097: }
                   1098: 
1.1.1.6   root     1099: /* The "info blockstats" command. */
1.1.1.13! root     1100: void bdrv_info_stats(Monitor *mon)
1.1.1.6   root     1101: {
                   1102:     BlockDriverState *bs;
                   1103: 
                   1104:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.13! root     1105:         monitor_printf(mon, "%s:"
        !          1106:                        " rd_bytes=%" PRIu64
        !          1107:                        " wr_bytes=%" PRIu64
        !          1108:                        " rd_operations=%" PRIu64
        !          1109:                        " wr_operations=%" PRIu64
        !          1110:                        "\n",
        !          1111:                        bs->device_name,
        !          1112:                        bs->rd_bytes, bs->wr_bytes,
        !          1113:                        bs->rd_ops, bs->wr_ops);
1.1.1.6   root     1114:     }
                   1115: }
                   1116: 
1.1.1.8   root     1117: const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
                   1118: {
                   1119:     if (bs->backing_hd && bs->backing_hd->encrypted)
                   1120:         return bs->backing_file;
                   1121:     else if (bs->encrypted)
                   1122:         return bs->filename;
                   1123:     else
                   1124:         return NULL;
                   1125: }
                   1126: 
1.1.1.6   root     1127: void bdrv_get_backing_filename(BlockDriverState *bs,
1.1.1.5   root     1128:                                char *filename, int filename_size)
                   1129: {
                   1130:     if (!bs->backing_hd) {
                   1131:         pstrcpy(filename, filename_size, "");
                   1132:     } else {
                   1133:         pstrcpy(filename, filename_size, bs->backing_file);
                   1134:     }
                   1135: }
                   1136: 
1.1.1.6   root     1137: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1138:                           const uint8_t *buf, int nb_sectors)
                   1139: {
                   1140:     BlockDriver *drv = bs->drv;
                   1141:     if (!drv)
                   1142:         return -ENOMEDIUM;
                   1143:     if (!drv->bdrv_write_compressed)
                   1144:         return -ENOTSUP;
1.1.1.11  root     1145:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1146:         return -EIO;
1.1.1.5   root     1147:     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
                   1148: }
1.1.1.6   root     1149: 
1.1.1.5   root     1150: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
                   1151: {
                   1152:     BlockDriver *drv = bs->drv;
                   1153:     if (!drv)
                   1154:         return -ENOMEDIUM;
                   1155:     if (!drv->bdrv_get_info)
                   1156:         return -ENOTSUP;
                   1157:     memset(bdi, 0, sizeof(*bdi));
                   1158:     return drv->bdrv_get_info(bs, bdi);
                   1159: }
                   1160: 
1.1.1.13! root     1161: int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
        !          1162:                       int64_t pos, int size)
1.1.1.9   root     1163: {
                   1164:     BlockDriver *drv = bs->drv;
                   1165:     if (!drv)
                   1166:         return -ENOMEDIUM;
1.1.1.13! root     1167:     if (!drv->bdrv_save_vmstate)
1.1.1.9   root     1168:         return -ENOTSUP;
1.1.1.13! root     1169:     return drv->bdrv_save_vmstate(bs, buf, pos, size);
1.1.1.9   root     1170: }
                   1171: 
1.1.1.13! root     1172: int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
        !          1173:                       int64_t pos, int size)
1.1.1.9   root     1174: {
                   1175:     BlockDriver *drv = bs->drv;
                   1176:     if (!drv)
                   1177:         return -ENOMEDIUM;
1.1.1.13! root     1178:     if (!drv->bdrv_load_vmstate)
1.1.1.9   root     1179:         return -ENOTSUP;
1.1.1.13! root     1180:     return drv->bdrv_load_vmstate(bs, buf, pos, size);
1.1.1.9   root     1181: }
                   1182: 
1.1       root     1183: /**************************************************************/
1.1.1.5   root     1184: /* handling of snapshots */
1.1       root     1185: 
1.1.1.6   root     1186: int bdrv_snapshot_create(BlockDriverState *bs,
1.1.1.5   root     1187:                          QEMUSnapshotInfo *sn_info)
                   1188: {
                   1189:     BlockDriver *drv = bs->drv;
                   1190:     if (!drv)
                   1191:         return -ENOMEDIUM;
                   1192:     if (!drv->bdrv_snapshot_create)
                   1193:         return -ENOTSUP;
                   1194:     return drv->bdrv_snapshot_create(bs, sn_info);
                   1195: }
1.1       root     1196: 
1.1.1.6   root     1197: int bdrv_snapshot_goto(BlockDriverState *bs,
1.1.1.5   root     1198:                        const char *snapshot_id)
1.1       root     1199: {
1.1.1.5   root     1200:     BlockDriver *drv = bs->drv;
                   1201:     if (!drv)
                   1202:         return -ENOMEDIUM;
                   1203:     if (!drv->bdrv_snapshot_goto)
                   1204:         return -ENOTSUP;
                   1205:     return drv->bdrv_snapshot_goto(bs, snapshot_id);
1.1       root     1206: }
                   1207: 
1.1.1.5   root     1208: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1.1       root     1209: {
1.1.1.5   root     1210:     BlockDriver *drv = bs->drv;
                   1211:     if (!drv)
                   1212:         return -ENOMEDIUM;
                   1213:     if (!drv->bdrv_snapshot_delete)
                   1214:         return -ENOTSUP;
                   1215:     return drv->bdrv_snapshot_delete(bs, snapshot_id);
                   1216: }
1.1       root     1217: 
1.1.1.6   root     1218: int bdrv_snapshot_list(BlockDriverState *bs,
1.1.1.5   root     1219:                        QEMUSnapshotInfo **psn_info)
                   1220: {
                   1221:     BlockDriver *drv = bs->drv;
                   1222:     if (!drv)
                   1223:         return -ENOMEDIUM;
                   1224:     if (!drv->bdrv_snapshot_list)
                   1225:         return -ENOTSUP;
                   1226:     return drv->bdrv_snapshot_list(bs, psn_info);
                   1227: }
                   1228: 
                   1229: #define NB_SUFFIXES 4
                   1230: 
                   1231: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
                   1232: {
                   1233:     static const char suffixes[NB_SUFFIXES] = "KMGT";
                   1234:     int64_t base;
                   1235:     int i;
                   1236: 
                   1237:     if (size <= 999) {
                   1238:         snprintf(buf, buf_size, "%" PRId64, size);
                   1239:     } else {
                   1240:         base = 1024;
                   1241:         for(i = 0; i < NB_SUFFIXES; i++) {
                   1242:             if (size < (10 * base)) {
1.1.1.6   root     1243:                 snprintf(buf, buf_size, "%0.1f%c",
1.1.1.5   root     1244:                          (double)size / base,
                   1245:                          suffixes[i]);
                   1246:                 break;
                   1247:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1.1.1.6   root     1248:                 snprintf(buf, buf_size, "%" PRId64 "%c",
1.1.1.5   root     1249:                          ((size + (base >> 1)) / base),
                   1250:                          suffixes[i]);
                   1251:                 break;
                   1252:             }
                   1253:             base = base * 1024;
                   1254:         }
1.1       root     1255:     }
1.1.1.5   root     1256:     return buf;
                   1257: }
                   1258: 
                   1259: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
                   1260: {
                   1261:     char buf1[128], date_buf[128], clock_buf[128];
                   1262: #ifdef _WIN32
                   1263:     struct tm *ptm;
1.1.1.2   root     1264: #else
1.1.1.5   root     1265:     struct tm tm;
1.1.1.2   root     1266: #endif
1.1.1.5   root     1267:     time_t ti;
                   1268:     int64_t secs;
                   1269: 
                   1270:     if (!sn) {
1.1.1.6   root     1271:         snprintf(buf, buf_size,
                   1272:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1273:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
                   1274:     } else {
                   1275:         ti = sn->date_sec;
1.1       root     1276: #ifdef _WIN32
1.1.1.5   root     1277:         ptm = localtime(&ti);
                   1278:         strftime(date_buf, sizeof(date_buf),
                   1279:                  "%Y-%m-%d %H:%M:%S", ptm);
                   1280: #else
                   1281:         localtime_r(&ti, &tm);
                   1282:         strftime(date_buf, sizeof(date_buf),
                   1283:                  "%Y-%m-%d %H:%M:%S", &tm);
1.1       root     1284: #endif
1.1.1.5   root     1285:         secs = sn->vm_clock_nsec / 1000000000;
                   1286:         snprintf(clock_buf, sizeof(clock_buf),
                   1287:                  "%02d:%02d:%02d.%03d",
                   1288:                  (int)(secs / 3600),
                   1289:                  (int)((secs / 60) % 60),
1.1.1.6   root     1290:                  (int)(secs % 60),
1.1.1.5   root     1291:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
                   1292:         snprintf(buf, buf_size,
1.1.1.6   root     1293:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1294:                  sn->id_str, sn->name,
                   1295:                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
                   1296:                  date_buf,
                   1297:                  clock_buf);
                   1298:     }
                   1299:     return buf;
1.1       root     1300: }
                   1301: 
                   1302: 
1.1.1.5   root     1303: /**************************************************************/
                   1304: /* async I/Os */
                   1305: 
1.1.1.7   root     1306: BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
1.1.1.13! root     1307:                                  QEMUIOVector *qiov, int nb_sectors,
1.1.1.7   root     1308:                                  BlockDriverCompletionFunc *cb, void *opaque)
                   1309: {
1.1.1.5   root     1310:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1311:     BlockDriverAIOCB *ret;
1.1.1.5   root     1312: 
                   1313:     if (!drv)
                   1314:         return NULL;
1.1.1.7   root     1315:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1316:         return NULL;
1.1.1.5   root     1317: 
1.1.1.13! root     1318:     ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
        !          1319:                               cb, opaque);
1.1.1.6   root     1320: 
                   1321:     if (ret) {
                   1322:        /* Update stats even though technically transfer has not happened. */
                   1323:        bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
                   1324:        bs->rd_ops ++;
                   1325:     }
                   1326: 
                   1327:     return ret;
1.1       root     1328: }
                   1329: 
1.1.1.13! root     1330: BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
        !          1331:                                   QEMUIOVector *qiov, int nb_sectors,
        !          1332:                                   BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1333: {
1.1.1.5   root     1334:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1335:     BlockDriverAIOCB *ret;
1.1       root     1336: 
1.1.1.5   root     1337:     if (!drv)
                   1338:         return NULL;
                   1339:     if (bs->read_only)
                   1340:         return NULL;
1.1.1.7   root     1341:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1342:         return NULL;
1.1.1.4   root     1343: 
1.1.1.13! root     1344:     ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
        !          1345:                                cb, opaque);
1.1.1.6   root     1346: 
                   1347:     if (ret) {
                   1348:        /* Update stats even though technically transfer has not happened. */
                   1349:        bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
                   1350:        bs->wr_ops ++;
                   1351:     }
                   1352: 
                   1353:     return ret;
1.1.1.5   root     1354: }
                   1355: 
                   1356: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1.1.1.4   root     1357: {
1.1.1.10  root     1358:     acb->pool->cancel(acb);
1.1.1.5   root     1359: }
1.1.1.4   root     1360: 
                   1361: 
1.1.1.5   root     1362: /**************************************************************/
                   1363: /* async block device emulation */
1.1.1.4   root     1364: 
1.1.1.13! root     1365: typedef struct BlockDriverAIOCBSync {
        !          1366:     BlockDriverAIOCB common;
        !          1367:     QEMUBH *bh;
        !          1368:     int ret;
        !          1369:     /* vector translation state */
        !          1370:     QEMUIOVector *qiov;
        !          1371:     uint8_t *bounce;
        !          1372:     int is_write;
        !          1373: } BlockDriverAIOCBSync;
        !          1374: 
        !          1375: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
        !          1376: {
        !          1377:     BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
        !          1378:     qemu_bh_delete(acb->bh);
        !          1379:     acb->bh = NULL;
        !          1380:     qemu_aio_release(acb);
        !          1381: }
        !          1382: 
        !          1383: static AIOPool bdrv_em_aio_pool = {
        !          1384:     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
        !          1385:     .cancel             = bdrv_aio_cancel_em,
        !          1386: };
        !          1387: 
1.1.1.5   root     1388: static void bdrv_aio_bh_cb(void *opaque)
1.1.1.4   root     1389: {
1.1.1.5   root     1390:     BlockDriverAIOCBSync *acb = opaque;
1.1.1.13! root     1391: 
        !          1392:     if (!acb->is_write)
        !          1393:         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
        !          1394:     qemu_vfree(acb->bounce);
1.1.1.5   root     1395:     acb->common.cb(acb->common.opaque, acb->ret);
1.1.1.13! root     1396:     qemu_bh_delete(acb->bh);
        !          1397:     acb->bh = NULL;
1.1.1.5   root     1398:     qemu_aio_release(acb);
1.1.1.4   root     1399: }
                   1400: 
1.1.1.13! root     1401: static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
        !          1402:                                             int64_t sector_num,
        !          1403:                                             QEMUIOVector *qiov,
        !          1404:                                             int nb_sectors,
        !          1405:                                             BlockDriverCompletionFunc *cb,
        !          1406:                                             void *opaque,
        !          1407:                                             int is_write)
        !          1408: 
1.1       root     1409: {
1.1.1.5   root     1410:     BlockDriverAIOCBSync *acb;
1.1       root     1411: 
1.1.1.13! root     1412:     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
        !          1413:     acb->is_write = is_write;
        !          1414:     acb->qiov = qiov;
        !          1415:     acb->bounce = qemu_blockalign(bs, qiov->size);
        !          1416: 
1.1.1.5   root     1417:     if (!acb->bh)
                   1418:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1.1.1.13! root     1419: 
        !          1420:     if (is_write) {
        !          1421:         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
        !          1422:         acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
        !          1423:     } else {
        !          1424:         acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
        !          1425:     }
        !          1426: 
1.1.1.5   root     1427:     qemu_bh_schedule(acb->bh);
1.1.1.13! root     1428: 
1.1.1.5   root     1429:     return &acb->common;
                   1430: }
1.1       root     1431: 
1.1.1.13! root     1432: static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
        !          1433:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root     1434:         BlockDriverCompletionFunc *cb, void *opaque)
                   1435: {
1.1.1.13! root     1436:     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
1.1.1.5   root     1437: }
                   1438: 
1.1.1.13! root     1439: static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
        !          1440:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
        !          1441:         BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5   root     1442: {
1.1.1.13! root     1443:     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
1.1       root     1444: }
                   1445: 
1.1.1.5   root     1446: /**************************************************************/
                   1447: /* sync block device emulation */
                   1448: 
                   1449: static void bdrv_rw_em_cb(void *opaque, int ret)
1.1.1.4   root     1450: {
1.1.1.5   root     1451:     *(int *)opaque = ret;
1.1.1.4   root     1452: }
                   1453: 
1.1.1.5   root     1454: #define NOT_DONE 0x7fffffff
                   1455: 
1.1.1.6   root     1456: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1457:                         uint8_t *buf, int nb_sectors)
                   1458: {
                   1459:     int async_ret;
                   1460:     BlockDriverAIOCB *acb;
1.1.1.13! root     1461:     struct iovec iov;
        !          1462:     QEMUIOVector qiov;
1.1.1.5   root     1463: 
                   1464:     async_ret = NOT_DONE;
1.1.1.13! root     1465:     iov.iov_base = (void *)buf;
        !          1466:     iov.iov_len = nb_sectors * 512;
        !          1467:     qemu_iovec_init_external(&qiov, &iov, 1);
        !          1468:     acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
        !          1469:         bdrv_rw_em_cb, &async_ret);
1.1.1.7   root     1470:     if (acb == NULL)
1.1.1.5   root     1471:         return -1;
1.1.1.7   root     1472: 
1.1.1.5   root     1473:     while (async_ret == NOT_DONE) {
                   1474:         qemu_aio_wait();
                   1475:     }
1.1.1.7   root     1476: 
1.1.1.5   root     1477:     return async_ret;
                   1478: }
                   1479: 
                   1480: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                   1481:                          const uint8_t *buf, int nb_sectors)
                   1482: {
                   1483:     int async_ret;
                   1484:     BlockDriverAIOCB *acb;
1.1.1.13! root     1485:     struct iovec iov;
        !          1486:     QEMUIOVector qiov;
1.1.1.5   root     1487: 
                   1488:     async_ret = NOT_DONE;
1.1.1.13! root     1489:     iov.iov_base = (void *)buf;
        !          1490:     iov.iov_len = nb_sectors * 512;
        !          1491:     qemu_iovec_init_external(&qiov, &iov, 1);
        !          1492:     acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
        !          1493:         bdrv_rw_em_cb, &async_ret);
1.1.1.7   root     1494:     if (acb == NULL)
1.1.1.5   root     1495:         return -1;
                   1496:     while (async_ret == NOT_DONE) {
                   1497:         qemu_aio_wait();
                   1498:     }
                   1499:     return async_ret;
                   1500: }
1.1       root     1501: 
                   1502: void bdrv_init(void)
                   1503: {
1.1.1.13! root     1504:     module_call_init(MODULE_INIT_BLOCK);
1.1.1.10  root     1505: }
                   1506: 
1.1.1.13! root     1507: void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
        !          1508:                    BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5   root     1509: {
                   1510:     BlockDriverAIOCB *acb;
                   1511: 
1.1.1.10  root     1512:     if (pool->free_aiocb) {
                   1513:         acb = pool->free_aiocb;
                   1514:         pool->free_aiocb = acb->next;
1.1.1.5   root     1515:     } else {
1.1.1.10  root     1516:         acb = qemu_mallocz(pool->aiocb_size);
                   1517:         acb->pool = pool;
1.1.1.5   root     1518:     }
                   1519:     acb->bs = bs;
                   1520:     acb->cb = cb;
                   1521:     acb->opaque = opaque;
                   1522:     return acb;
                   1523: }
                   1524: 
                   1525: void qemu_aio_release(void *p)
                   1526: {
1.1.1.10  root     1527:     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
                   1528:     AIOPool *pool = acb->pool;
                   1529:     acb->next = pool->free_aiocb;
                   1530:     pool->free_aiocb = acb;
1.1.1.5   root     1531: }
                   1532: 
                   1533: /**************************************************************/
                   1534: /* removable device support */
                   1535: 
                   1536: /**
                   1537:  * Return TRUE if the media is present
                   1538:  */
                   1539: int bdrv_is_inserted(BlockDriverState *bs)
                   1540: {
                   1541:     BlockDriver *drv = bs->drv;
                   1542:     int ret;
                   1543:     if (!drv)
                   1544:         return 0;
                   1545:     if (!drv->bdrv_is_inserted)
                   1546:         return 1;
                   1547:     ret = drv->bdrv_is_inserted(bs);
                   1548:     return ret;
                   1549: }
                   1550: 
                   1551: /**
                   1552:  * Return TRUE if the media changed since the last call to this
1.1.1.6   root     1553:  * function. It is currently only used for floppy disks
1.1.1.5   root     1554:  */
                   1555: int bdrv_media_changed(BlockDriverState *bs)
                   1556: {
                   1557:     BlockDriver *drv = bs->drv;
                   1558:     int ret;
                   1559: 
                   1560:     if (!drv || !drv->bdrv_media_changed)
                   1561:         ret = -ENOTSUP;
                   1562:     else
                   1563:         ret = drv->bdrv_media_changed(bs);
                   1564:     if (ret == -ENOTSUP)
                   1565:         ret = bs->media_changed;
                   1566:     bs->media_changed = 0;
                   1567:     return ret;
                   1568: }
                   1569: 
                   1570: /**
                   1571:  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
                   1572:  */
1.1.1.13! root     1573: int bdrv_eject(BlockDriverState *bs, int eject_flag)
1.1.1.5   root     1574: {
                   1575:     BlockDriver *drv = bs->drv;
                   1576:     int ret;
                   1577: 
1.1.1.13! root     1578:     if (bs->locked) {
        !          1579:         return -EBUSY;
        !          1580:     }
        !          1581: 
1.1.1.5   root     1582:     if (!drv || !drv->bdrv_eject) {
                   1583:         ret = -ENOTSUP;
                   1584:     } else {
                   1585:         ret = drv->bdrv_eject(bs, eject_flag);
                   1586:     }
                   1587:     if (ret == -ENOTSUP) {
                   1588:         if (eject_flag)
                   1589:             bdrv_close(bs);
1.1.1.13! root     1590:         ret = 0;
1.1.1.5   root     1591:     }
1.1.1.13! root     1592: 
        !          1593:     return ret;
1.1.1.5   root     1594: }
                   1595: 
                   1596: int bdrv_is_locked(BlockDriverState *bs)
                   1597: {
                   1598:     return bs->locked;
                   1599: }
                   1600: 
                   1601: /**
                   1602:  * Lock or unlock the media (if it is locked, the user won't be able
                   1603:  * to eject it manually).
                   1604:  */
                   1605: void bdrv_set_locked(BlockDriverState *bs, int locked)
                   1606: {
                   1607:     BlockDriver *drv = bs->drv;
                   1608: 
                   1609:     bs->locked = locked;
                   1610:     if (drv && drv->bdrv_set_locked) {
                   1611:         drv->bdrv_set_locked(bs, locked);
                   1612:     }
1.1       root     1613: }
1.1.1.6   root     1614: 
                   1615: /* needed for generic scsi interface */
                   1616: 
                   1617: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   1618: {
                   1619:     BlockDriver *drv = bs->drv;
                   1620: 
                   1621:     if (drv && drv->bdrv_ioctl)
                   1622:         return drv->bdrv_ioctl(bs, req, buf);
                   1623:     return -ENOTSUP;
                   1624: }
1.1.1.13! root     1625: 
        !          1626: BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
        !          1627:         unsigned long int req, void *buf,
        !          1628:         BlockDriverCompletionFunc *cb, void *opaque)
        !          1629: {
        !          1630:     BlockDriver *drv = bs->drv;
        !          1631: 
        !          1632:     if (drv && drv->bdrv_aio_ioctl)
        !          1633:         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
        !          1634:     return NULL;
        !          1635: }
        !          1636: 
        !          1637: void *qemu_blockalign(BlockDriverState *bs, size_t size)
        !          1638: {
        !          1639:     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
        !          1640: }

unix.superglobalmegacorp.com