Annotation of qemu/block.c, revision 1.1.1.6

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.6 ! root       24: #include "qemu-common.h"
        !            25: #ifndef QEMU_IMG
        !            26: #include "console.h"
        !            27: #endif
1.1       root       28: #include "block_int.h"
                     29: 
                     30: #ifdef _BSD
                     31: #include <sys/types.h>
                     32: #include <sys/stat.h>
                     33: #include <sys/ioctl.h>
                     34: #include <sys/queue.h>
                     35: #include <sys/disk.h>
                     36: #endif
                     37: 
1.1.1.5   root       38: #define SECTOR_BITS 9
                     39: #define SECTOR_SIZE (1 << SECTOR_BITS)
1.1.1.2   root       40: 
1.1.1.5   root       41: typedef struct BlockDriverAIOCBSync {
                     42:     BlockDriverAIOCB common;
                     43:     QEMUBH *bh;
                     44:     int ret;
                     45: } BlockDriverAIOCBSync;
                     46: 
                     47: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
                     48:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                     49:         BlockDriverCompletionFunc *cb, void *opaque);
                     50: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
                     51:         int64_t sector_num, const uint8_t *buf, int nb_sectors,
                     52:         BlockDriverCompletionFunc *cb, void *opaque);
                     53: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
1.1.1.6 ! root       54: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root       55:                         uint8_t *buf, int nb_sectors);
                     56: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                     57:                          const uint8_t *buf, int nb_sectors);
1.1.1.3   root       58: 
1.1.1.6 ! root       59: BlockDriverState *bdrv_first;
1.1       root       60: static BlockDriver *first_drv;
                     61: 
1.1.1.5   root       62: int path_is_absolute(const char *path)
                     63: {
                     64:     const char *p;
                     65: #ifdef _WIN32
                     66:     /* specific case for names like: "\\.\d:" */
                     67:     if (*path == '/' || *path == '\\')
                     68:         return 1;
                     69: #endif
                     70:     p = strchr(path, ':');
                     71:     if (p)
                     72:         p++;
                     73:     else
                     74:         p = path;
                     75: #ifdef _WIN32
                     76:     return (*p == '/' || *p == '\\');
                     77: #else
                     78:     return (*p == '/');
                     79: #endif
1.1.1.2   root       80: }
                     81: 
1.1.1.5   root       82: /* if filename is absolute, just copy it to dest. Otherwise, build a
                     83:    path to it by considering it is relative to base_path. URL are
                     84:    supported. */
                     85: void path_combine(char *dest, int dest_size,
                     86:                   const char *base_path,
                     87:                   const char *filename)
                     88: {
                     89:     const char *p, *p1;
                     90:     int len;
                     91: 
                     92:     if (dest_size <= 0)
                     93:         return;
                     94:     if (path_is_absolute(filename)) {
                     95:         pstrcpy(dest, dest_size, filename);
                     96:     } else {
                     97:         p = strchr(base_path, ':');
                     98:         if (p)
                     99:             p++;
                    100:         else
                    101:             p = base_path;
                    102:         p1 = strrchr(base_path, '/');
                    103: #ifdef _WIN32
                    104:         {
                    105:             const char *p2;
                    106:             p2 = strrchr(base_path, '\\');
                    107:             if (!p1 || p2 > p1)
                    108:                 p1 = p2;
1.1.1.2   root      109:         }
1.1.1.5   root      110: #endif
                    111:         if (p1)
                    112:             p1++;
                    113:         else
                    114:             p1 = base_path;
                    115:         if (p1 > p)
                    116:             p = p1;
                    117:         len = p - base_path;
                    118:         if (len > dest_size - 1)
                    119:             len = dest_size - 1;
                    120:         memcpy(dest, base_path, len);
                    121:         dest[len] = '\0';
                    122:         pstrcat(dest, dest_size, filename);
1.1.1.2   root      123:     }
                    124: }
                    125: 
                    126: 
1.1.1.6 ! root      127: static void bdrv_register(BlockDriver *bdrv)
1.1       root      128: {
1.1.1.5   root      129:     if (!bdrv->bdrv_aio_read) {
                    130:         /* add AIO emulation layer */
                    131:         bdrv->bdrv_aio_read = bdrv_aio_read_em;
                    132:         bdrv->bdrv_aio_write = bdrv_aio_write_em;
                    133:         bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
                    134:         bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
                    135:     } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
                    136:         /* add synchronous IO emulation layer */
                    137:         bdrv->bdrv_read = bdrv_read_em;
                    138:         bdrv->bdrv_write = bdrv_write_em;
                    139:     }
1.1       root      140:     bdrv->next = first_drv;
                    141:     first_drv = bdrv;
                    142: }
                    143: 
                    144: /* create a new block device (by default it is empty) */
                    145: BlockDriverState *bdrv_new(const char *device_name)
                    146: {
                    147:     BlockDriverState **pbs, *bs;
                    148: 
                    149:     bs = qemu_mallocz(sizeof(BlockDriverState));
                    150:     if(!bs)
                    151:         return NULL;
                    152:     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
                    153:     if (device_name[0] != '\0') {
                    154:         /* insert at the end */
                    155:         pbs = &bdrv_first;
                    156:         while (*pbs != NULL)
                    157:             pbs = &(*pbs)->next;
                    158:         *pbs = bs;
                    159:     }
                    160:     return bs;
                    161: }
                    162: 
                    163: BlockDriver *bdrv_find_format(const char *format_name)
                    164: {
                    165:     BlockDriver *drv1;
                    166:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
                    167:         if (!strcmp(drv1->format_name, format_name))
                    168:             return drv1;
                    169:     }
                    170:     return NULL;
                    171: }
                    172: 
1.1.1.6 ! root      173: int bdrv_create(BlockDriver *drv,
1.1       root      174:                 const char *filename, int64_t size_in_sectors,
                    175:                 const char *backing_file, int flags)
                    176: {
                    177:     if (!drv->bdrv_create)
                    178:         return -ENOTSUP;
                    179:     return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
                    180: }
                    181: 
                    182: #ifdef _WIN32
1.1.1.2   root      183: void get_tmp_filename(char *filename, int size)
1.1       root      184: {
1.1.1.5   root      185:     char temp_dir[MAX_PATH];
1.1.1.6 ! root      186: 
1.1.1.5   root      187:     GetTempPath(MAX_PATH, temp_dir);
                    188:     GetTempFileName(temp_dir, "qem", 0, filename);
1.1       root      189: }
                    190: #else
1.1.1.2   root      191: void get_tmp_filename(char *filename, int size)
1.1       root      192: {
                    193:     int fd;
                    194:     /* XXX: race condition possible */
                    195:     pstrcpy(filename, size, "/tmp/vl.XXXXXX");
                    196:     fd = mkstemp(filename);
                    197:     close(fd);
                    198: }
                    199: #endif
                    200: 
