Annotation of qemu/block.c, revision 1.1.1.14

1.1       root        1: /*
                      2:  * QEMU System Emulator block driver
1.1.1.6   root        3:  *
1.1       root        4:  * Copyright (c) 2003 Fabrice Bellard
1.1.1.6   root        5:  *
1.1       root        6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
1.1.1.7   root       24: #include "config-host.h"
1.1.1.6   root       25: #include "qemu-common.h"
1.1.1.13  root       26: #include "monitor.h"
1.1       root       27: #include "block_int.h"
1.1.1.13  root       28: #include "module.h"
1.1.1.14! root       29: #include "qemu-objects.h"
1.1       root       30: 
1.1.1.14! root       31: #ifdef CONFIG_BSD
1.1       root       32: #include <sys/types.h>
                     33: #include <sys/stat.h>
                     34: #include <sys/ioctl.h>
1.1.1.14! root       35: #include <sys/queue.h>
1.1.1.13  root       36: #ifndef __DragonFly__
1.1       root       37: #include <sys/disk.h>
                     38: #endif
1.1.1.13  root       39: #endif
                     40: 
                     41: #ifdef _WIN32
                     42: #include <windows.h>
                     43: #endif
1.1       root       44: 
1.1.1.13  root       45: static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
                     46:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root       47:         BlockDriverCompletionFunc *cb, void *opaque);
1.1.1.13  root       48: static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
                     49:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root       50:         BlockDriverCompletionFunc *cb, void *opaque);
1.1.1.14! root       51: static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
        !            52:         BlockDriverCompletionFunc *cb, void *opaque);
1.1.1.6   root       53: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root       54:                         uint8_t *buf, int nb_sectors);
                     55: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                     56:                          const uint8_t *buf, int nb_sectors);
1.1.1.3   root       57: 
1.1.1.6   root       58: BlockDriverState *bdrv_first;
1.1.1.7   root       59: 
1.1       root       60: static BlockDriver *first_drv;
                     61: 
1.1.1.14! root       62: /* If non-zero, use only whitelisted block drivers */
        !            63: static int use_bdrv_whitelist;
        !            64: 
1.1.1.5   root       65: int path_is_absolute(const char *path)
                     66: {
                     67:     const char *p;
                     68: #ifdef _WIN32
                     69:     /* specific case for names like: "\\.\d:" */
                     70:     if (*path == '/' || *path == '\\')
                     71:         return 1;
                     72: #endif
                     73:     p = strchr(path, ':');
                     74:     if (p)
                     75:         p++;
                     76:     else
                     77:         p = path;
                     78: #ifdef _WIN32
                     79:     return (*p == '/' || *p == '\\');
                     80: #else
                     81:     return (*p == '/');
                     82: #endif
1.1.1.2   root       83: }
                     84: 
1.1.1.5   root       85: /* if filename is absolute, just copy it to dest. Otherwise, build a
                     86:    path to it by considering it is relative to base_path. URL are
                     87:    supported. */
                     88: void path_combine(char *dest, int dest_size,
                     89:                   const char *base_path,
                     90:                   const char *filename)
                     91: {
                     92:     const char *p, *p1;
                     93:     int len;
                     94: 
                     95:     if (dest_size <= 0)
                     96:         return;
                     97:     if (path_is_absolute(filename)) {
                     98:         pstrcpy(dest, dest_size, filename);
                     99:     } else {
                    100:         p = strchr(base_path, ':');
                    101:         if (p)
                    102:             p++;
                    103:         else
                    104:             p = base_path;
                    105:         p1 = strrchr(base_path, '/');
                    106: #ifdef _WIN32
                    107:         {
                    108:             const char *p2;
                    109:             p2 = strrchr(base_path, '\\');
                    110:             if (!p1 || p2 > p1)
                    111:                 p1 = p2;
1.1.1.2   root      112:         }
1.1.1.5   root      113: #endif
                    114:         if (p1)
                    115:             p1++;
                    116:         else
                    117:             p1 = base_path;
                    118:         if (p1 > p)
                    119:             p = p1;
                    120:         len = p - base_path;
                    121:         if (len > dest_size - 1)
                    122:             len = dest_size - 1;
                    123:         memcpy(dest, base_path, len);
                    124:         dest[len] = '\0';
                    125:         pstrcat(dest, dest_size, filename);
1.1.1.2   root      126:     }
                    127: }
                    128: 
1.1.1.13  root      129: void bdrv_register(BlockDriver *bdrv)
1.1       root      130: {
1.1.1.13  root      131:     if (!bdrv->bdrv_aio_readv) {
1.1.1.5   root      132:         /* add AIO emulation layer */
1.1.1.13  root      133:         bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
                    134:         bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
                    135:     } else if (!bdrv->bdrv_read) {
1.1.1.5   root      136:         /* add synchronous IO emulation layer */
                    137:         bdrv->bdrv_read = bdrv_read_em;
                    138:         bdrv->bdrv_write = bdrv_write_em;
                    139:     }
1.1.1.14! root      140: 
        !           141:     if (!bdrv->bdrv_aio_flush)
        !           142:         bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
        !           143: 
1.1       root      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: 
1.1.1.14! root      175: static int bdrv_is_whitelisted(BlockDriver *drv)
        !           176: {
        !           177:     static const char *whitelist[] = {
        !           178:         CONFIG_BDRV_WHITELIST
        !           179:     };
        !           180:     const char **p;
        !           181: 
        !           182:     if (!whitelist[0])
        !           183:         return 1;               /* no whitelist, anything goes */
        !           184: 
        !           185:     for (p = whitelist; *p; p++) {
        !           186:         if (!strcmp(drv->format_name, *p)) {
        !           187:             return 1;
        !           188:         }
        !           189:     }
        !           190:     return 0;
        !           191: }
        !           192: 
        !           193: BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
        !           194: {
        !           195:     BlockDriver *drv = bdrv_find_format(format_name);
        !           196:     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
        !           197: }
        !           198: 
1.1.1.13  root      199: int bdrv_create(BlockDriver *drv, const char* filename,
                    200:     QEMUOptionParameter *options)
1.1       root      201: {
                    202:     if (!drv->bdrv_create)
                    203:         return -ENOTSUP;
1.1.1.13  root      204: 
                    205:     return drv->bdrv_create(filename, options);
1.1       root      206: }
                    207: 
                    208: #ifdef _WIN32
1.1.1.2   root      209: void get_tmp_filename(char *filename, int size)
1.1       root      210: {
1.1.1.5   root      211:     char temp_dir[MAX_PATH];
1.1.1.6   root      212: 
1.1.1.5   root      213:     GetTempPath(MAX_PATH, temp_dir);
                    214:     GetTempFileName(temp_dir, "qem", 0, filename);
1.1       root      215: }
                    216: #else
1.1.1.2   root      217: void get_tmp_filename(char *filename, int size)
1.1       root      218: {
                    219:     int fd;
1.1.1.7   root      220:     const char *tmpdir;
1.1       root      221:     /* XXX: race condition possible */
1.1.1.7   root      222:     tmpdir = getenv("TMPDIR");
                    223:     if (!tmpdir)
                    224:         tmpdir = "/tmp";
                    225:     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
1.1       root      226:     fd = mkstemp(filename);
                    227:     close(fd);
                    228: }
                    229: #endif
                    230: 
1.1.1.5   root      231: #ifdef _WIN32
                    232: static int is_windows_drive_prefix(const char *filename)
                    233: {
                    234:     return (((filename[0] >= 'a' && filename[0] <= 'z') ||
                    235:              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
                    236:             filename[1] == ':');
                    237: }
1.1.1.6   root      238: 
1.1.1.13  root      239: int is_windows_drive(const char *filename)
1.1.1.5   root      240: {
1.1.1.6   root      241:     if (is_windows_drive_prefix(filename) &&
1.1.1.5   root      242:         filename[2] == '\0')
                    243:         return 1;
                    244:     if (strstart(filename, "\\\\.\\", NULL) ||
                    245:         strstart(filename, "//./", NULL))
                    246:         return 1;
                    247:     return 0;
                    248: }
                    249: #endif
                    250: 
                    251: static BlockDriver *find_protocol(const char *filename)
                    252: {
                    253:     BlockDriver *drv1;
                    254:     char protocol[128];
                    255:     int len;
                    256:     const char *p;
                    257: 
                    258: #ifdef _WIN32
                    259:     if (is_windows_drive(filename) ||
                    260:         is_windows_drive_prefix(filename))
1.1.1.13  root      261:         return bdrv_find_format("raw");
1.1.1.5   root      262: #endif
                    263:     p = strchr(filename, ':');
                    264:     if (!p)
1.1.1.13  root      265:         return bdrv_find_format("raw");
1.1.1.5   root      266:     len = p - filename;
                    267:     if (len > sizeof(protocol) - 1)
                    268:         len = sizeof(protocol) - 1;
                    269:     memcpy(protocol, filename, len);
                    270:     protocol[len] = '\0';
                    271:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.6   root      272:         if (drv1->protocol_name &&
1.1.1.5   root      273:             !strcmp(drv1->protocol_name, protocol))
                    274:             return drv1;
                    275:     }
                    276:     return NULL;
                    277: }
                    278: 
1.1.1.13  root      279: /*
                    280:  * Detect host devices. By convention, /dev/cdrom[N] is always
                    281:  * recognized as a host CDROM.
                    282:  */
                    283: static BlockDriver *find_hdev_driver(const char *filename)
                    284: {
                    285:     int score_max = 0, score;
                    286:     BlockDriver *drv = NULL, *d;
                    287: 
                    288:     for (d = first_drv; d; d = d->next) {
                    289:         if (d->bdrv_probe_device) {
                    290:             score = d->bdrv_probe_device(filename);
                    291:             if (score > score_max) {
                    292:                 score_max = score;
                    293:                 drv = d;
                    294:             }
                    295:         }
                    296:     }
                    297: 
                    298:     return drv;
                    299: }
                    300: 
1.1       root      301: static BlockDriver *find_image_format(const char *filename)
                    302: {
1.1.1.5   root      303:     int ret, score, score_max;
1.1       root      304:     BlockDriver *drv1, *drv;
1.1.1.5   root      305:     uint8_t buf[2048];
                    306:     BlockDriverState *bs;
1.1.1.6   root      307: 
1.1.1.5   root      308:     drv = find_protocol(filename);
                    309:     /* no need to test disk image formats for vvfat */
1.1.1.13  root      310:     if (drv && strcmp(drv->format_name, "vvfat") == 0)
1.1.1.5   root      311:         return drv;
                    312: 
                    313:     ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
                    314:     if (ret < 0)
                    315:         return NULL;
                    316:     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
                    317:     bdrv_delete(bs);
                    318:     if (ret < 0) {
                    319:         return NULL;
                    320:     }
                    321: 
1.1       root      322:     score_max = 0;
                    323:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.5   root      324:         if (drv1->bdrv_probe) {
                    325:             score = drv1->bdrv_probe(buf, ret, filename);
                    326:             if (score > score_max) {
                    327:                 score_max = score;
                    328:                 drv = drv1;
                    329:             }
1.1       root      330:         }
                    331:     }
                    332:     return drv;
                    333: }
                    334: 
