Annotation of qemu/block.c, revision 1.1.1.12

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: 
1.1.1.11  root      536:     if (offset < 0)
                    537:         return -EIO;
                    538: 
                    539:     if ((offset > len) || (len - offset < size))
1.1.1.7   root      540:         return -EIO;
                    541: 
                    542:     return 0;
                    543: }
                    544: 
                    545: static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                    546:                               int nb_sectors)
                    547: {
                    548:     int64_t offset;
                    549: 
                    550:     /* Deal with byte accesses */
                    551:     if (sector_num < 0)
                    552:         offset = -sector_num;
                    553:     else
                    554:         offset = sector_num * 512;
                    555: 
                    556:     return bdrv_check_byte_request(bs, offset, nb_sectors * 512);
                    557: }
                    558: 
1.1.1.5   root      559: /* return < 0 if error. See bdrv_write() for the return codes */
1.1.1.6   root      560: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1.1       root      561:               uint8_t *buf, int nb_sectors)
                    562: {
                    563:     BlockDriver *drv = bs->drv;
                    564: 
1.1.1.5   root      565:     if (!drv)
                    566:         return -ENOMEDIUM;
1.1.1.7   root      567:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    568:         return -EIO;
1.1       root      569: 
1.1.1.5   root      570:     if (drv->bdrv_pread) {
                    571:         int ret, len;
                    572:         len = nb_sectors * 512;
                    573:         ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
                    574:         if (ret < 0)
                    575:             return ret;
                    576:         else if (ret != len)
                    577:             return -EINVAL;
1.1.1.6   root      578:         else {
                    579:            bs->rd_bytes += (unsigned) len;
                    580:            bs->rd_ops ++;
1.1.1.5   root      581:             return 0;
1.1.1.6   root      582:        }
1.1.1.5   root      583:     } else {
                    584:         return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
1.1       root      585:     }
                    586: }
                    587: 
1.1.1.6   root      588: /* Return < 0 if error. Important errors are:
1.1.1.5   root      589:   -EIO         generic I/O error (may happen for all errors)
                    590:   -ENOMEDIUM   No media inserted.
                    591:   -EINVAL      Invalid sector number or nb_sectors
                    592:   -EACCES      Trying to write a read-only device
                    593: */
1.1.1.6   root      594: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1.1       root      595:                const uint8_t *buf, int nb_sectors)
                    596: {
1.1.1.5   root      597:     BlockDriver *drv = bs->drv;
                    598:     if (!bs->drv)
                    599:         return -ENOMEDIUM;
1.1       root      600:     if (bs->read_only)
1.1.1.5   root      601:         return -EACCES;
1.1.1.7   root      602:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                    603:         return -EIO;
                    604: 
1.1.1.5   root      605:     if (drv->bdrv_pwrite) {
1.1.1.7   root      606:         int ret, len, count = 0;
1.1.1.5   root      607:         len = nb_sectors * 512;
1.1.1.7   root      608:         do {
                    609:             ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len - count);
                    610:             if (ret < 0) {
                    611:                 printf("bdrv_write ret=%d\n", ret);
                    612:                 return ret;
                    613:             }
                    614:             count += ret;
                    615:             buf += ret;
                    616:         } while (count != len);
                    617:         bs->wr_bytes += (unsigned) len;
                    618:         bs->wr_ops ++;
                    619:         return 0;
1.1.1.5   root      620:     }
1.1.1.7   root      621:     return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
1.1       root      622: }
                    623: 
1.1.1.6   root      624: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      625:                          uint8_t *buf, int count1)
                    626: {
                    627:     uint8_t tmp_buf[SECTOR_SIZE];
                    628:     int len, nb_sectors, count;
                    629:     int64_t sector_num;
                    630: 
                    631:     count = count1;
                    632:     /* first read to align to sector start */
                    633:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    634:     if (len > count)
                    635:         len = count;
                    636:     sector_num = offset >> SECTOR_BITS;
                    637:     if (len > 0) {
                    638:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    639:             return -EIO;
                    640:         memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
                    641:         count -= len;
                    642:         if (count == 0)
                    643:             return count1;
                    644:         sector_num++;
                    645:         buf += len;
                    646:     }
                    647: 
                    648:     /* read the sectors "in place" */
                    649:     nb_sectors = count >> SECTOR_BITS;
                    650:     if (nb_sectors > 0) {
                    651:         if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
                    652:             return -EIO;
                    653:         sector_num += nb_sectors;
                    654:         len = nb_sectors << SECTOR_BITS;
                    655:         buf += len;
                    656:         count -= len;
                    657:     }
                    658: 
                    659:     /* add data from the last sector */
                    660:     if (count > 0) {
                    661:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    662:             return -EIO;
                    663:         memcpy(buf, tmp_buf, count);
                    664:     }
                    665:     return count1;
                    666: }
                    667: 