1.1.1.5   root      201: #ifdef _WIN32
                    202: static int is_windows_drive_prefix(const char *filename)
                    203: {
                    204:     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
                    205:              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
                    206:             filename[1] == ':');
                    207: }
1.1.1.6 ! root      208: 
1.1.1.5   root      209: static int is_windows_drive(const char *filename)
                    210: {
1.1.1.6 ! root      211:     if (is_windows_drive_prefix(filename) &&
1.1.1.5   root      212:         filename[2] == '\0')
                    213:         return 1;
                    214:     if (strstart(filename, "\\\\.\\", NULL) ||
                    215:         strstart(filename, "//./", NULL))
                    216:         return 1;
                    217:     return 0;
                    218: }
                    219: #endif
                    220: 
                    221: static BlockDriver *find_protocol(const char *filename)
                    222: {
                    223:     BlockDriver *drv1;
                    224:     char protocol[128];
                    225:     int len;
                    226:     const char *p;
                    227: 
                    228: #ifdef _WIN32
                    229:     if (is_windows_drive(filename) ||
                    230:         is_windows_drive_prefix(filename))
                    231:         return &bdrv_raw;
                    232: #endif
                    233:     p = strchr(filename, ':');
                    234:     if (!p)
                    235:         return &bdrv_raw;
                    236:     len = p - filename;
                    237:     if (len > sizeof(protocol) - 1)
                    238:         len = sizeof(protocol) - 1;
                    239:     memcpy(protocol, filename, len);
                    240:     protocol[len] = '\0';
                    241:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.6 ! root      242:         if (drv1->protocol_name &&
1.1.1.5   root      243:             !strcmp(drv1->protocol_name, protocol))
                    244:             return drv1;
                    245:     }
                    246:     return NULL;
                    247: }
                    248: 
1.1       root      249: /* XXX: force raw format if block or character device ? It would
                    250:    simplify the BSD case */
                    251: static BlockDriver *find_image_format(const char *filename)
                    252: {
1.1.1.5   root      253:     int ret, score, score_max;
1.1       root      254:     BlockDriver *drv1, *drv;
1.1.1.5   root      255:     uint8_t buf[2048];
                    256:     BlockDriverState *bs;
1.1.1.6 ! root      257: 
1.1.1.5   root      258:     /* detect host devices. By convention, /dev/cdrom[N] is always
                    259:        recognized as a host CDROM */
                    260:     if (strstart(filename, "/dev/cdrom", NULL))
                    261:         return &bdrv_host_device;
                    262: #ifdef _WIN32
                    263:     if (is_windows_drive(filename))
                    264:         return &bdrv_host_device;
                    265: #else
                    266:     {
                    267:         struct stat st;
1.1.1.6 ! root      268:         if (stat(filename, &st) >= 0 &&
1.1.1.5   root      269:             (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
                    270:             return &bdrv_host_device;
1.1       root      271:         }
                    272:     }
1.1.1.5   root      273: #endif
1.1.1.6 ! root      274: 
1.1.1.5   root      275:     drv = find_protocol(filename);
                    276:     /* no need to test disk image formats for vvfat */
                    277:     if (drv == &bdrv_vvfat)
                    278:         return drv;
                    279: 
                    280:     ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
                    281:     if (ret < 0)
                    282:         return NULL;
                    283:     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
                    284:     bdrv_delete(bs);
                    285:     if (ret < 0) {
                    286:         return NULL;
                    287:     }
                    288: 
1.1       root      289:     score_max = 0;
                    290:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.5   root      291:         if (drv1->bdrv_probe) {
                    292:             score = drv1->bdrv_probe(buf, ret, filename);
                    293:             if (score > score_max) {
                    294:                 score_max = score;
                    295:                 drv = drv1;
                    296:             }
1.1       root      297:         }
                    298:     }
                    299:     return drv;
                    300: }
                    301: 
1.1.1.5   root      302: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
1.1       root      303: {
1.1.1.5   root      304:     BlockDriverState *bs;
                    305:     int ret;
                    306: 
                    307:     bs = bdrv_new("");
                    308:     if (!bs)
                    309:         return -ENOMEM;
                    310:     ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
                    311:     if (ret < 0) {
                    312:         bdrv_delete(bs);
                    313:         return ret;
1.1.1.2   root      314:     }
1.1.1.5   root      315:     *pbs = bs;
                    316:     return 0;
                    317: }
                    318: 
                    319: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
                    320: {
                    321:     return bdrv_open2(bs, filename, flags, NULL);
1.1       root      322: }
                    323: 
1.1.1.5   root      324: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
1.1       root      325:                BlockDriver *drv)
                    326: {
1.1.1.5   root      327:     int ret, open_flags;
1.1.1.6 ! root      328:     char tmp_filename[PATH_MAX];
        !           329:     char backing_filename[PATH_MAX];
        !           330: 
1.1       root      331:     bs->read_only = 0;
                    332:     bs->is_temporary = 0;
                    333:     bs->encrypted = 0;
                    334: 
1.1.1.5   root      335:     if (flags & BDRV_O_SNAPSHOT) {
1.1       root      336:         BlockDriverState *bs1;
                    337:         int64_t total_size;
1.1.1.6 ! root      338: 
1.1       root      339:         /* if snapshot, we create a temporary backing file and open it
                    340:            instead of opening 'filename' directly */
                    341: 
                    342:         /* if there is a backing file, use it */
                    343:         bs1 = bdrv_new("");
                    344:         if (!bs1) {
1.1.1.5   root      345:             return -ENOMEM;
1.1       root      346:         }
                    347:         if (bdrv_open(bs1, filename, 0) < 0) {
                    348:             bdrv_delete(bs1);
                    349:             return -1;
                    350:         }
1.1.1.5   root      351:         total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
1.1       root      352:         bdrv_delete(bs1);
1.1.1.6 ! root      353: 
1.1       root      354:         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
1.1.1.5   root      355:         realpath(filename, backing_filename);
1.1.1.6 ! root      356:         if (bdrv_create(&bdrv_qcow2, tmp_filename,
1.1.1.5   root      357:                         total_size, backing_filename, 0) < 0) {
1.1       root      358:             return -1;
                    359:         }
                    360:         filename = tmp_filename;
                    361:         bs->is_temporary = 1;
                    362:     }
                    363: 
                    364:     pstrcpy(bs->filename, sizeof(bs->filename), filename);
1.1.1.5   root      365:     if (flags & BDRV_O_FILE) {
                    366:         drv = find_protocol(filename);
1.1       root      367:         if (!drv)
1.1.1.5   root      368:             return -ENOENT;
                    369:     } else {
                    370:         if (!drv) {
                    371:             drv = find_image_format(filename);
                    372:             if (!drv)
                    373:                 return -1;
                    374:         }
1.1       root      375:     }
                    376:     bs->drv = drv;
                    377:     bs->opaque = qemu_mallocz(drv->instance_size);
                    378:     if (bs->opaque == NULL && drv->instance_size > 0)
                    379:         return -1;
1.1.1.5   root      380:     /* Note: for compatibility, we open disk image files as RDWR, and
                    381:        RDONLY as fallback */
                    382:     if (!(flags & BDRV_O_FILE))
1.1.1.6 ! root      383:         open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
1.1.1.5   root      384:     else
                    385:         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
                    386:     ret = drv->bdrv_open(bs, filename, open_flags);
                    387:     if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
                    388:         ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
                    389:         bs->read_only = 1;
                    390:     }