1.1.1.5   root      335: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
1.1       root      336: {
1.1.1.5   root      337:     BlockDriverState *bs;
                    338:     int ret;
                    339: 
                    340:     bs = bdrv_new("");
                    341:     ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
                    342:     if (ret < 0) {
                    343:         bdrv_delete(bs);
                    344:         return ret;
1.1.1.2   root      345:     }
1.1.1.7   root      346:     bs->growable = 1;
1.1.1.5   root      347:     *pbs = bs;
                    348:     return 0;
                    349: }
                    350: 
                    351: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
                    352: {
                    353:     return bdrv_open2(bs, filename, flags, NULL);
1.1       root      354: }
                    355: 
1.1.1.5   root      356: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
1.1       root      357:                BlockDriver *drv)
                    358: {
1.1.1.14! root      359:     int ret, open_flags, try_rw;
1.1.1.6   root      360:     char tmp_filename[PATH_MAX];
                    361:     char backing_filename[PATH_MAX];
                    362: 
1.1       root      363:     bs->is_temporary = 0;
                    364:     bs->encrypted = 0;
1.1.1.8   root      365:     bs->valid_key = 0;
1.1.1.13  root      366:     /* buffer_alignment defaulted to 512, drivers can change this value */
                    367:     bs->buffer_alignment = 512;
1.1       root      368: 
1.1.1.5   root      369:     if (flags & BDRV_O_SNAPSHOT) {
1.1       root      370:         BlockDriverState *bs1;
                    371:         int64_t total_size;
1.1.1.7   root      372:         int is_protocol = 0;
1.1.1.13  root      373:         BlockDriver *bdrv_qcow2;
                    374:         QEMUOptionParameter *options;
1.1.1.6   root      375: 
1.1       root      376:         /* if snapshot, we create a temporary backing file and open it
                    377:            instead of opening 'filename' directly */
                    378: 
                    379:         /* if there is a backing file, use it */
                    380:         bs1 = bdrv_new("");
1.1.1.13  root      381:         ret = bdrv_open2(bs1, filename, 0, drv);
1.1.1.8   root      382:         if (ret < 0) {
1.1       root      383:             bdrv_delete(bs1);
1.1.1.8   root      384:             return ret;
1.1       root      385:         }
1.1.1.14! root      386:         total_size = bdrv_getlength(bs1) >> BDRV_SECTOR_BITS;
1.1.1.7   root      387: 
                    388:         if (bs1->drv && bs1->drv->protocol_name)
                    389:             is_protocol = 1;
                    390: 
1.1       root      391:         bdrv_delete(bs1);
1.1.1.6   root      392: 
1.1       root      393:         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
1.1.1.7   root      394: 
                    395:         /* Real path is meaningless for protocols */
                    396:         if (is_protocol)
                    397:             snprintf(backing_filename, sizeof(backing_filename),
                    398:                      "%s", filename);
                    399:         else
                    400:             realpath(filename, backing_filename);
                    401: 
1.1.1.13  root      402:         bdrv_qcow2 = bdrv_find_format("qcow2");
                    403:         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
                    404: 
                    405:         set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size * 512);
                    406:         set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
                    407:         if (drv) {
                    408:             set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
                    409:                 drv->format_name);
                    410:         }
                    411: 
                    412:         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
1.1.1.8   root      413:         if (ret < 0) {
                    414:             return ret;
1.1       root      415:         }
1.1.1.13  root      416: 
1.1       root      417:         filename = tmp_filename;
1.1.1.13  root      418:         drv = bdrv_qcow2;
1.1       root      419:         bs->is_temporary = 1;
                    420:     }
                    421: 
                    422:     pstrcpy(bs->filename, sizeof(bs->filename), filename);
1.1.1.5   root      423:     if (flags & BDRV_O_FILE) {
                    424:         drv = find_protocol(filename);
1.1.1.8   root      425:     } else if (!drv) {
1.1.1.13  root      426:         drv = find_hdev_driver(filename);
                    427:         if (!drv) {
                    428:             drv = find_image_format(filename);
                    429:         }
1.1.1.8   root      430:     }
                    431:     if (!drv) {
                    432:         ret = -ENOENT;
                    433:         goto unlink_and_fail;
1.1       root      434:     }
                    435:     bs->drv = drv;
                    436:     bs->opaque = qemu_mallocz(drv->instance_size);
1.1.1.14! root      437: 
        !           438:     /*
        !           439:      * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
        !           440:      * write cache to the guest.  We do need the fdatasync to flush
        !           441:      * out transactions for block allocations, and we maybe have a
        !           442:      * volatile write cache in our backing device to deal with.
        !           443:      */
        !           444:     if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
        !           445:         bs->enable_write_cache = 1;
        !           446: 
1.1.1.5   root      447:     /* Note: for compatibility, we open disk image files as RDWR, and
                    448:        RDONLY as fallback */
1.1.1.14! root      449:     try_rw = !bs->read_only || bs->is_temporary;
1.1.1.5   root      450:     if (!(flags & BDRV_O_FILE))
1.1.1.14! root      451:         open_flags = (try_rw ? BDRV_O_RDWR : 0) |
        !           452:             (flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
1.1.1.5   root      453:     else
                    454:         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
1.1.1.14! root      455:     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv))
        !           456:         ret = -ENOTSUP;
        !           457:     else
        !           458:         ret = drv->bdrv_open(bs, filename, open_flags);
1.1.1.7   root      459:     if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
                    460:         ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
1.1.1.5   root      461:         bs->read_only = 1;
                    462:     }
1.1       root      463:     if (ret < 0) {
                    464:         qemu_free(bs->opaque);
1.1.1.5   root      465:         bs->opaque = NULL;
                    466:         bs->drv = NULL;
1.1.1.8   root      467:     unlink_and_fail:
                    468:         if (bs->is_temporary)
                    469:             unlink(filename);
1.1.1.5   root      470:         return ret;
                    471:     }
                    472:     if (drv->bdrv_getlength) {
1.1.1.14! root      473:         bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
1.1       root      474:     }
                    475: #ifndef _WIN32
                    476:     if (bs->is_temporary) {
                    477:         unlink(filename);
                    478:     }
                    479: #endif
1.1.1.5   root      480:     if (bs->backing_file[0] != '\0') {
1.1       root      481:         /* if there is a backing file, use it */
1.1.1.13  root      482:         BlockDriver *back_drv = NULL;
1.1       root      483:         bs->backing_hd = bdrv_new("");
1.1.1.14! root      484:         /* pass on read_only property to the backing_hd */
        !           485:         bs->backing_hd->read_only = bs->read_only;
1.1.1.5   root      486:         path_combine(backing_filename, sizeof(backing_filename),
                    487:                      filename, bs->backing_file);
1.1.1.13  root      488:         if (bs->backing_format[0] != '\0')
                    489:             back_drv = bdrv_find_format(bs->backing_format);
                    490:         ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
                    491:                          back_drv);
1.1.1.8   root      492:         if (ret < 0) {
                    493:             bdrv_close(bs);
                    494:             return ret;
                    495:         }
1.1       root      496:     }
                    497: 
1.1.1.13  root      498:     if (!bdrv_key_required(bs)) {
                    499:         /* call the change callback */
                    500:         bs->media_changed = 1;
                    501:         if (bs->change_cb)
                    502:             bs->change_cb(bs->change_opaque);
                    503:     }
1.1       root      504:     return 0;
                    505: }
                    506: 
                    507: void bdrv_close(BlockDriverState *bs)
                    508: {
1.1.1.5   root      509:     if (bs->drv) {
1.1       root      510:         if (bs->backing_hd)
                    511:             bdrv_delete(bs->backing_hd);
                    512:         bs->drv->bdrv_close(bs);
                    513:         qemu_free(bs->opaque);
                    514: #ifdef _WIN32
                    515:         if (bs->is_temporary) {
                    516:             unlink(bs->filename);
                    517:         }
                    518: #endif
                    519:         bs->opaque = NULL;
                    520:         bs->drv = NULL;
                    521: 
                    522:         /* call the change callback */
1.1.1.5   root      523:         bs->media_changed = 1;
1.1       root      524:         if (bs->change_cb)
                    525:             bs->change_cb(bs->change_opaque);
                    526:     }
                    527: }
                    528: 
                    529: void bdrv_delete(BlockDriverState *bs)
                    530: {
1.1.1.7   root      531:     BlockDriverState **pbs;
                    532: 
                    533:     pbs = &bdrv_first;
                    534:     while (*pbs != bs && *pbs != NULL)
                    535:         pbs = &(*pbs)->next;
                    536:     if (*pbs == bs)
                    537:         *pbs = bs->next;
                    538: 
1.1       root      539:     bdrv_close(bs);
                    540:     qemu_free(bs);
                    541: }
                    542: 
1.1.1.13  root      543: /*
                    544:  * Run consistency checks on an image
                    545:  *
                    546:  * Returns the number of errors or -errno when an internal error occurs
                    547:  */
                    548: int bdrv_check(BlockDriverState *bs)
                    549: {
                    550:     if (bs->drv->bdrv_check == NULL) {
                    551:         return -ENOTSUP;
                    552:     }
                    553: 
                    554:     return bs->drv->bdrv_check(bs);
                    555: }
                    556: 
1.1       root      557: /* commit COW file into the raw image */
                    558: int bdrv_commit(BlockDriverState *bs)
                    559: {
1.1.1.5   root      560:     BlockDriver *drv = bs->drv;
                    561:     int64_t i, total_sectors;
1.1       root      562:     int n, j;
                    563:     unsigned char sector[512];
                    564: 
1.1.1.5   root      565:     if (!drv)
                    566:         return -ENOMEDIUM;
1.1       root      567: 
                    568:     if (bs->read_only) {
                    569:        return -EACCES;
                    570:     }
                    571: 
                    572:     if (!bs->backing_hd) {
                    573:        return -ENOTSUP;
                    574:     }
                    575: 
1.1.1.14! root      576:     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
1.1.1.5   root      577:     for (i = 0; i < total_sectors;) {
                    578:         if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
1.1       root      579:             for(j = 0; j < n; j++) {
                    580:                 if (bdrv_read(bs, i, sector, 1) != 0) {
                    581:                     return -EIO;
                    582:                 }
                    583: 
                    584:                 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
                    585:                     return -EIO;
                    586:                 }
                    587:                 i++;
                    588:            }
                    589:        } else {
                    590:             i += n;
                    591:         }
                    592:     }
