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