1.1       root      391:     if (ret < 0) {
                    392:         qemu_free(bs->opaque);
1.1.1.5   root      393:         bs->opaque = NULL;
                    394:         bs->drv = NULL;
                    395:         return ret;
                    396:     }
                    397:     if (drv->bdrv_getlength) {
                    398:         bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
1.1       root      399:     }
                    400: #ifndef _WIN32
                    401:     if (bs->is_temporary) {
                    402:         unlink(filename);
                    403:     }
                    404: #endif
1.1.1.5   root      405:     if (bs->backing_file[0] != '\0') {
1.1       root      406:         /* if there is a backing file, use it */
                    407:         bs->backing_hd = bdrv_new("");
                    408:         if (!bs->backing_hd) {
                    409:         fail:
                    410:             bdrv_close(bs);
1.1.1.5   root      411:             return -ENOMEM;
1.1       root      412:         }
1.1.1.5   root      413:         path_combine(backing_filename, sizeof(backing_filename),
                    414:                      filename, bs->backing_file);
                    415:         if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
1.1       root      416:             goto fail;
                    417:     }
                    418: 
                    419:     /* call the change callback */
1.1.1.5   root      420:     bs->media_changed = 1;
1.1       root      421:     if (bs->change_cb)
                    422:         bs->change_cb(bs->change_opaque);
                    423: 
                    424:     return 0;
                    425: }
                    426: 
                    427: void bdrv_close(BlockDriverState *bs)
                    428: {
1.1.1.5   root      429:     if (bs->drv) {
1.1       root      430:         if (bs->backing_hd)
                    431:             bdrv_delete(bs->backing_hd);
                    432:         bs->drv->bdrv_close(bs);
                    433:         qemu_free(bs->opaque);
                    434: #ifdef _WIN32
                    435:         if (bs->is_temporary) {
                    436:             unlink(bs->filename);
                    437:         }
                    438: #endif
                    439:         bs->opaque = NULL;
                    440:         bs->drv = NULL;
                    441: 
                    442:         /* call the change callback */
1.1.1.5   root      443:         bs->media_changed = 1;
1.1       root      444:         if (bs->change_cb)
                    445:             bs->change_cb(bs->change_opaque);
                    446:     }
                    447: }
                    448: 
                    449: void bdrv_delete(BlockDriverState *bs)
                    450: {
                    451:     /* XXX: remove the driver list */
                    452:     bdrv_close(bs);
                    453:     qemu_free(bs);
                    454: }
                    455: 
                    456: /* commit COW file into the raw image */
                    457: int bdrv_commit(BlockDriverState *bs)
                    458: {
1.1.1.5   root      459:     BlockDriver *drv = bs->drv;
                    460:     int64_t i, total_sectors;
1.1       root      461:     int n, j;
                    462:     unsigned char sector[512];
                    463: 
1.1.1.5   root      464:     if (!drv)
                    465:         return -ENOMEDIUM;
1.1       root      466: 
                    467:     if (bs->read_only) {
                    468:        return -EACCES;
                    469:     }
                    470: 
                    471:     if (!bs->backing_hd) {
                    472:        return -ENOTSUP;
                    473:     }
                    474: 
1.1.1.5   root      475:     total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
                    476:     for (i = 0; i < total_sectors;) {
                    477:         if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
1.1       root      478:             for(j = 0; j < n; j++) {
                    479:                 if (bdrv_read(bs, i, sector, 1) != 0) {
                    480:                     return -EIO;
                    481:                 }
                    482: 
                    483:                 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
                    484:                     return -EIO;
                    485:                 }
                    486:                 i++;
                    487:            }
                    488:        } else {
                    489:             i += n;
                    490:         }
                    491:     }
1.1.1.2   root      492: 
1.1.1.5   root      493:     if (drv->bdrv_make_empty)
                    494:        return drv->bdrv_make_empty(bs);
1.1.1.2   root      495: 
1.1       root      496:     return 0;
                    497: }
                    498: 
1.1.1.5   root      499: /* return < 0 if error. See bdrv_write() for the return codes */
1.1.1.6 ! root      500: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1.1       root      501:               uint8_t *buf, int nb_sectors)
                    502: {
                    503:     BlockDriver *drv = bs->drv;
                    504: 
1.1.1.5   root      505:     if (!drv)
                    506:         return -ENOMEDIUM;
1.1       root      507: 
1.1.1.5   root      508:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1.1       root      509:             memcpy(buf, bs->boot_sector_data, 512);
1.1.1.5   root      510:         sector_num++;
                    511:         nb_sectors--;
                    512:         buf += 512;
                    513:         if (nb_sectors == 0)
                    514:             return 0;
                    515:     }
                    516:     if (drv->bdrv_pread) {
                    517:         int ret, len;
                    518:         len = nb_sectors * 512;
                    519:         ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
                    520:         if (ret < 0)
                    521:             return ret;
                    522:         else if (ret != len)
                    523:             return -EINVAL;
1.1.1.6 ! root      524:         else {
        !           525:            bs->rd_bytes += (unsigned) len;
        !           526:            bs->rd_ops ++;
1.1.1.5   root      527:             return 0;
1.1.1.6 ! root      528:        }
1.1.1.5   root      529:     } else {
                    530:         return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
1.1       root      531:     }
                    532: }
                    533: 
1.1.1.6 ! root      534: /* Return < 0 if error. Important errors are:
1.1.1.5   root      535:   -EIO         generic I/O error (may happen for all errors)
                    536:   -ENOMEDIUM   No media inserted.
                    537:   -EINVAL      Invalid sector number or nb_sectors
                    538:   -EACCES      Trying to write a read-only device
                    539: */