1.1.1.2   root      593: 
1.1.1.5   root      594:     if (drv->bdrv_make_empty)
                    595:        return drv->bdrv_make_empty(bs);
1.1.1.2   root      596: 
1.1       root      597:     return 0;
                    598: }
                    599: 
1.1.1.7   root      600: static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
                    601:                                    size_t size)
                    602: {
                    603:     int64_t len;
                    604: 
                    605:     if (!bdrv_is_inserted(bs))
                    606:         return -ENOMEDIUM;
                    607: 
                    608:     if (bs->growable)
                    609:         return 0;
                    610: 
                    611:     len = bdrv_getlength(bs);
                    612: 
1.1.1.11  root      613:     if (offset < 0)
                    614:         return -EIO;
                    615: 
                    616:     if ((offset > len) || (len - offset < size))
1.1.1.7   root      617:         return -EIO;
                    618: 
                    619:     return 0;
                    620: }
                    621: 
                    622: static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                    623:                               int nb_sectors)
                    624: {
1.1.1.13  root      625:     return bdrv_check_byte_request(bs, sector_num * 512, nb_sectors * 512);
1.1.1.7   root      626: }
                    627: 
1.1.1.5   root      628: /* return < 0 if error. See bdrv_write() for the return codes */
1.1.1.6   root      629: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1.1       root      630:               uint8_t *buf, int nb_sectors)
                    631: {
                    632:     BlockDriver *drv = bs->drv;
                    633: 
1.1.1.5   root      634:     if (!drv)
                    635:         return -ENOMEDIUM;
1.1.1.7   root      636:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    637:         return -EIO;
1.1       root      638: 
1.1.1.13  root      639:     return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
1.1       root      640: }
                    641: 
1.1.1.14! root      642: static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
        !           643:                              int nb_sectors, int dirty)
        !           644: {
        !           645:     int64_t start, end;
        !           646:     unsigned long val, idx, bit;
        !           647: 
        !           648:     start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
        !           649:     end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
        !           650: 
        !           651:     for (; start <= end; start++) {
        !           652:         idx = start / (sizeof(unsigned long) * 8);
        !           653:         bit = start % (sizeof(unsigned long) * 8);
        !           654:         val = bs->dirty_bitmap[idx];
        !           655:         if (dirty) {
        !           656:             val |= 1 << bit;
        !           657:         } else {
        !           658:             val &= ~(1 << bit);
        !           659:         }
        !           660:         bs->dirty_bitmap[idx] = val;
        !           661:     }
        !           662: }
        !           663: 
1.1.1.6   root      664: /* Return < 0 if error. Important errors are:
1.1.1.5   root      665:   -EIO         generic I/O error (may happen for all errors)
                    666:   -ENOMEDIUM   No media inserted.
                    667:   -EINVAL      Invalid sector number or nb_sectors
                    668:   -EACCES      Trying to write a read-only device
                    669: */
1.1.1.6   root      670: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1.1       root      671:                const uint8_t *buf, int nb_sectors)
                    672: {
1.1.1.5   root      673:     BlockDriver *drv = bs->drv;
                    674:     if (!bs->drv)
                    675:         return -ENOMEDIUM;
1.1       root      676:     if (bs->read_only)
1.1.1.5   root      677:         return -EACCES;
1.1.1.7   root      678:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    679:         return -EIO;
                    680: 
1.1.1.14! root      681:     if (bs->dirty_bitmap) {
        !           682:         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
        !           683:     }
        !           684: 
1.1.1.7   root      685:     return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
1.1       root      686: }
                    687: 
1.1.1.13  root      688: int bdrv_pread(BlockDriverState *bs, int64_t offset,
                    689:                void *buf, int count1)
1.1.1.5   root      690: {
1.1.1.14! root      691:     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
1.1.1.5   root      692:     int len, nb_sectors, count;
                    693:     int64_t sector_num;
                    694: 
                    695:     count = count1;
                    696:     /* first read to align to sector start */
1.1.1.14! root      697:     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
1.1.1.5   root      698:     if (len > count)
                    699:         len = count;
1.1.1.14! root      700:     sector_num = offset >> BDRV_SECTOR_BITS;
1.1.1.5   root      701:     if (len > 0) {
                    702:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    703:             return -EIO;
1.1.1.14! root      704:         memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
1.1.1.5   root      705:         count -= len;
                    706:         if (count == 0)
                    707:             return count1;
                    708:         sector_num++;
                    709:         buf += len;
                    710:     }
                    711: 
                    712:     /* read the sectors "in place" */
1.1.1.14! root      713:     nb_sectors = count >> BDRV_SECTOR_BITS;
1.1.1.5   root      714:     if (nb_sectors > 0) {
                    715:         if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
                    716:             return -EIO;
                    717:         sector_num += nb_sectors;
1.1.1.14! root      718:         len = nb_sectors << BDRV_SECTOR_BITS;
1.1.1.5   root      719:         buf += len;
                    720:         count -= len;
                    721:     }
                    722: 
                    723:     /* add data from the last sector */
                    724:     if (count > 0) {
                    725:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    726:             return -EIO;
                    727:         memcpy(buf, tmp_buf, count);
                    728:     }
                    729:     return count1;
                    730: }
                    731: 
1.1.1.13  root      732: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
                    733:                 const void *buf, int count1)
1.1.1.5   root      734: {
1.1.1.14! root      735:     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
1.1.1.5   root      736:     int len, nb_sectors, count;
                    737:     int64_t sector_num;
                    738: 
                    739:     count = count1;
                    740:     /* first write to align to sector start */
1.1.1.14! root      741:     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
1.1.1.5   root      742:     if (len > count)
                    743:         len = count;
1.1.1.14! root      744:     sector_num = offset >> BDRV_SECTOR_BITS;
1.1.1.5   root      745:     if (len > 0) {
                    746:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    747:             return -EIO;
1.1.1.14! root      748:         memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
1.1.1.5   root      749:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    750:             return -EIO;
                    751:         count -= len;
                    752:         if (count == 0)
                    753:             return count1;
                    754:         sector_num++;
                    755:         buf += len;
                    756:     }
                    757: 
                    758:     /* write the sectors "in place" */
1.1.1.14! root      759:     nb_sectors = count >> BDRV_SECTOR_BITS;
1.1.1.5   root      760:     if (nb_sectors > 0) {
                    761:         if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
                    762:             return -EIO;
                    763:         sector_num += nb_sectors;
1.1.1.14! root      764:         len = nb_sectors << BDRV_SECTOR_BITS;
1.1.1.5   root      765:         buf += len;
                    766:         count -= len;
                    767:     }
                    768: 
                    769:     /* add data from the last sector */
                    770:     if (count > 0) {
                    771:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    772:             return -EIO;
                    773:         memcpy(tmp_buf, buf, count);
                    774:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    775:             return -EIO;
                    776:     }
                    777:     return count1;
                    778: }
                    779: 
                    780: /**
                    781:  * Truncate file to 'offset' bytes (needed only for file protocols)
                    782:  */
                    783: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
                    784: {
                    785:     BlockDriver *drv = bs->drv;
                    786:     if (!drv)
                    787:         return -ENOMEDIUM;
                    788:     if (!drv->bdrv_truncate)
                    789:         return -ENOTSUP;
1.1.1.14! root      790:     if (bs->read_only)
        !           791:         return -EACCES;
1.1.1.5   root      792:     return drv->bdrv_truncate(bs, offset);
                    793: }
                    794: 
                    795: /**
                    796:  * Length of a file in bytes. Return < 0 if error or unknown.
                    797:  */
                    798: int64_t bdrv_getlength(BlockDriverState *bs)
                    799: {
                    800:     BlockDriver *drv = bs->drv;
                    801:     if (!drv)
                    802:         return -ENOMEDIUM;
                    803:     if (!drv->bdrv_getlength) {
                    804:         /* legacy mode */
1.1.1.14! root      805:         return bs->total_sectors * BDRV_SECTOR_SIZE;
1.1.1.5   root      806:     }
                    807:     return drv->bdrv_getlength(bs);
                    808: }
                    809: 
                    810: /* return 0 as number of sectors if no device present or error */
1.1.1.6   root      811: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1.1       root      812: {
1.1.1.5   root      813:     int64_t length;
                    814:     length = bdrv_getlength(bs);
                    815:     if (length < 0)
                    816:         length = 0;
                    817:     else
1.1.1.14! root      818:         length = length >> BDRV_SECTOR_BITS;
1.1.1.5   root      819:     *nb_sectors_ptr = length;
1.1       root      820: }
                    821: 
