* [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).