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,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 | } |