1.1.1.7   root      822: struct partition {
                    823:         uint8_t boot_ind;           /* 0x80 - active */
                    824:         uint8_t head;               /* starting head */
                    825:         uint8_t sector;             /* starting sector */
                    826:         uint8_t cyl;                /* starting cylinder */
                    827:         uint8_t sys_ind;            /* What partition type */
                    828:         uint8_t end_head;           /* end head */
                    829:         uint8_t end_sector;         /* end sector */
                    830:         uint8_t end_cyl;            /* end cylinder */
                    831:         uint32_t start_sect;        /* starting sector counting from 0 */
                    832:         uint32_t nr_sects;          /* nr of sectors in partition */
                    833: } __attribute__((packed));
                    834: 
                    835: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
                    836: static int guess_disk_lchs(BlockDriverState *bs,
                    837:                            int *pcylinders, int *pheads, int *psectors)
                    838: {
                    839:     uint8_t buf[512];
                    840:     int ret, i, heads, sectors, cylinders;
                    841:     struct partition *p;
                    842:     uint32_t nr_sects;
                    843:     uint64_t nb_sectors;
                    844: 
                    845:     bdrv_get_geometry(bs, &nb_sectors);
                    846: 
                    847:     ret = bdrv_read(bs, 0, buf, 1);
                    848:     if (ret < 0)
                    849:         return -1;
                    850:     /* test msdos magic */
                    851:     if (buf[510] != 0x55 || buf[511] != 0xaa)
                    852:         return -1;
                    853:     for(i = 0; i < 4; i++) {
                    854:         p = ((struct partition *)(buf + 0x1be)) + i;
                    855:         nr_sects = le32_to_cpu(p->nr_sects);
                    856:         if (nr_sects && p->end_head) {
                    857:             /* We make the assumption that the partition terminates on
                    858:                a cylinder boundary */
                    859:             heads = p->end_head + 1;
                    860:             sectors = p->end_sector & 63;
                    861:             if (sectors == 0)
                    862:                 continue;
                    863:             cylinders = nb_sectors / (heads * sectors);
                    864:             if (cylinders < 1 || cylinders > 16383)
                    865:                 continue;
                    866:             *pheads = heads;
                    867:             *psectors = sectors;
                    868:             *pcylinders = cylinders;
                    869: #if 0
                    870:             printf("guessed geometry: LCHS=%d %d %d\n",
                    871:                    cylinders, heads, sectors);
                    872: #endif
                    873:             return 0;
                    874:         }
                    875:     }
                    876:     return -1;
                    877: }
                    878: 
                    879: void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1.1       root      880: {
1.1.1.7   root      881:     int translation, lba_detected = 0;
                    882:     int cylinders, heads, secs;
                    883:     uint64_t nb_sectors;
                    884: 
                    885:     /* if a geometry hint is available, use it */
                    886:     bdrv_get_geometry(bs, &nb_sectors);
                    887:     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
                    888:     translation = bdrv_get_translation_hint(bs);
                    889:     if (cylinders != 0) {
                    890:         *pcyls = cylinders;
                    891:         *pheads = heads;
                    892:         *psecs = secs;
                    893:     } else {
                    894:         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
                    895:             if (heads > 16) {
                    896:                 /* if heads > 16, it means that a BIOS LBA
                    897:                    translation was active, so the default
                    898:                    hardware geometry is OK */
                    899:                 lba_detected = 1;
                    900:                 goto default_geometry;
                    901:             } else {
                    902:                 *pcyls = cylinders;
                    903:                 *pheads = heads;
                    904:                 *psecs = secs;
                    905:                 /* disable any translation to be in sync with
                    906:                    the logical geometry */
                    907:                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
                    908:                     bdrv_set_translation_hint(bs,
                    909:                                               BIOS_ATA_TRANSLATION_NONE);
                    910:                 }
                    911:             }
                    912:         } else {
                    913:         default_geometry:
                    914:             /* if no geometry, use a standard physical disk geometry */
                    915:             cylinders = nb_sectors / (16 * 63);
                    916: 
                    917:             if (cylinders > 16383)
                    918:                 cylinders = 16383;
                    919:             else if (cylinders < 2)
                    920:                 cylinders = 2;
                    921:             *pcyls = cylinders;
                    922:             *pheads = 16;
                    923:             *psecs = 63;
                    924:             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
                    925:                 if ((*pcyls * *pheads) <= 131072) {
                    926:                     bdrv_set_translation_hint(bs,
                    927:                                               BIOS_ATA_TRANSLATION_LARGE);
                    928:                 } else {
                    929:                     bdrv_set_translation_hint(bs,
                    930:                                               BIOS_ATA_TRANSLATION_LBA);
                    931:                 }
                    932:             }
                    933:         }
                    934:         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
                    935:     }
1.1       root      936: }
                    937: 
1.1.1.6   root      938: void bdrv_set_geometry_hint(BlockDriverState *bs,
1.1       root      939:                             int cyls, int heads, int secs)
                    940: {
                    941:     bs->cyls = cyls;
                    942:     bs->heads = heads;
                    943:     bs->secs = secs;
                    944: }
                    945: 
                    946: void bdrv_set_type_hint(BlockDriverState *bs, int type)
                    947: {
                    948:     bs->type = type;
                    949:     bs->removable = ((type == BDRV_TYPE_CDROM ||
                    950:                       type == BDRV_TYPE_FLOPPY));
                    951: }
                    952: 
                    953: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
                    954: {
                    955:     bs->translation = translation;
                    956: }
                    957: 
1.1.1.6   root      958: void bdrv_get_geometry_hint(BlockDriverState *bs,
1.1       root      959:                             int *pcyls, int *pheads, int *psecs)
                    960: {
                    961:     *pcyls = bs->cyls;
                    962:     *pheads = bs->heads;
                    963:     *psecs = bs->secs;
                    964: }
                    965: 
                    966: int bdrv_get_type_hint(BlockDriverState *bs)
                    967: {
                    968:     return bs->type;
                    969: }
                    970: 
                    971: int bdrv_get_translation_hint(BlockDriverState *bs)
                    972: {
                    973:     return bs->translation;
                    974: }
                    975: 
                    976: int bdrv_is_removable(BlockDriverState *bs)
                    977: {
                    978:     return bs->removable;
                    979: }
                    980: 
                    981: int bdrv_is_read_only(BlockDriverState *bs)
                    982: {
                    983:     return bs->read_only;
                    984: }
                    985: 
1.1.1.14! root      986: int bdrv_set_read_only(BlockDriverState *bs, int read_only)
        !           987: {
        !           988:     int ret = bs->read_only;
        !           989:     bs->read_only = read_only;
        !           990:     return ret;
        !           991: }
        !           992: 
1.1.1.6   root      993: int bdrv_is_sg(BlockDriverState *bs)
                    994: {
                    995:     return bs->sg;
                    996: }
                    997: 
1.1.1.14! root      998: int bdrv_enable_write_cache(BlockDriverState *bs)
        !           999: {
        !          1000:     return bs->enable_write_cache;
        !          1001: }
        !          1002: 
1.1.1.5   root     1003: /* XXX: no longer used */
1.1.1.6   root     1004: void bdrv_set_change_cb(BlockDriverState *bs,
1.1       root     1005:                         void (*change_cb)(void *opaque), void *opaque)
                   1006: {
                   1007:     bs->change_cb = change_cb;
                   1008:     bs->change_opaque = opaque;
                   1009: }
                   1010: 
                   1011: int bdrv_is_encrypted(BlockDriverState *bs)
                   1012: {
                   1013:     if (bs->backing_hd && bs->backing_hd->encrypted)
                   1014:         return 1;
                   1015:     return bs->encrypted;
                   1016: }
                   1017: 
1.1.1.8   root     1018: int bdrv_key_required(BlockDriverState *bs)
                   1019: {
                   1020:     BlockDriverState *backing_hd = bs->backing_hd;
                   1021: 
                   1022:     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
                   1023:         return 1;
                   1024:     return (bs->encrypted && !bs->valid_key);
                   1025: }
                   1026: 
1.1       root     1027: int bdrv_set_key(BlockDriverState *bs, const char *key)
                   1028: {
                   1029:     int ret;
                   1030:     if (bs->backing_hd && bs->backing_hd->encrypted) {
                   1031:         ret = bdrv_set_key(bs->backing_hd, key);
                   1032:         if (ret < 0)
                   1033:             return ret;
                   1034:         if (!bs->encrypted)
                   1035:             return 0;
                   1036:     }
                   1037:     if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
                   1038:         return -1;
1.1.1.8   root     1039:     ret = bs->drv->bdrv_set_key(bs, key);
1.1.1.13  root     1040:     if (ret < 0) {
                   1041:         bs->valid_key = 0;
                   1042:     } else if (!bs->valid_key) {
                   1043:         bs->valid_key = 1;
                   1044:         /* call the change callback now, we skipped it on open */
                   1045:         bs->media_changed = 1;
                   1046:         if (bs->change_cb)
                   1047:             bs->change_cb(bs->change_opaque);
                   1048:     }
1.1.1.8   root     1049:     return ret;
1.1       root     1050: }
                   1051: 
                   1052: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
                   1053: {
1.1.1.5   root     1054:     if (!bs->drv) {
1.1       root     1055:         buf[0] = '\0';
                   1056:     } else {
                   1057:         pstrcpy(buf, buf_size, bs->drv->format_name);
                   1058:     }
                   1059: }
                   1060: 
1.1.1.6   root     1061: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1.1       root     1062:                          void *opaque)
                   1063: {
                   1064:     BlockDriver *drv;
                   1065: 
                   1066:     for (drv = first_drv; drv != NULL; drv = drv->next) {
                   1067:         it(opaque, drv->format_name);
                   1068:     }
                   1069: }
                   1070: 
                   1071: BlockDriverState *bdrv_find(const char *name)
                   1072: {
                   1073:     BlockDriverState *bs;
                   1074: 
                   1075:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                   1076:         if (!strcmp(name, bs->device_name))
                   1077:             return bs;
                   1078:     }
                   1079:     return NULL;
                   1080: }
                   1081: 
1.1.1.8   root     1082: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1.1       root     1083: {
                   1084:     BlockDriverState *bs;
                   1085: 
                   1086:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.8   root     1087:         it(opaque, bs);
1.1       root     1088:     }
                   1089: }
                   1090: 
                   1091: const char *bdrv_get_device_name(BlockDriverState *bs)
                   1092: {
                   1093:     return bs->device_name;
                   1094: }
                   1095: 
1.1.1.4   root     1096: void bdrv_flush(BlockDriverState *bs)
                   1097: {
1.1.1.13  root     1098:     if (!bs->drv)
                   1099:         return;
1.1.1.4   root     1100:     if (bs->drv->bdrv_flush)
                   1101:         bs->drv->bdrv_flush(bs);
                   1102:     if (bs->backing_hd)
                   1103:         bdrv_flush(bs->backing_hd);
                   1104: }
                   1105: 