1.1.1.6 ! root      540: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1.1       root      541:                const uint8_t *buf, int nb_sectors)
                    542: {
1.1.1.5   root      543:     BlockDriver *drv = bs->drv;
                    544:     if (!bs->drv)
                    545:         return -ENOMEDIUM;
1.1       root      546:     if (bs->read_only)
1.1.1.5   root      547:         return -EACCES;
1.1.1.2   root      548:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1.1.1.6 ! root      549:         memcpy(bs->boot_sector_data, buf, 512);
1.1.1.2   root      550:     }
1.1.1.5   root      551:     if (drv->bdrv_pwrite) {
                    552:         int ret, len;
                    553:         len = nb_sectors * 512;
                    554:         ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
                    555:         if (ret < 0)
                    556:             return ret;
                    557:         else if (ret != len)
                    558:             return -EIO;
1.1.1.6 ! root      559:         else {
        !           560:            bs->wr_bytes += (unsigned) len;
        !           561:            bs->wr_ops ++;
1.1.1.5   root      562:             return 0;
1.1.1.6 ! root      563:        }
1.1.1.5   root      564:     } else {
                    565:         return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
                    566:     }
1.1       root      567: }
                    568: 
1.1.1.6 ! root      569: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      570:                          uint8_t *buf, int count1)
                    571: {
                    572:     uint8_t tmp_buf[SECTOR_SIZE];
                    573:     int len, nb_sectors, count;
                    574:     int64_t sector_num;
                    575: 
                    576:     count = count1;
                    577:     /* first read to align to sector start */
                    578:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    579:     if (len > count)
                    580:         len = count;
                    581:     sector_num = offset >> SECTOR_BITS;
                    582:     if (len > 0) {
                    583:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    584:             return -EIO;
                    585:         memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
                    586:         count -= len;
                    587:         if (count == 0)
                    588:             return count1;
                    589:         sector_num++;
                    590:         buf += len;
                    591:     }
                    592: 
                    593:     /* read the sectors "in place" */
                    594:     nb_sectors = count >> SECTOR_BITS;
                    595:     if (nb_sectors > 0) {
                    596:         if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
                    597:             return -EIO;
                    598:         sector_num += nb_sectors;
                    599:         len = nb_sectors << SECTOR_BITS;
                    600:         buf += len;
                    601:         count -= len;
                    602:     }
                    603: 
                    604:     /* add data from the last sector */
                    605:     if (count > 0) {
                    606:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    607:             return -EIO;
                    608:         memcpy(buf, tmp_buf, count);
                    609:     }
                    610:     return count1;
                    611: }
                    612: 
1.1.1.6 ! root      613: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      614:                           const uint8_t *buf, int count1)
                    615: {
                    616:     uint8_t tmp_buf[SECTOR_SIZE];
                    617:     int len, nb_sectors, count;
                    618:     int64_t sector_num;
                    619: 
                    620:     count = count1;
                    621:     /* first write to align to sector start */
                    622:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    623:     if (len > count)
                    624:         len = count;
                    625:     sector_num = offset >> SECTOR_BITS;
                    626:     if (len > 0) {
                    627:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    628:             return -EIO;
                    629:         memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
                    630:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    631:             return -EIO;
                    632:         count -= len;
                    633:         if (count == 0)
                    634:             return count1;
                    635:         sector_num++;
                    636:         buf += len;
                    637:     }
                    638: 
                    639:     /* write the sectors "in place" */
                    640:     nb_sectors = count >> SECTOR_BITS;
                    641:     if (nb_sectors > 0) {
                    642:         if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
                    643:             return -EIO;
                    644:         sector_num += nb_sectors;
                    645:         len = nb_sectors << SECTOR_BITS;
                    646:         buf += len;
                    647:         count -= len;
                    648:     }
                    649: 
                    650:     /* add data from the last sector */
                    651:     if (count > 0) {
                    652:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    653:             return -EIO;
                    654:         memcpy(tmp_buf, buf, count);
                    655:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    656:             return -EIO;
                    657:     }
                    658:     return count1;
                    659: }
                    660: 
                    661: /**
1.1.1.6 ! root      662:  * Read with byte offsets (needed only for file protocols)
1.1.1.5   root      663:  */
1.1.1.6 ! root      664: int bdrv_pread(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      665:                void *buf1, int count1)
                    666: {
                    667:     BlockDriver *drv = bs->drv;
                    668: 
                    669:     if (!drv)
                    670:         return -ENOMEDIUM;
                    671:     if (!drv->bdrv_pread)
                    672:         return bdrv_pread_em(bs, offset, buf1, count1);
                    673:     return drv->bdrv_pread(bs, offset, buf1, count1);
                    674: }
                    675: 
1.1.1.6 ! root      676: /**
        !           677:  * Write with byte offsets (needed only for file protocols)
1.1.1.5   root      678:  */
1.1.1.6 ! root      679: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      680:                 const void *buf1, int count1)
                    681: {
                    682:     BlockDriver *drv = bs->drv;
                    683: 
                    684:     if (!drv)
                    685:         return -ENOMEDIUM;
                    686:     if (!drv->bdrv_pwrite)
                    687:         return bdrv_pwrite_em(bs, offset, buf1, count1);
                    688:     return drv->bdrv_pwrite(bs, offset, buf1, count1);
                    689: }
                    690: 
                    691: /**
                    692:  * Truncate file to 'offset' bytes (needed only for file protocols)
                    693:  */
                    694: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
                    695: {
                    696:     BlockDriver *drv = bs->drv;
                    697:     if (!drv)
                    698:         return -ENOMEDIUM;
                    699:     if (!drv->bdrv_truncate)
                    700:         return -ENOTSUP;
                    701:     return drv->bdrv_truncate(bs, offset);
                    702: }
                    703: 
                    704: /**
                    705:  * Length of a file in bytes. Return < 0 if error or unknown.
                    706:  */
                    707: int64_t bdrv_getlength(BlockDriverState *bs)
                    708: {
                    709:     BlockDriver *drv = bs->drv;
                    710:     if (!drv)
                    711:         return -ENOMEDIUM;
                    712:     if (!drv->bdrv_getlength) {
                    713:         /* legacy mode */
                    714:         return bs->total_sectors * SECTOR_SIZE;
                    715:     }
                    716:     return drv->bdrv_getlength(bs);
                    717: }
                    718: 
                    719: /* return 0 as number of sectors if no device present or error */
1.1.1.6 ! root      720: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1.1       root      721: {
1.1.1.5   root      722:     int64_t length;
                    723:     length = bdrv_getlength(bs);
                    724:     if (length < 0)
                    725:         length = 0;
                    726:     else
                    727:         length = length >> SECTOR_BITS;
                    728:     *nb_sectors_ptr = length;
1.1       root      729: }
                    730: 
                    731: /* force a given boot sector. */
                    732: void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
                    733: {
                    734:     bs->boot_sector_enabled = 1;
                    735:     if (size > 512)
                    736:         size = 512;
                    737:     memcpy(bs->boot_sector_data, data, size);
                    738:     memset(bs->boot_sector_data + size, 0, 512 - size);
                    739: }
                    740: 
