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,6 +209,27 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
209 return refcount_block_offset; 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 /* XXX: cache several refcount block clusters ? */ 233 /* XXX: cache several refcount block clusters ? */
213 static int update_refcount(BlockDriverState *bs, 234 static int update_refcount(BlockDriverState *bs,
214 int64_t offset, int64_t length, 235 int64_t offset, int64_t length,
@@ -238,10 +259,9 @@ static int update_refcount(BlockDriverState *bs, @@ -238,10 +259,9 @@ static int update_refcount(BlockDriverState *bs,
238 old_table_index = table_index; 259 old_table_index = table_index;
239 table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); 260 table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
240 if ((old_table_index >= 0) && (table_index != old_table_index)) { 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 return -EIO; 266 return -EIO;
247 } 267 }
@@ -278,10 +298,8 @@ static int update_refcount(BlockDriverState *bs, @@ -278,10 +298,8 @@ static int update_refcount(BlockDriverState *bs,
278 298
279 /* Write last changed block to disk */ 299 /* Write last changed block to disk */
280 if (refcount_block_offset != 0) { 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 return -EIO; 304 return -EIO;
287 } 305 }