File:  [Qemu by Fabrice Bellard] / qemu / block.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:47:23 2018 UTC (2 years, 5 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0091, HEAD
qemu 0.9.1

    1: /*
    2:  * QEMU System Emulator block driver
    3:  *
    4:  * Copyright (c) 2003 Fabrice Bellard
    5:  *
    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:  */
   24: #include "qemu-common.h"
   25: #ifndef QEMU_IMG
   26: #include "console.h"
   27: #endif
   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: 
   38: #define SECTOR_BITS 9
   39: #define SECTOR_SIZE (1 << SECTOR_BITS)
   40: 
   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);
   54: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
   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);
   58: 
   59: BlockDriverState *bdrv_first;
   60: static BlockDriver *first_drv;
   61: 
   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
   80: }
   81: 
   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;
  109:         }
  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);
  123:     }
  124: }
  125: 
  126: 
  127: static void bdrv_register(BlockDriver *bdrv)
  128: {
  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:     }
  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: 
  173: int bdrv_create(BlockDriver *drv,
  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
  183: void get_tmp_filename(char *filename, int size)
  184: {
  185:     char temp_dir[MAX_PATH];
  186: 
  187:     GetTempPath(MAX_PATH, temp_dir);
  188:     GetTempFileName(temp_dir, "qem", 0, filename);
  189: }
  190: #else
  191: void get_tmp_filename(char *filename, int size)
  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: 
  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: }
  208: 
  209: static int is_windows_drive(const char *filename)
  210: {
  211:     if (is_windows_drive_prefix(filename) &&
  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) {
  242:         if (drv1->protocol_name &&
  243:             !strcmp(drv1->protocol_name, protocol))
  244:             return drv1;
  245:     }
  246:     return NULL;
  247: }
  248: 
  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: {
  253:     int ret, score, score_max;
  254:     BlockDriver *drv1, *drv;
  255:     uint8_t buf[2048];
  256:     BlockDriverState *bs;
  257: 
  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;
  268:         if (stat(filename, &st) >= 0 &&
  269:             (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
  270:             return &bdrv_host_device;
  271:         }
  272:     }
  273: #endif
  274: 
  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: 
  289:     score_max = 0;
  290:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
  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:             }
  297:         }
  298:     }
  299:     return drv;
  300: }
  301: 
  302: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
  303: {
  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;
  314:     }
  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);
  322: }
  323: 
  324: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
  325:                BlockDriver *drv)
  326: {
  327:     int ret, open_flags;
  328:     char tmp_filename[PATH_MAX];
  329:     char backing_filename[PATH_MAX];
  330: 
  331:     bs->read_only = 0;
  332:     bs->is_temporary = 0;
  333:     bs->encrypted = 0;
  334: 
  335:     if (flags & BDRV_O_SNAPSHOT) {
  336:         BlockDriverState *bs1;
  337:         int64_t total_size;
  338: 
  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) {
  345:             return -ENOMEM;
  346:         }
  347:         if (bdrv_open(bs1, filename, 0) < 0) {
  348:             bdrv_delete(bs1);
  349:             return -1;
  350:         }
  351:         total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
  352:         bdrv_delete(bs1);
  353: 
  354:         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
  355:         realpath(filename, backing_filename);
  356:         if (bdrv_create(&bdrv_qcow2, tmp_filename,
  357:                         total_size, backing_filename, 0) < 0) {
  358:             return -1;
  359:         }
  360:         filename = tmp_filename;
  361:         bs->is_temporary = 1;
  362:     }
  363: 
  364:     pstrcpy(bs->filename, sizeof(bs->filename), filename);
  365:     if (flags & BDRV_O_FILE) {
  366:         drv = find_protocol(filename);
  367:         if (!drv)
  368:             return -ENOENT;
  369:     } else {
  370:         if (!drv) {
  371:             drv = find_image_format(filename);
  372:             if (!drv)
  373:                 return -1;
  374:         }
  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;
  380:     /* Note: for compatibility, we open disk image files as RDWR, and
  381:        RDONLY as fallback */
  382:     if (!(flags & BDRV_O_FILE))
  383:         open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
  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:     }
  391:     if (ret < 0) {
  392:         qemu_free(bs->opaque);
  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;
  399:     }
  400: #ifndef _WIN32
  401:     if (bs->is_temporary) {
  402:         unlink(filename);
  403:     }
  404: #endif
  405:     if (bs->backing_file[0] != '\0') {
  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);
  411:             return -ENOMEM;
  412:         }
  413:         path_combine(backing_filename, sizeof(backing_filename),
  414:                      filename, bs->backing_file);
  415:         if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
  416:             goto fail;
  417:     }
  418: 
  419:     /* call the change callback */
  420:     bs->media_changed = 1;
  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: {
  429:     if (bs->drv) {
  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 */
  443:         bs->media_changed = 1;
  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: {
  459:     BlockDriver *drv = bs->drv;
  460:     int64_t i, total_sectors;
  461:     int n, j;
  462:     unsigned char sector[512];
  463: 
  464:     if (!drv)
  465:         return -ENOMEDIUM;
  466: 
  467:     if (bs->read_only) {
  468: 	return -EACCES;
  469:     }
  470: 
  471:     if (!bs->backing_hd) {
  472: 	return -ENOTSUP;
  473:     }
  474: 
  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)) {
  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:     }
  492: 
  493:     if (drv->bdrv_make_empty)
  494: 	return drv->bdrv_make_empty(bs);
  495: 
  496:     return 0;
  497: }
  498: 
  499: /* return < 0 if error. See bdrv_write() for the return codes */
  500: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
  501:               uint8_t *buf, int nb_sectors)
  502: {
  503:     BlockDriver *drv = bs->drv;
  504: 
  505:     if (!drv)
  506:         return -ENOMEDIUM;
  507: 
  508:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
  509:             memcpy(buf, bs->boot_sector_data, 512);
  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;
  524:         else {
  525: 	    bs->rd_bytes += (unsigned) len;
  526: 	    bs->rd_ops ++;
  527:             return 0;
  528: 	}
  529:     } else {
  530:         return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
  531:     }
  532: }
  533: 
  534: /* Return < 0 if error. Important errors are:
  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: */
  540: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
  541:                const uint8_t *buf, int nb_sectors)
  542: {
  543:     BlockDriver *drv = bs->drv;
  544:     if (!bs->drv)
  545:         return -ENOMEDIUM;
  546:     if (bs->read_only)
  547:         return -EACCES;
  548:     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
  549:         memcpy(bs->boot_sector_data, buf, 512);
  550:     }
  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;
  559:         else {
  560: 	    bs->wr_bytes += (unsigned) len;
  561: 	    bs->wr_ops ++;
  562:             return 0;
  563: 	}
  564:     } else {
  565:         return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
  566:     }
  567: }
  568: 
  569: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
  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: 
  613: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
  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: /**
  662:  * Read with byte offsets (needed only for file protocols)
  663:  */
  664: int bdrv_pread(BlockDriverState *bs, int64_t offset,
  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: 
  676: /**
  677:  * Write with byte offsets (needed only for file protocols)
  678:  */
  679: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
  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 */
  720: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
  721: {
  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;
  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: 
  741: void bdrv_set_geometry_hint(BlockDriverState *bs,
  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: 
  761: void bdrv_get_geometry_hint(BlockDriverState *bs,
  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: 
  789: int bdrv_is_sg(BlockDriverState *bs)
  790: {
  791:     return bs->sg;
  792: }
  793: 
  794: /* XXX: no longer used */
  795: void bdrv_set_change_cb(BlockDriverState *bs,
  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: {
  826:     if (!bs->drv) {
  827:         buf[0] = '\0';
  828:     } else {
  829:         pstrcpy(buf, buf_size, bs->drv->format_name);
  830:     }
  831: }
  832: 
  833: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
  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: 
  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: 
  876: #ifndef QEMU_IMG
  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:         }
  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: 	    }
  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: 
  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,
  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: 
  946: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
  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: }
  956: 
  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: 
  968: /**************************************************************/
  969: /* handling of snapshots */
  970: 
  971: int bdrv_snapshot_create(BlockDriverState *bs,
  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: }
  981: 
  982: int bdrv_snapshot_goto(BlockDriverState *bs,
  983:                        const char *snapshot_id)
  984: {
  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);
  991: }
  992: 
  993: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
  994: {
  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: }
 1002: 
 1003: int bdrv_snapshot_list(BlockDriverState *bs,
 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)) {
 1028:                 snprintf(buf, buf_size, "%0.1f%c",
 1029:                          (double)size / base,
 1030:                          suffixes[i]);
 1031:                 break;
 1032:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
 1033:                 snprintf(buf, buf_size, "%" PRId64 "%c",
 1034:                          ((size + (base >> 1)) / base),
 1035:                          suffixes[i]);
 1036:                 break;
 1037:             }
 1038:             base = base * 1024;
 1039:         }
 1040:     }
 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;
 1049: #else
 1050:     struct tm tm;
 1051: #endif
 1052:     time_t ti;
 1053:     int64_t secs;
 1054: 
 1055:     if (!sn) {
 1056:         snprintf(buf, buf_size,
 1057:                  "%-10s%-20s%7s%20s%15s",
 1058:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
 1059:     } else {
 1060:         ti = sn->date_sec;
 1061: #ifdef _WIN32
 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);
 1069: #endif
 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),
 1075:                  (int)(secs % 60),
 1076:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
 1077:         snprintf(buf, buf_size,
 1078:                  "%-10s%-20s%7s%20s%15s",
 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;
 1085: }
 1086: 
 1087: 
 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)
 1094: {
 1095:     BlockDriver *drv = bs->drv;
 1096:     BlockDriverAIOCB *ret;
 1097: 
 1098:     if (!drv)
 1099:         return NULL;
 1100: 
 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: 
 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;
 1118: }
 1119: 
 1120: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
 1121:                                  const uint8_t *buf, int nb_sectors,
 1122:                                  BlockDriverCompletionFunc *cb, void *opaque)
 1123: {
 1124:     BlockDriver *drv = bs->drv;
 1125:     BlockDriverAIOCB *ret;
 1126: 
 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) {
 1132:         memcpy(bs->boot_sector_data, buf, 512);
 1133:     }
 1134: 
 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;
 1144: }
 1145: 
 1146: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
 1147: {
 1148:     BlockDriver *drv = acb->bs->drv;
 1149: 
 1150:     drv->bdrv_aio_cancel(acb);
 1151: }
 1152: 
 1153: 
 1154: /**************************************************************/
 1155: /* async block device emulation */
 1156: 
 1157: #ifdef QEMU_IMG
 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: }
 1167: 
 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;
 1176: }
 1177: 
 1178: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
 1179: {
 1180: }
 1181: #else
 1182: static void bdrv_aio_bh_cb(void *opaque)
 1183: {
 1184:     BlockDriverAIOCBSync *acb = opaque;
 1185:     acb->common.cb(acb->common.opaque, acb->ret);
 1186:     qemu_aio_release(acb);
 1187: }
 1188: 
 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)
 1192: {
 1193:     BlockDriverAIOCBSync *acb;
 1194:     int ret;
 1195: 
 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: }
 1204: 
 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);
 1226: }
 1227: #endif /* !QEMU_IMG */
 1228: 
 1229: /**************************************************************/
 1230: /* sync block device emulation */
 1231: 
 1232: static void bdrv_rw_em_cb(void *opaque, int ret)
 1233: {
 1234:     *(int *)opaque = ret;
 1235: }
 1236: 
 1237: #define NOT_DONE 0x7fffffff
 1238: 
 1239: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
 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();
 1247:     acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
 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();
 1268:     acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
 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: }
 1280: 
 1281: void bdrv_init(void)
 1282: {
 1283:     bdrv_register(&bdrv_raw);
 1284:     bdrv_register(&bdrv_host_device);
 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);
 1295:     bdrv_register(&bdrv_qcow2);
 1296:     bdrv_register(&bdrv_parallels);
 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
 1348:  * function. It is currently only used for floppy disks
 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:     }
 1401: }
 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