qcow2: Use bdrv_(p)write_sync for metadata writes

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2010-06-16 17:44:35 +02:00
parent 5e5557d970
commit 8b3b720620
4 changed files with 40 additions and 41 deletions

View File

@ -64,8 +64,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
for(i = 0; i < s->l1_size; i++) for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[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); ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
if (ret != new_l1_size2) if (ret < 0)
goto fail; goto fail;
for(i = 0; i < s->l1_size; i++) for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = be64_to_cpu(new_l1_table[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); BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
cpu_to_be32w((uint32_t*)data, new_l1_size); cpu_to_be32w((uint32_t*)data, new_l1_size);
cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset); cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
if (ret != sizeof(data)) { if (ret < 0) {
goto fail; goto fail;
} }
qemu_free(s->l1_table); qemu_free(s->l1_table);
@ -87,7 +87,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
fail: fail:
qemu_free(new_l1_table); qemu_free(new_l1_table);
qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2); 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) void qcow2_l2_cache_reset(BlockDriverState *bs)
@ -207,7 +207,7 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index)
} }
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); 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)); buf, sizeof(buf));
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -263,7 +263,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
} }
/* write the l2 table to the file */ /* write the l2 table to the file */
BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); 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)); s->l2_size * sizeof(uint64_t));
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
@ -413,8 +413,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
&s->aes_encrypt_key); &s->aes_encrypt_key);
} }
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE); BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start, ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start,
s->cluster_data, n); s->cluster_data, n);
if (ret < 0) if (ret < 0)
return ret; return ret;
return 0; return 0;
@ -631,10 +631,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
l2_table[l2_index] = cpu_to_be64(cluster_offset); 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_offset + l2_index * sizeof(uint64_t),
l2_table + l2_index, l2_table + l2_index,
sizeof(uint64_t)) != sizeof(uint64_t)) sizeof(uint64_t)) < 0)
return 0; return 0;
return cluster_offset; return cluster_offset;
@ -655,7 +655,7 @@ static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,
int ret; int ret;
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); 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); &l2_table[l2_start_index], len);
if (ret < 0) { if (ret < 0) {
return ret; return ret;

View File

@ -44,8 +44,8 @@ static int write_refcount_block(BlockDriverState *bs)
} }
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE); BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE);
if (bdrv_pwrite(bs->file, s->refcount_block_cache_offset, if (bdrv_pwrite_sync(bs->file, s->refcount_block_cache_offset,
s->refcount_block_cache, size) != size) s->refcount_block_cache, size) < 0)
{ {
return -EIO; 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 */ /* Now the new refcount block needs to be written to disk */
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE); 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); s->cluster_size);
if (ret < 0) { if (ret < 0) {
goto fail_block; 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) { if (refcount_table_index < s->refcount_table_size) {
uint64_t data64 = cpu_to_be64(new_block); uint64_t data64 = cpu_to_be64(new_block);
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP); 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), s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
&data64, sizeof(data64)); &data64, sizeof(data64));
if (ret < 0) { if (ret < 0) {
@ -359,7 +359,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
/* Write refcount blocks to disk */ /* Write refcount blocks to disk */
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); 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); blocks_clusters * s->cluster_size);
qemu_free(new_blocks); qemu_free(new_blocks);
if (ret < 0) { 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); 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)); table_size * sizeof(uint64_t));
if (ret < 0) { if (ret < 0) {
goto fail_table; 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_be64w((uint64_t*)data, table_offset);
cpu_to_be32w((uint32_t*)(data + 8), table_clusters); cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE); 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)); data, sizeof(data));
if (ret < 0) { if (ret < 0) {
goto fail_table; goto fail_table;
@ -444,7 +444,7 @@ static int write_refcount_block_entries(BlockDriverState *bs,
size = (last_index - first_index) << REFCOUNT_SHIFT; size = (last_index - first_index) << REFCOUNT_SHIFT;
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART); 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), refcount_block_offset + (first_index << REFCOUNT_SHIFT),
&s->refcount_block_cache[first_index], size); &s->refcount_block_cache[first_index], size);
if (ret < 0) { if (ret < 0) {
@ -826,8 +826,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
} }
} }
if (l2_modified) { if (l2_modified) {
if (bdrv_pwrite(bs->file, if (bdrv_pwrite_sync(bs->file,
l2_offset, l2_table, l2_size) != l2_size) l2_offset, l2_table, l2_size) < 0)
goto fail; goto fail;
} }
@ -850,8 +850,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (l1_modified) { if (l1_modified) {
for(i = 0; i < l1_size; i++) for(i = 0; i < l1_size; i++)
cpu_to_be64s(&l1_table[i]); cpu_to_be64s(&l1_table[i]);
if (bdrv_pwrite(bs->file, l1_table_offset, l1_table, if (bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table,
l1_size2) != l1_size2) l1_size2) < 0)
goto fail; goto fail;
for(i = 0; i < l1_size; i++) for(i = 0; i < l1_size; i++)
be64_to_cpus(&l1_table[i]); be64_to_cpus(&l1_table[i]);

View File

@ -158,25 +158,25 @@ static int qcow_write_snapshots(BlockDriverState *bs)
h.id_str_size = cpu_to_be16(id_str_size); h.id_str_size = cpu_to_be16(id_str_size);
h.name_size = cpu_to_be16(name_size); h.name_size = cpu_to_be16(name_size);
offset = align_offset(offset, 8); 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; goto fail;
offset += sizeof(h); 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; goto fail;
offset += id_str_size; 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; goto fail;
offset += name_size; offset += name_size;
} }
/* update the various header fields */ /* update the various header fields */
data64 = cpu_to_be64(snapshots_offset); data64 = cpu_to_be64(snapshots_offset);
if (bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset), if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset),
&data64, sizeof(data64)) != sizeof(data64)) &data64, sizeof(data64)) < 0)
goto fail; goto fail;
data32 = cpu_to_be32(s->nb_snapshots); data32 = cpu_to_be32(s->nb_snapshots);
if (bdrv_pwrite(bs->file, offsetof(QCowHeader, nb_snapshots), if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
&data32, sizeof(data32)) != sizeof(data32)) &data32, sizeof(data32)) < 0)
goto fail; goto fail;
/* free the old snapshot table */ /* 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++) { for(i = 0; i < s->l1_size; i++) {
l1_table[i] = cpu_to_be64(s->l1_table[i]); l1_table[i] = cpu_to_be64(s->l1_table[i]);
} }
if (bdrv_pwrite(bs->file, sn->l1_table_offset, if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset,
l1_table, s->l1_size * sizeof(uint64_t)) != l1_table, s->l1_size * sizeof(uint64_t)) < 0)
(s->l1_size * sizeof(uint64_t)))
goto fail; goto fail;
qemu_free(l1_table); qemu_free(l1_table);
l1_table = NULL; 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, if (bdrv_pread(bs->file, sn->l1_table_offset,
s->l1_table, l1_size2) != l1_size2) s->l1_table, l1_size2) != l1_size2)
goto fail; goto fail;
if (bdrv_pwrite(bs->file, s->l1_table_offset, if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
s->l1_table, l1_size2) != l1_size2) s->l1_table, l1_size2) < 0)
goto fail; goto fail;
for(i = 0;i < s->l1_size; i++) { for(i = 0;i < s->l1_size; i++) {
be64_to_cpus(&s->l1_table[i]); be64_to_cpus(&s->l1_table[i]);

View File

@ -735,7 +735,7 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
backing_file_offset = sizeof(QCowHeader) + offset; 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) { if (ret < 0) {
goto fail; goto fail;
} }
@ -744,13 +744,13 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset); uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);
uint32_t be_backing_file_size = cpu_to_be32(backing_file_len); 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)); &be_backing_file_offset, sizeof(uint64_t));
if (ret < 0) { if (ret < 0) {
goto fail; 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)); &be_backing_file_size, sizeof(uint32_t));
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
@ -1131,8 +1131,8 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
/* write updated header.size */ /* write updated header.size */
offset = cpu_to_be64(offset); offset = cpu_to_be64(offset);
ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, size), ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
&offset, sizeof(uint64_t)); &offset, sizeof(uint64_t));
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }