File:  [Qemu by Fabrice Bellard] / qemu / block.c
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:50:42 2018 UTC (2 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0100, HEAD
qemu 0.10.0

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

unix.superglobalmegacorp.com