Commit 9923e05e1adbba54b1a646ae39f8aa8fc88d78a6

Authored by Kevin Wolf
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 }
... ...