Commit 9923e05e1adbba54b1a646ae39f8aa8fc88d78a6
Committed by
Anthony Liguori
1 parent
4c1612d9
update_refcount: Write complete sectors
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>
Showing
1 changed file
with
26 additions
and
8 deletions
block/qcow2-refcount.c
| ... | ... | @@ -209,6 +209,27 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index) |
| 209 | 209 | return refcount_block_offset; |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | +#define REFCOUNTS_PER_SECTOR (512 >> REFCOUNT_SHIFT) | |
| 213 | +static int write_refcount_block_entries(BDRVQcowState *s, | |
| 214 | + int64_t refcount_block_offset, int first_index, int last_index) | |
| 215 | +{ | |
| 216 | + size_t size; | |
| 217 | + | |
| 218 | + first_index &= ~(REFCOUNTS_PER_SECTOR - 1); | |
| 219 | + last_index = (last_index + REFCOUNTS_PER_SECTOR) | |
| 220 | + & ~(REFCOUNTS_PER_SECTOR - 1); | |
| 221 | + | |
| 222 | + size = (last_index - first_index) << REFCOUNT_SHIFT; | |
| 223 | + if (bdrv_pwrite(s->hd, | |
| 224 | + refcount_block_offset + (first_index << REFCOUNT_SHIFT), | |
| 225 | + &s->refcount_block_cache[first_index], size) != size) | |
| 226 | + { | |
| 227 | + return -EIO; | |
| 228 | + } | |
| 229 | + | |
| 230 | + return 0; | |
| 231 | +} | |
| 232 | + | |
| 212 | 233 | /* XXX: cache several refcount block clusters ? */ |
| 213 | 234 | static int update_refcount(BlockDriverState *bs, |
| 214 | 235 | int64_t offset, int64_t length, |
| ... | ... | @@ -238,10 +259,9 @@ static int update_refcount(BlockDriverState *bs, |
| 238 | 259 | old_table_index = table_index; |
| 239 | 260 | table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); |
| 240 | 261 | if ((old_table_index >= 0) && (table_index != old_table_index)) { |
| 241 | - size_t size = (last_index - first_index + 1) << REFCOUNT_SHIFT; | |
| 242 | - if (bdrv_pwrite(s->hd, | |
| 243 | - refcount_block_offset + (first_index << REFCOUNT_SHIFT), | |
| 244 | - &s->refcount_block_cache[first_index], size) != size) | |
| 262 | + | |
| 263 | + if (write_refcount_block_entries(s, refcount_block_offset, | |
| 264 | + first_index, last_index) < 0) | |
| 245 | 265 | { |
| 246 | 266 | return -EIO; |
| 247 | 267 | } |
| ... | ... | @@ -278,10 +298,8 @@ static int update_refcount(BlockDriverState *bs, |
| 278 | 298 | |
| 279 | 299 | /* Write last changed block to disk */ |
| 280 | 300 | if (refcount_block_offset != 0) { |
| 281 | - size_t size = (last_index - first_index + 1) << REFCOUNT_SHIFT; | |
| 282 | - if (bdrv_pwrite(s->hd, | |
| 283 | - refcount_block_offset + (first_index << REFCOUNT_SHIFT), | |
| 284 | - &s->refcount_block_cache[first_index], size) != size) | |
| 301 | + if (write_refcount_block_entries(s, refcount_block_offset, | |
| 302 | + first_index, last_index) < 0) | |
| 285 | 303 | { |
| 286 | 304 | return -EIO; |
| 287 | 305 | } | ... | ... |