1.1.1.6   root      668: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      669:                           const uint8_t *buf, int count1)
                    670: {
                    671:     uint8_t tmp_buf[SECTOR_SIZE];
                    672:     int len, nb_sectors, count;
                    673:     int64_t sector_num;
                    674: 
                    675:     count = count1;
                    676:     /* first write to align to sector start */
                    677:     len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
                    678:     if (len > count)
                    679:         len = count;
                    680:     sector_num = offset >> SECTOR_BITS;
                    681:     if (len > 0) {
                    682:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    683:             return -EIO;
                    684:         memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
                    685:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    686:             return -EIO;
                    687:         count -= len;
                    688:         if (count == 0)
                    689:             return count1;
                    690:         sector_num++;
                    691:         buf += len;
                    692:     }
                    693: 
                    694:     /* write the sectors "in place" */
                    695:     nb_sectors = count >> SECTOR_BITS;
                    696:     if (nb_sectors > 0) {
                    697:         if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
                    698:             return -EIO;
                    699:         sector_num += nb_sectors;
                    700:         len = nb_sectors << SECTOR_BITS;
                    701:         buf += len;
                    702:         count -= len;
                    703:     }
                    704: 
                    705:     /* add data from the last sector */
                    706:     if (count > 0) {
                    707:         if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
                    708:             return -EIO;
                    709:         memcpy(tmp_buf, buf, count);
                    710:         if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
                    711:             return -EIO;
                    712:     }
                    713:     return count1;
                    714: }
                    715: 
                    716: /**
1.1.1.6   root      717:  * Read with byte offsets (needed only for file protocols)
1.1.1.5   root      718:  */
1.1.1.6   root      719: int bdrv_pread(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      720:                void *buf1, int count1)
                    721: {
                    722:     BlockDriver *drv = bs->drv;
                    723: 
                    724:     if (!drv)
                    725:         return -ENOMEDIUM;
1.1.1.7   root      726:     if (bdrv_check_byte_request(bs, offset, count1))
                    727:         return -EIO;
                    728: 
1.1.1.5   root      729:     if (!drv->bdrv_pread)
                    730:         return bdrv_pread_em(bs, offset, buf1, count1);
                    731:     return drv->bdrv_pread(bs, offset, buf1, count1);
                    732: }
                    733: 
1.1.1.6   root      734: /**
                    735:  * Write with byte offsets (needed only for file protocols)
1.1.1.5   root      736:  */
1.1.1.6   root      737: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1.1.1.5   root      738:                 const void *buf1, int count1)
                    739: {
                    740:     BlockDriver *drv = bs->drv;
                    741: 
                    742:     if (!drv)
                    743:         return -ENOMEDIUM;
1.1.1.7   root      744:     if (bdrv_check_byte_request(bs, offset, count1))
                    745:         return -EIO;
                    746: 
1.1.1.5   root      747:     if (!drv->bdrv_pwrite)
                    748:         return bdrv_pwrite_em(bs, offset, buf1, count1);
                    749:     return drv->bdrv_pwrite(bs, offset, buf1, count1);
                    750: }
                    751: 
                    752: /**
                    753:  * Truncate file to 'offset' bytes (needed only for file protocols)
                    754:  */
                    755: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
                    756: {
                    757:     BlockDriver *drv = bs->drv;
                    758:     if (!drv)
                    759:         return -ENOMEDIUM;
                    760:     if (!drv->bdrv_truncate)
                    761:         return -ENOTSUP;
                    762:     return drv->bdrv_truncate(bs, offset);
                    763: }
                    764: 
                    765: /**
                    766:  * Length of a file in bytes. Return < 0 if error or unknown.
                    767:  */
                    768: int64_t bdrv_getlength(BlockDriverState *bs)
                    769: {
                    770:     BlockDriver *drv = bs->drv;
                    771:     if (!drv)
                    772:         return -ENOMEDIUM;
                    773:     if (!drv->bdrv_getlength) {
                    774:         /* legacy mode */
                    775:         return bs->total_sectors * SECTOR_SIZE;
                    776:     }
                    777:     return drv->bdrv_getlength(bs);
                    778: }
                    779: 
                    780: /* return 0 as number of sectors if no device present or error */
1.1.1.6   root      781: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1.1       root      782: {
1.1.1.5   root      783:     int64_t length;
                    784:     length = bdrv_getlength(bs);
                    785:     if (length < 0)
                    786:         length = 0;
                    787:     else
                    788:         length = length >> SECTOR_BITS;
                    789:     *nb_sectors_ptr = length;
1.1       root      790: }
                    791: 
1.1.1.7   root      792: struct partition {
                    793:         uint8_t boot_ind;           /* 0x80 - active */
                    794:         uint8_t head;               /* starting head */
                    795:         uint8_t sector;             /* starting sector */
                    796:         uint8_t cyl;                /* starting cylinder */
                    797:         uint8_t sys_ind;            /* What partition type */
                    798:         uint8_t end_head;           /* end head */
                    799:         uint8_t end_sector;         /* end sector */
                    800:         uint8_t end_cyl;            /* end cylinder */
                    801:         uint32_t start_sect;        /* starting sector counting from 0 */
                    802:         uint32_t nr_sects;          /* nr of sectors in partition */
                    803: } __attribute__((packed));
                    804: 
                    805: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
                    806: static int guess_disk_lchs(BlockDriverState *bs,
                    807:                            int *pcylinders, int *pheads, int *psectors)
                    808: {
                    809:     uint8_t buf[512];
                    810:     int ret, i, heads, sectors, cylinders;
                    811:     struct partition *p;
                    812:     uint32_t nr_sects;
                    813:     uint64_t nb_sectors;
                    814: 
                    815:     bdrv_get_geometry(bs, &nb_sectors);
                    816: 
                    817:     ret = bdrv_read(bs, 0, buf, 1);
                    818:     if (ret < 0)
                    819:         return -1;
                    820:     /* test msdos magic */
                    821:     if (buf[510] != 0x55 || buf[511] != 0xaa)
                    822:         return -1;
                    823:     for(i = 0; i < 4; i++) {
                    824:         p = ((struct partition *)(buf + 0x1be)) + i;
                    825:         nr_sects = le32_to_cpu(p->nr_sects);
                    826:         if (nr_sects && p->end_head) {
                    827:             /* We make the assumption that the partition terminates on
                    828:                a cylinder boundary */
                    829:             heads = p->end_head + 1;
                    830:             sectors = p->end_sector & 63;
                    831:             if (sectors == 0)
                    832:                 continue;
                    833:             cylinders = nb_sectors / (heads * sectors);
                    834:             if (cylinders < 1 || cylinders > 16383)
                    835:                 continue;
                    836:             *pheads = heads;
                    837:             *psectors = sectors;
                    838:             *pcylinders = cylinders;
                    839: #if 0
                    840:             printf("guessed geometry: LCHS=%d %d %d\n",
                    841:                    cylinders, heads, sectors);
                    842: #endif
                    843:             return 0;
                    844:         }
                    845:     }
                    846:     return -1;
                    847: }
                    848: 
                    849: void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1.1       root      850: {
1.1.1.7   root      851:     int translation, lba_detected = 0;
                    852:     int cylinders, heads, secs;
                    853:     uint64_t nb_sectors;
                    854: 
                    855:     /* if a geometry hint is available, use it */
                    856:     bdrv_get_geometry(bs, &nb_sectors);
                    857:     bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
                    858:     translation = bdrv_get_translation_hint(bs);
                    859:     if (cylinders != 0) {
                    860:         *pcyls = cylinders;
                    861:         *pheads = heads;
                    862:         *psecs = secs;
                    863:     } else {
                    864:         if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
                    865:             if (heads > 16) {
                    866:                 /* if heads > 16, it means that a BIOS LBA
                    867:                    translation was active, so the default
                    868:                    hardware geometry is OK */
                    869:                 lba_detected = 1;
                    870:                 goto default_geometry;
                    871:             } else {
                    872:                 *pcyls = cylinders;
                    873:                 *pheads = heads;
                    874:                 *psecs = secs;
                    875:                 /* disable any translation to be in sync with
                    876:                    the logical geometry */
                    877:                 if (translation == BIOS_ATA_TRANSLATION_AUTO) {
                    878:                     bdrv_set_translation_hint(bs,
                    879:                                               BIOS_ATA_TRANSLATION_NONE);
                    880:                 }
                    881:             }
                    882:         } else {
                    883:         default_geometry:
                    884:             /* if no geometry, use a standard physical disk geometry */
                    885:             cylinders = nb_sectors / (16 * 63);
                    886: 
                    887:             if (cylinders > 16383)
                    888:                 cylinders = 16383;
                    889:             else if (cylinders < 2)
                    890:                 cylinders = 2;
                    891:             *pcyls = cylinders;
                    892:             *pheads = 16;
                    893:             *psecs = 63;
                    894:             if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
                    895:                 if ((*pcyls * *pheads) <= 131072) {
                    896:                     bdrv_set_translation_hint(bs,
                    897:                                               BIOS_ATA_TRANSLATION_LARGE);
                    898:                 } else {
                    899:                     bdrv_set_translation_hint(bs,
                    900:                                               BIOS_ATA_TRANSLATION_LBA);
                    901:                 }
                    902:             }
                    903:         }
                    904:         bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
                    905:     }