1.1.1.6 ! root      741: void bdrv_set_geometry_hint(BlockDriverState *bs,
1.1       root      742:                             int cyls, int heads, int secs)
                    743: {
                    744:     bs->cyls = cyls;
                    745:     bs->heads = heads;
                    746:     bs->secs = secs;
                    747: }
                    748: 
                    749: void bdrv_set_type_hint(BlockDriverState *bs, int type)
                    750: {
                    751:     bs->type = type;
                    752:     bs->removable = ((type == BDRV_TYPE_CDROM ||
                    753:                       type == BDRV_TYPE_FLOPPY));
                    754: }
                    755: 
                    756: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
                    757: {
                    758:     bs->translation = translation;
                    759: }
                    760: 
1.1.1.6 ! root      761: void bdrv_get_geometry_hint(BlockDriverState *bs,
1.1       root      762:                             int *pcyls, int *pheads, int *psecs)
                    763: {
                    764:     *pcyls = bs->cyls;
                    765:     *pheads = bs->heads;
                    766:     *psecs = bs->secs;
                    767: }
                    768: 
                    769: int bdrv_get_type_hint(BlockDriverState *bs)
                    770: {
                    771:     return bs->type;
                    772: }
                    773: 
                    774: int bdrv_get_translation_hint(BlockDriverState *bs)
                    775: {
                    776:     return bs->translation;
                    777: }
                    778: 
                    779: int bdrv_is_removable(BlockDriverState *bs)
                    780: {
                    781:     return bs->removable;
                    782: }
                    783: 
                    784: int bdrv_is_read_only(BlockDriverState *bs)
                    785: {
                    786:     return bs->read_only;
                    787: }
                    788: 
1.1.1.6 ! root      789: int bdrv_is_sg(BlockDriverState *bs)
        !           790: {
        !           791:     return bs->sg;
        !           792: }
        !           793: 
1.1.1.5   root      794: /* XXX: no longer used */
1.1.1.6 ! root      795: void bdrv_set_change_cb(BlockDriverState *bs,
1.1       root      796:                         void (*change_cb)(void *opaque), void *opaque)
                    797: {
                    798:     bs->change_cb = change_cb;
                    799:     bs->change_opaque = opaque;
                    800: }
                    801: 
                    802: int bdrv_is_encrypted(BlockDriverState *bs)
                    803: {
                    804:     if (bs->backing_hd && bs->backing_hd->encrypted)
                    805:         return 1;
                    806:     return bs->encrypted;
                    807: }
                    808: 
                    809: int bdrv_set_key(BlockDriverState *bs, const char *key)
                    810: {
                    811:     int ret;
                    812:     if (bs->backing_hd && bs->backing_hd->encrypted) {
                    813:         ret = bdrv_set_key(bs->backing_hd, key);
                    814:         if (ret < 0)
                    815:             return ret;
                    816:         if (!bs->encrypted)
                    817:             return 0;
                    818:     }
                    819:     if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
                    820:         return -1;
                    821:     return bs->drv->bdrv_set_key(bs, key);
                    822: }
                    823: 
                    824: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
                    825: {
1.1.1.5   root      826:     if (!bs->drv) {
1.1       root      827:         buf[0] = '\0';
                    828:     } else {
                    829:         pstrcpy(buf, buf_size, bs->drv->format_name);
                    830:     }
                    831: }
                    832: 
1.1.1.6 ! root      833: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1.1       root      834:                          void *opaque)
                    835: {
                    836:     BlockDriver *drv;
                    837: 
                    838:     for (drv = first_drv; drv != NULL; drv = drv->next) {
                    839:         it(opaque, drv->format_name);
                    840:     }
                    841: }
                    842: 
                    843: BlockDriverState *bdrv_find(const char *name)
                    844: {
                    845:     BlockDriverState *bs;
                    846: 
                    847:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                    848:         if (!strcmp(name, bs->device_name))
                    849:             return bs;
                    850:     }
                    851:     return NULL;
                    852: }
                    853: 
                    854: void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
                    855: {
                    856:     BlockDriverState *bs;
                    857: 
                    858:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                    859:         it(opaque, bs->device_name);
                    860:     }
                    861: }
                    862: 
                    863: const char *bdrv_get_device_name(BlockDriverState *bs)
                    864: {
                    865:     return bs->device_name;
                    866: }
                    867: 
1.1.1.4   root      868: void bdrv_flush(BlockDriverState *bs)
                    869: {
                    870:     if (bs->drv->bdrv_flush)
                    871:         bs->drv->bdrv_flush(bs);
                    872:     if (bs->backing_hd)
                    873:         bdrv_flush(bs->backing_hd);
                    874: }
                    875: 
1.1.1.6 ! root      876: #ifndef QEMU_IMG
1.1       root      877: void bdrv_info(void)
                    878: {
                    879:     BlockDriverState *bs;
                    880: 
                    881:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                    882:         term_printf("%s:", bs->device_name);
                    883:         term_printf(" type=");
                    884:         switch(bs->type) {
                    885:         case BDRV_TYPE_HD:
                    886:             term_printf("hd");
                    887:             break;
                    888:         case BDRV_TYPE_CDROM:
                    889:             term_printf("cdrom");
                    890:             break;
                    891:         case BDRV_TYPE_FLOPPY:
                    892:             term_printf("floppy");
                    893:             break;
                    894:         }
                    895:         term_printf(" removable=%d", bs->removable);
                    896:         if (bs->removable) {
                    897:             term_printf(" locked=%d", bs->locked);
                    898:         }
1.1.1.5   root      899:         if (bs->drv) {
                    900:             term_printf(" file=");
                    901:            term_print_filename(bs->filename);
                    902:             if (bs->backing_file[0] != '\0') {
                    903:                 term_printf(" backing_file=");
                    904:                term_print_filename(bs->backing_file);
                    905:            }
1.1       root      906:             term_printf(" ro=%d", bs->read_only);
                    907:             term_printf(" drv=%s", bs->drv->format_name);
                    908:             if (bs->encrypted)
                    909:                 term_printf(" encrypted");
                    910:         } else {
                    911:             term_printf(" [not inserted]");
                    912:         }
                    913:         term_printf("\n");
                    914:     }
                    915: }
                    916: 
