cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-block-vhdx-update-log-guid-in-header-and-first-write.patch

9ae3a8
From c310637234eeafe32d0eb5626f91e12b5a2399b9 Mon Sep 17 00:00:00 2001
9ae3a8
From: Jeffrey Cody <jcody@redhat.com>
9ae3a8
Date: Wed, 20 Nov 2013 19:43:55 +0100
9ae3a8
Subject: [PATCH 12/25] block: vhdx - update log guid in header, and first write tracker
9ae3a8
9ae3a8
RH-Author: Jeffrey Cody <jcody@redhat.com>
9ae3a8
Message-id: <313d521b2aab6f6657de5b4fbb9cc10e58d9d5c4.1384975172.git.jcody@redhat.com>
9ae3a8
Patchwork-id: 55806
9ae3a8
O-Subject: [RHEL7 qemu-kvm PATCH 12/26] block: vhdx - update log guid in header, and first write tracker
9ae3a8
Bugzilla: 879234
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
9ae3a8
Allow tracking of first file write in the VHDX image, as well as
9ae3a8
the ability to update the GUID in the header.  This is in preparation
9ae3a8
for log support.
9ae3a8
9ae3a8
Signed-off-by: Jeff Cody <jcody@redhat.com>
9ae3a8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
(cherry picked from commit c3906c5e8281b37a526c706596af8575d6ac00d3)
9ae3a8
---
9ae3a8
 block/vhdx.c | 30 ++++++++++++++++++++++++------
9ae3a8
 block/vhdx.h |  6 ++++++
9ae3a8
 2 files changed, 30 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/vhdx.c |   30 ++++++++++++++++++++++++------
9ae3a8
 block/vhdx.h |    6 ++++++
9ae3a8
 2 files changed, 30 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/vhdx.c b/block/vhdx.c
9ae3a8
index 2efece1..49219df 100644
9ae3a8
--- a/block/vhdx.c
9ae3a8
+++ b/block/vhdx.c
9ae3a8
@@ -230,7 +230,7 @@ static int vhdx_probe(const uint8_t *buf, int buf_size, const char *filename)
9ae3a8
  *  - non-current header is updated with largest sequence number
9ae3a8
  */
9ae3a8
 static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
9ae3a8
-                              bool generate_data_write_guid)
9ae3a8
+                              bool generate_data_write_guid, MSGUID *log_guid)
9ae3a8
 {
9ae3a8
     int ret = 0;
9ae3a8
     int hdr_idx = 0;
9ae3a8
@@ -262,6 +262,11 @@ static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
9ae3a8
         vhdx_guid_generate(&inactive_header->data_write_guid);
9ae3a8
     }
9ae3a8
 
9ae3a8
+    /* update the log guid if present */
9ae3a8
+    if (log_guid) {
9ae3a8
+        inactive_header->log_guid = *log_guid;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     /* the header checksum is not over just the packed size of VHDXHeader,
9ae3a8
      * but rather over the entire 'reserved' range for the header, which is
9ae3a8
      * 4KB (VHDX_HEADER_SIZE). */
9ae3a8
@@ -294,16 +299,16 @@ exit:
9ae3a8
  * The VHDX spec calls for header updates to be performed twice, so that both
9ae3a8
  * the current and non-current header have valid info
9ae3a8
  */
9ae3a8
-static int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
9ae3a8
-                               bool generate_data_write_guid)
9ae3a8
+int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
9ae3a8
+                        bool generate_data_write_guid, MSGUID *log_guid)
9ae3a8
 {
9ae3a8
     int ret;
9ae3a8
 
9ae3a8
-    ret = vhdx_update_header(bs, s, generate_data_write_guid);
9ae3a8
+    ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
9ae3a8
     if (ret < 0) {
9ae3a8
         return ret;
9ae3a8
     }
9ae3a8
-    ret = vhdx_update_header(bs, s, generate_data_write_guid);
9ae3a8
+    ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
9ae3a8
     return ret;
9ae3a8
 }
9ae3a8
 
9ae3a8
@@ -784,6 +789,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
 
9ae3a8
 
9ae3a8
     s->bat = NULL;
9ae3a8
+    s->first_visible_write = true;
9ae3a8
 
9ae3a8
     qemu_co_mutex_init(&s->lock);
9ae3a8
 
9ae3a8
@@ -864,7 +870,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
     }
9ae3a8
 
9ae3a8
     if (flags & BDRV_O_RDWR) {
9ae3a8
-        ret = vhdx_update_headers(bs, s, false);
9ae3a8
+        ret = vhdx_update_headers(bs, s, false, NULL);
9ae3a8
         if (ret < 0) {
9ae3a8
             goto fail;
9ae3a8
         }
9ae3a8
@@ -1022,6 +1028,18 @@ exit:
9ae3a8
 
9ae3a8
 
9ae3a8
 
9ae3a8
+/* Per the spec, on the first write of guest-visible data to the file the
9ae3a8
+ * data write guid must be updated in the header */
9ae3a8
+int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
9ae3a8
+{
9ae3a8
+    int ret = 0;
9ae3a8
+    if (s->first_visible_write) {
9ae3a8
+        s->first_visible_write = false;
9ae3a8
+        ret = vhdx_update_headers(bs, s, true, NULL);
9ae3a8
+    }
9ae3a8
+    return ret;
9ae3a8
+}
9ae3a8
+
9ae3a8
 static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
9ae3a8
                                       int nb_sectors, QEMUIOVector *qiov)
9ae3a8
 {
9ae3a8
diff --git a/block/vhdx.h b/block/vhdx.h
9ae3a8
index 55975a2..81785e5 100644
9ae3a8
--- a/block/vhdx.h
9ae3a8
+++ b/block/vhdx.h
9ae3a8
@@ -361,6 +361,7 @@ typedef struct BDRVVHDXState {
9ae3a8
     VHDXBatEntry *bat;
9ae3a8
     uint64_t bat_offset;
9ae3a8
 
9ae3a8
+    bool first_visible_write;
9ae3a8
     MSGUID session_guid;
9ae3a8
 
9ae3a8
     VHDXLogEntries log;
9ae3a8
@@ -373,6 +374,9 @@ typedef struct BDRVVHDXState {
9ae3a8
 
9ae3a8
 void vhdx_guid_generate(MSGUID *guid);
9ae3a8
 
9ae3a8
+int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw,
9ae3a8
+                        MSGUID *log_guid);
9ae3a8
+
9ae3a8
 uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset);
9ae3a8
 uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
9ae3a8
                             int crc_offset);
9ae3a8
@@ -402,4 +406,6 @@ void vhdx_log_data_le_export(VHDXLogDataSector *d);
9ae3a8
 void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr);
9ae3a8
 void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr);
9ae3a8
 
9ae3a8
+int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s);
9ae3a8
+
9ae3a8
 #endif
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8