1.1       root      906: }
                    907: 
1.1.1.6   root      908: void bdrv_set_geometry_hint(BlockDriverState *bs,
1.1       root      909:                             int cyls, int heads, int secs)
                    910: {
                    911:     bs->cyls = cyls;
                    912:     bs->heads = heads;
                    913:     bs->secs = secs;
                    914: }
                    915: 
                    916: void bdrv_set_type_hint(BlockDriverState *bs, int type)
                    917: {
                    918:     bs->type = type;
                    919:     bs->removable = ((type == BDRV_TYPE_CDROM ||
                    920:                       type == BDRV_TYPE_FLOPPY));
                    921: }
                    922: 
                    923: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
                    924: {
                    925:     bs->translation = translation;
                    926: }
                    927: 
1.1.1.6   root      928: void bdrv_get_geometry_hint(BlockDriverState *bs,
1.1       root      929:                             int *pcyls, int *pheads, int *psecs)
                    930: {
                    931:     *pcyls = bs->cyls;
                    932:     *pheads = bs->heads;
                    933:     *psecs = bs->secs;
                    934: }
                    935: 
                    936: int bdrv_get_type_hint(BlockDriverState *bs)
                    937: {
                    938:     return bs->type;
                    939: }
                    940: 
                    941: int bdrv_get_translation_hint(BlockDriverState *bs)
                    942: {
                    943:     return bs->translation;
                    944: }
                    945: 
                    946: int bdrv_is_removable(BlockDriverState *bs)
                    947: {
                    948:     return bs->removable;
                    949: }
                    950: 
                    951: int bdrv_is_read_only(BlockDriverState *bs)
                    952: {
                    953:     return bs->read_only;
                    954: }
                    955: 
1.1.1.6   root      956: int bdrv_is_sg(BlockDriverState *bs)
                    957: {
                    958:     return bs->sg;
                    959: }
                    960: 
1.1.1.5   root      961: /* XXX: no longer used */
1.1.1.6   root      962: void bdrv_set_change_cb(BlockDriverState *bs,
1.1       root      963:                         void (*change_cb)(void *opaque), void *opaque)
                    964: {
                    965:     bs->change_cb = change_cb;
                    966:     bs->change_opaque = opaque;
                    967: }
                    968: 
                    969: int bdrv_is_encrypted(BlockDriverState *bs)
                    970: {
                    971:     if (bs->backing_hd && bs->backing_hd->encrypted)
                    972:         return 1;
                    973:     return bs->encrypted;
                    974: }
                    975: 
1.1.1.8   root      976: int bdrv_key_required(BlockDriverState *bs)
                    977: {
                    978:     BlockDriverState *backing_hd = bs->backing_hd;
                    979: 
                    980:     if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
                    981:         return 1;
                    982:     return (bs->encrypted && !bs->valid_key);
                    983: }
                    984: 
1.1       root      985: int bdrv_set_key(BlockDriverState *bs, const char *key)
                    986: {
                    987:     int ret;
                    988:     if (bs->backing_hd && bs->backing_hd->encrypted) {
                    989:         ret = bdrv_set_key(bs->backing_hd, key);
                    990:         if (ret < 0)
                    991:             return ret;
                    992:         if (!bs->encrypted)
                    993:             return 0;
                    994:     }
                    995:     if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
                    996:         return -1;
1.1.1.8   root      997:     ret = bs->drv->bdrv_set_key(bs, key);
                    998:     bs->valid_key = (ret == 0);
                    999:     return ret;
1.1       root     1000: }
                   1001: 
                   1002: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
                   1003: {
1.1.1.5   root     1004:     if (!bs->drv) {
1.1       root     1005:         buf[0] = '\0';
                   1006:     } else {
                   1007:         pstrcpy(buf, buf_size, bs->drv->format_name);
                   1008:     }
                   1009: }
                   1010: 
