Annotation of qemu/block.c, revision 1.1.1.10

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

unix.superglobalmegacorp.com