1.1.1.6 ! root      917: /* The "info blockstats" command. */
        !           918: void bdrv_info_stats (void)
        !           919: {
        !           920:     BlockDriverState *bs;
        !           921: 
        !           922:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
        !           923:        term_printf ("%s:"
        !           924:                     " rd_bytes=%" PRIu64
        !           925:                     " wr_bytes=%" PRIu64
        !           926:                     " rd_operations=%" PRIu64
        !           927:                     " wr_operations=%" PRIu64
        !           928:                     "\n",
        !           929:                     bs->device_name,
        !           930:                     bs->rd_bytes, bs->wr_bytes,
        !           931:                     bs->rd_ops, bs->wr_ops);
        !           932:     }
        !           933: }
        !           934: #endif
        !           935: 
        !           936: void bdrv_get_backing_filename(BlockDriverState *bs,
1.1.1.5   root      937:                                char *filename, int filename_size)
                    938: {
                    939:     if (!bs->backing_hd) {
                    940:         pstrcpy(filename, filename_size, "");
                    941:     } else {
                    942:         pstrcpy(filename, filename_size, bs->backing_file);
                    943:     }
                    944: }
                    945: 
1.1.1.6 ! root      946: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root      947:                           const uint8_t *buf, int nb_sectors)
                    948: {
                    949:     BlockDriver *drv = bs->drv;
                    950:     if (!drv)
                    951:         return -ENOMEDIUM;
                    952:     if (!drv->bdrv_write_compressed)
                    953:         return -ENOTSUP;
                    954:     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
                    955: }
1.1.1.6 ! root      956: 
1.1.1.5   root      957: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
                    958: {
                    959:     BlockDriver *drv = bs->drv;
                    960:     if (!drv)
                    961:         return -ENOMEDIUM;
                    962:     if (!drv->bdrv_get_info)
                    963:         return -ENOTSUP;
                    964:     memset(bdi, 0, sizeof(*bdi));
                    965:     return drv->bdrv_get_info(bs, bdi);
                    966: }
                    967: 
1.1       root      968: /**************************************************************/
1.1.1.5   root      969: /* handling of snapshots */
1.1       root      970: 
1.1.1.6 ! root      971: int bdrv_snapshot_create(BlockDriverState *bs,
1.1.1.5   root      972:                          QEMUSnapshotInfo *sn_info)
                    973: {
                    974:     BlockDriver *drv = bs->drv;
                    975:     if (!drv)
                    976:         return -ENOMEDIUM;
                    977:     if (!drv->bdrv_snapshot_create)
                    978:         return -ENOTSUP;
                    979:     return drv->bdrv_snapshot_create(bs, sn_info);
                    980: }
1.1       root      981: 
1.1.1.6 ! root      982: int bdrv_snapshot_goto(BlockDriverState *bs,
1.1.1.5   root      983:                        const char *snapshot_id)
1.1       root      984: {
1.1.1.5   root      985:     BlockDriver *drv = bs->drv;
                    986:     if (!drv)
                    987:         return -ENOMEDIUM;
                    988:     if (!drv->bdrv_snapshot_goto)
                    989:         return -ENOTSUP;
                    990:     return drv->bdrv_snapshot_goto(bs, snapshot_id);
1.1       root      991: }
                    992: 
1.1.1.5   root      993: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1.1       root      994: {
1.1.1.5   root      995:     BlockDriver *drv = bs->drv;
                    996:     if (!drv)
                    997:         return -ENOMEDIUM;
                    998:     if (!drv->bdrv_snapshot_delete)
                    999:         return -ENOTSUP;
                   1000:     return drv->bdrv_snapshot_delete(bs, snapshot_id);
                   1001: }
1.1       root     1002: 
1.1.1.6 ! root     1003: int bdrv_snapshot_list(BlockDriverState *bs,
1.1.1.5   root     1004:                        QEMUSnapshotInfo **psn_info)
                   1005: {
                   1006:     BlockDriver *drv = bs->drv;
                   1007:     if (!drv)
                   1008:         return -ENOMEDIUM;
                   1009:     if (!drv->bdrv_snapshot_list)
                   1010:         return -ENOTSUP;
                   1011:     return drv->bdrv_snapshot_list(bs, psn_info);
                   1012: }
                   1013: 
                   1014: #define NB_SUFFIXES 4
                   1015: 
                   1016: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
                   1017: {
                   1018:     static const char suffixes[NB_SUFFIXES] = "KMGT";
                   1019:     int64_t base;
                   1020:     int i;
                   1021: 
                   1022:     if (size <= 999) {
                   1023:         snprintf(buf, buf_size, "%" PRId64, size);
                   1024:     } else {
                   1025:         base = 1024;
                   1026:         for(i = 0; i < NB_SUFFIXES; i++) {
                   1027:             if (size < (10 * base)) {
1.1.1.6 ! root     1028:                 snprintf(buf, buf_size, "%0.1f%c",
1.1.1.5   root     1029:                          (double)size / base,
                   1030:                          suffixes[i]);
                   1031:                 break;
                   1032:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1.1.1.6 ! root     1033:                 snprintf(buf, buf_size, "%" PRId64 "%c",
1.1.1.5   root     1034:                          ((size + (base >> 1)) / base),
                   1035:                          suffixes[i]);
                   1036:                 break;
                   1037:             }
                   1038:             base = base * 1024;
                   1039:         }
1.1       root     1040:     }
1.1.1.5   root     1041:     return buf;
                   1042: }
                   1043: 
                   1044: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
                   1045: {
                   1046:     char buf1[128], date_buf[128], clock_buf[128];
                   1047: #ifdef _WIN32
                   1048:     struct tm *ptm;
1.1.1.2   root     1049: #else
1.1.1.5   root     1050:     struct tm tm;
1.1.1.2   root     1051: #endif
1.1.1.5   root     1052:     time_t ti;
                   1053:     int64_t secs;
                   1054: 
                   1055:     if (!sn) {
1.1.1.6 ! root     1056:         snprintf(buf, buf_size,
        !          1057:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1058:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
                   1059:     } else {
                   1060:         ti = sn->date_sec;
1.1       root     1061: #ifdef _WIN32
1.1.1.5   root     1062:         ptm = localtime(&ti);
                   1063:         strftime(date_buf, sizeof(date_buf),
                   1064:                  "%Y-%m-%d %H:%M:%S", ptm);
                   1065: #else
                   1066:         localtime_r(&ti, &tm);
                   1067:         strftime(date_buf, sizeof(date_buf),
                   1068:                  "%Y-%m-%d %H:%M:%S", &tm);
1.1       root     1069: #endif
1.1.1.5   root     1070:         secs = sn->vm_clock_nsec / 1000000000;
                   1071:         snprintf(clock_buf, sizeof(clock_buf),
                   1072:                  "%02d:%02d:%02d.%03d",
                   1073:                  (int)(secs / 3600),
                   1074:                  (int)((secs / 60) % 60),
1.1.1.6 ! root     1075:                  (int)(secs % 60),
1.1.1.5   root     1076:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
                   1077:         snprintf(buf, buf_size,
1.1.1.6 ! root     1078:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1079:                  sn->id_str, sn->name,
                   1080:                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
                   1081:                  date_buf,
                   1082:                  clock_buf);
                   1083:     }
                   1084:     return buf;
1.1       root     1085: }
                   1086: 
                   1087: 
1.1.1.5   root     1088: /**************************************************************/
                   1089: /* async I/Os */
                   1090: 
                   1091: BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
                   1092:                                 uint8_t *buf, int nb_sectors,
                   1093:                                 BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1094: {
1.1.1.5   root     1095:     BlockDriver *drv = bs->drv;
1.1.1.6 ! root     1096:     BlockDriverAIOCB *ret;
1.1.1.5   root     1097: 
                   1098:     if (!drv)
                   1099:         return NULL;
1.1.1.6 ! root     1100: 
1.1.1.5   root     1101:     /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
                   1102:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
                   1103:         memcpy(buf, bs->boot_sector_data, 512);
                   1104:         sector_num++;
                   1105:         nb_sectors--;
                   1106:         buf += 512;
                   1107:     }
                   1108: 
1.1.1.6 ! root     1109:     ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
        !          1110: 
        !          1111:     if (ret) {
        !          1112:        /* Update stats even though technically transfer has not happened. */
        !          1113:        bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
        !          1114:        bs->rd_ops ++;
        !          1115:     }
        !          1116: 
        !          1117:     return ret;
1.1       root     1118: }
                   1119: 
1.1.1.5   root     1120: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
                   1121:                                  const uint8_t *buf, int nb_sectors,
                   1122:                                  BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1123: {
1.1.1.5   root     1124:     BlockDriver *drv = bs->drv;
1.1.1.6 ! root     1125:     BlockDriverAIOCB *ret;
1.1       root     1126: 
1.1.1.5   root     1127:     if (!drv)
                   1128:         return NULL;
                   1129:     if (bs->read_only)
                   1130:         return NULL;
                   1131:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1.1.1.6 ! root     1132:         memcpy(bs->boot_sector_data, buf, 512);
1.1.1.5   root     1133:     }
1.1.1.4   root     1134: 
1.1.1.6 ! root     1135:     ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
        !          1136: 
        !          1137:     if (ret) {
        !          1138:        /* Update stats even though technically transfer has not happened. */
        !          1139:        bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
        !          1140:        bs->wr_ops ++;
        !          1141:     }
        !          1142: 
        !          1143:     return ret;
1.1.1.5   root     1144: }
                   1145: 
                   1146: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1.1.1.4   root     1147: {
1.1.1.5   root     1148:     BlockDriver *drv = acb->bs->drv;
1.1.1.4   root     1149: 
1.1.1.5   root     1150:     drv->bdrv_aio_cancel(acb);
                   1151: }