1.1.1.6   root     1011: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1.1       root     1012:                          void *opaque)
                   1013: {
                   1014:     BlockDriver *drv;
                   1015: 
                   1016:     for (drv = first_drv; drv != NULL; drv = drv->next) {
                   1017:         it(opaque, drv->format_name);
                   1018:     }
                   1019: }
                   1020: 
                   1021: BlockDriverState *bdrv_find(const char *name)
                   1022: {
                   1023:     BlockDriverState *bs;
                   1024: 
                   1025:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                   1026:         if (!strcmp(name, bs->device_name))
                   1027:             return bs;
                   1028:     }
                   1029:     return NULL;
                   1030: }
                   1031: 
1.1.1.8   root     1032: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1.1       root     1033: {
                   1034:     BlockDriverState *bs;
                   1035: 
                   1036:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.8   root     1037:         it(opaque, bs);
1.1       root     1038:     }
                   1039: }
                   1040: 
                   1041: const char *bdrv_get_device_name(BlockDriverState *bs)
                   1042: {
                   1043:     return bs->device_name;
                   1044: }
                   1045: 
1.1.1.4   root     1046: void bdrv_flush(BlockDriverState *bs)
                   1047: {
                   1048:     if (bs->drv->bdrv_flush)
                   1049:         bs->drv->bdrv_flush(bs);
                   1050:     if (bs->backing_hd)
                   1051:         bdrv_flush(bs->backing_hd);
                   1052: }
                   1053: 
1.1.1.7   root     1054: void bdrv_flush_all(void)
                   1055: {
                   1056:     BlockDriverState *bs;
                   1057: 
                   1058:     for (bs = bdrv_first; bs != NULL; bs = bs->next)
                   1059:         if (bs->drv && !bdrv_is_read_only(bs) && 
                   1060:             (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
                   1061:             bdrv_flush(bs);
                   1062: }
                   1063: 
                   1064: /*
                   1065:  * Returns true iff the specified sector is present in the disk image. Drivers
                   1066:  * not implementing the functionality are assumed to not support backing files,
                   1067:  * hence all their sectors are reported as allocated.
                   1068:  *
                   1069:  * 'pnum' is set to the number of sectors (including and immediately following
                   1070:  * the specified sector) that are known to be in the same
                   1071:  * allocated/unallocated state.
                   1072:  *
                   1073:  * 'nb_sectors' is the max value 'pnum' should be set to.
                   1074:  */
                   1075: int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                   1076:        int *pnum)
                   1077: {
                   1078:     int64_t n;
                   1079:     if (!bs->drv->bdrv_is_allocated) {
                   1080:         if (sector_num >= bs->total_sectors) {
                   1081:             *pnum = 0;
                   1082:             return 0;
                   1083:         }
                   1084:         n = bs->total_sectors - sector_num;
                   1085:         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
                   1086:         return 1;
                   1087:     }
                   1088:     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
                   1089: }
                   1090: 
1.1       root     1091: void bdrv_info(void)
                   1092: {
                   1093:     BlockDriverState *bs;
                   1094: 
                   1095:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                   1096:         term_printf("%s:", bs->device_name);
                   1097:         term_printf(" type=");
                   1098:         switch(bs->type) {
                   1099:         case BDRV_TYPE_HD:
                   1100:             term_printf("hd");
                   1101:             break;
                   1102:         case BDRV_TYPE_CDROM:
                   1103:             term_printf("cdrom");
                   1104:             break;
                   1105:         case BDRV_TYPE_FLOPPY:
                   1106:             term_printf("floppy");
                   1107:             break;
                   1108:         }
                   1109:         term_printf(" removable=%d", bs->removable);
                   1110:         if (bs->removable) {
                   1111:             term_printf(" locked=%d", bs->locked);
                   1112:         }
1.1.1.5   root     1113:         if (bs->drv) {
                   1114:             term_printf(" file=");
                   1115:            term_print_filename(bs->filename);
                   1116:             if (bs->backing_file[0] != '\0') {
                   1117:                 term_printf(" backing_file=");
                   1118:                term_print_filename(bs->backing_file);
                   1119:            }
1.1       root     1120:             term_printf(" ro=%d", bs->read_only);
                   1121:             term_printf(" drv=%s", bs->drv->format_name);
1.1.1.8   root     1122:             term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
1.1       root     1123:         } else {
                   1124:             term_printf(" [not inserted]");
                   1125:         }
                   1126:         term_printf("\n");
                   1127:     }
                   1128: }
                   1129: 
1.1.1.6   root     1130: /* The "info blockstats" command. */
                   1131: void bdrv_info_stats (void)
                   1132: {
                   1133:     BlockDriverState *bs;
                   1134: 
                   1135:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
                   1136:        term_printf ("%s:"
                   1137:                     " rd_bytes=%" PRIu64
                   1138:                     " wr_bytes=%" PRIu64
                   1139:                     " rd_operations=%" PRIu64
                   1140:                     " wr_operations=%" PRIu64
1.1.1.8   root     1141:                      "\n",
1.1.1.6   root     1142:                     bs->device_name,
                   1143:                     bs->rd_bytes, bs->wr_bytes,
                   1144:                     bs->rd_ops, bs->wr_ops);
                   1145:     }
                   1146: }
                   1147: 
1.1.1.8   root     1148: const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
                   1149: {
                   1150:     if (bs->backing_hd && bs->backing_hd->encrypted)
                   1151:         return bs->backing_file;
                   1152:     else if (bs->encrypted)
                   1153:         return bs->filename;
                   1154:     else
                   1155:         return NULL;
                   1156: }
                   1157: 
