diff mbox

block: vhdx - force FileOffsetMB field to '0' for certain block states

Message ID a9fe92f53f07e6ab1693811e4312c0d1e958500b.1421787566.git.jcody@redhat.com
State New
Headers show

Commit Message

Jeff Cody Jan. 20, 2015, 9:01 p.m. UTC
The v1.0.0 spec calls out PAYLOAD_BLOCK_ZERO FileOffsetMB field as being
'reserved'.  In practice, this means that Hyper-V will fail to read a
disk image with PAYLOAD_BLOCK_ZERO block states with a FileOffsetMB
value other than 0.

The other states that indicate a block that is not there
(PAYLOAD_BLOCK_UNDEFINED, PAYLOAD_BLOCK_NOT_PRESENT,
 PAYLOAD_BLOCK_UNMAPPED) have multiple options for what FileOffsetMB may
be set to, and '0' is explicitly called out as an option.

For all the above states, we will also just set the FileOffsetMB value
to 0.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 block/vhdx.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Max Reitz Jan. 22, 2015, 5:28 p.m. UTC | #1
On 2015-01-20 at 16:01, Jeff Cody wrote:
> The v1.0.0 spec calls out PAYLOAD_BLOCK_ZERO FileOffsetMB field as being
> 'reserved'.  In practice, this means that Hyper-V will fail to read a
> disk image with PAYLOAD_BLOCK_ZERO block states with a FileOffsetMB
> value other than 0.
>
> The other states that indicate a block that is not there
> (PAYLOAD_BLOCK_UNDEFINED, PAYLOAD_BLOCK_NOT_PRESENT,
>   PAYLOAD_BLOCK_UNMAPPED) have multiple options for what FileOffsetMB may
> be set to, and '0' is explicitly called out as an option.
>
> For all the above states, we will also just set the FileOffsetMB value
> to 0.
>
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>   block/vhdx.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>
Max Reitz Jan. 23, 2015, 2:47 p.m. UTC | #2
On 2015-01-20 at 16:01, Jeff Cody wrote:
> The v1.0.0 spec calls out PAYLOAD_BLOCK_ZERO FileOffsetMB field as being
> 'reserved'.  In practice, this means that Hyper-V will fail to read a
> disk image with PAYLOAD_BLOCK_ZERO block states with a FileOffsetMB
> value other than 0.
>
> The other states that indicate a block that is not there
> (PAYLOAD_BLOCK_UNDEFINED, PAYLOAD_BLOCK_NOT_PRESENT,
>   PAYLOAD_BLOCK_UNMAPPED) have multiple options for what FileOffsetMB may
> be set to, and '0' is explicitly called out as an option.
>
> For all the above states, we will also just set the FileOffsetMB value
> to 0.
>
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>   block/vhdx.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)

Thanks, applied to my block tree:

https://github.com/XanClic/qemu/commits/block
diff mbox

Patch

diff --git a/block/vhdx.c b/block/vhdx.c
index 06f2b1a..bb3ed45 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1174,7 +1174,18 @@  static void vhdx_update_bat_table_entry(BlockDriverState *bs, BDRVVHDXState *s,
 {
     /* The BAT entry is a uint64, with 44 bits for the file offset in units of
      * 1MB, and 3 bits for the block state. */
-    s->bat[sinfo->bat_idx]  = sinfo->file_offset;
+    if ((state == PAYLOAD_BLOCK_ZERO)        ||
+        (state == PAYLOAD_BLOCK_UNDEFINED)   ||
+        (state == PAYLOAD_BLOCK_NOT_PRESENT) ||
+        (state == PAYLOAD_BLOCK_UNMAPPED)) {
+        s->bat[sinfo->bat_idx]  = 0;  /* For PAYLOAD_BLOCK_ZERO, the
+                                         FileOffsetMB field is denoted as
+                                         'reserved' in the v1.0 spec.  If it is
+                                         non-zero, MS Hyper-V will fail to read
+                                         the disk image */
+    } else {
+        s->bat[sinfo->bat_idx]  = sinfo->file_offset;
+    }
 
     s->bat[sinfo->bat_idx] |= state & VHDX_BAT_STATE_BIT_MASK;