1.1.1.7   root     1106: void bdrv_flush_all(void)
                   1107: {
                   1108:     BlockDriverState *bs;
                   1109: 
                   1110:     for (bs = bdrv_first; bs != NULL; bs = bs->next)
                   1111:         if (bs->drv && !bdrv_is_read_only(bs) && 
                   1112:             (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
                   1113:             bdrv_flush(bs);
                   1114: }
                   1115: 
                   1116: /*
                   1117:  * Returns true iff the specified sector is present in the disk image. Drivers
                   1118:  * not implementing the functionality are assumed to not support backing files,
                   1119:  * hence all their sectors are reported as allocated.
                   1120:  *
                   1121:  * 'pnum' is set to the number of sectors (including and immediately following
                   1122:  * the specified sector) that are known to be in the same
                   1123:  * allocated/unallocated state.
                   1124:  *
                   1125:  * 'nb_sectors' is the max value 'pnum' should be set to.
                   1126:  */
                   1127: int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                   1128:        int *pnum)
                   1129: {
                   1130:     int64_t n;
                   1131:     if (!bs->drv->bdrv_is_allocated) {
                   1132:         if (sector_num >= bs->total_sectors) {
                   1133:             *pnum = 0;
                   1134:             return 0;
                   1135:         }
                   1136:         n = bs->total_sectors - sector_num;
                   1137:         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
                   1138:         return 1;
                   1139:     }
                   1140:     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
                   1141: }
                   1142: 
1.1.1.14! root     1143: static void bdrv_print_dict(QObject *obj, void *opaque)
1.1       root     1144: {
1.1.1.14! root     1145:     QDict *bs_dict;
        !          1146:     Monitor *mon = opaque;
        !          1147: 
        !          1148:     bs_dict = qobject_to_qdict(obj);
        !          1149: 
        !          1150:     monitor_printf(mon, "%s: type=%s removable=%d",
        !          1151:                         qdict_get_str(bs_dict, "device"),
        !          1152:                         qdict_get_str(bs_dict, "type"),
        !          1153:                         qdict_get_bool(bs_dict, "removable"));
        !          1154: 
        !          1155:     if (qdict_get_bool(bs_dict, "removable")) {
        !          1156:         monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
        !          1157:     }
        !          1158: 
        !          1159:     if (qdict_haskey(bs_dict, "inserted")) {
        !          1160:         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
        !          1161: 
        !          1162:         monitor_printf(mon, " file=");
        !          1163:         monitor_print_filename(mon, qdict_get_str(qdict, "file"));
        !          1164:         if (qdict_haskey(qdict, "backing_file")) {
        !          1165:             monitor_printf(mon, " backing_file=");
        !          1166:             monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
        !          1167:         }
        !          1168:         monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
        !          1169:                             qdict_get_bool(qdict, "ro"),
        !          1170:                             qdict_get_str(qdict, "drv"),
        !          1171:                             qdict_get_bool(qdict, "encrypted"));
        !          1172:     } else {
        !          1173:         monitor_printf(mon, " [not inserted]");
        !          1174:     }
        !          1175: 
        !          1176:     monitor_printf(mon, "\n");
        !          1177: }
        !          1178: 
        !          1179: void bdrv_info_print(Monitor *mon, const QObject *data)
        !          1180: {
        !          1181:     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
        !          1182: }
        !          1183: 
        !          1184: /**
        !          1185:  * bdrv_info(): Block devices information
        !          1186:  *
        !          1187:  * Each block device information is stored in a QDict and the
        !          1188:  * returned QObject is a QList of all devices.
        !          1189:  *
        !          1190:  * The QDict contains the following:
        !          1191:  *
        !          1192:  * - "device": device name
        !          1193:  * - "type": device type
        !          1194:  * - "removable": true if the device is removable, false otherwise
        !          1195:  * - "locked": true if the device is locked, false otherwise
        !          1196:  * - "inserted": only present if the device is inserted, it is a QDict
        !          1197:  *    containing the following:
        !          1198:  *          - "file": device file name
        !          1199:  *          - "ro": true if read-only, false otherwise
        !          1200:  *          - "drv": driver format name
        !          1201:  *          - "backing_file": backing file name if one is used
        !          1202:  *          - "encrypted": true if encrypted, false otherwise
        !          1203:  *
        !          1204:  * Example:
        !          1205:  *
        !          1206:  * [ { "device": "ide0-hd0", "type": "hd", "removable": false, "locked": false,
        !          1207:  *     "inserted": { "file": "/tmp/foobar", "ro": false, "drv": "qcow2" } },
        !          1208:  *   { "device": "floppy0", "type": "floppy", "removable": true,
        !          1209:  *     "locked": false } ]
        !          1210:  */
        !          1211: void bdrv_info(Monitor *mon, QObject **ret_data)
        !          1212: {
        !          1213:     QList *bs_list;
1.1       root     1214:     BlockDriverState *bs;
                   1215: 
1.1.1.14! root     1216:     bs_list = qlist_new();
        !          1217: 
1.1       root     1218:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.14! root     1219:         QObject *bs_obj;
        !          1220:         const char *type = "unknown";
        !          1221: 
1.1       root     1222:         switch(bs->type) {
                   1223:         case BDRV_TYPE_HD:
1.1.1.14! root     1224:             type = "hd";
1.1       root     1225:             break;
                   1226:         case BDRV_TYPE_CDROM:
1.1.1.14! root     1227:             type = "cdrom";
1.1       root     1228:             break;
                   1229:         case BDRV_TYPE_FLOPPY:
1.1.1.14! root     1230:             type = "floppy";
1.1       root     1231:             break;
                   1232:         }
1.1.1.14! root     1233: 
        !          1234:         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
        !          1235:                                     "'removable': %i, 'locked': %i }",
        !          1236:                                     bs->device_name, type, bs->removable,
        !          1237:                                     bs->locked);
        !          1238:         assert(bs_obj != NULL);
        !          1239: 
1.1.1.5   root     1240:         if (bs->drv) {
1.1.1.14! root     1241:             QObject *obj;
        !          1242:             QDict *bs_dict = qobject_to_qdict(bs_obj);
        !          1243: 
        !          1244:             obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
        !          1245:                                      "'encrypted': %i }",
        !          1246:                                      bs->filename, bs->read_only,
        !          1247:                                      bs->drv->format_name,
        !          1248:                                      bdrv_is_encrypted(bs));
        !          1249:             assert(obj != NULL);
1.1.1.5   root     1250:             if (bs->backing_file[0] != '\0') {
1.1.1.14! root     1251:                 QDict *qdict = qobject_to_qdict(obj);
        !          1252:                 qdict_put(qdict, "backing_file",
        !          1253:                           qstring_from_str(bs->backing_file));
1.1.1.13  root     1254:             }
1.1.1.14! root     1255: 
        !          1256:             qdict_put_obj(bs_dict, "inserted", obj);
1.1       root     1257:         }
1.1.1.14! root     1258:         qlist_append_obj(bs_list, bs_obj);
1.1       root     1259:     }
1.1.1.14! root     1260: 
        !          1261:     *ret_data = QOBJECT(bs_list);
        !          1262: }
        !          1263: 
        !          1264: static void bdrv_stats_iter(QObject *data, void *opaque)
        !          1265: {
        !          1266:     QDict *qdict;
        !          1267:     Monitor *mon = opaque;
        !          1268: 
        !          1269:     qdict = qobject_to_qdict(data);
        !          1270:     monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
        !          1271: 
        !          1272:     qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
        !          1273:     monitor_printf(mon, " rd_bytes=%" PRId64
        !          1274:                         " wr_bytes=%" PRId64
        !          1275:                         " rd_operations=%" PRId64
        !          1276:                         " wr_operations=%" PRId64
        !          1277:                         "\n",
        !          1278:                         qdict_get_int(qdict, "rd_bytes"),
        !          1279:                         qdict_get_int(qdict, "wr_bytes"),
        !          1280:                         qdict_get_int(qdict, "rd_operations"),
        !          1281:                         qdict_get_int(qdict, "wr_operations"));
        !          1282: }
        !          1283: 
        !          1284: void bdrv_stats_print(Monitor *mon, const QObject *data)
        !          1285: {
        !          1286:     qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
1.1       root     1287: }
                   1288: 
1.1.1.14! root     1289: /**
        !          1290:  * bdrv_info_stats(): show block device statistics
        !          1291:  *
        !          1292:  * Each device statistic information is stored in a QDict and
        !          1293:  * the returned QObject is a QList of all devices.
        !          1294:  *
        !          1295:  * The QDict contains the following:
        !          1296:  *
        !          1297:  * - "device": device name
        !          1298:  * - "stats": A QDict with the statistics information, it contains:
        !          1299:  *     - "rd_bytes": bytes read
        !          1300:  *     - "wr_bytes": bytes written
        !          1301:  *     - "rd_operations": read operations
        !          1302:  *     - "wr_operations": write operations
        !          1303:  * 
        !          1304:  * Example:
        !          1305:  *
        !          1306:  * [ { "device": "ide0-hd0",
        !          1307:  *               "stats": { "rd_bytes": 512,
        !          1308:  *                          "wr_bytes": 0,
        !          1309:  *                          "rd_operations": 1,
        !          1310:  *                          "wr_operations": 0 } },
        !          1311:  *   { "device": "ide1-cd0",
        !          1312:  *               "stats": { "rd_bytes": 0,
        !          1313:  *                          "wr_bytes": 0,
        !          1314:  *                          "rd_operations": 0,
        !          1315:  *                          "wr_operations": 0 } } ]
        !          1316:  */
        !          1317: void bdrv_info_stats(Monitor *mon, QObject **ret_data)
1.1.1.6   root     1318: {
1.1.1.14! root     1319:     QObject *obj;
        !          1320:     QList *devices;
1.1.1.6   root     1321:     BlockDriverState *bs;
                   1322: 
1.1.1.14! root     1323:     devices = qlist_new();
        !          1324: 
1.1.1.6   root     1325:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.14! root     1326:         obj = qobject_from_jsonf("{ 'device': %s, 'stats': {"
        !          1327:                                  "'rd_bytes': %" PRId64 ","
        !          1328:                                  "'wr_bytes': %" PRId64 ","
        !          1329:                                  "'rd_operations': %" PRId64 ","
        !          1330:                                  "'wr_operations': %" PRId64
        !          1331:                                  "} }",
        !          1332:                                  bs->device_name,
        !          1333:                                  bs->rd_bytes, bs->wr_bytes,
        !          1334:                                  bs->rd_ops, bs->wr_ops);
        !          1335:         assert(obj != NULL);
        !          1336:         qlist_append_obj(devices, obj);
1.1.1.6   root     1337:     }
1.1.1.14! root     1338: 
        !          1339:     *ret_data = QOBJECT(devices);
1.1.1.6   root     1340: }
                   1341: 
1.1.1.8   root     1342: const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
                   1343: {
                   1344:     if (bs->backing_hd && bs->backing_hd->encrypted)
                   1345:         return bs->backing_file;
                   1346:     else if (bs->encrypted)
                   1347:         return bs->filename;
                   1348:     else
                   1349:         return NULL;
                   1350: }
                   1351: 
1.1.1.6   root     1352: void bdrv_get_backing_filename(BlockDriverState *bs,
1.1.1.5   root     1353:                                char *filename, int filename_size)
                   1354: {
                   1355:     if (!bs->backing_hd) {
                   1356:         pstrcpy(filename, filename_size, "");
                   1357:     } else {
                   1358:         pstrcpy(filename, filename_size, bs->backing_file);
                   1359:     }
                   1360: }
                   1361: 
1.1.1.6   root     1362: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1363:                           const uint8_t *buf, int nb_sectors)
                   1364: {
                   1365:     BlockDriver *drv = bs->drv;
                   1366:     if (!drv)
                   1367:         return -ENOMEDIUM;
                   1368:     if (!drv->bdrv_write_compressed)
                   1369:         return -ENOTSUP;
1.1.1.11  root     1370:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1371:         return -EIO;
1.1.1.14! root     1372: 
        !          1373:     if (bs->dirty_bitmap) {
        !          1374:         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
        !          1375:     }
        !          1376: 
1.1.1.5   root     1377:     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
                   1378: }