1.1.1.6   root     1158: void bdrv_get_backing_filename(BlockDriverState *bs,
1.1.1.5   root     1159:                                char *filename, int filename_size)
                   1160: {
                   1161:     if (!bs->backing_hd) {
                   1162:         pstrcpy(filename, filename_size, "");
                   1163:     } else {
                   1164:         pstrcpy(filename, filename_size, bs->backing_file);
                   1165:     }
                   1166: }
                   1167: 
1.1.1.6   root     1168: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1169:                           const uint8_t *buf, int nb_sectors)
                   1170: {
                   1171:     BlockDriver *drv = bs->drv;
                   1172:     if (!drv)
                   1173:         return -ENOMEDIUM;
                   1174:     if (!drv->bdrv_write_compressed)
                   1175:         return -ENOTSUP;
1.1.1.11  root     1176:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1177:         return -EIO;
1.1.1.5   root     1178:     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
                   1179: }
1.1.1.6   root     1180: 
1.1.1.5   root     1181: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
                   1182: {
                   1183:     BlockDriver *drv = bs->drv;
                   1184:     if (!drv)
                   1185:         return -ENOMEDIUM;
                   1186:     if (!drv->bdrv_get_info)
                   1187:         return -ENOTSUP;
                   1188:     memset(bdi, 0, sizeof(*bdi));
                   1189:     return drv->bdrv_get_info(bs, bdi);
                   1190: }
                   1191: 
1.1.1.9   root     1192: int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
                   1193: {
                   1194:     BlockDriver *drv = bs->drv;
                   1195:     if (!drv)
                   1196:         return -ENOMEDIUM;
                   1197:     if (!drv->bdrv_put_buffer)
                   1198:         return -ENOTSUP;
                   1199:     return drv->bdrv_put_buffer(bs, buf, pos, size);
                   1200: }
                   1201: 
                   1202: int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
                   1203: {
                   1204:     BlockDriver *drv = bs->drv;
                   1205:     if (!drv)
                   1206:         return -ENOMEDIUM;
                   1207:     if (!drv->bdrv_get_buffer)
                   1208:         return -ENOTSUP;
                   1209:     return drv->bdrv_get_buffer(bs, buf, pos, size);
                   1210: }
                   1211: 
1.1       root     1212: /**************************************************************/
1.1.1.5   root     1213: /* handling of snapshots */
1.1       root     1214: 
1.1.1.6   root     1215: int bdrv_snapshot_create(BlockDriverState *bs,
1.1.1.5   root     1216:                          QEMUSnapshotInfo *sn_info)
                   1217: {
                   1218:     BlockDriver *drv = bs->drv;
                   1219:     if (!drv)
                   1220:         return -ENOMEDIUM;
                   1221:     if (!drv->bdrv_snapshot_create)
                   1222:         return -ENOTSUP;
                   1223:     return drv->bdrv_snapshot_create(bs, sn_info);
                   1224: }
1.1       root     1225: 
1.1.1.6   root     1226: int bdrv_snapshot_goto(BlockDriverState *bs,
1.1.1.5   root     1227:                        const char *snapshot_id)
1.1       root     1228: {
1.1.1.5   root     1229:     BlockDriver *drv = bs->drv;
                   1230:     if (!drv)
                   1231:         return -ENOMEDIUM;
                   1232:     if (!drv->bdrv_snapshot_goto)
                   1233:         return -ENOTSUP;
                   1234:     return drv->bdrv_snapshot_goto(bs, snapshot_id);
1.1       root     1235: }
                   1236: 
1.1.1.5   root     1237: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1.1       root     1238: {
1.1.1.5   root     1239:     BlockDriver *drv = bs->drv;
                   1240:     if (!drv)
                   1241:         return -ENOMEDIUM;
                   1242:     if (!drv->bdrv_snapshot_delete)
                   1243:         return -ENOTSUP;
                   1244:     return drv->bdrv_snapshot_delete(bs, snapshot_id);
                   1245: }
