]> git.proxmox.com Git - mirror_qemu.git/blobdiff - block/bochs.c
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-pull-request' into...
[mirror_qemu.git] / block / bochs.c
index f0e18c0b84ddfbdbfcc35591e5ca1b9815f39db1..962f18592d67438c6ee3a8df9af2657bbd6f591a 100644 (file)
  */
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
+#include "qemu/bswap.h"
+#include "qemu/error-report.h"
 
 /**************************************************************/
 
@@ -83,14 +84,14 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
     const struct bochs_header *bochs = (const void *)buf;
 
     if (buf_size < HEADER_SIZE)
-       return 0;
+        return 0;
 
     if (!strcmp(bochs->magic, HEADER_MAGIC) &&
-       !strcmp(bochs->type, REDOLOG_TYPE) &&
-       !strcmp(bochs->subtype, GROWING_TYPE) &&
-       ((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
-       (le32_to_cpu(bochs->version) == HEADER_V1)))
-       return 100;
+        !strcmp(bochs->type, REDOLOG_TYPE) &&
+        !strcmp(bochs->subtype, GROWING_TYPE) &&
+        ((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
+        (le32_to_cpu(bochs->version) == HEADER_V1)))
+        return 100;
 
     return 0;
 }
@@ -103,10 +104,19 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
     struct bochs_header bochs;
     int ret;
 
-    bs->read_only = 1; // no write support yet
-    bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */
+    /* No write support yet */
+    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
+    if (ret < 0) {
+        return ret;
+    }
 
-    ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs));
+    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
+                               false, errp);
+    if (!bs->file) {
+        return -EINVAL;
+    }
+
+    ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
     if (ret < 0) {
         return ret;
     }
@@ -114,8 +124,8 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
     if (strcmp(bochs.magic, HEADER_MAGIC) ||
         strcmp(bochs.type, REDOLOG_TYPE) ||
         strcmp(bochs.subtype, GROWING_TYPE) ||
-       ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
-       (le32_to_cpu(bochs.version) != HEADER_V1))) {
+        ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
+        (le32_to_cpu(bochs.version) != HEADER_V1))) {
         error_setg(errp, "Image not in Bochs format");
         return -EINVAL;
     }
@@ -140,14 +150,14 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
         return -ENOMEM;
     }
 
-    ret = bdrv_pread(bs->file->bs, le32_to_cpu(bochs.header), s->catalog_bitmap,
+    ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
                      s->catalog_size * 4);
     if (ret < 0) {
         goto fail;
     }
 
     for (i = 0; i < s->catalog_size; i++)
-       le32_to_cpus(&s->catalog_bitmap[i]);
+        le32_to_cpus(&s->catalog_bitmap[i]);
 
     s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
 
@@ -188,6 +198,11 @@ fail:
     return ret;
 }
 
+static void bochs_refresh_limits(BlockDriverState *bs, Error **errp)
+{
+    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
+}
+
 static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
 {
     BDRVBochsState *s = bs->opaque;
@@ -201,7 +216,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
     extent_offset = (offset % s->extent_size) / 512;
 
     if (s->catalog_bitmap[extent_index] == 0xffffffff) {
-       return 0; /* not allocated */
+        return 0; /* not allocated */
     }
 
     bitmap_offset = s->data_offset +
@@ -209,14 +224,14 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
         (s->extent_blocks + s->bitmap_blocks));
 
     /* read in bitmap for current extent */
-    ret = bdrv_pread(bs->file->bs, bitmap_offset + (extent_offset / 8),
+    ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
                      &bitmap_entry, 1);
     if (ret < 0) {
         return ret;
     }
 
     if (!((bitmap_entry >> (extent_offset % 8)) & 1)) {
-       return 0; /* not allocated */
+        return 0; /* not allocated */
     }
 
     return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
@@ -250,7 +265,7 @@ bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);
 
         if (block_offset > 0) {
-            ret = bdrv_co_preadv(bs->file->bs, block_offset, 512,
+            ret = bdrv_co_preadv(bs->file, block_offset, 512,
                                  &local_qiov, 0);
             if (ret < 0) {
                 goto fail;
@@ -282,6 +297,8 @@ static BlockDriver bdrv_bochs = {
     .instance_size     = sizeof(BDRVBochsState),
     .bdrv_probe                = bochs_probe,
     .bdrv_open         = bochs_open,
+    .bdrv_child_perm     = bdrv_format_default_perms,
+    .bdrv_refresh_limits = bochs_refresh_limits,
     .bdrv_co_preadv = bochs_co_preadv,
     .bdrv_close                = bochs_close,
 };