1.1.1.6   root     1379: 
1.1.1.5   root     1380: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
                   1381: {
                   1382:     BlockDriver *drv = bs->drv;
                   1383:     if (!drv)
                   1384:         return -ENOMEDIUM;
                   1385:     if (!drv->bdrv_get_info)
                   1386:         return -ENOTSUP;
                   1387:     memset(bdi, 0, sizeof(*bdi));
                   1388:     return drv->bdrv_get_info(bs, bdi);
                   1389: }
                   1390: 
1.1.1.13  root     1391: int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
                   1392:                       int64_t pos, int size)
1.1.1.9   root     1393: {
                   1394:     BlockDriver *drv = bs->drv;
                   1395:     if (!drv)
                   1396:         return -ENOMEDIUM;
1.1.1.13  root     1397:     if (!drv->bdrv_save_vmstate)
1.1.1.9   root     1398:         return -ENOTSUP;
1.1.1.13  root     1399:     return drv->bdrv_save_vmstate(bs, buf, pos, size);
1.1.1.9   root     1400: }
                   1401: 
1.1.1.13  root     1402: int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
                   1403:                       int64_t pos, int size)
1.1.1.9   root     1404: {
                   1405:     BlockDriver *drv = bs->drv;
                   1406:     if (!drv)
                   1407:         return -ENOMEDIUM;
1.1.1.13  root     1408:     if (!drv->bdrv_load_vmstate)
1.1.1.9   root     1409:         return -ENOTSUP;
1.1.1.13  root     1410:     return drv->bdrv_load_vmstate(bs, buf, pos, size);
1.1.1.9   root     1411: }
                   1412: 
1.1       root     1413: /**************************************************************/
1.1.1.5   root     1414: /* handling of snapshots */
1.1       root     1415: 
1.1.1.6   root     1416: int bdrv_snapshot_create(BlockDriverState *bs,
1.1.1.5   root     1417:                          QEMUSnapshotInfo *sn_info)
                   1418: {
                   1419:     BlockDriver *drv = bs->drv;
                   1420:     if (!drv)
                   1421:         return -ENOMEDIUM;
                   1422:     if (!drv->bdrv_snapshot_create)
                   1423:         return -ENOTSUP;
                   1424:     return drv->bdrv_snapshot_create(bs, sn_info);
                   1425: }
1.1       root     1426: 
1.1.1.6   root     1427: int bdrv_snapshot_goto(BlockDriverState *bs,
1.1.1.5   root     1428:                        const char *snapshot_id)
1.1       root     1429: {
1.1.1.5   root     1430:     BlockDriver *drv = bs->drv;
                   1431:     if (!drv)
                   1432:         return -ENOMEDIUM;
                   1433:     if (!drv->bdrv_snapshot_goto)
                   1434:         return -ENOTSUP;
                   1435:     return drv->bdrv_snapshot_goto(bs, snapshot_id);
1.1       root     1436: }
                   1437: 
1.1.1.5   root     1438: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1.1       root     1439: {
1.1.1.5   root     1440:     BlockDriver *drv = bs->drv;
                   1441:     if (!drv)
                   1442:         return -ENOMEDIUM;
                   1443:     if (!drv->bdrv_snapshot_delete)
                   1444:         return -ENOTSUP;
                   1445:     return drv->bdrv_snapshot_delete(bs, snapshot_id);
                   1446: }
1.1       root     1447: 
1.1.1.6   root     1448: int bdrv_snapshot_list(BlockDriverState *bs,
1.1.1.5   root     1449:                        QEMUSnapshotInfo **psn_info)
                   1450: {
                   1451:     BlockDriver *drv = bs->drv;
                   1452:     if (!drv)
                   1453:         return -ENOMEDIUM;
                   1454:     if (!drv->bdrv_snapshot_list)
                   1455:         return -ENOTSUP;
                   1456:     return drv->bdrv_snapshot_list(bs, psn_info);
                   1457: }
                   1458: 
                   1459: #define NB_SUFFIXES 4
                   1460: 
                   1461: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
                   1462: {
                   1463:     static const char suffixes[NB_SUFFIXES] = "KMGT";
                   1464:     int64_t base;
                   1465:     int i;
                   1466: 
                   1467:     if (size <= 999) {
                   1468:         snprintf(buf, buf_size, "%" PRId64, size);
                   1469:     } else {
                   1470:         base = 1024;
                   1471:         for(i = 0; i < NB_SUFFIXES; i++) {
                   1472:             if (size < (10 * base)) {
1.1.1.6   root     1473:                 snprintf(buf, buf_size, "%0.1f%c",
1.1.1.5   root     1474:                          (double)size / base,
                   1475:                          suffixes[i]);
                   1476:                 break;
                   1477:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1.1.1.6   root     1478:                 snprintf(buf, buf_size, "%" PRId64 "%c",
1.1.1.5   root     1479:                          ((size + (base >> 1)) / base),
                   1480:                          suffixes[i]);
                   1481:                 break;
                   1482:             }
                   1483:             base = base * 1024;
                   1484:         }
1.1       root     1485:     }
1.1.1.5   root     1486:     return buf;
                   1487: }
                   1488: 
                   1489: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
                   1490: {
                   1491:     char buf1[128], date_buf[128], clock_buf[128];
                   1492: #ifdef _WIN32
                   1493:     struct tm *ptm;
1.1.1.2   root     1494: #else
1.1.1.5   root     1495:     struct tm tm;
1.1.1.2   root     1496: #endif
1.1.1.5   root     1497:     time_t ti;
                   1498:     int64_t secs;
                   1499: 
                   1500:     if (!sn) {
1.1.1.6   root     1501:         snprintf(buf, buf_size,
                   1502:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1503:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
                   1504:     } else {
                   1505:         ti = sn->date_sec;
1.1       root     1506: #ifdef _WIN32
1.1.1.5   root     1507:         ptm = localtime(&ti);
                   1508:         strftime(date_buf, sizeof(date_buf),
                   1509:                  "%Y-%m-%d %H:%M:%S", ptm);
                   1510: #else
                   1511:         localtime_r(&ti, &tm);
                   1512:         strftime(date_buf, sizeof(date_buf),
                   1513:                  "%Y-%m-%d %H:%M:%S", &tm);
1.1       root     1514: #endif
1.1.1.5   root     1515:         secs = sn->vm_clock_nsec / 1000000000;
                   1516:         snprintf(clock_buf, sizeof(clock_buf),
                   1517:                  "%02d:%02d:%02d.%03d",
                   1518:                  (int)(secs / 3600),
                   1519:                  (int)((secs / 60) % 60),
1.1.1.6   root     1520:                  (int)(secs % 60),
1.1.1.5   root     1521:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
                   1522:         snprintf(buf, buf_size,
1.1.1.6   root     1523:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1524:                  sn->id_str, sn->name,
                   1525:                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
                   1526:                  date_buf,
                   1527:                  clock_buf);
                   1528:     }
                   1529:     return buf;
1.1       root     1530: }
                   1531: 
                   1532: 
1.1.1.5   root     1533: /**************************************************************/
                   1534: /* async I/Os */
                   1535: 
1.1.1.7   root     1536: BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
1.1.1.13  root     1537:                                  QEMUIOVector *qiov, int nb_sectors,
1.1.1.7   root     1538:                                  BlockDriverCompletionFunc *cb, void *opaque)
                   1539: {
1.1.1.5   root     1540:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1541:     BlockDriverAIOCB *ret;
1.1.1.5   root     1542: 
                   1543:     if (!drv)
                   1544:         return NULL;
1.1.1.7   root     1545:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1546:         return NULL;
1.1.1.5   root     1547: 
1.1.1.13  root     1548:     ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
                   1549:                               cb, opaque);
1.1.1.6   root     1550: 
                   1551:     if (ret) {
                   1552:        /* Update stats even though technically transfer has not happened. */
1.1.1.14! root     1553:        bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
1.1.1.6   root     1554:        bs->rd_ops ++;
                   1555:     }
                   1556: 
                   1557:     return ret;
1.1       root     1558: }
                   1559: 
1.1.1.13  root     1560: BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                   1561:                                   QEMUIOVector *qiov, int nb_sectors,
                   1562:                                   BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1563: {
1.1.1.5   root     1564:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1565:     BlockDriverAIOCB *ret;
1.1       root     1566: 
1.1.1.5   root     1567:     if (!drv)
                   1568:         return NULL;
                   1569:     if (bs->read_only)
                   1570:         return NULL;
1.1.1.7   root     1571:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1572:         return NULL;
1.1.1.4   root     1573: 
1.1.1.14! root     1574:     if (bs->dirty_bitmap) {
        !          1575:         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
        !          1576:     }
        !          1577: 
1.1.1.13  root     1578:     ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
                   1579:                                cb, opaque);
1.1.1.6   root     1580: 
                   1581:     if (ret) {
                   1582:        /* Update stats even though technically transfer has not happened. */
1.1.1.14! root     1583:        bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
1.1.1.6   root     1584:        bs->wr_ops ++;
                   1585:     }
                   1586: 
                   1587:     return ret;
1.1.1.5   root     1588: }
                   1589: 