1.1       root     1246: 
1.1.1.6   root     1247: int bdrv_snapshot_list(BlockDriverState *bs,
1.1.1.5   root     1248:                        QEMUSnapshotInfo **psn_info)
                   1249: {
                   1250:     BlockDriver *drv = bs->drv;
                   1251:     if (!drv)
                   1252:         return -ENOMEDIUM;
                   1253:     if (!drv->bdrv_snapshot_list)
                   1254:         return -ENOTSUP;
                   1255:     return drv->bdrv_snapshot_list(bs, psn_info);
                   1256: }
                   1257: 
                   1258: #define NB_SUFFIXES 4
                   1259: 
                   1260: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
                   1261: {
                   1262:     static const char suffixes[NB_SUFFIXES] = "KMGT";
                   1263:     int64_t base;
                   1264:     int i;
                   1265: 
                   1266:     if (size <= 999) {
                   1267:         snprintf(buf, buf_size, "%" PRId64, size);
                   1268:     } else {
                   1269:         base = 1024;
                   1270:         for(i = 0; i < NB_SUFFIXES; i++) {
                   1271:             if (size < (10 * base)) {
1.1.1.6   root     1272:                 snprintf(buf, buf_size, "%0.1f%c",
1.1.1.5   root     1273:                          (double)size / base,
                   1274:                          suffixes[i]);
                   1275:                 break;
                   1276:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1.1.1.6   root     1277:                 snprintf(buf, buf_size, "%" PRId64 "%c",
1.1.1.5   root     1278:                          ((size + (base >> 1)) / base),
                   1279:                          suffixes[i]);
                   1280:                 break;
                   1281:             }
                   1282:             base = base * 1024;
                   1283:         }
1.1       root     1284:     }
1.1.1.5   root     1285:     return buf;
                   1286: }
                   1287: 
                   1288: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
                   1289: {
                   1290:     char buf1[128], date_buf[128], clock_buf[128];
                   1291: #ifdef _WIN32
                   1292:     struct tm *ptm;
1.1.1.2   root     1293: #else
1.1.1.5   root     1294:     struct tm tm;
1.1.1.2   root     1295: #endif
1.1.1.5   root     1296:     time_t ti;
                   1297:     int64_t secs;
                   1298: 
                   1299:     if (!sn) {
1.1.1.6   root     1300:         snprintf(buf, buf_size,
                   1301:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1302:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
                   1303:     } else {
                   1304:         ti = sn->date_sec;
1.1       root     1305: #ifdef _WIN32
1.1.1.5   root     1306:         ptm = localtime(&ti);
                   1307:         strftime(date_buf, sizeof(date_buf),
                   1308:                  "%Y-%m-%d %H:%M:%S", ptm);
                   1309: #else
                   1310:         localtime_r(&ti, &tm);
                   1311:         strftime(date_buf, sizeof(date_buf),
                   1312:                  "%Y-%m-%d %H:%M:%S", &tm);
1.1       root     1313: #endif
1.1.1.5   root     1314:         secs = sn->vm_clock_nsec / 1000000000;
                   1315:         snprintf(clock_buf, sizeof(clock_buf),
                   1316:                  "%02d:%02d:%02d.%03d",
                   1317:                  (int)(secs / 3600),
                   1318:                  (int)((secs / 60) % 60),
1.1.1.6   root     1319:                  (int)(secs % 60),
1.1.1.5   root     1320:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
                   1321:         snprintf(buf, buf_size,
1.1.1.6   root     1322:                  "%-10s%-20s%7s%20s%15s",
1.1.1.5   root     1323:                  sn->id_str, sn->name,
                   1324:                  get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
                   1325:                  date_buf,
                   1326:                  clock_buf);
                   1327:     }
                   1328:     return buf;
1.1       root     1329: }
                   1330: 
                   1331: 
1.1.1.5   root     1332: /**************************************************************/
                   1333: /* async I/Os */
                   1334: 
1.1.1.12! root     1335: typedef struct VectorTranslationAIOCB {
        !          1336:     BlockDriverAIOCB common;
1.1.1.7   root     1337:     QEMUIOVector *iov;
                   1338:     uint8_t *bounce;
                   1339:     int is_write;
                   1340:     BlockDriverAIOCB *aiocb;
1.1.1.12! root     1341: } VectorTranslationAIOCB;
1.1.1.7   root     1342: 
1.1.1.12! root     1343: static void bdrv_aio_cancel_vector(BlockDriverAIOCB *_acb)
1.1.1.10  root     1344: {
1.1.1.12! root     1345:     VectorTranslationAIOCB *acb
        !          1346:         = container_of(_acb, VectorTranslationAIOCB, common);
1.1.1.10  root     1347: 
1.1.1.12! root     1348:     bdrv_aio_cancel(acb->aiocb);
1.1.1.10  root     1349: }
                   1350: 
1.1.1.7   root     1351: static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
                   1352: {
1.1.1.12! root     1353:     VectorTranslationAIOCB *s = (VectorTranslationAIOCB *)opaque;
1.1.1.7   root     1354: 
                   1355:     if (!s->is_write) {
                   1356:         qemu_iovec_from_buffer(s->iov, s->bounce, s->iov->size);
                   1357:     }
                   1358:     qemu_vfree(s->bounce);
1.1.1.12! root     1359:     s->common.cb(s->common.opaque, ret);
        !          1360:     qemu_aio_release(s);
1.1.1.7   root     1361: }
                   1362: 
                   1363: static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
                   1364:                                             int64_t sector_num,
                   1365:                                             QEMUIOVector *iov,
                   1366:                                             int nb_sectors,
                   1367:                                             BlockDriverCompletionFunc *cb,
                   1368:                                             void *opaque,
                   1369:                                             int is_write)
                   1370: 
                   1371: {
1.1.1.12! root     1372:     VectorTranslationAIOCB *s = qemu_aio_get_pool(&vectored_aio_pool, bs,
        !          1373:                                                   cb, opaque);
1.1.1.7   root     1374: 
                   1375:     s->iov = iov;
                   1376:     s->bounce = qemu_memalign(512, nb_sectors * 512);
                   1377:     s->is_write = is_write;
                   1378:     if (is_write) {
                   1379:         qemu_iovec_to_buffer(s->iov, s->bounce);
                   1380:         s->aiocb = bdrv_aio_write(bs, sector_num, s->bounce, nb_sectors,
                   1381:                                   bdrv_aio_rw_vector_cb, s);
                   1382:     } else {
                   1383:         s->aiocb = bdrv_aio_read(bs, sector_num, s->bounce, nb_sectors,
                   1384:                                  bdrv_aio_rw_vector_cb, s);
                   1385:     }
1.1.1.12! root     1386:     if (!s->aiocb) {
        !          1387:         qemu_vfree(s->bounce);
        !          1388:         qemu_aio_release(s);
        !          1389:         return NULL;
        !          1390:     }
        !          1391:     return &s->common;
1.1.1.7   root     1392: }
                   1393: 
                   1394: BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                   1395:                                  QEMUIOVector *iov, int nb_sectors,
                   1396:                                  BlockDriverCompletionFunc *cb, void *opaque)
                   1397: {
                   1398:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1399:         return NULL;
                   1400: 
                   1401:     return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
                   1402:                               cb, opaque, 0);
                   1403: }
                   1404: 
                   1405: BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                   1406:                                   QEMUIOVector *iov, int nb_sectors,
                   1407:                                   BlockDriverCompletionFunc *cb, void *opaque)
                   1408: {
                   1409:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1410:         return NULL;
                   1411: 
                   1412:     return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
                   1413:                               cb, opaque, 1);
                   1414: }
                   1415: 