1.1.1.4   root     1152: 
                   1153: 
1.1.1.5   root     1154: /**************************************************************/
                   1155: /* async block device emulation */
1.1.1.4   root     1156: 
1.1.1.6 ! root     1157: #ifdef QEMU_IMG
1.1.1.5   root     1158: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
                   1159:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                   1160:         BlockDriverCompletionFunc *cb, void *opaque)
                   1161: {
                   1162:     int ret;
                   1163:     ret = bdrv_read(bs, sector_num, buf, nb_sectors);
                   1164:     cb(opaque, ret);
                   1165:     return NULL;
                   1166: }
1.1.1.4   root     1167: 
1.1.1.5   root     1168: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
                   1169:         int64_t sector_num, const uint8_t *buf, int nb_sectors,
                   1170:         BlockDriverCompletionFunc *cb, void *opaque)
                   1171: {
                   1172:     int ret;
                   1173:     ret = bdrv_write(bs, sector_num, buf, nb_sectors);
                   1174:     cb(opaque, ret);
                   1175:     return NULL;
1.1.1.4   root     1176: }
                   1177: 
1.1.1.5   root     1178: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
1.1.1.4   root     1179: {
                   1180: }
                   1181: #else
1.1.1.5   root     1182: static void bdrv_aio_bh_cb(void *opaque)
1.1.1.4   root     1183: {
1.1.1.5   root     1184:     BlockDriverAIOCBSync *acb = opaque;
                   1185:     acb->common.cb(acb->common.opaque, acb->ret);
                   1186:     qemu_aio_release(acb);
1.1.1.4   root     1187: }
                   1188: 
1.1.1.5   root     1189: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
                   1190:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                   1191:         BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1192: {
1.1.1.5   root     1193:     BlockDriverAIOCBSync *acb;
                   1194:     int ret;
1.1       root     1195: 
1.1.1.5   root     1196:     acb = qemu_aio_get(bs, cb, opaque);
                   1197:     if (!acb->bh)
                   1198:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
                   1199:     ret = bdrv_read(bs, sector_num, buf, nb_sectors);
                   1200:     acb->ret = ret;
                   1201:     qemu_bh_schedule(acb->bh);
                   1202:     return &acb->common;
                   1203: }
1.1       root     1204: 
1.1.1.5   root     1205: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
                   1206:         int64_t sector_num, const uint8_t *buf, int nb_sectors,
                   1207:         BlockDriverCompletionFunc *cb, void *opaque)
                   1208: {
                   1209:     BlockDriverAIOCBSync *acb;
                   1210:     int ret;
                   1211: 
                   1212:     acb = qemu_aio_get(bs, cb, opaque);
                   1213:     if (!acb->bh)
                   1214:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
                   1215:     ret = bdrv_write(bs, sector_num, buf, nb_sectors);
                   1216:     acb->ret = ret;
                   1217:     qemu_bh_schedule(acb->bh);
                   1218:     return &acb->common;
                   1219: }
                   1220: 
                   1221: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
                   1222: {
                   1223:     BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
                   1224:     qemu_bh_cancel(acb->bh);
                   1225:     qemu_aio_release(acb);
1.1       root     1226: }
1.1.1.6 ! root     1227: #endif /* !QEMU_IMG */
1.1       root     1228: 
1.1.1.5   root     1229: /**************************************************************/
                   1230: /* sync block device emulation */
                   1231: 
                   1232: static void bdrv_rw_em_cb(void *opaque, int ret)
1.1.1.4   root     1233: {
1.1.1.5   root     1234:     *(int *)opaque = ret;
1.1.1.4   root     1235: }
                   1236: 
1.1.1.5   root     1237: #define NOT_DONE 0x7fffffff
                   1238: 