1.1.1.14! root     1590: 
        !          1591: typedef struct MultiwriteCB {
        !          1592:     int error;
        !          1593:     int num_requests;
        !          1594:     int num_callbacks;
        !          1595:     struct {
        !          1596:         BlockDriverCompletionFunc *cb;
        !          1597:         void *opaque;
        !          1598:         QEMUIOVector *free_qiov;
        !          1599:         void *free_buf;
        !          1600:     } callbacks[];
        !          1601: } MultiwriteCB;
        !          1602: 
        !          1603: static void multiwrite_user_cb(MultiwriteCB *mcb)
        !          1604: {
        !          1605:     int i;
        !          1606: 
        !          1607:     for (i = 0; i < mcb->num_callbacks; i++) {
        !          1608:         mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
        !          1609:         qemu_free(mcb->callbacks[i].free_qiov);
        !          1610:         qemu_free(mcb->callbacks[i].free_buf);
        !          1611:     }
        !          1612: }
        !          1613: 
        !          1614: static void multiwrite_cb(void *opaque, int ret)
        !          1615: {
        !          1616:     MultiwriteCB *mcb = opaque;
        !          1617: 
        !          1618:     if (ret < 0) {
        !          1619:         mcb->error = ret;
        !          1620:         multiwrite_user_cb(mcb);
        !          1621:     }
        !          1622: 
        !          1623:     mcb->num_requests--;
        !          1624:     if (mcb->num_requests == 0) {
        !          1625:         if (mcb->error == 0) {
        !          1626:             multiwrite_user_cb(mcb);
        !          1627:         }
        !          1628:         qemu_free(mcb);
        !          1629:     }
        !          1630: }
        !          1631: 
        !          1632: static int multiwrite_req_compare(const void *a, const void *b)
        !          1633: {
        !          1634:     return (((BlockRequest*) a)->sector - ((BlockRequest*) b)->sector);
        !          1635: }
        !          1636: 
        !          1637: /*
        !          1638:  * Takes a bunch of requests and tries to merge them. Returns the number of
        !          1639:  * requests that remain after merging.
        !          1640:  */
        !          1641: static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
        !          1642:     int num_reqs, MultiwriteCB *mcb)
        !          1643: {
        !          1644:     int i, outidx;
        !          1645: 
        !          1646:     // Sort requests by start sector
        !          1647:     qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
        !          1648: 
        !          1649:     // Check if adjacent requests touch the same clusters. If so, combine them,
        !          1650:     // filling up gaps with zero sectors.
        !          1651:     outidx = 0;
        !          1652:     for (i = 1; i < num_reqs; i++) {
        !          1653:         int merge = 0;
        !          1654:         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
        !          1655: 
        !          1656:         // This handles the cases that are valid for all block drivers, namely
        !          1657:         // exactly sequential writes and overlapping writes.
        !          1658:         if (reqs[i].sector <= oldreq_last) {
        !          1659:             merge = 1;
        !          1660:         }
        !          1661: 
        !          1662:         // The block driver may decide that it makes sense to combine requests
        !          1663:         // even if there is a gap of some sectors between them. In this case,
        !          1664:         // the gap is filled with zeros (therefore only applicable for yet
        !          1665:         // unused space in format like qcow2).
        !          1666:         if (!merge && bs->drv->bdrv_merge_requests) {
        !          1667:             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
        !          1668:         }
        !          1669: 
        !          1670:         if (merge) {
        !          1671:             size_t size;
        !          1672:             QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
        !          1673:             qemu_iovec_init(qiov,
        !          1674:                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
        !          1675: 
        !          1676:             // Add the first request to the merged one. If the requests are
        !          1677:             // overlapping, drop the last sectors of the first request.
        !          1678:             size = (reqs[i].sector - reqs[outidx].sector) << 9;
        !          1679:             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
        !          1680: 
        !          1681:             // We might need to add some zeros between the two requests
        !          1682:             if (reqs[i].sector > oldreq_last) {
        !          1683:                 size_t zero_bytes = (reqs[i].sector - oldreq_last) << 9;
        !          1684:                 uint8_t *buf = qemu_blockalign(bs, zero_bytes);
        !          1685:                 memset(buf, 0, zero_bytes);
        !          1686:                 qemu_iovec_add(qiov, buf, zero_bytes);
        !          1687:                 mcb->callbacks[i].free_buf = buf;
        !          1688:             }
        !          1689: 
        !          1690:             // Add the second request
        !          1691:             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
        !          1692: 
        !          1693:             reqs[outidx].nb_sectors += reqs[i].nb_sectors;
        !          1694:             reqs[outidx].qiov = qiov;
        !          1695: 
        !          1696:             mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
        !          1697:         } else {
        !          1698:             outidx++;
        !          1699:             reqs[outidx].sector     = reqs[i].sector;
        !          1700:             reqs[outidx].nb_sectors = reqs[i].nb_sectors;
        !          1701:             reqs[outidx].qiov       = reqs[i].qiov;
        !          1702:         }
        !          1703:     }
        !          1704: 
        !          1705:     return outidx + 1;
        !          1706: }
        !          1707: 
        !          1708: /*
        !          1709:  * Submit multiple AIO write requests at once.
        !          1710:  *
        !          1711:  * On success, the function returns 0 and all requests in the reqs array have
        !          1712:  * been submitted. In error case this function returns -1, and any of the
        !          1713:  * requests may or may not be submitted yet. In particular, this means that the
        !          1714:  * callback will be called for some of the requests, for others it won't. The
        !          1715:  * caller must check the error field of the BlockRequest to wait for the right
        !          1716:  * callbacks (if error != 0, no callback will be called).
        !          1717:  *
        !          1718:  * The implementation may modify the contents of the reqs array, e.g. to merge
        !          1719:  * requests. However, the fields opaque and error are left unmodified as they
        !          1720:  * are used to signal failure for a single request to the caller.
        !          1721:  */
        !          1722: int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
        !          1723: {
        !          1724:     BlockDriverAIOCB *acb;
        !          1725:     MultiwriteCB *mcb;
        !          1726:     int i;
        !          1727: 
        !          1728:     if (num_reqs == 0) {
        !          1729:         return 0;
        !          1730:     }
        !          1731: 
        !          1732:     // Create MultiwriteCB structure
        !          1733:     mcb = qemu_mallocz(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
        !          1734:     mcb->num_requests = 0;
        !          1735:     mcb->num_callbacks = num_reqs;
        !          1736: 
        !          1737:     for (i = 0; i < num_reqs; i++) {
        !          1738:         mcb->callbacks[i].cb = reqs[i].cb;
        !          1739:         mcb->callbacks[i].opaque = reqs[i].opaque;
        !          1740:     }
        !          1741: 
        !          1742:     // Check for mergable requests
        !          1743:     num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
        !          1744: 
        !          1745:     // Run the aio requests
        !          1746:     for (i = 0; i < num_reqs; i++) {
        !          1747:         acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
        !          1748:             reqs[i].nb_sectors, multiwrite_cb, mcb);
        !          1749: 
        !          1750:         if (acb == NULL) {
        !          1751:             // We can only fail the whole thing if no request has been
        !          1752:             // submitted yet. Otherwise we'll wait for the submitted AIOs to
        !          1753:             // complete and report the error in the callback.
        !          1754:             if (mcb->num_requests == 0) {
        !          1755:                 reqs[i].error = EIO;
        !          1756:                 goto fail;
        !          1757:             } else {
        !          1758:                 mcb->error = EIO;
        !          1759:                 break;
        !          1760:             }
        !          1761:         } else {
        !          1762:             mcb->num_requests++;
        !          1763:         }
        !          1764:     }
        !          1765: 
        !          1766:     return 0;
        !          1767: 
        !          1768: fail:
        !          1769:     free(mcb);
        !          1770:     return -1;
        !          1771: }
        !          1772: 
        !          1773: BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
        !          1774:         BlockDriverCompletionFunc *cb, void *opaque)
        !          1775: {
        !          1776:     BlockDriver *drv = bs->drv;
        !          1777: 
        !          1778:     if (!drv)
        !          1779:         return NULL;
        !          1780: 
        !          1781:     /*
        !          1782:      * Note that unlike bdrv_flush the driver is reponsible for flushing a
        !          1783:      * backing image if it exists.
        !          1784:      */
        !          1785:     return drv->bdrv_aio_flush(bs, cb, opaque);
        !          1786: }
        !          1787: 
1.1.1.5   root     1788: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1.1.1.4   root     1789: {
1.1.1.10  root     1790:     acb->pool->cancel(acb);
1.1.1.5   root     1791: }
1.1.1.4   root     1792: 
                   1793: 
1.1.1.5   root     1794: /**************************************************************/
                   1795: /* async block device emulation */
1.1.1.4   root     1796: 
1.1.1.13  root     1797: typedef struct BlockDriverAIOCBSync {
                   1798:     BlockDriverAIOCB common;
                   1799:     QEMUBH *bh;
                   1800:     int ret;
                   1801:     /* vector translation state */
                   1802:     QEMUIOVector *qiov;
                   1803:     uint8_t *bounce;
                   1804:     int is_write;
                   1805: } BlockDriverAIOCBSync;
                   1806: 
                   1807: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
                   1808: {
                   1809:     BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
                   1810:     qemu_bh_delete(acb->bh);
                   1811:     acb->bh = NULL;
                   1812:     qemu_aio_release(acb);
                   1813: }
                   1814: 
                   1815: static AIOPool bdrv_em_aio_pool = {
                   1816:     .aiocb_size         = sizeof(BlockDriverAIOCBSync),
                   1817:     .cancel             = bdrv_aio_cancel_em,
                   1818: };
                   1819: 
1.1.1.5   root     1820: static void bdrv_aio_bh_cb(void *opaque)
1.1.1.4   root     1821: {
1.1.1.5   root     1822:     BlockDriverAIOCBSync *acb = opaque;
1.1.1.13  root     1823: 
                   1824:     if (!acb->is_write)
                   1825:         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
                   1826:     qemu_vfree(acb->bounce);
1.1.1.5   root     1827:     acb->common.cb(acb->common.opaque, acb->ret);
1.1.1.13  root     1828:     qemu_bh_delete(acb->bh);
                   1829:     acb->bh = NULL;
1.1.1.5   root     1830:     qemu_aio_release(acb);
1.1.1.4   root     1831: }
                   1832: 
1.1.1.13  root     1833: static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
                   1834:                                             int64_t sector_num,
                   1835:                                             QEMUIOVector *qiov,
                   1836:                                             int nb_sectors,
                   1837:                                             BlockDriverCompletionFunc *cb,
                   1838:                                             void *opaque,
                   1839:                                             int is_write)
                   1840: 
1.1       root     1841: {
1.1.1.5   root     1842:     BlockDriverAIOCBSync *acb;
1.1       root     1843: 
1.1.1.13  root     1844:     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
                   1845:     acb->is_write = is_write;
                   1846:     acb->qiov = qiov;
                   1847:     acb->bounce = qemu_blockalign(bs, qiov->size);
                   1848: 
1.1.1.5   root     1849:     if (!acb->bh)
                   1850:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1.1.1.13  root     1851: 
                   1852:     if (is_write) {
                   1853:         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
                   1854:         acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
                   1855:     } else {
                   1856:         acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
                   1857:     }
                   1858: 
1.1.1.5   root     1859:     qemu_bh_schedule(acb->bh);
1.1.1.13  root     1860: 
1.1.1.5   root     1861:     return &acb->common;
                   1862: }
1.1       root     1863: 
1.1.1.13  root     1864: static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
                   1865:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
1.1.1.5   root     1866:         BlockDriverCompletionFunc *cb, void *opaque)
                   1867: {
1.1.1.13  root     1868:     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
1.1.1.5   root     1869: }
                   1870: 
1.1.1.13  root     1871: static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
                   1872:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
                   1873:         BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5   root     1874: {
1.1.1.13  root     1875:     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
1.1       root     1876: }
                   1877: 