1.1.1.5   root     1416: BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
                   1417:                                 uint8_t *buf, int nb_sectors,
                   1418:                                 BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1419: {
1.1.1.5   root     1420:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1421:     BlockDriverAIOCB *ret;
1.1.1.5   root     1422: 
                   1423:     if (!drv)
                   1424:         return NULL;
1.1.1.7   root     1425:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1426:         return NULL;
1.1.1.5   root     1427: 
1.1.1.6   root     1428:     ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
                   1429: 
                   1430:     if (ret) {
                   1431:        /* Update stats even though technically transfer has not happened. */
                   1432:        bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
                   1433:        bs->rd_ops ++;
                   1434:     }
                   1435: 
                   1436:     return ret;
1.1       root     1437: }
                   1438: 
1.1.1.5   root     1439: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
                   1440:                                  const uint8_t *buf, int nb_sectors,
                   1441:                                  BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1442: {
1.1.1.5   root     1443:     BlockDriver *drv = bs->drv;
1.1.1.6   root     1444:     BlockDriverAIOCB *ret;
1.1       root     1445: 
1.1.1.5   root     1446:     if (!drv)
                   1447:         return NULL;
                   1448:     if (bs->read_only)
                   1449:         return NULL;
1.1.1.7   root     1450:     if (bdrv_check_request(bs, sector_num, nb_sectors))
                   1451:         return NULL;
1.1.1.4   root     1452: 
1.1.1.6   root     1453:     ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
                   1454: 
                   1455:     if (ret) {
                   1456:        /* Update stats even though technically transfer has not happened. */
                   1457:        bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
                   1458:        bs->wr_ops ++;
                   1459:     }
                   1460: 
                   1461:     return ret;
1.1.1.5   root     1462: }
                   1463: 
                   1464: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1.1.1.4   root     1465: {
1.1.1.10  root     1466:     acb->pool->cancel(acb);
1.1.1.5   root     1467: }
1.1.1.4   root     1468: 
                   1469: 
1.1.1.5   root     1470: /**************************************************************/
                   1471: /* async block device emulation */
1.1.1.4   root     1472: 
1.1.1.5   root     1473: static void bdrv_aio_bh_cb(void *opaque)
1.1.1.4   root     1474: {
1.1.1.5   root     1475:     BlockDriverAIOCBSync *acb = opaque;
                   1476:     acb->common.cb(acb->common.opaque, acb->ret);
                   1477:     qemu_aio_release(acb);
1.1.1.4   root     1478: }
                   1479: 
1.1.1.5   root     1480: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
                   1481:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                   1482:         BlockDriverCompletionFunc *cb, void *opaque)
1.1       root     1483: {
1.1.1.5   root     1484:     BlockDriverAIOCBSync *acb;
                   1485:     int ret;
1.1       root     1486: 
1.1.1.5   root     1487:     acb = qemu_aio_get(bs, cb, opaque);
                   1488:     if (!acb->bh)
                   1489:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
                   1490:     ret = bdrv_read(bs, sector_num, buf, nb_sectors);
                   1491:     acb->ret = ret;
                   1492:     qemu_bh_schedule(acb->bh);
                   1493:     return &acb->common;
                   1494: }
1.1       root     1495: 
1.1.1.5   root     1496: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
                   1497:         int64_t sector_num, const uint8_t *buf, int nb_sectors,
                   1498:         BlockDriverCompletionFunc *cb, void *opaque)
                   1499: {
                   1500:     BlockDriverAIOCBSync *acb;
                   1501:     int ret;
                   1502: 
                   1503:     acb = qemu_aio_get(bs, cb, opaque);
                   1504:     if (!acb->bh)
                   1505:         acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
                   1506:     ret = bdrv_write(bs, sector_num, buf, nb_sectors);
                   1507:     acb->ret = ret;
                   1508:     qemu_bh_schedule(acb->bh);
                   1509:     return &acb->common;
                   1510: }
                   1511: 
                   1512: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
                   1513: {
                   1514:     BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
                   1515:     qemu_bh_cancel(acb->bh);
                   1516:     qemu_aio_release(acb);
1.1       root     1517: }
                   1518: 
1.1.1.5   root     1519: /**************************************************************/
                   1520: /* sync block device emulation */
                   1521: 
                   1522: static void bdrv_rw_em_cb(void *opaque, int ret)
1.1.1.4   root     1523: {
1.1.1.5   root     1524:     *(int *)opaque = ret;
1.1.1.4   root     1525: }
                   1526: 
1.1.1.5   root     1527: #define NOT_DONE 0x7fffffff
                   1528: 
1.1.1.6   root     1529: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5   root     1530:                         uint8_t *buf, int nb_sectors)
                   1531: {
                   1532:     int async_ret;
                   1533:     BlockDriverAIOCB *acb;
                   1534: 
                   1535:     async_ret = NOT_DONE;
1.1.1.6   root     1536:     acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1.1.1.5   root     1537:                         bdrv_rw_em_cb, &async_ret);
1.1.1.7   root     1538:     if (acb == NULL)
1.1.1.5   root     1539:         return -1;
1.1.1.7   root     1540: 
1.1.1.5   root     1541:     while (async_ret == NOT_DONE) {
                   1542:         qemu_aio_wait();
                   1543:     }
1.1.1.7   root     1544: 
1.1.1.5   root     1545:     return async_ret;
                   1546: }
                   1547: 
                   1548: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                   1549:                          const uint8_t *buf, int nb_sectors)
                   1550: {
                   1551:     int async_ret;
                   1552:     BlockDriverAIOCB *acb;
                   1553: 
                   1554:     async_ret = NOT_DONE;
1.1.1.6   root     1555:     acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1.1.1.5   root     1556:                          bdrv_rw_em_cb, &async_ret);
1.1.1.7   root     1557:     if (acb == NULL)
1.1.1.5   root     1558:         return -1;
                   1559:     while (async_ret == NOT_DONE) {
                   1560:         qemu_aio_wait();
                   1561:     }
                   1562:     return async_ret;
                   1563: }
