Commit 643e5399bbb1dd6113e787c4d86c942a3a7c76ca

Authored by aliguori
1 parent a32ef786

Write table offset and size in one syscall (Gleb Natapov)

Otherwise if VM is killed between two writes data may be lost.
But if offset and size fields are at the same disk block one
write should update them both simultaneously.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5859 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 9 additions and 17 deletions
block-qcow2.c
... ... @@ -429,8 +429,7 @@ static int grow_l1_table(BlockDriverState *bs, int min_size)
429 429 int new_l1_size, new_l1_size2, ret, i;
430 430 uint64_t *new_l1_table;
431 431 uint64_t new_l1_table_offset;
432   - uint64_t data64;
433   - uint32_t data32;
  432 + uint8_t data[12];
434 433  
435 434 new_l1_size = s->l1_size;
436 435 if (min_size <= new_l1_size)
... ... @@ -460,13 +459,10 @@ static int grow_l1_table(BlockDriverState *bs, int min_size)
460 459 new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
461 460  
462 461 /* set new table */
463   - data64 = cpu_to_be64(new_l1_table_offset);
464   - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_table_offset),
465   - &data64, sizeof(data64)) != sizeof(data64))
466   - goto fail;
467   - data32 = cpu_to_be32(new_l1_size);
468   - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size),
469   - &data32, sizeof(data32)) != sizeof(data32))
  462 + cpu_to_be32w((uint32_t*)data, new_l1_size);
  463 + cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
  464 + if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,
  465 + sizeof(data)) != sizeof(data))
470 466 goto fail;
471 467 qemu_free(s->l1_table);
472 468 free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
... ... @@ -2281,8 +2277,7 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
2281 2277 int new_table_size, new_table_size2, refcount_table_clusters, i, ret;
2282 2278 uint64_t *new_table;
2283 2279 int64_t table_offset;
2284   - uint64_t data64;
2285   - uint32_t data32;
  2280 + uint8_t data[12];
2286 2281 int old_table_size;
2287 2282 int64_t old_table_offset;
2288 2283  
... ... @@ -2321,13 +2316,10 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
2321 2316 for(i = 0; i < s->refcount_table_size; i++)
2322 2317 be64_to_cpus(&new_table[i]);
2323 2318  
2324   - data64 = cpu_to_be64(table_offset);
  2319 + cpu_to_be64w((uint64_t*)data, table_offset);
  2320 + cpu_to_be32w((uint32_t*)(data + 8), refcount_table_clusters);
2325 2321 if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
2326   - &data64, sizeof(data64)) != sizeof(data64))
2327   - goto fail;
2328   - data32 = cpu_to_be32(refcount_table_clusters);
2329   - if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_clusters),
2330   - &data32, sizeof(data32)) != sizeof(data32))
  2322 + data, sizeof(data)) != sizeof(data))
2331 2323 goto fail;
2332 2324 qemu_free(s->refcount_table);
2333 2325 old_table_offset = s->refcount_table_offset;
... ...