1 /* 2 * Block driver for the QCOW version 2 format 3 * 4 * Copyright (c) 2004-2006 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "qemu-common.h" 27 #include "block/block_int.h" 28 #include "block/qcow2.h" 29 #include "qemu/error-report.h" 30 31 void qcow2_free_snapshots(BlockDriverState *bs) 32 { 33 BDRVQcow2State *s = bs->opaque; 34 int i; 35 36 for(i = 0; i < s->nb_snapshots; i++) { 37 g_free(s->snapshots[i].name); 38 g_free(s->snapshots[i].id_str); 39 } 40 g_free(s->snapshots); 41 s->snapshots = NULL; 42 s->nb_snapshots = 0; 43 } 44 45 int qcow2_read_snapshots(BlockDriverState *bs) 46 { 47 BDRVQcow2State *s = bs->opaque; 48 QCowSnapshotHeader h; 49 QCowSnapshotExtraData extra; 50 QCowSnapshot *sn; 51 int i, id_str_size, name_size; 52 int64_t offset; 53 uint32_t extra_data_size; 54 int ret; 55 56 if (!s->nb_snapshots) { 57 s->snapshots = NULL; 58 s->snapshots_size = 0; 59 return 0; 60 } 61 62 offset = s->snapshots_offset; 63 s->snapshots = g_new0(QCowSnapshot, s->nb_snapshots); 64 65 for(i = 0; i < s->nb_snapshots; i++) { 66 /* Read statically sized part of the snapshot header */ 67 offset = align_offset(offset, 8); 68 ret = bdrv_pread(bs->file->bs, offset, &h, sizeof(h)); 69 if (ret < 0) { 70 goto fail; 71 } 72 73 offset += sizeof(h); 74 sn = s->snapshots + i; 75 sn->l1_table_offset = be64_to_cpu(h.l1_table_offset); 76 sn->l1_size = be32_to_cpu(h.l1_size); 77 sn->vm_state_size = be32_to_cpu(h.vm_state_size); 78 sn->date_sec = be32_to_cpu(h.date_sec); 79 sn->date_nsec = be32_to_cpu(h.date_nsec); 80 sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec); 81 extra_data_size = be32_to_cpu(h.extra_data_size); 82 83 id_str_size = be16_to_cpu(h.id_str_size); 84 name_size = be16_to_cpu(h.name_size); 85 86 /* Read extra data */ 87 ret = bdrv_pread(bs->file->bs, offset, &extra, 88 MIN(sizeof(extra), extra_data_size)); 89 if (ret < 0) { 90 goto fail; 91 } 92 offset += extra_data_size; 93 94 if (extra_data_size >= 8) { 95 sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large); 96 } 97 98 if (extra_data_size >= 16) { 99 sn->disk_size = be64_to_cpu(extra.disk_size); 100 } else { 101 sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; 102 } 103 104 /* Read snapshot ID */ 105 sn->id_str = g_malloc(id_str_size + 1); 106 ret = bdrv_pread(bs->file->bs, offset, sn->id_str, id_str_size); 107 if (ret < 0) { 108 goto fail; 109 } 110 offset += id_str_size; 111 sn->id_str[id_str_size] = '\0'; 112 113 /* Read snapshot name */ 114 sn->name = g_malloc(name_size + 1); 115 ret = bdrv_pread(bs->file->bs, offset, sn->name, name_size); 116 if (ret < 0) { 117 goto fail; 118 } 119 offset += name_size; 120 sn->name[name_size] = '\0'; 121 122 if (offset - s->snapshots_offset > QCOW_MAX_SNAPSHOTS_SIZE) { 123 ret = -EFBIG; 124 goto fail; 125 } 126 } 127 128 assert(offset - s->snapshots_offset <= INT_MAX); 129 s->snapshots_size = offset - s->snapshots_offset; 130 return 0; 131 132 fail: 133 qcow2_free_snapshots(bs); 134 return ret; 135 } 136 137 /* add at the end of the file a new list of snapshots */ 138 static int qcow2_write_snapshots(BlockDriverState *bs) 139 { 140 BDRVQcow2State *s = bs->opaque; 141 QCowSnapshot *sn; 142 QCowSnapshotHeader h; 143 QCowSnapshotExtraData extra; 144 int i, name_size, id_str_size, snapshots_size; 145 struct { 146 uint32_t nb_snapshots; 147 uint64_t snapshots_offset; 148 } QEMU_PACKED header_data; 149 int64_t offset, snapshots_offset = 0; 150 int ret; 151 152 /* compute the size of the snapshots */ 153 offset = 0; 154 for(i = 0; i < s->nb_snapshots; i++) { 155 sn = s->snapshots + i; 156 offset = align_offset(offset, 8); 157 offset += sizeof(h); 158 offset += sizeof(extra); 159 offset += strlen(sn->id_str); 160 offset += strlen(sn->name); 161 162 if (offset > QCOW_MAX_SNAPSHOTS_SIZE) { 163 ret = -EFBIG; 164 goto fail; 165 } 166 } 167 168 assert(offset <= INT_MAX); 169 snapshots_size = offset; 170 171 /* Allocate space for the new snapshot list */ 172 snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size); 173 offset = snapshots_offset; 174 if (offset < 0) { 175 ret = offset; 176 goto fail; 177 } 178 ret = bdrv_flush(bs); 179 if (ret < 0) { 180 goto fail; 181 } 182 183 /* The snapshot list position has not yet been updated, so these clusters 184 * must indeed be completely free */ 185 ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size); 186 if (ret < 0) { 187 goto fail; 188 } 189 190 191 /* Write all snapshots to the new list */ 192 for(i = 0; i < s->nb_snapshots; i++) { 193 sn = s->snapshots + i; 194 memset(&h, 0, sizeof(h)); 195 h.l1_table_offset = cpu_to_be64(sn->l1_table_offset); 196 h.l1_size = cpu_to_be32(sn->l1_size); 197 /* If it doesn't fit in 32 bit, older implementations should treat it 198 * as a disk-only snapshot rather than truncate the VM state */ 199 if (sn->vm_state_size <= 0xffffffff) { 200 h.vm_state_size = cpu_to_be32(sn->vm_state_size); 201 } 202 h.date_sec = cpu_to_be32(sn->date_sec); 203 h.date_nsec = cpu_to_be32(sn->date_nsec); 204 h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); 205 h.extra_data_size = cpu_to_be32(sizeof(extra)); 206 207 memset(&extra, 0, sizeof(extra)); 208 extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); 209 extra.disk_size = cpu_to_be64(sn->disk_size); 210 211 id_str_size = strlen(sn->id_str); 212 name_size = strlen(sn->name); 213 assert(id_str_size <= UINT16_MAX && name_size <= UINT16_MAX); 214 h.id_str_size = cpu_to_be16(id_str_size); 215 h.name_size = cpu_to_be16(name_size); 216 offset = align_offset(offset, 8); 217 218 ret = bdrv_pwrite(bs->file->bs, offset, &h, sizeof(h)); 219 if (ret < 0) { 220 goto fail; 221 } 222 offset += sizeof(h); 223 224 ret = bdrv_pwrite(bs->file->bs, offset, &extra, sizeof(extra)); 225 if (ret < 0) { 226 goto fail; 227 } 228 offset += sizeof(extra); 229 230 ret = bdrv_pwrite(bs->file->bs, offset, sn->id_str, id_str_size); 231 if (ret < 0) { 232 goto fail; 233 } 234 offset += id_str_size; 235 236 ret = bdrv_pwrite(bs->file->bs, offset, sn->name, name_size); 237 if (ret < 0) { 238 goto fail; 239 } 240 offset += name_size; 241 } 242 243 /* 244 * Update the header to point to the new snapshot table. This requires the 245 * new table and its refcounts to be stable on disk. 246 */ 247 ret = bdrv_flush(bs); 248 if (ret < 0) { 249 goto fail; 250 } 251 252 QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) != 253 offsetof(QCowHeader, nb_snapshots) + sizeof(header_data.nb_snapshots)); 254 255 header_data.nb_snapshots = cpu_to_be32(s->nb_snapshots); 256 header_data.snapshots_offset = cpu_to_be64(snapshots_offset); 257 258 ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, nb_snapshots), 259 &header_data, sizeof(header_data)); 260 if (ret < 0) { 261 goto fail; 262 } 263 264 /* free the old snapshot table */ 265 qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size, 266 QCOW2_DISCARD_SNAPSHOT); 267 s->snapshots_offset = snapshots_offset; 268 s->snapshots_size = snapshots_size; 269 return 0; 270 271 fail: 272 if (snapshots_offset > 0) { 273 qcow2_free_clusters(bs, snapshots_offset, snapshots_size, 274 QCOW2_DISCARD_ALWAYS); 275 } 276 return ret; 277 } 278 279 static void find_new_snapshot_id(BlockDriverState *bs, 280 char *id_str, int id_str_size) 281 { 282 BDRVQcow2State *s = bs->opaque; 283 QCowSnapshot *sn; 284 int i; 285 unsigned long id, id_max = 0; 286 287 for(i = 0; i < s->nb_snapshots; i++) { 288 sn = s->snapshots + i; 289 id = strtoul(sn->id_str, NULL, 10); 290 if (id > id_max) 291 id_max = id; 292 } 293 snprintf(id_str, id_str_size, "%lu", id_max + 1); 294 } 295 296 static int find_snapshot_by_id_and_name(BlockDriverState *bs, 297 const char *id, 298 const char *name) 299 { 300 BDRVQcow2State *s = bs->opaque; 301 int i; 302 303 if (id && name) { 304 for (i = 0; i < s->nb_snapshots; i++) { 305 if (!strcmp(s->snapshots[i].id_str, id) && 306 !strcmp(s->snapshots[i].name, name)) { 307 return i; 308 } 309 } 310 } else if (id) { 311 for (i = 0; i < s->nb_snapshots; i++) { 312 if (!strcmp(s->snapshots[i].id_str, id)) { 313 return i; 314 } 315 } 316 } else if (name) { 317 for (i = 0; i < s->nb_snapshots; i++) { 318 if (!strcmp(s->snapshots[i].name, name)) { 319 return i; 320 } 321 } 322 } 323 324 return -1; 325 } 326 327 static int find_snapshot_by_id_or_name(BlockDriverState *bs, 328 const char *id_or_name) 329 { 330 int ret; 331 332 ret = find_snapshot_by_id_and_name(bs, id_or_name, NULL); 333 if (ret >= 0) { 334 return ret; 335 } 336 return find_snapshot_by_id_and_name(bs, NULL, id_or_name); 337 } 338 339 /* if no id is provided, a new one is constructed */ 340 int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) 341 { 342 BDRVQcow2State *s = bs->opaque; 343 QCowSnapshot *new_snapshot_list = NULL; 344 QCowSnapshot *old_snapshot_list = NULL; 345 QCowSnapshot sn1, *sn = &sn1; 346 int i, ret; 347 uint64_t *l1_table = NULL; 348 int64_t l1_table_offset; 349 350 if (s->nb_snapshots >= QCOW_MAX_SNAPSHOTS) { 351 return -EFBIG; 352 } 353 354 memset(sn, 0, sizeof(*sn)); 355 356 /* Generate an ID */ 357 find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str)); 358 359 /* Check that the ID is unique */ 360 if (find_snapshot_by_id_and_name(bs, sn_info->id_str, NULL) >= 0) { 361 return -EEXIST; 362 } 363 364 /* Populate sn with passed data */ 365 sn->id_str = g_strdup(sn_info->id_str); 366 sn->name = g_strdup(sn_info->name); 367 368 sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; 369 sn->vm_state_size = sn_info->vm_state_size; 370 sn->date_sec = sn_info->date_sec; 371 sn->date_nsec = sn_info->date_nsec; 372 sn->vm_clock_nsec = sn_info->vm_clock_nsec; 373 374 /* Allocate the L1 table of the snapshot and copy the current one there. */ 375 l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); 376 if (l1_table_offset < 0) { 377 ret = l1_table_offset; 378 goto fail; 379 } 380 381 sn->l1_table_offset = l1_table_offset; 382 sn->l1_size = s->l1_size; 383 384 l1_table = g_try_new(uint64_t, s->l1_size); 385 if (s->l1_size && l1_table == NULL) { 386 ret = -ENOMEM; 387 goto fail; 388 } 389 390 for(i = 0; i < s->l1_size; i++) { 391 l1_table[i] = cpu_to_be64(s->l1_table[i]); 392 } 393 394 ret = qcow2_pre_write_overlap_check(bs, 0, sn->l1_table_offset, 395 s->l1_size * sizeof(uint64_t)); 396 if (ret < 0) { 397 goto fail; 398 } 399 400 ret = bdrv_pwrite(bs->file->bs, sn->l1_table_offset, l1_table, 401 s->l1_size * sizeof(uint64_t)); 402 if (ret < 0) { 403 goto fail; 404 } 405 406 g_free(l1_table); 407 l1_table = NULL; 408 409 /* 410 * Increase the refcounts of all clusters and make sure everything is 411 * stable on disk before updating the snapshot table to contain a pointer 412 * to the new L1 table. 413 */ 414 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1); 415 if (ret < 0) { 416 goto fail; 417 } 418 419 /* Append the new snapshot to the snapshot list */ 420 new_snapshot_list = g_new(QCowSnapshot, s->nb_snapshots + 1); 421 if (s->snapshots) { 422 memcpy(new_snapshot_list, s->snapshots, 423 s->nb_snapshots * sizeof(QCowSnapshot)); 424 old_snapshot_list = s->snapshots; 425 } 426 s->snapshots = new_snapshot_list; 427 s->snapshots[s->nb_snapshots++] = *sn; 428 429 ret = qcow2_write_snapshots(bs); 430 if (ret < 0) { 431 g_free(s->snapshots); 432 s->snapshots = old_snapshot_list; 433 s->nb_snapshots--; 434 goto fail; 435 } 436 437 g_free(old_snapshot_list); 438 439 /* The VM state isn't needed any more in the active L1 table; in fact, it 440 * hurts by causing expensive COW for the next snapshot. */ 441 qcow2_discard_clusters(bs, qcow2_vm_state_offset(s), 442 align_offset(sn->vm_state_size, s->cluster_size) 443 >> BDRV_SECTOR_BITS, 444 QCOW2_DISCARD_NEVER, false); 445 446 #ifdef DEBUG_ALLOC 447 { 448 BdrvCheckResult result = {0}; 449 qcow2_check_refcounts(bs, &result, 0); 450 } 451 #endif 452 return 0; 453 454 fail: 455 g_free(sn->id_str); 456 g_free(sn->name); 457 g_free(l1_table); 458 459 return ret; 460 } 461 462 /* copy the snapshot 'snapshot_name' into the current disk image */ 463 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) 464 { 465 BDRVQcow2State *s = bs->opaque; 466 QCowSnapshot *sn; 467 int i, snapshot_index; 468 int cur_l1_bytes, sn_l1_bytes; 469 int ret; 470 uint64_t *sn_l1_table = NULL; 471 472 /* Search the snapshot */ 473 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 474 if (snapshot_index < 0) { 475 return -ENOENT; 476 } 477 sn = &s->snapshots[snapshot_index]; 478 479 if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) { 480 error_report("qcow2: Loading snapshots with different disk " 481 "size is not implemented"); 482 ret = -ENOTSUP; 483 goto fail; 484 } 485 486 /* 487 * Make sure that the current L1 table is big enough to contain the whole 488 * L1 table of the snapshot. If the snapshot L1 table is smaller, the 489 * current one must be padded with zeros. 490 */ 491 ret = qcow2_grow_l1_table(bs, sn->l1_size, true); 492 if (ret < 0) { 493 goto fail; 494 } 495 496 cur_l1_bytes = s->l1_size * sizeof(uint64_t); 497 sn_l1_bytes = sn->l1_size * sizeof(uint64_t); 498 499 /* 500 * Copy the snapshot L1 table to the current L1 table. 501 * 502 * Before overwriting the old current L1 table on disk, make sure to 503 * increase all refcounts for the clusters referenced by the new one. 504 * Decrease the refcount referenced by the old one only when the L1 505 * table is overwritten. 506 */ 507 sn_l1_table = g_try_malloc0(cur_l1_bytes); 508 if (cur_l1_bytes && sn_l1_table == NULL) { 509 ret = -ENOMEM; 510 goto fail; 511 } 512 513 ret = bdrv_pread(bs->file->bs, sn->l1_table_offset, 514 sn_l1_table, sn_l1_bytes); 515 if (ret < 0) { 516 goto fail; 517 } 518 519 ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset, 520 sn->l1_size, 1); 521 if (ret < 0) { 522 goto fail; 523 } 524 525 ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1, 526 s->l1_table_offset, cur_l1_bytes); 527 if (ret < 0) { 528 goto fail; 529 } 530 531 ret = bdrv_pwrite_sync(bs->file->bs, s->l1_table_offset, sn_l1_table, 532 cur_l1_bytes); 533 if (ret < 0) { 534 goto fail; 535 } 536 537 /* 538 * Decrease refcount of clusters of current L1 table. 539 * 540 * At this point, the in-memory s->l1_table points to the old L1 table, 541 * whereas on disk we already have the new one. 542 * 543 * qcow2_update_snapshot_refcount special cases the current L1 table to use 544 * the in-memory data instead of really using the offset to load a new one, 545 * which is why this works. 546 */ 547 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, 548 s->l1_size, -1); 549 550 /* 551 * Now update the in-memory L1 table to be in sync with the on-disk one. We 552 * need to do this even if updating refcounts failed. 553 */ 554 for(i = 0;i < s->l1_size; i++) { 555 s->l1_table[i] = be64_to_cpu(sn_l1_table[i]); 556 } 557 558 if (ret < 0) { 559 goto fail; 560 } 561 562 g_free(sn_l1_table); 563 sn_l1_table = NULL; 564 565 /* 566 * Update QCOW_OFLAG_COPIED in the active L1 table (it may have changed 567 * when we decreased the refcount of the old snapshot. 568 */ 569 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); 570 if (ret < 0) { 571 goto fail; 572 } 573 574 #ifdef DEBUG_ALLOC 575 { 576 BdrvCheckResult result = {0}; 577 qcow2_check_refcounts(bs, &result, 0); 578 } 579 #endif 580 return 0; 581 582 fail: 583 g_free(sn_l1_table); 584 return ret; 585 } 586 587 int qcow2_snapshot_delete(BlockDriverState *bs, 588 const char *snapshot_id, 589 const char *name, 590 Error **errp) 591 { 592 BDRVQcow2State *s = bs->opaque; 593 QCowSnapshot sn; 594 int snapshot_index, ret; 595 596 /* Search the snapshot */ 597 snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name); 598 if (snapshot_index < 0) { 599 error_setg(errp, "Can't find the snapshot"); 600 return -ENOENT; 601 } 602 sn = s->snapshots[snapshot_index]; 603 604 /* Remove it from the snapshot list */ 605 memmove(s->snapshots + snapshot_index, 606 s->snapshots + snapshot_index + 1, 607 (s->nb_snapshots - snapshot_index - 1) * sizeof(sn)); 608 s->nb_snapshots--; 609 ret = qcow2_write_snapshots(bs); 610 if (ret < 0) { 611 error_setg_errno(errp, -ret, 612 "Failed to remove snapshot from snapshot list"); 613 return ret; 614 } 615 616 /* 617 * The snapshot is now unused, clean up. If we fail after this point, we 618 * won't recover but just leak clusters. 619 */ 620 g_free(sn.id_str); 621 g_free(sn.name); 622 623 /* 624 * Now decrease the refcounts of clusters referenced by the snapshot and 625 * free the L1 table. 626 */ 627 ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset, 628 sn.l1_size, -1); 629 if (ret < 0) { 630 error_setg_errno(errp, -ret, "Failed to free the cluster and L1 table"); 631 return ret; 632 } 633 qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t), 634 QCOW2_DISCARD_SNAPSHOT); 635 636 /* must update the copied flag on the current cluster offsets */ 637 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); 638 if (ret < 0) { 639 error_setg_errno(errp, -ret, 640 "Failed to update snapshot status in disk"); 641 return ret; 642 } 643 644 #ifdef DEBUG_ALLOC 645 { 646 BdrvCheckResult result = {0}; 647 qcow2_check_refcounts(bs, &result, 0); 648 } 649 #endif 650 return 0; 651 } 652 653 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) 654 { 655 BDRVQcow2State *s = bs->opaque; 656 QEMUSnapshotInfo *sn_tab, *sn_info; 657 QCowSnapshot *sn; 658 int i; 659 660 if (!s->nb_snapshots) { 661 *psn_tab = NULL; 662 return s->nb_snapshots; 663 } 664 665 sn_tab = g_new0(QEMUSnapshotInfo, s->nb_snapshots); 666 for(i = 0; i < s->nb_snapshots; i++) { 667 sn_info = sn_tab + i; 668 sn = s->snapshots + i; 669 pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), 670 sn->id_str); 671 pstrcpy(sn_info->name, sizeof(sn_info->name), 672 sn->name); 673 sn_info->vm_state_size = sn->vm_state_size; 674 sn_info->date_sec = sn->date_sec; 675 sn_info->date_nsec = sn->date_nsec; 676 sn_info->vm_clock_nsec = sn->vm_clock_nsec; 677 } 678 *psn_tab = sn_tab; 679 return s->nb_snapshots; 680 } 681 682 int qcow2_snapshot_load_tmp(BlockDriverState *bs, 683 const char *snapshot_id, 684 const char *name, 685 Error **errp) 686 { 687 int i, snapshot_index; 688 BDRVQcow2State *s = bs->opaque; 689 QCowSnapshot *sn; 690 uint64_t *new_l1_table; 691 int new_l1_bytes; 692 int ret; 693 694 assert(bs->read_only); 695 696 /* Search the snapshot */ 697 snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name); 698 if (snapshot_index < 0) { 699 error_setg(errp, 700 "Can't find snapshot"); 701 return -ENOENT; 702 } 703 sn = &s->snapshots[snapshot_index]; 704 705 /* Allocate and read in the snapshot's L1 table */ 706 if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) { 707 error_setg(errp, "Snapshot L1 table too large"); 708 return -EFBIG; 709 } 710 new_l1_bytes = sn->l1_size * sizeof(uint64_t); 711 new_l1_table = qemu_try_blockalign(bs->file->bs, 712 align_offset(new_l1_bytes, 512)); 713 if (new_l1_table == NULL) { 714 return -ENOMEM; 715 } 716 717 ret = bdrv_pread(bs->file->bs, sn->l1_table_offset, 718 new_l1_table, new_l1_bytes); 719 if (ret < 0) { 720 error_setg(errp, "Failed to read l1 table for snapshot"); 721 qemu_vfree(new_l1_table); 722 return ret; 723 } 724 725 /* Switch the L1 table */ 726 qemu_vfree(s->l1_table); 727 728 s->l1_size = sn->l1_size; 729 s->l1_table_offset = sn->l1_table_offset; 730 s->l1_table = new_l1_table; 731 732 for(i = 0;i < s->l1_size; i++) { 733 be64_to_cpus(&s->l1_table[i]); 734 } 735 736 return 0; 737 } 738