* [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes
@ 2010-06-18 15:03 Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 1/6] block: Add bdrv_(p)write_sync Kevin Wolf
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
This addresses the data integrity problems which are described for qcow at
http://wiki.qemu.org/Features/Qcow2DataIntegrity#Metadata_update_ordering.2C_Part_2
These problems are the same for all writable image formats, so this series
contains a patch for each of them.
The only exception is VDI which uses AIO for writing its metadata. It needs
a different fix.
Kevin Wolf (6):
block: Add bdrv_(p)write_sync
cow: Use bdrv_(p)write_sync for metadata writes
qcow: Use bdrv_(p)write_sync for metadata writes
qcow2: Use bdrv_(p)write_sync for metadata writes
vmdk: Use bdrv_(p)write_sync for metadata writes
vpc: Use bdrv_(p)write_sync for metadata writes
block.c | 37 +++++++++++++++++++++++++++++++++++++
block.h | 4 ++++
block/cow.c | 20 +++++++++++---------
block/qcow.c | 18 ++++++++++--------
block/qcow2-cluster.c | 24 ++++++++++++------------
block/qcow2-refcount.c | 24 ++++++++++++------------
block/qcow2-snapshot.c | 23 +++++++++++------------
block/qcow2.c | 10 +++++-----
block/vmdk.c | 10 +++++-----
block/vpc.c | 9 +++++----
10 files changed, 112 insertions(+), 67 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/6] block: Add bdrv_(p)write_sync
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 2/6] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Add new functions that write and flush the written data to disk immediately.
This is what needs to be used for image format metadata to maintain integrity
for cache=... modes that don't use O_DSYNC. (Actually, we only need barriers,
and therefore the functions are defined as such, but flushes is what is
implemented in this patch - we can try to change that later)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 37 +++++++++++++++++++++++++++++++++++++
block.h | 4 ++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/block.c b/block.c
index 0765fbc..7b64c2d 100644
--- a/block.c
+++ b/block.c
@@ -1010,6 +1010,43 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
return count1;
}
+/*
+ * Writes to the file and ensures that no writes are reordered across this
+ * request (acts as a barrier)
+ *
+ * Returns 0 on success, -errno in error cases.
+ */
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+ const void *buf, int count)
+{
+ int ret;
+
+ ret = bdrv_pwrite(bs, offset, buf, count);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* No flush needed for cache=writethrough, it uses O_DSYNC */
+ if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) {
+ bdrv_flush(bs);
+ }
+
+ return 0;
+}
+
+/*
+ * Writes to the file and ensures that no writes are reordered across this
+ * request (acts as a barrier)
+ *
+ * Returns 0 on success, -errno in error cases.
+ */
+int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ return bdrv_pwrite_sync(bs, BDRV_SECTOR_SIZE * sector_num,
+ buf, BDRV_SECTOR_SIZE * nb_sectors);
+}
+
/**
* Truncate file to 'offset' bytes (needed only for file protocols)
*/
diff --git a/block.h b/block.h
index 9df9b38..6a157f4 100644
--- a/block.h
+++ b/block.h
@@ -80,6 +80,10 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
void *buf, int count);
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
const void *buf, int count);
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+ const void *buf, int count);
+int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int64_t bdrv_getlength(BlockDriverState *bs);
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/6] cow: Use bdrv_(p)write_sync for metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 1/6] block: Add bdrv_(p)write_sync Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 3/6] qcow: " Kevin Wolf
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
While at it, correct the wrong usage of errno.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/cow.c | 20 +++++++++++---------
1 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/block/cow.c b/block/cow.c
index d146434..eedcc48 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -97,17 +97,18 @@ static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
{
uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
uint8_t bitmap;
+ int ret;
- if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
- sizeof(bitmap)) {
- return -errno;
+ ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
+ if (ret < 0) {
+ return ret;
}
bitmap |= (1 << (bitnum % 8));
- if (bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap)) !=
- sizeof(bitmap)) {
- return -errno;
+ ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap));
+ if (ret < 0) {
+ return ret;
}
return 0;
}
@@ -116,10 +117,11 @@ static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
{
uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
uint8_t bitmap;
+ int ret;
- if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
- sizeof(bitmap)) {
- return -errno;
+ ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
+ if (ret < 0) {
+ return ret;
}
return !!(bitmap & (1 << (bitnum % 8)));
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/6] qcow: Use bdrv_(p)write_sync for metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 1/6] block: Add bdrv_(p)write_sync Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 2/6] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 4/6] qcow2: " Kevin Wolf
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/block/qcow.c b/block/qcow.c
index 449858f..816103d 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -273,8 +273,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* update the L1 entry */
s->l1_table[l1_index] = l2_offset;
tmp = cpu_to_be64(l2_offset);
- if (bdrv_pwrite(bs->file, s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) != sizeof(tmp))
+ if (bdrv_pwrite_sync(bs->file,
+ s->l1_table_offset + l1_index * sizeof(tmp),
+ &tmp, sizeof(tmp)) < 0)
return 0;
new_l2_table = 1;
}
@@ -302,8 +303,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
l2_table = s->l2_cache + (min_index << s->l2_bits);
if (new_l2_table) {
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- if (bdrv_pwrite(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
+ if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
+ s->l2_size * sizeof(uint64_t)) < 0)
return 0;
} else {
if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
@@ -368,8 +369,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* update L2 table */
tmp = cpu_to_be64(cluster_offset);
l2_table[l2_index] = tmp;
- if (bdrv_pwrite(bs->file,
- l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
+ if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
+ &tmp, sizeof(tmp)) < 0)
return 0;
}
return cluster_offset;
@@ -835,8 +836,9 @@ static int qcow_make_empty(BlockDriverState *bs)
int ret;
memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
+ if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
+ l1_length) < 0)
+ return -1;
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
if (ret < 0)
return ret;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/6] qcow2: Use bdrv_(p)write_sync for metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
` (2 preceding siblings ...)
2010-06-18 15:03 ` [Qemu-devel] [PATCH 3/6] qcow: " Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 5/6] vmdk: " Kevin Wolf
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-cluster.c | 24 ++++++++++++------------
block/qcow2-refcount.c | 24 ++++++++++++------------
block/qcow2-snapshot.c | 23 +++++++++++------------
block/qcow2.c | 10 +++++-----
4 files changed, 40 insertions(+), 41 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index ff1fc26..b023148 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -64,8 +64,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
- ret = bdrv_pwrite(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
- if (ret != new_l1_size2)
+ ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
+ if (ret < 0)
goto fail;
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
@@ -74,8 +74,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
cpu_to_be32w((uint32_t*)data, new_l1_size);
cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
- if (ret != sizeof(data)) {
+ ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
+ if (ret < 0) {
goto fail;
}
qemu_free(s->l1_table);
@@ -87,7 +87,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
fail:
qemu_free(new_l1_table);
qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
- return ret < 0 ? ret : -EIO;
+ return ret;
}
void qcow2_l2_cache_reset(BlockDriverState *bs)
@@ -208,7 +208,7 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index)
}
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
- ret = bdrv_pwrite(bs->file, s->l1_table_offset + 8 * l1_start_index,
+ ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
buf, sizeof(buf));
if (ret < 0) {
return ret;
@@ -264,7 +264,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
}
/* write the l2 table to the file */
BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
- ret = bdrv_pwrite(bs->file, l2_offset, l2_table,
+ ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
s->l2_size * sizeof(uint64_t));
if (ret < 0) {
goto fail;
@@ -414,8 +414,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
&s->aes_encrypt_key);
}
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
- ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start,
- s->cluster_data, n);
+ ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start,
+ s->cluster_data, n);
if (ret < 0)
return ret;
return 0;
@@ -632,10 +632,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
l2_table[l2_index] = cpu_to_be64(cluster_offset);
- if (bdrv_pwrite(bs->file,
+ if (bdrv_pwrite_sync(bs->file,
l2_offset + l2_index * sizeof(uint64_t),
l2_table + l2_index,
- sizeof(uint64_t)) != sizeof(uint64_t))
+ sizeof(uint64_t)) < 0)
return 0;
return cluster_offset;
@@ -656,7 +656,7 @@ static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,
int ret;
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
- ret = bdrv_pwrite(bs->file, l2_offset + start_offset,
+ ret = bdrv_pwrite_sync(bs->file, l2_offset + start_offset,
&l2_table[l2_start_index], len);
if (ret < 0) {
return ret;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 41e1da9..c2d0e61 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -44,8 +44,8 @@ static int write_refcount_block(BlockDriverState *bs)
}
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE);
- if (bdrv_pwrite(bs->file, s->refcount_block_cache_offset,
- s->refcount_block_cache, size) != size)
+ if (bdrv_pwrite_sync(bs->file, s->refcount_block_cache_offset,
+ s->refcount_block_cache, size) < 0)
{
return -EIO;
}
@@ -269,7 +269,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
/* Now the new refcount block needs to be written to disk */
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);
- ret = bdrv_pwrite(bs->file, new_block, s->refcount_block_cache,
+ ret = bdrv_pwrite_sync(bs->file, new_block, s->refcount_block_cache,
s->cluster_size);
if (ret < 0) {
goto fail_block;
@@ -279,7 +279,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
if (refcount_table_index < s->refcount_table_size) {
uint64_t data64 = cpu_to_be64(new_block);
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
- ret = bdrv_pwrite(bs->file,
+ ret = bdrv_pwrite_sync(bs->file,
s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
&data64, sizeof(data64));
if (ret < 0) {
@@ -359,7 +359,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
/* Write refcount blocks to disk */
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
- ret = bdrv_pwrite(bs->file, meta_offset, new_blocks,
+ ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
blocks_clusters * s->cluster_size);
qemu_free(new_blocks);
if (ret < 0) {
@@ -372,7 +372,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
}
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
- ret = bdrv_pwrite(bs->file, table_offset, new_table,
+ ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
table_size * sizeof(uint64_t));
if (ret < 0) {
goto fail_table;
@@ -387,7 +387,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
cpu_to_be64w((uint64_t*)data, table_offset);
cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, refcount_table_offset),
+ ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),
data, sizeof(data));
if (ret < 0) {
goto fail_table;
@@ -444,7 +444,7 @@ static int write_refcount_block_entries(BlockDriverState *bs,
size = (last_index - first_index) << REFCOUNT_SHIFT;
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
- ret = bdrv_pwrite(bs->file,
+ ret = bdrv_pwrite_sync(bs->file,
refcount_block_offset + (first_index << REFCOUNT_SHIFT),
&s->refcount_block_cache[first_index], size);
if (ret < 0) {
@@ -826,8 +826,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
}
if (l2_modified) {
- if (bdrv_pwrite(bs->file,
- l2_offset, l2_table, l2_size) != l2_size)
+ if (bdrv_pwrite_sync(bs->file,
+ l2_offset, l2_table, l2_size) < 0)
goto fail;
}
@@ -850,8 +850,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (l1_modified) {
for(i = 0; i < l1_size; i++)
cpu_to_be64s(&l1_table[i]);
- if (bdrv_pwrite(bs->file, l1_table_offset, l1_table,
- l1_size2) != l1_size2)
+ if (bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table,
+ l1_size2) < 0)
goto fail;
for(i = 0; i < l1_size; i++)
be64_to_cpus(&l1_table[i]);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 2a21c17..6228612 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -158,25 +158,25 @@ static int qcow_write_snapshots(BlockDriverState *bs)
h.id_str_size = cpu_to_be16(id_str_size);
h.name_size = cpu_to_be16(name_size);
offset = align_offset(offset, 8);
- if (bdrv_pwrite(bs->file, offset, &h, sizeof(h)) != sizeof(h))
+ if (bdrv_pwrite_sync(bs->file, offset, &h, sizeof(h)) < 0)
goto fail;
offset += sizeof(h);
- if (bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size) != id_str_size)
+ if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0)
goto fail;
offset += id_str_size;
- if (bdrv_pwrite(bs->file, offset, sn->name, name_size) != name_size)
+ if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0)
goto fail;
offset += name_size;
}
/* update the various header fields */
data64 = cpu_to_be64(snapshots_offset);
- if (bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset),
- &data64, sizeof(data64)) != sizeof(data64))
+ if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset),
+ &data64, sizeof(data64)) < 0)
goto fail;
data32 = cpu_to_be32(s->nb_snapshots);
- if (bdrv_pwrite(bs->file, offsetof(QCowHeader, nb_snapshots),
- &data32, sizeof(data32)) != sizeof(data32))
+ if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
+ &data32, sizeof(data32)) < 0)
goto fail;
/* free the old snapshot table */
@@ -284,9 +284,8 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
for(i = 0; i < s->l1_size; i++) {
l1_table[i] = cpu_to_be64(s->l1_table[i]);
}
- if (bdrv_pwrite(bs->file, sn->l1_table_offset,
- l1_table, s->l1_size * sizeof(uint64_t)) !=
- (s->l1_size * sizeof(uint64_t)))
+ if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset,
+ l1_table, s->l1_size * sizeof(uint64_t)) < 0)
goto fail;
qemu_free(l1_table);
l1_table = NULL;
@@ -335,8 +334,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
if (bdrv_pread(bs->file, sn->l1_table_offset,
s->l1_table, l1_size2) != l1_size2)
goto fail;
- if (bdrv_pwrite(bs->file, s->l1_table_offset,
- s->l1_table, l1_size2) != l1_size2)
+ if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
+ s->l1_table, l1_size2) < 0)
goto fail;
for(i = 0;i < s->l1_size; i++) {
be64_to_cpus(&s->l1_table[i]);
diff --git a/block/qcow2.c b/block/qcow2.c
index 1562557..70c5bb3 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -736,7 +736,7 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
backing_file_offset = sizeof(QCowHeader) + offset;
}
- ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);
+ ret = bdrv_pwrite_sync(bs->file, sizeof(QCowHeader), buf, ext_size);
if (ret < 0) {
goto fail;
}
@@ -745,13 +745,13 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);
uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),
+ ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_offset),
&be_backing_file_offset, sizeof(uint64_t));
if (ret < 0) {
goto fail;
}
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),
+ ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_size),
&be_backing_file_size, sizeof(uint32_t));
if (ret < 0) {
goto fail;
@@ -1035,8 +1035,8 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
/* write updated header.size */
offset = cpu_to_be64(offset);
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, size),
- &offset, sizeof(uint64_t));
+ ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
+ &offset, sizeof(uint64_t));
if (ret < 0) {
return ret;
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 5/6] vmdk: Use bdrv_(p)write_sync for metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
` (3 preceding siblings ...)
2010-06-18 15:03 ` [Qemu-devel] [PATCH 4/6] qcow2: " Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 6/6] vpc: " Kevin Wolf
2010-06-20 7:46 ` [Qemu-devel] [PATCH 0/6] block: Add flush after " Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index e659908..2d4ba42 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -150,7 +150,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
pstrcat(desc, sizeof(desc), tmp_desc);
}
- if (bdrv_pwrite(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+ if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
return -1;
return 0;
}
@@ -471,14 +471,14 @@ static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
BDRVVmdkState *s = bs->opaque;
/* update L2 table */
- if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+ if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset), sizeof(m_data->offset)) < 0)
return -1;
/* update backup L2 table */
if (s->l1_backup_table_offset != 0) {
m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
- if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+ if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset), sizeof(m_data->offset)) < 0)
return -1;
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 6/6] vpc: Use bdrv_(p)write_sync for metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
` (4 preceding siblings ...)
2010-06-18 15:03 ` [Qemu-devel] [PATCH 5/6] vmdk: " Kevin Wolf
@ 2010-06-18 15:03 ` Kevin Wolf
2010-06-20 7:46 ` [Qemu-devel] [PATCH 0/6] block: Add flush after " Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-06-18 15:03 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vpc.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/vpc.c b/block/vpc.c
index f1f73e2..e50509e 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -261,7 +261,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
s->last_bitmap_offset = bitmap_offset;
memset(bitmap, 0xff, s->bitmap_size);
- bdrv_pwrite(bs->file, bitmap_offset, bitmap, s->bitmap_size);
+ bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
}
// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
@@ -311,7 +311,7 @@ static int rewrite_footer(BlockDriverState* bs)
BDRVVPCState *s = bs->opaque;
int64_t offset = s->free_data_block_offset;
- ret = bdrv_pwrite(bs->file, offset, s->footer_buf, HEADER_SIZE);
+ ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
if (ret < 0)
return ret;
@@ -346,7 +346,8 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
// Initialize the block's bitmap
memset(bitmap, 0xff, s->bitmap_size);
- bdrv_pwrite(bs->file, s->free_data_block_offset, bitmap, s->bitmap_size);
+ bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
+ s->bitmap_size);
// Write new footer (the old one will be overwritten)
s->free_data_block_offset += s->block_size + s->bitmap_size;
@@ -357,7 +358,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
// Write BAT entry to disk
bat_offset = s->bat_offset + (4 * index);
bat_value = be32_to_cpu(s->pagetable[index]);
- ret = bdrv_pwrite(bs->file, bat_offset, &bat_value, 4);
+ ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
if (ret < 0)
goto fail;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
` (5 preceding siblings ...)
2010-06-18 15:03 ` [Qemu-devel] [PATCH 6/6] vpc: " Kevin Wolf
@ 2010-06-20 7:46 ` Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2010-06-20 7:46 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
Nice to see these patches :).
Stefan
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-06-20 7:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-18 15:03 [Qemu-devel] [PATCH 0/6] block: Add flush after metadata writes Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 1/6] block: Add bdrv_(p)write_sync Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 2/6] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 3/6] qcow: " Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 4/6] qcow2: " Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 5/6] vmdk: " Kevin Wolf
2010-06-18 15:03 ` [Qemu-devel] [PATCH 6/6] vpc: " Kevin Wolf
2010-06-20 7:46 ` [Qemu-devel] [PATCH 0/6] block: Add flush after " Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).