1.1       root     1564: 
                   1565: void bdrv_init(void)
                   1566: {
1.1.1.12! root     1567:     aio_pool_init(&vectored_aio_pool, sizeof(VectorTranslationAIOCB),
1.1.1.10  root     1568:                   bdrv_aio_cancel_vector);
                   1569: 
1.1       root     1570:     bdrv_register(&bdrv_raw);
1.1.1.5   root     1571:     bdrv_register(&bdrv_host_device);
1.1       root     1572: #ifndef _WIN32
                   1573:     bdrv_register(&bdrv_cow);
                   1574: #endif
                   1575:     bdrv_register(&bdrv_qcow);
                   1576:     bdrv_register(&bdrv_vmdk);
                   1577:     bdrv_register(&bdrv_cloop);
                   1578:     bdrv_register(&bdrv_dmg);
                   1579:     bdrv_register(&bdrv_bochs);
                   1580:     bdrv_register(&bdrv_vpc);
                   1581:     bdrv_register(&bdrv_vvfat);
1.1.1.5   root     1582:     bdrv_register(&bdrv_qcow2);
1.1.1.6   root     1583:     bdrv_register(&bdrv_parallels);
1.1.1.7   root     1584:     bdrv_register(&bdrv_nbd);
1.1.1.5   root     1585: }
                   1586: 
1.1.1.10  root     1587: void aio_pool_init(AIOPool *pool, int aiocb_size,
                   1588:                    void (*cancel)(BlockDriverAIOCB *acb))
                   1589: {
                   1590:     pool->aiocb_size = aiocb_size;
                   1591:     pool->cancel = cancel;
                   1592:     pool->free_aiocb = NULL;
                   1593: }
                   1594: 
                   1595: void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs,
                   1596:                         BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5   root     1597: {
                   1598:     BlockDriverAIOCB *acb;
                   1599: 
1.1.1.10  root     1600:     if (pool->free_aiocb) {
                   1601:         acb = pool->free_aiocb;
                   1602:         pool->free_aiocb = acb->next;
1.1.1.5   root     1603:     } else {
1.1.1.10  root     1604:         acb = qemu_mallocz(pool->aiocb_size);
                   1605:         acb->pool = pool;
1.1.1.5   root     1606:     }
                   1607:     acb->bs = bs;
                   1608:     acb->cb = cb;
                   1609:     acb->opaque = opaque;
                   1610:     return acb;
                   1611: }
                   1612: 
1.1.1.10  root     1613: void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
                   1614:                    void *opaque)
                   1615: {
                   1616:     return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque);
                   1617: }
                   1618: 
1.1.1.5   root     1619: void qemu_aio_release(void *p)
                   1620: {
1.1.1.10  root     1621:     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
                   1622:     AIOPool *pool = acb->pool;
                   1623:     acb->next = pool->free_aiocb;
                   1624:     pool->free_aiocb = acb;
1.1.1.5   root     1625: }
                   1626: 
                   1627: /**************************************************************/
                   1628: /* removable device support */
                   1629: 
                   1630: /**
                   1631:  * Return TRUE if the media is present
                   1632:  */
                   1633: int bdrv_is_inserted(BlockDriverState *bs)
                   1634: {
                   1635:     BlockDriver *drv = bs->drv;
                   1636:     int ret;
                   1637:     if (!drv)
                   1638:         return 0;
                   1639:     if (!drv->bdrv_is_inserted)
                   1640:         return 1;
                   1641:     ret = drv->bdrv_is_inserted(bs);
                   1642:     return ret;
                   1643: }
                   1644: 
                   1645: /**
                   1646:  * Return TRUE if the media changed since the last call to this
1.1.1.6   root     1647:  * function. It is currently only used for floppy disks
1.1.1.5   root     1648:  */
                   1649: int bdrv_media_changed(BlockDriverState *bs)
                   1650: {
                   1651:     BlockDriver *drv = bs->drv;
                   1652:     int ret;
                   1653: 
                   1654:     if (!drv || !drv->bdrv_media_changed)
                   1655:         ret = -ENOTSUP;
                   1656:     else
                   1657:         ret = drv->bdrv_media_changed(bs);
                   1658:     if (ret == -ENOTSUP)
                   1659:         ret = bs->media_changed;
                   1660:     bs->media_changed = 0;
                   1661:     return ret;
                   1662: }
                   1663: 
                   1664: /**
                   1665:  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
                   1666:  */
                   1667: void bdrv_eject(BlockDriverState *bs, int eject_flag)
                   1668: {
                   1669:     BlockDriver *drv = bs->drv;
                   1670:     int ret;
                   1671: 
                   1672:     if (!drv || !drv->bdrv_eject) {
                   1673:         ret = -ENOTSUP;
                   1674:     } else {
                   1675:         ret = drv->bdrv_eject(bs, eject_flag);
                   1676:     }
                   1677:     if (ret == -ENOTSUP) {
                   1678:         if (eject_flag)
                   1679:             bdrv_close(bs);
                   1680:     }
                   1681: }
                   1682: 
                   1683: int bdrv_is_locked(BlockDriverState *bs)
                   1684: {
                   1685:     return bs->locked;
                   1686: }
                   1687: 
                   1688: /**
                   1689:  * Lock or unlock the media (if it is locked, the user won't be able
                   1690:  * to eject it manually).
                   1691:  */
                   1692: void bdrv_set_locked(BlockDriverState *bs, int locked)
                   1693: {
                   1694:     BlockDriver *drv = bs->drv;
                   1695: 
                   1696:     bs->locked = locked;
                   1697:     if (drv && drv->bdrv_set_locked) {
                   1698:         drv->bdrv_set_locked(bs, locked);
                   1699:     }
1.1       root     1700: }
1.1.1.6   root     1701: 
                   1702: /* needed for generic scsi interface */
                   1703: 
                   1704: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   1705: {
                   1706:     BlockDriver *drv = bs->drv;
                   1707: 
                   1708:     if (drv && drv->bdrv_ioctl)
                   1709:         return drv->bdrv_ioctl(bs, req, buf);
                   1710:     return -ENOTSUP;
                   1711: }

unix.superglobalmegacorp.com