1.1.1.14! root     1878: static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
        !          1879:         BlockDriverCompletionFunc *cb, void *opaque)
        !          1880: {
        !          1881:     BlockDriverAIOCBSync *acb;
        !          1882: 
        !          1883:     acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
        !          1884:     acb->is_write = 1; /* don't bounce in the completion hadler */
        !          1885:     acb->qiov = NULL;
        !          1886:     acb->bounce = NULL;
        !          1887:     acb->ret = 0;
        !          1888: 
        !          1889:     if (!acb->bh)
        !          1890:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
        !          1891: 
        !          1892:     bdrv_flush(bs);
        !          1893:     qemu_bh_schedule(acb->bh);
        !          1894:     return &acb->common;
        !          1895: }
        !          1896: 
1.1.1.5   root     1897: /**************************************************************/
                   1898: /* sync block device emulation */
                   1899: 
                   1900: static void bdrv_rw_em_cb(void *opaque, int ret)
1.1.1.4   root     1901: {
1.1.1.5   root     1902:     *(int *)opaque = ret;
1.1.1.4   root     1903: }
                   1904: 
1.1.1.5   root     1905: #define NOT_DONE 0x7fffffff
                   1906: 
1.1.1.6   root     1907: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1908:                         uint8_t *buf, int nb_sectors)
                   1909: {
                   1910:     int async_ret;
                   1911:     BlockDriverAIOCB *acb;
1.1.1.13  root     1912:     struct iovec iov;
                   1913:     QEMUIOVector qiov;
1.1.1.5   root     1914: 
1.1.1.14! root     1915:     async_context_push();
        !          1916: 
1.1.1.5   root     1917:     async_ret = NOT_DONE;
1.1.1.13  root     1918:     iov.iov_base = (void *)buf;
                   1919:     iov.iov_len = nb_sectors * 512;
                   1920:     qemu_iovec_init_external(&qiov, &iov, 1);
                   1921:     acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
                   1922:         bdrv_rw_em_cb, &async_ret);
1.1.1.14! root     1923:     if (acb == NULL) {
        !          1924:         async_ret = -1;
        !          1925:         goto fail;
        !          1926:     }
1.1.1.7   root     1927: 
1.1.1.5   root     1928:     while (async_ret == NOT_DONE) {
                   1929:         qemu_aio_wait();
                   1930:     }
1.1.1.7   root     1931: 
1.1.1.14! root     1932: 
        !          1933: fail:
        !          1934:     async_context_pop();
1.1.1.5   root     1935:     return async_ret;
                   1936: }
                   1937: 
                   1938: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                   1939:                          const uint8_t *buf, int nb_sectors)
                   1940: {
                   1941:     int async_ret;
                   1942:     BlockDriverAIOCB *acb;
1.1.1.13  root     1943:     struct iovec iov;
                   1944:     QEMUIOVector qiov;
1.1.1.5   root     1945: 
1.1.1.14! root     1946:     async_context_push();
        !          1947: 
1.1.1.5   root     1948:     async_ret = NOT_DONE;
1.1.1.13  root     1949:     iov.iov_base = (void *)buf;
                   1950:     iov.iov_len = nb_sectors * 512;
                   1951:     qemu_iovec_init_external(&qiov, &iov, 1);
                   1952:     acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
                   1953:         bdrv_rw_em_cb, &async_ret);
1.1.1.14! root     1954:     if (acb == NULL) {
        !          1955:         async_ret = -1;
        !          1956:         goto fail;
        !          1957:     }
1.1.1.5   root     1958:     while (async_ret == NOT_DONE) {
                   1959:         qemu_aio_wait();
                   1960:     }
1.1.1.14! root     1961: 
        !          1962: fail:
        !          1963:     async_context_pop();
1.1.1.5   root     1964:     return async_ret;
                   1965: }
1.1       root     1966: 
                   1967: void bdrv_init(void)
                   1968: {
1.1.1.13  root     1969:     module_call_init(MODULE_INIT_BLOCK);
1.1.1.10  root     1970: }
                   1971: 
1.1.1.14! root     1972: void bdrv_init_with_whitelist(void)
        !          1973: {
        !          1974:     use_bdrv_whitelist = 1;
        !          1975:     bdrv_init();
        !          1976: }
        !          1977: 
1.1.1.13  root     1978: void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
                   1979:                    BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5   root     1980: {
                   1981:     BlockDriverAIOCB *acb;
                   1982: 
1.1.1.10  root     1983:     if (pool->free_aiocb) {
                   1984:         acb = pool->free_aiocb;
                   1985:         pool->free_aiocb = acb->next;
1.1.1.5   root     1986:     } else {
1.1.1.10  root     1987:         acb = qemu_mallocz(pool->aiocb_size);
                   1988:         acb->pool = pool;
1.1.1.5   root     1989:     }
                   1990:     acb->bs = bs;
                   1991:     acb->cb = cb;
                   1992:     acb->opaque = opaque;
                   1993:     return acb;
                   1994: }
                   1995: 
                   1996: void qemu_aio_release(void *p)
                   1997: {
1.1.1.10  root     1998:     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
                   1999:     AIOPool *pool = acb->pool;
                   2000:     acb->next = pool->free_aiocb;
                   2001:     pool->free_aiocb = acb;
1.1.1.5   root     2002: }
                   2003: 
                   2004: /**************************************************************/
                   2005: /* removable device support */
                   2006: 
                   2007: /**
                   2008:  * Return TRUE if the media is present
                   2009:  */
                   2010: int bdrv_is_inserted(BlockDriverState *bs)
                   2011: {
                   2012:     BlockDriver *drv = bs->drv;
                   2013:     int ret;
                   2014:     if (!drv)
                   2015:         return 0;
                   2016:     if (!drv->bdrv_is_inserted)
                   2017:         return 1;
                   2018:     ret = drv->bdrv_is_inserted(bs);
                   2019:     return ret;
                   2020: }
                   2021: 
                   2022: /**
                   2023:  * Return TRUE if the media changed since the last call to this
1.1.1.6   root     2024:  * function. It is currently only used for floppy disks
1.1.1.5   root     2025:  */
                   2026: int bdrv_media_changed(BlockDriverState *bs)
                   2027: {
                   2028:     BlockDriver *drv = bs->drv;
                   2029:     int ret;
                   2030: 
                   2031:     if (!drv || !drv->bdrv_media_changed)
                   2032:         ret = -ENOTSUP;
                   2033:     else
                   2034:         ret = drv->bdrv_media_changed(bs);
                   2035:     if (ret == -ENOTSUP)
                   2036:         ret = bs->media_changed;
                   2037:     bs->media_changed = 0;
                   2038:     return ret;
                   2039: }
                   2040: 
                   2041: /**
                   2042:  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
                   2043:  */
1.1.1.13  root     2044: int bdrv_eject(BlockDriverState *bs, int eject_flag)
1.1.1.5   root     2045: {
                   2046:     BlockDriver *drv = bs->drv;
                   2047:     int ret;
                   2048: 
1.1.1.13  root     2049:     if (bs->locked) {
                   2050:         return -EBUSY;
                   2051:     }
                   2052: 
1.1.1.5   root     2053:     if (!drv || !drv->bdrv_eject) {
                   2054:         ret = -ENOTSUP;
                   2055:     } else {
                   2056:         ret = drv->bdrv_eject(bs, eject_flag);
                   2057:     }
                   2058:     if (ret == -ENOTSUP) {
                   2059:         if (eject_flag)
                   2060:             bdrv_close(bs);
1.1.1.13  root     2061:         ret = 0;
1.1.1.5   root     2062:     }
1.1.1.13  root     2063: 
                   2064:     return ret;
1.1.1.5   root     2065: }
                   2066: 
                   2067: int bdrv_is_locked(BlockDriverState *bs)
                   2068: {
                   2069:     return bs->locked;
                   2070: }
                   2071: 
                   2072: /**
                   2073:  * Lock or unlock the media (if it is locked, the user won't be able
                   2074:  * to eject it manually).
                   2075:  */
                   2076: void bdrv_set_locked(BlockDriverState *bs, int locked)
                   2077: {
                   2078:     BlockDriver *drv = bs->drv;
                   2079: 
                   2080:     bs->locked = locked;
                   2081:     if (drv && drv->bdrv_set_locked) {
                   2082:         drv->bdrv_set_locked(bs, locked);
                   2083:     }
1.1       root     2084: }
1.1.1.6   root     2085: 
                   2086: /* needed for generic scsi interface */
                   2087: 
                   2088: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   2089: {
                   2090:     BlockDriver *drv = bs->drv;
                   2091: 
                   2092:     if (drv && drv->bdrv_ioctl)
                   2093:         return drv->bdrv_ioctl(bs, req, buf);
                   2094:     return -ENOTSUP;
                   2095: }
1.1.1.13  root     2096: 
                   2097: BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
                   2098:         unsigned long int req, void *buf,
                   2099:         BlockDriverCompletionFunc *cb, void *opaque)
                   2100: {
                   2101:     BlockDriver *drv = bs->drv;
                   2102: 
                   2103:     if (drv && drv->bdrv_aio_ioctl)
                   2104:         return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
                   2105:     return NULL;
                   2106: }
                   2107: 
1.1.1.14! root     2108: 
        !          2109: 
1.1.1.13  root     2110: void *qemu_blockalign(BlockDriverState *bs, size_t size)
                   2111: {
                   2112:     return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
                   2113: }
1.1.1.14! root     2114: 
        !          2115: void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
        !          2116: {
        !          2117:     int64_t bitmap_size;
        !          2118: 
        !          2119:     if (enable) {
        !          2120:         if (!bs->dirty_bitmap) {
        !          2121:             bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
        !          2122:                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
        !          2123:             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
        !          2124: 
        !          2125:             bs->dirty_bitmap = qemu_mallocz(bitmap_size);
        !          2126:         }
        !          2127:     } else {
        !          2128:         if (bs->dirty_bitmap) {
        !          2129:             qemu_free(bs->dirty_bitmap);
        !          2130:             bs->dirty_bitmap = NULL;
        !          2131:         }
        !          2132:     }
        !          2133: }
        !          2134: 
        !          2135: int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
        !          2136: {
        !          2137:     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
        !          2138: 
        !          2139:     if (bs->dirty_bitmap &&
        !          2140:         (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
        !          2141:         return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
        !          2142:             (1 << (chunk % (sizeof(unsigned long) * 8)));
        !          2143:     } else {
        !          2144:         return 0;
        !          2145:     }
        !          2146: }
        !          2147: 
        !          2148: void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
        !          2149:                       int nr_sectors)
        !          2150: {
        !          2151:     set_dirty_bitmap(bs, cur_sector, nr_sectors, 0);
        !          2152: }

unix.superglobalmegacorp.com