diff options
author | Eduardo Habkost <ehabkost@redhat.com> | 2009-09-09 17:29:08 -0300 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2009-09-09 18:02:08 -0300 |
commit | 8176dbe8b32625a54583e695799bc8c8b9bc86eb (patch) | |
tree | 1742f424837f0dbeab3f4b78130569d31ccc2c26 | |
parent | d340f30fe6f2af6179ebba0aaf641f8645db4e87 (diff) |
update_refcount: Write complete sectors
Message-id: <1252527484-19604-6-git-send-email-ehabkost@redhat.com>
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
Patchwork-id: 3387
O-Subject: [PATCH 5/5] update_refcount: Write complete sectors
Bugzilla:
Author: Kevin Wolf <kwolf@redhat.com>
Bugzilla: 520693
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
RH-Acked-by: Andrea Arcangeli <aarcange@redhat.com>
When updating the refcount blocks in update_refcount(), write complete sectors
instead of updating single entries.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
qemu/block-qcow2.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
qemu/block-qcow2.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
-rw-r--r-- | qemu/block-qcow2.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/qemu/block-qcow2.c b/qemu/block-qcow2.c index 50561f15..37a73e0d 100644 --- a/qemu/block-qcow2.c +++ b/qemu/block-qcow2.c @@ -2628,6 +2628,27 @@ static int update_cluster_refcount(BlockDriverState *bs, return get_refcount(bs, cluster_index); } +#define REFCOUNTS_PER_SECTOR (512 >> REFCOUNT_SHIFT) +static int write_refcount_block_entries(BDRVQcowState *s, + int64_t refcount_block_offset, int first_index, int last_index) +{ + size_t size; + + first_index &= ~(REFCOUNTS_PER_SECTOR - 1); + last_index = (last_index + REFCOUNTS_PER_SECTOR) + & ~(REFCOUNTS_PER_SECTOR - 1); + + size = (last_index - first_index) << REFCOUNT_SHIFT; + if (bdrv_pwrite(s->hd, + refcount_block_offset + (first_index << REFCOUNT_SHIFT), + &s->refcount_block_cache[first_index], size) != size) + { + return -EIO; + } + + return 0; +} + /* XXX: cache several refcount block clusters ? */ static int update_refcount(BlockDriverState *bs, int64_t offset, int64_t length, @@ -2657,10 +2678,9 @@ static int update_refcount(BlockDriverState *bs, old_table_index = table_index; table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); if ((old_table_index >= 0) && (table_index != old_table_index)) { - size_t size = (last_index - first_index + 1) << REFCOUNT_SHIFT; - if (bdrv_pwrite(s->hd, - refcount_block_offset + (first_index << REFCOUNT_SHIFT), - &s->refcount_block_cache[first_index], size) != size) + + if (write_refcount_block_entries(s, refcount_block_offset, + first_index, last_index) < 0) { return -EIO; } @@ -2697,10 +2717,8 @@ static int update_refcount(BlockDriverState *bs, /* Write last changed block to disk */ if (refcount_block_offset != 0) { - size_t size = (last_index - first_index + 1) << REFCOUNT_SHIFT; - if (bdrv_pwrite(s->hd, - refcount_block_offset + (first_index << REFCOUNT_SHIFT), - &s->refcount_block_cache[first_index], size) != size) + if (write_refcount_block_entries(s, refcount_block_offset, + first_index, last_index) < 0) { return -EIO; } |