]> Git Repo - qemu.git/blobdiff - block/bochs.c
block: Split bdrv_new_root() off bdrv_new()
[qemu.git] / block / bochs.c
index 826ec1203c9ed04fda15bb55ef7274dd2ba2eba7..199ac2b9af7ba4b61a64b4171c2700fadf0f71cc 100644 (file)
@@ -131,7 +131,11 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
         return -EFBIG;
     }
 
-    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
+    s->catalog_bitmap = g_try_new(uint32_t, s->catalog_size);
+    if (s->catalog_size && s->catalog_bitmap == NULL) {
+        error_setg(errp, "Could not allocate memory for catalog");
+        return -ENOMEM;
+    }
 
     ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
                      s->catalog_size * 4);
@@ -148,16 +152,26 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
     s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
 
     s->extent_size = le32_to_cpu(bochs.extent);
-    if (s->extent_size == 0) {
-        error_setg(errp, "Extent size may not be zero");
-        return -EINVAL;
+    if (s->extent_size < BDRV_SECTOR_SIZE) {
+        /* bximage actually never creates extents smaller than 4k */
+        error_setg(errp, "Extent size must be at least 512");
+        ret = -EINVAL;
+        goto fail;
+    } else if (!is_power_of_2(s->extent_size)) {
+        error_setg(errp, "Extent size %" PRIu32 " is not a power of two",
+                   s->extent_size);
+        ret = -EINVAL;
+        goto fail;
     } else if (s->extent_size > 0x800000) {
         error_setg(errp, "Extent size %" PRIu32 " is too large",
                    s->extent_size);
-        return -EINVAL;
+        ret = -EINVAL;
+        goto fail;
     }
 
-    if (s->catalog_size < bs->total_sectors / s->extent_size) {
+    if (s->catalog_size < DIV_ROUND_UP(bs->total_sectors,
+                                       s->extent_size / BDRV_SECTOR_SIZE))
+    {
         error_setg(errp, "Catalog size is too small for this disk size");
         ret = -EINVAL;
         goto fail;
@@ -177,13 +191,14 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
     uint64_t offset = sector_num * 512;
     uint64_t extent_index, extent_offset, bitmap_offset;
     char bitmap_entry;
+    int ret;
 
     // seek to sector
     extent_index = offset / s->extent_size;
     extent_offset = (offset % s->extent_size) / 512;
 
     if (s->catalog_bitmap[extent_index] == 0xffffffff) {
-       return -1; /* not allocated */
+       return 0; /* not allocated */
     }
 
     bitmap_offset = s->data_offset +
@@ -191,13 +206,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 */
-    if (bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
-                   &bitmap_entry, 1) != 1) {
-        return -1;
+    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 -1; /* not allocated */
+       return 0; /* not allocated */
     }
 
     return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
@@ -210,13 +226,16 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num,
 
     while (nb_sectors > 0) {
         int64_t block_offset = seek_to_sector(bs, sector_num);
-        if (block_offset >= 0) {
+        if (block_offset < 0) {
+            return block_offset;
+        } else if (block_offset > 0) {
             ret = bdrv_pread(bs->file, block_offset, buf, 512);
-            if (ret != 512) {
-                return -1;
+            if (ret < 0) {
+                return ret;
             }
-        } else
+        } else {
             memset(buf, 0, 512);
+        }
         nb_sectors--;
         sector_num++;
         buf += 512;
This page took 0.026371 seconds and 4 git commands to generate.