]> Git Repo - qemu.git/blobdiff - block.c
use new cursor struct + functions for vmware vga and sdl.
[qemu.git] / block.c
diff --git a/block.c b/block.c
index f463ec477add418c9bb5e0bb54436e57fd7ed32d..0b0966c5715034581f1b723601c55cbefb7d4379 100644 (file)
--- a/block.c
+++ b/block.c
@@ -287,16 +287,18 @@ static BlockDriver *find_protocol(const char *filename)
     char protocol[128];
     int len;
     const char *p;
+    int is_drive;
 
     /* TODO Drivers without bdrv_file_open must be specified explicitly */
 
 #ifdef _WIN32
-    if (is_windows_drive(filename) ||
-        is_windows_drive_prefix(filename))
-        return bdrv_find_format("file");
+    is_drive = is_windows_drive(filename) ||
+        is_windows_drive_prefix(filename);
+#else
+    is_drive = 0;
 #endif
     p = strchr(filename, ':');
-    if (!p) {
+    if (!p || is_drive) {
         drv1 = find_hdev_driver(filename);
         if (!drv1) {
             drv1 = bdrv_find_format("file");
@@ -324,14 +326,14 @@ static BlockDriver *find_image_format(const char *filename)
     uint8_t buf[2048];
     BlockDriverState *bs;
 
-    drv = find_protocol(filename);
-    /* no need to test disk image formats for vvfat */
-    if (drv && strcmp(drv->format_name, "vvfat") == 0)
-        return drv;
-
     ret = bdrv_file_open(&bs, filename, 0);
     if (ret < 0)
         return NULL;
+
+    /* Return the raw BlockDriver * to scsi-generic devices */
+    if (bs->sg)
+        return bdrv_find_format("raw");
+
     ret = bdrv_pread(bs, 0, buf, sizeof(buf));
     bdrv_delete(bs);
     if (ret < 0) {
@@ -359,6 +361,10 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
 {
     BlockDriver *drv = bs->drv;
 
+    /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
+    if (bs->sg)
+        return 0;
+
     /* query actual device if possible, otherwise just trust the hint */
     if (drv->bdrv_getlength) {
         int64_t length = drv->bdrv_getlength(bs);
@@ -540,6 +546,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
         }
 
         ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
+        free_option_parameters(options);
         if (ret < 0) {
             return ret;
         }
@@ -698,12 +705,12 @@ int bdrv_commit(BlockDriverState *bs)
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_rw = bdrv_new("");
-        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL);
+        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, drv);
         if (rw_ret < 0) {
             bdrv_delete(bs_rw);
             /* try to re-open read-only */
             bs_ro = bdrv_new("");
-            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
+            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
             if (ret < 0) {
                 bdrv_delete(bs_ro);
                 /* drive not functional anymore */
@@ -755,7 +762,7 @@ ro_cleanup:
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_ro = bdrv_new("");
-        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
+        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
         if (ret < 0) {
             bdrv_delete(bs_ro);
             /* drive not functional anymore */
@@ -1579,9 +1586,9 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
  *     - "wr_operations": write operations
  *     - "wr_highest_offset": Highest offset of a sector written since the
  *       BlockDriverState has been opened
- *     - "parent": Contains recursively the statistics of the underlying
- *       protocol (e.g. the host file for a qcow2 image). If there is no
- *       underlying protocol, this field is omitted.
+ * - "parent": A QDict recursively holding the statistics of the underlying
+ *    protocol (e.g. the host file for a qcow2 image). If there is no
+ *    underlying protocol, this field is omitted.
  *
  * Example:
  *
@@ -1590,15 +1597,14 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
  *                          "wr_bytes": 0,
  *                          "rd_operations": 1,
  *                          "wr_operations": 0,
- *                          "wr_highest_offset": 0,
- *                          "parent": {
- *                              "stats": { "rd_bytes": 1024,
- *                                         "wr_bytes": 0,
- *                                         "rd_operations": 2,
- *                                         "wr_operations": 0,
- *                                         "wr_highest_offset": 0,
- *                              }
- *                          } } },
+ *                          "wr_highest_offset": 0 },
+ *               "parent": {
+ *                      "stats": { "rd_bytes": 1024,
+ *                                 "wr_bytes": 0,
+ *                                 "rd_operations": 2,
+ *                                 "wr_operations": 0,
+ *                                 "wr_highest_offset": 0,
+ *                      } } },
  *   { "device": "ide1-cd0",
  *               "stats": { "rd_bytes": 0,
  *                          "wr_bytes": 0,
@@ -1932,7 +1938,19 @@ static void multiwrite_cb(void *opaque, int ret)
 
 static int multiwrite_req_compare(const void *a, const void *b)
 {
-    return (((BlockRequest*) a)->sector - ((BlockRequest*) b)->sector);
+    const BlockRequest *req1 = a, *req2 = b;
+
+    /*
+     * Note that we can't simply subtract req2->sector from req1->sector
+     * here as that could overflow the return value.
+     */
+    if (req1->sector > req2->sector) {
+        return 1;
+    } else if (req1->sector < req2->sector) {
+        return -1;
+    } else {
+        return 0;
+    }
 }
 
 /*
@@ -2072,7 +2090,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
     return 0;
 
 fail:
-    free(mcb);
+    qemu_free(mcb);
     return -1;
 }
 
@@ -2107,7 +2125,8 @@ typedef struct BlockDriverAIOCBSync {
 
 static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
 {
-    BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
+    BlockDriverAIOCBSync *acb =
+        container_of(blockacb, BlockDriverAIOCBSync, common);
     qemu_bh_delete(acb->bh);
     acb->bh = NULL;
     qemu_aio_release(acb);
This page took 0.028979 seconds and 4 git commands to generate.