1.1.1.6 ! root     1239: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1240:                         uint8_t *buf, int nb_sectors)
                   1241: {
                   1242:     int async_ret;
                   1243:     BlockDriverAIOCB *acb;
                   1244: 
                   1245:     async_ret = NOT_DONE;
                   1246:     qemu_aio_wait_start();
1.1.1.6 ! root     1247:     acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1.1.1.5   root     1248:                         bdrv_rw_em_cb, &async_ret);
                   1249:     if (acb == NULL) {
                   1250:         qemu_aio_wait_end();
                   1251:         return -1;
                   1252:     }
                   1253:     while (async_ret == NOT_DONE) {
                   1254:         qemu_aio_wait();
                   1255:     }
                   1256:     qemu_aio_wait_end();
                   1257:     return async_ret;
                   1258: }
                   1259: 
                   1260: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                   1261:                          const uint8_t *buf, int nb_sectors)
                   1262: {
                   1263:     int async_ret;
                   1264:     BlockDriverAIOCB *acb;
                   1265: 
                   1266:     async_ret = NOT_DONE;
                   1267:     qemu_aio_wait_start();
1.1.1.6 ! root     1268:     acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1.1.1.5   root     1269:                          bdrv_rw_em_cb, &async_ret);
                   1270:     if (acb == NULL) {
                   1271:         qemu_aio_wait_end();
                   1272:         return -1;
                   1273:     }
                   1274:     while (async_ret == NOT_DONE) {
                   1275:         qemu_aio_wait();
                   1276:     }
                   1277:     qemu_aio_wait_end();
                   1278:     return async_ret;
                   1279: }
1.1       root     1280: 
                   1281: void bdrv_init(void)
                   1282: {
                   1283:     bdrv_register(&bdrv_raw);
1.1.1.5   root     1284:     bdrv_register(&bdrv_host_device);
1.1       root     1285: #ifndef _WIN32
                   1286:     bdrv_register(&bdrv_cow);
                   1287: #endif
                   1288:     bdrv_register(&bdrv_qcow);
                   1289:     bdrv_register(&bdrv_vmdk);
                   1290:     bdrv_register(&bdrv_cloop);
                   1291:     bdrv_register(&bdrv_dmg);
                   1292:     bdrv_register(&bdrv_bochs);
                   1293:     bdrv_register(&bdrv_vpc);
                   1294:     bdrv_register(&bdrv_vvfat);
1.1.1.5   root     1295:     bdrv_register(&bdrv_qcow2);
1.1.1.6 ! root     1296:     bdrv_register(&bdrv_parallels);
1.1.1.5   root     1297: }
                   1298: 
                   1299: void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
                   1300:                    void *opaque)
                   1301: {
                   1302:     BlockDriver *drv;
                   1303:     BlockDriverAIOCB *acb;
                   1304: 
                   1305:     drv = bs->drv;
                   1306:     if (drv->free_aiocb) {
                   1307:         acb = drv->free_aiocb;
                   1308:         drv->free_aiocb = acb->next;
                   1309:     } else {
                   1310:         acb = qemu_mallocz(drv->aiocb_size);
                   1311:         if (!acb)
                   1312:             return NULL;
                   1313:     }
                   1314:     acb->bs = bs;
                   1315:     acb->cb = cb;
                   1316:     acb->opaque = opaque;
                   1317:     return acb;
                   1318: }
                   1319: 
                   1320: void qemu_aio_release(void *p)
                   1321: {
                   1322:     BlockDriverAIOCB *acb = p;
                   1323:     BlockDriver *drv = acb->bs->drv;
                   1324:     acb->next = drv->free_aiocb;
                   1325:     drv->free_aiocb = acb;
                   1326: }
                   1327: 
                   1328: /**************************************************************/
                   1329: /* removable device support */
                   1330: 
                   1331: /**
                   1332:  * Return TRUE if the media is present
                   1333:  */
                   1334: int bdrv_is_inserted(BlockDriverState *bs)
                   1335: {
                   1336:     BlockDriver *drv = bs->drv;
                   1337:     int ret;
                   1338:     if (!drv)
                   1339:         return 0;
                   1340:     if (!drv->bdrv_is_inserted)
                   1341:         return 1;
                   1342:     ret = drv->bdrv_is_inserted(bs);
                   1343:     return ret;
                   1344: }
                   1345: 
                   1346: /**
                   1347:  * Return TRUE if the media changed since the last call to this
1.1.1.6 ! root     1348:  * function. It is currently only used for floppy disks
1.1.1.5   root     1349:  */
                   1350: int bdrv_media_changed(BlockDriverState *bs)
                   1351: {
                   1352:     BlockDriver *drv = bs->drv;
                   1353:     int ret;
                   1354: 
                   1355:     if (!drv || !drv->bdrv_media_changed)
                   1356:         ret = -ENOTSUP;
                   1357:     else
                   1358:         ret = drv->bdrv_media_changed(bs);
                   1359:     if (ret == -ENOTSUP)
                   1360:         ret = bs->media_changed;
                   1361:     bs->media_changed = 0;
                   1362:     return ret;
                   1363: }
                   1364: 
                   1365: /**
                   1366:  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
                   1367:  */
                   1368: void bdrv_eject(BlockDriverState *bs, int eject_flag)
                   1369: {
                   1370:     BlockDriver *drv = bs->drv;
                   1371:     int ret;
                   1372: 
                   1373:     if (!drv || !drv->bdrv_eject) {
                   1374:         ret = -ENOTSUP;
                   1375:     } else {
                   1376:         ret = drv->bdrv_eject(bs, eject_flag);
                   1377:     }
                   1378:     if (ret == -ENOTSUP) {
                   1379:         if (eject_flag)
                   1380:             bdrv_close(bs);
                   1381:     }
                   1382: }
                   1383: 
                   1384: int bdrv_is_locked(BlockDriverState *bs)
                   1385: {
                   1386:     return bs->locked;
                   1387: }
                   1388: 
                   1389: /**
                   1390:  * Lock or unlock the media (if it is locked, the user won't be able
                   1391:  * to eject it manually).
                   1392:  */
                   1393: void bdrv_set_locked(BlockDriverState *bs, int locked)
                   1394: {
                   1395:     BlockDriver *drv = bs->drv;
                   1396: 
                   1397:     bs->locked = locked;
                   1398:     if (drv && drv->bdrv_set_locked) {
                   1399:         drv->bdrv_set_locked(bs, locked);
                   1400:     }
1.1       root     1401: }
1.1.1.6 ! root     1402: 
        !          1403: /* needed for generic scsi interface */
        !          1404: 
        !          1405: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
        !          1406: {
        !          1407:     BlockDriver *drv = bs->drv;
        !          1408: 
        !          1409:     if (drv && drv->bdrv_ioctl)
        !          1410:         return drv->bdrv_ioctl(bs, req, buf);
        !          1411:     return -ENOTSUP;
        !          1412: }

unix.superglobalmegacorp.com