yeahuh / 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

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