qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches (v2)

# gpg: Signature made Mon 14 Sep 2015 15:56:54 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (23 commits)
qcow2: Make qcow2_alloc_bytes() more explicit
vmdk: Fix next_cluster_sector for compressed write
iotests: Add test for checking large image files
qcow2: Make size_to_clusters() return uint64_t
qemu-iotests: More qcow2 reopen tests
qemu-iotests: Reopen qcow2 with lazy-refcounts change
qcow2: Support updating driver-specific options in reopen
qcow2: Make qcow2_update_options() suitable for transactions
qcow2: Fix memory leak in qcow2_update_options() error path
qcow2: Leave s unchanged on qcow2_update_options() failure
qcow2: Move rest of option handling to qcow2_update_options()
qcow2: Move qcow2_update_options() call up
qcow2: Factor out qcow2_update_options()
qcow2: Improve error message
qemu-io: Add command 'reopen'
qemu-io: Remove duplicate 'open' error message
block: Allow specifying driver-specific options to reopen
qcow2: Rename BDRVQcowState to BDRVQcow2State
block: Drop bdrv_find_whitelisted_format()
block: Drop drv parameter from bdrv_fill_options()
...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+973 -409
+80 -70
block.c
··· 85 85 static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, 86 86 const char *reference, QDict *options, int flags, 87 87 BlockDriverState *parent, 88 - const BdrvChildRole *child_role, 89 - BlockDriver *drv, Error **errp); 88 + const BdrvChildRole *child_role, Error **errp); 90 89 91 90 static void bdrv_dirty_bitmap_truncate(BlockDriverState *bs); 92 91 /* If non-zero, use only whitelisted block drivers */ ··· 312 311 } 313 312 } 314 313 return 0; 315 - } 316 - 317 - BlockDriver *bdrv_find_whitelisted_format(const char *format_name, 318 - bool read_only) 319 - { 320 - BlockDriver *drv = bdrv_find_format(format_name); 321 - return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL; 322 314 } 323 315 324 316 typedef struct CreateCo { ··· 997 989 * block driver has been specified explicitly. 998 990 */ 999 991 static int bdrv_fill_options(QDict **options, const char **pfilename, 1000 - int *flags, BlockDriver *drv, Error **errp) 992 + int *flags, Error **errp) 1001 993 { 1002 994 const char *filename = *pfilename; 1003 995 const char *drvname; 1004 996 bool protocol = *flags & BDRV_O_PROTOCOL; 1005 997 bool parse_filename = false; 1006 - BlockDriver *tmp_drv; 998 + BlockDriver *drv = NULL; 1007 999 Error *local_err = NULL; 1008 1000 1009 1001 /* Parse json: pseudo-protocol */ ··· 1022 1014 } 1023 1015 1024 1016 drvname = qdict_get_try_str(*options, "driver"); 1025 - 1026 - /* If the user has explicitly specified the driver, this choice should 1027 - * override the BDRV_O_PROTOCOL flag */ 1028 - tmp_drv = drv; 1029 - if (!tmp_drv && drvname) { 1030 - tmp_drv = bdrv_find_format(drvname); 1031 - } 1032 - if (tmp_drv) { 1033 - protocol = tmp_drv->bdrv_file_open; 1017 + if (drvname) { 1018 + drv = bdrv_find_format(drvname); 1019 + if (!drv) { 1020 + error_setg(errp, "Unknown driver '%s'", drvname); 1021 + return -ENOENT; 1022 + } 1023 + /* If the user has explicitly specified the driver, this choice should 1024 + * override the BDRV_O_PROTOCOL flag */ 1025 + protocol = drv->bdrv_file_open; 1034 1026 } 1035 1027 1036 1028 if (protocol) { ··· 1054 1046 /* Find the right block driver */ 1055 1047 filename = qdict_get_try_str(*options, "filename"); 1056 1048 1057 - if (drv) { 1058 - if (drvname) { 1059 - error_setg(errp, "Driver specified twice"); 1060 - return -EINVAL; 1061 - } 1062 - drvname = drv->format_name; 1063 - qdict_put(*options, "driver", qstring_from_str(drvname)); 1064 - } else { 1065 - if (!drvname && protocol) { 1066 - if (filename) { 1067 - drv = bdrv_find_protocol(filename, parse_filename, errp); 1068 - if (!drv) { 1069 - return -EINVAL; 1070 - } 1071 - 1072 - drvname = drv->format_name; 1073 - qdict_put(*options, "driver", qstring_from_str(drvname)); 1074 - } else { 1075 - error_setg(errp, "Must specify either driver or file"); 1049 + if (!drvname && protocol) { 1050 + if (filename) { 1051 + drv = bdrv_find_protocol(filename, parse_filename, errp); 1052 + if (!drv) { 1076 1053 return -EINVAL; 1077 1054 } 1078 - } else if (drvname) { 1079 - drv = bdrv_find_format(drvname); 1080 - if (!drv) { 1081 - error_setg(errp, "Unknown driver '%s'", drvname); 1082 - return -ENOENT; 1083 - } 1055 + 1056 + drvname = drv->format_name; 1057 + qdict_put(*options, "driver", qstring_from_str(drvname)); 1058 + } else { 1059 + error_setg(errp, "Must specify either driver or file"); 1060 + return -EINVAL; 1084 1061 } 1085 1062 } 1086 1063 ··· 1227 1204 assert(bs->backing_hd == NULL); 1228 1205 ret = bdrv_open_inherit(&backing_hd, 1229 1206 *backing_filename ? backing_filename : NULL, 1230 - NULL, options, 0, bs, &child_backing, 1231 - NULL, &local_err); 1207 + NULL, options, 0, bs, &child_backing, &local_err); 1232 1208 if (ret < 0) { 1233 1209 bdrv_unref(backing_hd); 1234 1210 backing_hd = NULL; ··· 1291 1267 1292 1268 bs = NULL; 1293 1269 ret = bdrv_open_inherit(&bs, filename, reference, image_options, 0, 1294 - parent, child_role, NULL, errp); 1270 + parent, child_role, errp); 1295 1271 if (ret < 0) { 1296 1272 goto done; 1297 1273 } ··· 1385 1361 qstring_from_str("file")); 1386 1362 qdict_put(snapshot_options, "file.filename", 1387 1363 qstring_from_str(tmp_filename)); 1364 + qdict_put(snapshot_options, "driver", 1365 + qstring_from_str("qcow2")); 1388 1366 1389 1367 bs_snapshot = bdrv_new(); 1390 1368 1391 1369 ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options, 1392 - flags, &bdrv_qcow2, &local_err); 1370 + flags, &local_err); 1393 1371 if (ret < 0) { 1394 1372 error_propagate(errp, local_err); 1395 1373 goto out; ··· 1420 1398 static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, 1421 1399 const char *reference, QDict *options, int flags, 1422 1400 BlockDriverState *parent, 1423 - const BdrvChildRole *child_role, 1424 - BlockDriver *drv, Error **errp) 1401 + const BdrvChildRole *child_role, Error **errp) 1425 1402 { 1426 1403 int ret; 1427 1404 BlockDriverState *file = NULL, *bs; 1405 + BlockDriver *drv = NULL; 1428 1406 const char *drvname; 1429 1407 Error *local_err = NULL; 1430 1408 int snapshot_flags = 0; ··· 1474 1452 flags = child_role->inherit_flags(parent->open_flags); 1475 1453 } 1476 1454 1477 - ret = bdrv_fill_options(&options, &filename, &flags, drv, &local_err); 1455 + ret = bdrv_fill_options(&options, &filename, &flags, &local_err); 1478 1456 if (local_err) { 1479 1457 goto fail; 1480 1458 } 1481 1459 1482 1460 /* Find the right image format driver */ 1483 - drv = NULL; 1484 1461 drvname = qdict_get_try_str(options, "driver"); 1485 1462 if (drvname) { 1486 1463 drv = bdrv_find_format(drvname); ··· 1635 1612 } 1636 1613 1637 1614 int bdrv_open(BlockDriverState **pbs, const char *filename, 1638 - const char *reference, QDict *options, int flags, 1639 - BlockDriver *drv, Error **errp) 1615 + const char *reference, QDict *options, int flags, Error **errp) 1640 1616 { 1641 1617 return bdrv_open_inherit(pbs, filename, reference, options, flags, NULL, 1642 - NULL, drv, errp); 1618 + NULL, errp); 1643 1619 } 1644 1620 1645 1621 typedef struct BlockReopenQueueEntry { ··· 1659 1635 * atomic 'set'. 1660 1636 * 1661 1637 * bs is the BlockDriverState to add to the reopen queue. 1638 + * 1639 + * options contains the changed options for the associated bs 1640 + * (the BlockReopenQueue takes ownership) 1662 1641 * 1663 1642 * flags contains the open flags for the associated bs 1664 1643 * ··· 1667 1646 * 1668 1647 */ 1669 1648 BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, 1670 - BlockDriverState *bs, int flags) 1649 + BlockDriverState *bs, 1650 + QDict *options, int flags) 1671 1651 { 1672 1652 assert(bs != NULL); 1673 1653 1674 1654 BlockReopenQueueEntry *bs_entry; 1675 1655 BdrvChild *child; 1656 + QDict *old_options; 1676 1657 1677 1658 if (bs_queue == NULL) { 1678 1659 bs_queue = g_new0(BlockReopenQueue, 1); 1679 1660 QSIMPLEQ_INIT(bs_queue); 1680 1661 } 1681 1662 1663 + if (!options) { 1664 + options = qdict_new(); 1665 + } 1666 + 1667 + old_options = qdict_clone_shallow(bs->options); 1668 + qdict_join(options, old_options, false); 1669 + QDECREF(old_options); 1670 + 1682 1671 /* bdrv_open() masks this flag out */ 1683 1672 flags &= ~BDRV_O_PROTOCOL; 1684 1673 ··· 1690 1679 } 1691 1680 1692 1681 child_flags = child->role->inherit_flags(flags); 1693 - bdrv_reopen_queue(bs_queue, child->bs, child_flags); 1682 + /* TODO Pass down child flags (backing.*, extents.*, ...) */ 1683 + bdrv_reopen_queue(bs_queue, child->bs, NULL, child_flags); 1694 1684 } 1695 1685 1696 1686 bs_entry = g_new0(BlockReopenQueueEntry, 1); 1697 1687 QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry); 1698 1688 1699 1689 bs_entry->state.bs = bs; 1690 + bs_entry->state.options = options; 1700 1691 bs_entry->state.flags = flags; 1701 1692 1702 1693 return bs_queue; ··· 1749 1740 if (ret && bs_entry->prepared) { 1750 1741 bdrv_reopen_abort(&bs_entry->state); 1751 1742 } 1743 + QDECREF(bs_entry->state.options); 1752 1744 g_free(bs_entry); 1753 1745 } 1754 1746 g_free(bs_queue); ··· 1761 1753 { 1762 1754 int ret = -1; 1763 1755 Error *local_err = NULL; 1764 - BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, bdrv_flags); 1756 + BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, NULL, bdrv_flags); 1765 1757 1766 1758 ret = bdrv_reopen_multiple(queue, &local_err); 1767 1759 if (local_err != NULL) { ··· 1835 1827 bdrv_get_device_or_node_name(reopen_state->bs)); 1836 1828 ret = -1; 1837 1829 goto error; 1830 + } 1831 + 1832 + /* Options that are not handled are only okay if they are unchanged 1833 + * compared to the old state. It is expected that some options are only 1834 + * used for the initial open, but not reopen (e.g. filename) */ 1835 + if (qdict_size(reopen_state->options)) { 1836 + const QDictEntry *entry = qdict_first(reopen_state->options); 1837 + 1838 + do { 1839 + QString *new_obj = qobject_to_qstring(entry->value); 1840 + const char *new = qstring_get_str(new_obj); 1841 + const char *old = qdict_get_try_str(reopen_state->bs->options, 1842 + entry->key); 1843 + 1844 + if (!old || strcmp(new, old)) { 1845 + error_setg(errp, "Cannot change the option '%s'", entry->key); 1846 + ret = -EINVAL; 1847 + goto error; 1848 + } 1849 + } while ((entry = qdict_next(reopen_state->options, entry))); 1838 1850 } 1839 1851 1840 1852 ret = 0; ··· 3739 3751 const char *backing_fmt, *backing_file; 3740 3752 int64_t size; 3741 3753 BlockDriver *drv, *proto_drv; 3742 - BlockDriver *backing_drv = NULL; 3743 3754 Error *local_err = NULL; 3744 3755 int ret = 0; 3745 3756 ··· 3813 3824 } 3814 3825 3815 3826 backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT); 3816 - if (backing_fmt) { 3817 - backing_drv = bdrv_find_format(backing_fmt); 3818 - if (!backing_drv) { 3819 - error_setg(errp, "Unknown backing file format '%s'", 3820 - backing_fmt); 3821 - goto out; 3822 - } 3823 - } 3824 3827 3825 3828 // The size for the image must always be specified, with one exception: 3826 3829 // If we are using a backing file, we can obtain the size from there ··· 3831 3834 char *full_backing = g_new0(char, PATH_MAX); 3832 3835 int64_t size; 3833 3836 int back_flags; 3837 + QDict *backing_options = NULL; 3834 3838 3835 3839 bdrv_get_full_backing_filename_from_filename(filename, backing_file, 3836 3840 full_backing, PATH_MAX, ··· 3844 3848 back_flags = 3845 3849 flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); 3846 3850 3851 + if (backing_fmt) { 3852 + backing_options = qdict_new(); 3853 + qdict_put(backing_options, "driver", 3854 + qstring_from_str(backing_fmt)); 3855 + } 3856 + 3847 3857 bs = NULL; 3848 - ret = bdrv_open(&bs, full_backing, NULL, NULL, back_flags, 3849 - backing_drv, &local_err); 3858 + ret = bdrv_open(&bs, full_backing, NULL, backing_options, 3859 + back_flags, &local_err); 3850 3860 g_free(full_backing); 3851 3861 if (ret < 0) { 3852 3862 goto out;
+1 -1
block/block-backend.c
··· 126 126 return NULL; 127 127 } 128 128 129 - ret = bdrv_open(&blk->bs, filename, reference, options, flags, NULL, errp); 129 + ret = bdrv_open(&blk->bs, filename, reference, options, flags, errp); 130 130 if (ret < 0) { 131 131 blk_unref(blk); 132 132 return NULL;
+2 -2
block/commit.c
··· 236 236 237 237 /* convert base & overlay_bs to r/w, if necessary */ 238 238 if (!(orig_base_flags & BDRV_O_RDWR)) { 239 - reopen_queue = bdrv_reopen_queue(reopen_queue, base, 239 + reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL, 240 240 orig_base_flags | BDRV_O_RDWR); 241 241 } 242 242 if (!(orig_overlay_flags & BDRV_O_RDWR)) { 243 - reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, 243 + reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL, 244 244 orig_overlay_flags | BDRV_O_RDWR); 245 245 } 246 246 if (reopen_queue) {
+1 -1
block/parallels.c
··· 476 476 477 477 file = NULL; 478 478 ret = bdrv_open(&file, filename, NULL, NULL, 479 - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); 479 + BDRV_O_RDWR | BDRV_O_PROTOCOL, &local_err); 480 480 if (ret < 0) { 481 481 error_propagate(errp, local_err); 482 482 return ret;
+1 -1
block/qcow.c
··· 793 793 794 794 qcow_bs = NULL; 795 795 ret = bdrv_open(&qcow_bs, filename, NULL, NULL, 796 - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); 796 + BDRV_O_RDWR | BDRV_O_PROTOCOL, &local_err); 797 797 if (ret < 0) { 798 798 error_propagate(errp, local_err); 799 799 goto cleanup;
+7 -7
block/qcow2-cache.c
··· 55 55 static inline void *qcow2_cache_get_table_addr(BlockDriverState *bs, 56 56 Qcow2Cache *c, int table) 57 57 { 58 - BDRVQcowState *s = bs->opaque; 58 + BDRVQcow2State *s = bs->opaque; 59 59 return (uint8_t *) c->table_array + (size_t) table * s->cluster_size; 60 60 } 61 61 62 62 static inline int qcow2_cache_get_table_idx(BlockDriverState *bs, 63 63 Qcow2Cache *c, void *table) 64 64 { 65 - BDRVQcowState *s = bs->opaque; 65 + BDRVQcow2State *s = bs->opaque; 66 66 ptrdiff_t table_offset = (uint8_t *) table - (uint8_t *) c->table_array; 67 67 int idx = table_offset / s->cluster_size; 68 68 assert(idx >= 0 && idx < c->size && table_offset % s->cluster_size == 0); ··· 73 73 int i, int num_tables) 74 74 { 75 75 #if QEMU_MADV_DONTNEED != QEMU_MADV_INVALID 76 - BDRVQcowState *s = bs->opaque; 76 + BDRVQcow2State *s = bs->opaque; 77 77 void *t = qcow2_cache_get_table_addr(bs, c, i); 78 78 int align = getpagesize(); 79 79 size_t mem_size = (size_t) s->cluster_size * num_tables; ··· 121 121 122 122 Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables) 123 123 { 124 - BDRVQcowState *s = bs->opaque; 124 + BDRVQcow2State *s = bs->opaque; 125 125 Qcow2Cache *c; 126 126 127 127 c = g_new0(Qcow2Cache, 1); ··· 172 172 173 173 static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) 174 174 { 175 - BDRVQcowState *s = bs->opaque; 175 + BDRVQcow2State *s = bs->opaque; 176 176 int ret = 0; 177 177 178 178 if (!c->entries[i].dirty || !c->entries[i].offset) { ··· 229 229 230 230 int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) 231 231 { 232 - BDRVQcowState *s = bs->opaque; 232 + BDRVQcow2State *s = bs->opaque; 233 233 int result = 0; 234 234 int ret; 235 235 int i; ··· 306 306 static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c, 307 307 uint64_t offset, void **table, bool read_from_disk) 308 308 { 309 - BDRVQcowState *s = bs->opaque; 309 + BDRVQcow2State *s = bs->opaque; 310 310 int i; 311 311 int ret; 312 312 int lookup_index;
+42 -34
block/qcow2-cluster.c
··· 32 32 int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, 33 33 bool exact_size) 34 34 { 35 - BDRVQcowState *s = bs->opaque; 35 + BDRVQcow2State *s = bs->opaque; 36 36 int new_l1_size2, ret, i; 37 37 uint64_t *new_l1_table; 38 38 int64_t old_l1_table_offset, old_l1_size; ··· 148 148 static int l2_load(BlockDriverState *bs, uint64_t l2_offset, 149 149 uint64_t **l2_table) 150 150 { 151 - BDRVQcowState *s = bs->opaque; 151 + BDRVQcow2State *s = bs->opaque; 152 152 int ret; 153 153 154 154 ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table); ··· 163 163 #define L1_ENTRIES_PER_SECTOR (512 / 8) 164 164 int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index) 165 165 { 166 - BDRVQcowState *s = bs->opaque; 166 + BDRVQcow2State *s = bs->opaque; 167 167 uint64_t buf[L1_ENTRIES_PER_SECTOR] = { 0 }; 168 168 int l1_start_index; 169 169 int i, ret; ··· 203 203 204 204 static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table) 205 205 { 206 - BDRVQcowState *s = bs->opaque; 206 + BDRVQcow2State *s = bs->opaque; 207 207 uint64_t old_l2_offset; 208 208 uint64_t *l2_table = NULL; 209 209 int64_t l2_offset; ··· 298 298 * as contiguous. (This allows it, for example, to stop at the first compressed 299 299 * cluster which may require a different handling) 300 300 */ 301 - static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size, 301 + static int count_contiguous_clusters(int nb_clusters, int cluster_size, 302 302 uint64_t *l2_table, uint64_t stop_flags) 303 303 { 304 304 int i; ··· 321 321 return i; 322 322 } 323 323 324 - static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table) 324 + static int count_contiguous_free_clusters(int nb_clusters, uint64_t *l2_table) 325 325 { 326 326 int i; 327 327 ··· 339 339 /* The crypt function is compatible with the linux cryptoloop 340 340 algorithm for < 4 GB images. NOTE: out_buf == in_buf is 341 341 supported */ 342 - int qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num, 342 + int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, 343 343 uint8_t *out_buf, const uint8_t *in_buf, 344 344 int nb_sectors, bool enc, 345 345 Error **errp) ··· 387 387 uint64_t cluster_offset, 388 388 int n_start, int n_end) 389 389 { 390 - BDRVQcowState *s = bs->opaque; 390 + BDRVQcow2State *s = bs->opaque; 391 391 QEMUIOVector qiov; 392 392 struct iovec iov; 393 393 int n, ret; ··· 469 469 int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, 470 470 int *num, uint64_t *cluster_offset) 471 471 { 472 - BDRVQcowState *s = bs->opaque; 472 + BDRVQcow2State *s = bs->opaque; 473 473 unsigned int l2_index; 474 474 uint64_t l1_index, l2_offset, *l2_table; 475 475 int l1_bits, c; ··· 495 495 if (nb_needed > nb_available) { 496 496 nb_needed = nb_available; 497 497 } 498 + assert(nb_needed <= INT_MAX); 498 499 499 500 *cluster_offset = 0; 500 501 ··· 530 531 531 532 l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); 532 533 *cluster_offset = be64_to_cpu(l2_table[l2_index]); 534 + 535 + /* nb_needed <= INT_MAX, thus nb_clusters <= INT_MAX, too */ 533 536 nb_clusters = size_to_clusters(s, nb_needed << 9); 534 537 535 538 ret = qcow2_get_cluster_type(*cluster_offset); ··· 606 609 uint64_t **new_l2_table, 607 610 int *new_l2_index) 608 611 { 609 - BDRVQcowState *s = bs->opaque; 612 + BDRVQcow2State *s = bs->opaque; 610 613 unsigned int l2_index; 611 614 uint64_t l1_index, l2_offset; 612 615 uint64_t *l2_table = NULL; ··· 680 683 uint64_t offset, 681 684 int compressed_size) 682 685 { 683 - BDRVQcowState *s = bs->opaque; 686 + BDRVQcow2State *s = bs->opaque; 684 687 int l2_index, ret; 685 688 uint64_t *l2_table; 686 689 int64_t cluster_offset; ··· 725 728 726 729 static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r) 727 730 { 728 - BDRVQcowState *s = bs->opaque; 731 + BDRVQcow2State *s = bs->opaque; 729 732 int ret; 730 733 731 734 if (r->nb_sectors == 0) { ··· 754 757 755 758 int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) 756 759 { 757 - BDRVQcowState *s = bs->opaque; 760 + BDRVQcow2State *s = bs->opaque; 758 761 int i, j = 0, l2_index, ret; 759 762 uint64_t *old_cluster, *l2_table; 760 763 uint64_t cluster_offset = m->alloc_offset; ··· 837 840 * write, but require COW to be performed (this includes yet unallocated space, 838 841 * which must copy from the backing file) 839 842 */ 840 - static int count_cow_clusters(BDRVQcowState *s, int nb_clusters, 843 + static int count_cow_clusters(BDRVQcow2State *s, int nb_clusters, 841 844 uint64_t *l2_table, int l2_index) 842 845 { 843 846 int i; ··· 883 886 static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset, 884 887 uint64_t *cur_bytes, QCowL2Meta **m) 885 888 { 886 - BDRVQcowState *s = bs->opaque; 889 + BDRVQcow2State *s = bs->opaque; 887 890 QCowL2Meta *old_alloc; 888 891 uint64_t bytes = *cur_bytes; 889 892 ··· 956 959 static int handle_copied(BlockDriverState *bs, uint64_t guest_offset, 957 960 uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) 958 961 { 959 - BDRVQcowState *s = bs->opaque; 962 + BDRVQcow2State *s = bs->opaque; 960 963 int l2_index; 961 964 uint64_t cluster_offset; 962 965 uint64_t *l2_table; 963 - unsigned int nb_clusters; 966 + uint64_t nb_clusters; 964 967 unsigned int keep_clusters; 965 968 int ret; 966 969 ··· 979 982 980 983 l2_index = offset_to_l2_index(s, guest_offset); 981 984 nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); 985 + assert(nb_clusters <= INT_MAX); 982 986 983 987 /* Find L2 entry for the first involved cluster */ 984 988 ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); ··· 1061 1065 * restarted, but the whole request should not be failed. 1062 1066 */ 1063 1067 static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, 1064 - uint64_t *host_offset, unsigned int *nb_clusters) 1068 + uint64_t *host_offset, uint64_t *nb_clusters) 1065 1069 { 1066 - BDRVQcowState *s = bs->opaque; 1070 + BDRVQcow2State *s = bs->opaque; 1067 1071 1068 1072 trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset, 1069 1073 *host_offset, *nb_clusters); ··· 1079 1083 *host_offset = cluster_offset; 1080 1084 return 0; 1081 1085 } else { 1082 - int ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters); 1086 + int64_t ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters); 1083 1087 if (ret < 0) { 1084 1088 return ret; 1085 1089 } ··· 1111 1115 static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, 1112 1116 uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) 1113 1117 { 1114 - BDRVQcowState *s = bs->opaque; 1118 + BDRVQcow2State *s = bs->opaque; 1115 1119 int l2_index; 1116 1120 uint64_t *l2_table; 1117 1121 uint64_t entry; 1118 - unsigned int nb_clusters; 1122 + uint64_t nb_clusters; 1119 1123 int ret; 1120 1124 1121 1125 uint64_t alloc_cluster_offset; ··· 1133 1137 1134 1138 l2_index = offset_to_l2_index(s, guest_offset); 1135 1139 nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); 1140 + assert(nb_clusters <= INT_MAX); 1136 1141 1137 1142 /* Find L2 entry for the first involved cluster */ 1138 1143 ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); ··· 1263 1268 int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, 1264 1269 int *num, uint64_t *host_offset, QCowL2Meta **m) 1265 1270 { 1266 - BDRVQcowState *s = bs->opaque; 1271 + BDRVQcow2State *s = bs->opaque; 1267 1272 uint64_t start, remaining; 1268 1273 uint64_t cluster_offset; 1269 1274 uint64_t cur_bytes; ··· 1397 1402 1398 1403 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) 1399 1404 { 1400 - BDRVQcowState *s = bs->opaque; 1405 + BDRVQcow2State *s = bs->opaque; 1401 1406 int ret, csize, nb_csectors, sector_offset; 1402 1407 uint64_t coffset; 1403 1408 ··· 1426 1431 * clusters. 1427 1432 */ 1428 1433 static int discard_single_l2(BlockDriverState *bs, uint64_t offset, 1429 - unsigned int nb_clusters, enum qcow2_discard_type type, bool full_discard) 1434 + uint64_t nb_clusters, enum qcow2_discard_type type, 1435 + bool full_discard) 1430 1436 { 1431 - BDRVQcowState *s = bs->opaque; 1437 + BDRVQcow2State *s = bs->opaque; 1432 1438 uint64_t *l2_table; 1433 1439 int l2_index; 1434 1440 int ret; ··· 1441 1447 1442 1448 /* Limit nb_clusters to one L2 table */ 1443 1449 nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); 1450 + assert(nb_clusters <= INT_MAX); 1444 1451 1445 1452 for (i = 0; i < nb_clusters; i++) { 1446 1453 uint64_t old_l2_entry; ··· 1501 1508 int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, 1502 1509 int nb_sectors, enum qcow2_discard_type type, bool full_discard) 1503 1510 { 1504 - BDRVQcowState *s = bs->opaque; 1511 + BDRVQcow2State *s = bs->opaque; 1505 1512 uint64_t end_offset; 1506 - unsigned int nb_clusters; 1513 + uint64_t nb_clusters; 1507 1514 int ret; 1508 1515 1509 1516 end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS); ··· 1545 1552 * clusters. 1546 1553 */ 1547 1554 static int zero_single_l2(BlockDriverState *bs, uint64_t offset, 1548 - unsigned int nb_clusters) 1555 + uint64_t nb_clusters) 1549 1556 { 1550 - BDRVQcowState *s = bs->opaque; 1557 + BDRVQcow2State *s = bs->opaque; 1551 1558 uint64_t *l2_table; 1552 1559 int l2_index; 1553 1560 int ret; ··· 1560 1567 1561 1568 /* Limit nb_clusters to one L2 table */ 1562 1569 nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); 1570 + assert(nb_clusters <= INT_MAX); 1563 1571 1564 1572 for (i = 0; i < nb_clusters; i++) { 1565 1573 uint64_t old_offset; ··· 1583 1591 1584 1592 int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors) 1585 1593 { 1586 - BDRVQcowState *s = bs->opaque; 1587 - unsigned int nb_clusters; 1594 + BDRVQcow2State *s = bs->opaque; 1595 + uint64_t nb_clusters; 1588 1596 int ret; 1589 1597 1590 1598 /* The zero flag is only supported by version 3 and newer */ ··· 1628 1636 int64_t l1_entries, 1629 1637 BlockDriverAmendStatusCB *status_cb) 1630 1638 { 1631 - BDRVQcowState *s = bs->opaque; 1639 + BDRVQcow2State *s = bs->opaque; 1632 1640 bool is_active_l1 = (l1_table == s->l1_table); 1633 1641 uint64_t *l2_table = NULL; 1634 1642 int ret; ··· 1815 1823 int qcow2_expand_zero_clusters(BlockDriverState *bs, 1816 1824 BlockDriverAmendStatusCB *status_cb) 1817 1825 { 1818 - BDRVQcowState *s = bs->opaque; 1826 + BDRVQcow2State *s = bs->opaque; 1819 1827 uint64_t *l1_table = NULL; 1820 1828 int64_t l1_entries = 0, visited_l1_entries = 0; 1821 1829 int ret;
+43 -33
block/qcow2-refcount.c
··· 82 82 83 83 int qcow2_refcount_init(BlockDriverState *bs) 84 84 { 85 - BDRVQcowState *s = bs->opaque; 85 + BDRVQcow2State *s = bs->opaque; 86 86 unsigned int refcount_table_size2, i; 87 87 int ret; 88 88 ··· 116 116 117 117 void qcow2_refcount_close(BlockDriverState *bs) 118 118 { 119 - BDRVQcowState *s = bs->opaque; 119 + BDRVQcow2State *s = bs->opaque; 120 120 g_free(s->refcount_table); 121 121 } 122 122 ··· 214 214 int64_t refcount_block_offset, 215 215 void **refcount_block) 216 216 { 217 - BDRVQcowState *s = bs->opaque; 217 + BDRVQcow2State *s = bs->opaque; 218 218 int ret; 219 219 220 220 BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD); ··· 231 231 int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, 232 232 uint64_t *refcount) 233 233 { 234 - BDRVQcowState *s = bs->opaque; 234 + BDRVQcow2State *s = bs->opaque; 235 235 uint64_t refcount_table_index, block_index; 236 236 int64_t refcount_block_offset; 237 237 int ret; ··· 274 274 * Rounds the refcount table size up to avoid growing the table for each single 275 275 * refcount block that is allocated. 276 276 */ 277 - static unsigned int next_refcount_table_size(BDRVQcowState *s, 277 + static unsigned int next_refcount_table_size(BDRVQcow2State *s, 278 278 unsigned int min_size) 279 279 { 280 280 unsigned int min_clusters = (min_size >> (s->cluster_bits - 3)) + 1; ··· 290 290 291 291 292 292 /* Checks if two offsets are described by the same refcount block */ 293 - static int in_same_refcount_block(BDRVQcowState *s, uint64_t offset_a, 293 + static int in_same_refcount_block(BDRVQcow2State *s, uint64_t offset_a, 294 294 uint64_t offset_b) 295 295 { 296 296 uint64_t block_a = offset_a >> (s->cluster_bits + s->refcount_block_bits); ··· 308 308 static int alloc_refcount_block(BlockDriverState *bs, 309 309 int64_t cluster_index, void **refcount_block) 310 310 { 311 - BDRVQcowState *s = bs->opaque; 311 + BDRVQcow2State *s = bs->opaque; 312 312 unsigned int refcount_table_index; 313 313 int ret; 314 314 ··· 605 605 606 606 void qcow2_process_discards(BlockDriverState *bs, int ret) 607 607 { 608 - BDRVQcowState *s = bs->opaque; 608 + BDRVQcow2State *s = bs->opaque; 609 609 Qcow2DiscardRegion *d, *next; 610 610 611 611 QTAILQ_FOREACH_SAFE(d, &s->discards, next, next) { ··· 625 625 static void update_refcount_discard(BlockDriverState *bs, 626 626 uint64_t offset, uint64_t length) 627 627 { 628 - BDRVQcowState *s = bs->opaque; 628 + BDRVQcow2State *s = bs->opaque; 629 629 Qcow2DiscardRegion *d, *p, *next; 630 630 631 631 QTAILQ_FOREACH(d, &s->discards, next) { ··· 682 682 bool decrease, 683 683 enum qcow2_discard_type type) 684 684 { 685 - BDRVQcowState *s = bs->opaque; 685 + BDRVQcow2State *s = bs->opaque; 686 686 int64_t start, last, cluster_offset; 687 687 void *refcount_block = NULL; 688 688 int64_t old_table_index = -1; ··· 793 793 uint64_t addend, bool decrease, 794 794 enum qcow2_discard_type type) 795 795 { 796 - BDRVQcowState *s = bs->opaque; 796 + BDRVQcow2State *s = bs->opaque; 797 797 int ret; 798 798 799 799 ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend, ··· 815 815 /* return < 0 if error */ 816 816 static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size) 817 817 { 818 - BDRVQcowState *s = bs->opaque; 818 + BDRVQcow2State *s = bs->opaque; 819 819 uint64_t i, nb_clusters, refcount; 820 820 int ret; 821 821 ··· 875 875 return offset; 876 876 } 877 877 878 - int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, 879 - int nb_clusters) 878 + int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, 879 + int64_t nb_clusters) 880 880 { 881 - BDRVQcowState *s = bs->opaque; 881 + BDRVQcow2State *s = bs->opaque; 882 882 uint64_t cluster_index, refcount; 883 883 uint64_t i; 884 884 int ret; ··· 916 916 contiguous sectors. size must be <= cluster_size */ 917 917 int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size) 918 918 { 919 - BDRVQcowState *s = bs->opaque; 919 + BDRVQcow2State *s = bs->opaque; 920 920 int64_t offset; 921 921 size_t free_in_cluster; 922 922 int ret; ··· 949 949 950 950 if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) { 951 951 offset = new_cluster; 952 + free_in_cluster = s->cluster_size; 953 + } else { 954 + free_in_cluster += s->cluster_size; 952 955 } 953 956 } 954 957 955 958 assert(offset); 956 959 ret = update_refcount(bs, offset, size, 1, false, QCOW2_DISCARD_NEVER); 960 + if (ret < 0) { 961 + offset = 0; 962 + } 957 963 } while (ret == -EAGAIN); 958 964 if (ret < 0) { 959 965 return ret; ··· 992 998 void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry, 993 999 int nb_clusters, enum qcow2_discard_type type) 994 1000 { 995 - BDRVQcowState *s = bs->opaque; 1001 + BDRVQcow2State *s = bs->opaque; 996 1002 997 1003 switch (qcow2_get_cluster_type(l2_entry)) { 998 1004 case QCOW2_CLUSTER_COMPRESSED: ··· 1036 1042 int qcow2_update_snapshot_refcount(BlockDriverState *bs, 1037 1043 int64_t l1_table_offset, int l1_size, int addend) 1038 1044 { 1039 - BDRVQcowState *s = bs->opaque; 1045 + BDRVQcow2State *s = bs->opaque; 1040 1046 uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, refcount; 1041 1047 bool l1_allocated = false; 1042 1048 int64_t old_offset, old_l2_offset; ··· 1233 1239 /* refcount checking functions */ 1234 1240 1235 1241 1236 - static size_t refcount_array_byte_size(BDRVQcowState *s, uint64_t entries) 1242 + static size_t refcount_array_byte_size(BDRVQcow2State *s, uint64_t entries) 1237 1243 { 1238 1244 /* This assertion holds because there is no way we can address more than 1239 1245 * 2^(64 - 9) clusters at once (with cluster size 512 = 2^9, and because ··· 1256 1262 * refcount array buffer will be aligned to a cluster boundary, and the newly 1257 1263 * allocated area will be zeroed. 1258 1264 */ 1259 - static int realloc_refcount_array(BDRVQcowState *s, void **array, 1265 + static int realloc_refcount_array(BDRVQcow2State *s, void **array, 1260 1266 int64_t *size, int64_t new_size) 1261 1267 { 1262 - size_t old_byte_size, new_byte_size; 1268 + int64_t old_byte_size, new_byte_size; 1263 1269 void *new_ptr; 1264 1270 1265 1271 /* Round to clusters so the array can be directly written to disk */ ··· 1275 1281 1276 1282 assert(new_byte_size > 0); 1277 1283 1284 + if (new_byte_size > SIZE_MAX) { 1285 + return -ENOMEM; 1286 + } 1287 + 1278 1288 new_ptr = g_try_realloc(*array, new_byte_size); 1279 1289 if (!new_ptr) { 1280 1290 return -ENOMEM; 1281 1291 } 1282 1292 1283 1293 if (new_byte_size > old_byte_size) { 1284 - memset((void *)((uintptr_t)new_ptr + old_byte_size), 0, 1294 + memset((char *)new_ptr + old_byte_size, 0, 1285 1295 new_byte_size - old_byte_size); 1286 1296 } 1287 1297 ··· 1304 1314 int64_t *refcount_table_size, 1305 1315 int64_t offset, int64_t size) 1306 1316 { 1307 - BDRVQcowState *s = bs->opaque; 1317 + BDRVQcow2State *s = bs->opaque; 1308 1318 uint64_t start, last, cluster_offset, k, refcount; 1309 1319 int ret; 1310 1320 ··· 1357 1367 int64_t *refcount_table_size, int64_t l2_offset, 1358 1368 int flags) 1359 1369 { 1360 - BDRVQcowState *s = bs->opaque; 1370 + BDRVQcow2State *s = bs->opaque; 1361 1371 uint64_t *l2_table, l2_entry; 1362 1372 uint64_t next_contiguous_offset = 0; 1363 1373 int i, l2_size, nb_csectors, ret; ··· 1477 1487 int64_t l1_table_offset, int l1_size, 1478 1488 int flags) 1479 1489 { 1480 - BDRVQcowState *s = bs->opaque; 1490 + BDRVQcow2State *s = bs->opaque; 1481 1491 uint64_t *l1_table = NULL, l2_offset, l1_size2; 1482 1492 int i, ret; 1483 1493 ··· 1554 1564 static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, 1555 1565 BdrvCheckMode fix) 1556 1566 { 1557 - BDRVQcowState *s = bs->opaque; 1567 + BDRVQcow2State *s = bs->opaque; 1558 1568 uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size); 1559 1569 int ret; 1560 1570 uint64_t refcount; ··· 1673 1683 BdrvCheckMode fix, bool *rebuild, 1674 1684 void **refcount_table, int64_t *nb_clusters) 1675 1685 { 1676 - BDRVQcowState *s = bs->opaque; 1686 + BDRVQcow2State *s = bs->opaque; 1677 1687 int64_t i, size; 1678 1688 int ret; 1679 1689 ··· 1776 1786 BdrvCheckMode fix, bool *rebuild, 1777 1787 void **refcount_table, int64_t *nb_clusters) 1778 1788 { 1779 - BDRVQcowState *s = bs->opaque; 1789 + BDRVQcow2State *s = bs->opaque; 1780 1790 int64_t i; 1781 1791 QCowSnapshot *sn; 1782 1792 int ret; ··· 1840 1850 int64_t *highest_cluster, 1841 1851 void *refcount_table, int64_t nb_clusters) 1842 1852 { 1843 - BDRVQcowState *s = bs->opaque; 1853 + BDRVQcow2State *s = bs->opaque; 1844 1854 int64_t i; 1845 1855 uint64_t refcount1, refcount2; 1846 1856 int ret; ··· 1917 1927 int64_t *imrt_nb_clusters, 1918 1928 int64_t *first_free_cluster) 1919 1929 { 1920 - BDRVQcowState *s = bs->opaque; 1930 + BDRVQcow2State *s = bs->opaque; 1921 1931 int64_t cluster = *first_free_cluster, i; 1922 1932 bool first_gap = true; 1923 1933 int contiguous_free_clusters; ··· 1987 1997 void **refcount_table, 1988 1998 int64_t *nb_clusters) 1989 1999 { 1990 - BDRVQcowState *s = bs->opaque; 2000 + BDRVQcow2State *s = bs->opaque; 1991 2001 int64_t first_free_cluster = 0, reftable_offset = -1, cluster = 0; 1992 2002 int64_t refblock_offset, refblock_start, refblock_index; 1993 2003 uint32_t reftable_size = 0; ··· 2174 2184 int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res, 2175 2185 BdrvCheckMode fix) 2176 2186 { 2177 - BDRVQcowState *s = bs->opaque; 2187 + BDRVQcow2State *s = bs->opaque; 2178 2188 BdrvCheckResult pre_compare_res; 2179 2189 int64_t size, highest_cluster, nb_clusters; 2180 2190 void *refcount_table = NULL; ··· 2311 2321 int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset, 2312 2322 int64_t size) 2313 2323 { 2314 - BDRVQcowState *s = bs->opaque; 2324 + BDRVQcow2State *s = bs->opaque; 2315 2325 int chk = s->overlap_check & ~ign; 2316 2326 int i, j; 2317 2327
+10 -10
block/qcow2-snapshot.c
··· 29 29 30 30 void qcow2_free_snapshots(BlockDriverState *bs) 31 31 { 32 - BDRVQcowState *s = bs->opaque; 32 + BDRVQcow2State *s = bs->opaque; 33 33 int i; 34 34 35 35 for(i = 0; i < s->nb_snapshots; i++) { ··· 43 43 44 44 int qcow2_read_snapshots(BlockDriverState *bs) 45 45 { 46 - BDRVQcowState *s = bs->opaque; 46 + BDRVQcow2State *s = bs->opaque; 47 47 QCowSnapshotHeader h; 48 48 QCowSnapshotExtraData extra; 49 49 QCowSnapshot *sn; ··· 136 136 /* add at the end of the file a new list of snapshots */ 137 137 static int qcow2_write_snapshots(BlockDriverState *bs) 138 138 { 139 - BDRVQcowState *s = bs->opaque; 139 + BDRVQcow2State *s = bs->opaque; 140 140 QCowSnapshot *sn; 141 141 QCowSnapshotHeader h; 142 142 QCowSnapshotExtraData extra; ··· 278 278 static void find_new_snapshot_id(BlockDriverState *bs, 279 279 char *id_str, int id_str_size) 280 280 { 281 - BDRVQcowState *s = bs->opaque; 281 + BDRVQcow2State *s = bs->opaque; 282 282 QCowSnapshot *sn; 283 283 int i; 284 284 unsigned long id, id_max = 0; ··· 296 296 const char *id, 297 297 const char *name) 298 298 { 299 - BDRVQcowState *s = bs->opaque; 299 + BDRVQcow2State *s = bs->opaque; 300 300 int i; 301 301 302 302 if (id && name) { ··· 338 338 /* if no id is provided, a new one is constructed */ 339 339 int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) 340 340 { 341 - BDRVQcowState *s = bs->opaque; 341 + BDRVQcow2State *s = bs->opaque; 342 342 QCowSnapshot *new_snapshot_list = NULL; 343 343 QCowSnapshot *old_snapshot_list = NULL; 344 344 QCowSnapshot sn1, *sn = &sn1; ··· 461 461 /* copy the snapshot 'snapshot_name' into the current disk image */ 462 462 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) 463 463 { 464 - BDRVQcowState *s = bs->opaque; 464 + BDRVQcow2State *s = bs->opaque; 465 465 QCowSnapshot *sn; 466 466 int i, snapshot_index; 467 467 int cur_l1_bytes, sn_l1_bytes; ··· 587 587 const char *name, 588 588 Error **errp) 589 589 { 590 - BDRVQcowState *s = bs->opaque; 590 + BDRVQcow2State *s = bs->opaque; 591 591 QCowSnapshot sn; 592 592 int snapshot_index, ret; 593 593 ··· 650 650 651 651 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) 652 652 { 653 - BDRVQcowState *s = bs->opaque; 653 + BDRVQcow2State *s = bs->opaque; 654 654 QEMUSnapshotInfo *sn_tab, *sn_info; 655 655 QCowSnapshot *sn; 656 656 int i; ··· 683 683 Error **errp) 684 684 { 685 685 int i, snapshot_index; 686 - BDRVQcowState *s = bs->opaque; 686 + BDRVQcow2State *s = bs->opaque; 687 687 QCowSnapshot *sn; 688 688 uint64_t *new_l1_table; 689 689 int new_l1_bytes;
+314 -172
block/qcow2.c
··· 85 85 uint64_t end_offset, void **p_feature_table, 86 86 Error **errp) 87 87 { 88 - BDRVQcowState *s = bs->opaque; 88 + BDRVQcow2State *s = bs->opaque; 89 89 QCowExtension ext; 90 90 uint64_t offset; 91 91 int ret; ··· 187 187 188 188 static void cleanup_unknown_header_ext(BlockDriverState *bs) 189 189 { 190 - BDRVQcowState *s = bs->opaque; 190 + BDRVQcow2State *s = bs->opaque; 191 191 Qcow2UnknownHeaderExtension *uext, *next; 192 192 193 193 QLIST_FOREACH_SAFE(uext, &s->unknown_header_ext, next, next) { ··· 249 249 */ 250 250 int qcow2_mark_dirty(BlockDriverState *bs) 251 251 { 252 - BDRVQcowState *s = bs->opaque; 252 + BDRVQcow2State *s = bs->opaque; 253 253 uint64_t val; 254 254 int ret; 255 255 ··· 282 282 */ 283 283 static int qcow2_mark_clean(BlockDriverState *bs) 284 284 { 285 - BDRVQcowState *s = bs->opaque; 285 + BDRVQcow2State *s = bs->opaque; 286 286 287 287 if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) { 288 288 int ret; ··· 304 304 */ 305 305 int qcow2_mark_corrupt(BlockDriverState *bs) 306 306 { 307 - BDRVQcowState *s = bs->opaque; 307 + BDRVQcow2State *s = bs->opaque; 308 308 309 309 s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT; 310 310 return qcow2_update_header(bs); ··· 316 316 */ 317 317 int qcow2_mark_consistent(BlockDriverState *bs) 318 318 { 319 - BDRVQcowState *s = bs->opaque; 319 + BDRVQcow2State *s = bs->opaque; 320 320 321 321 if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) { 322 322 int ret = bdrv_flush(bs); ··· 351 351 static int validate_table_offset(BlockDriverState *bs, uint64_t offset, 352 352 uint64_t entries, size_t entry_len) 353 353 { 354 - BDRVQcowState *s = bs->opaque; 354 + BDRVQcow2State *s = bs->opaque; 355 355 uint64_t size; 356 356 357 357 /* Use signed INT64_MAX as the maximum even for uint64_t header fields, ··· 490 490 static void cache_clean_timer_cb(void *opaque) 491 491 { 492 492 BlockDriverState *bs = opaque; 493 - BDRVQcowState *s = bs->opaque; 493 + BDRVQcow2State *s = bs->opaque; 494 494 qcow2_cache_clean_unused(bs, s->l2_table_cache); 495 495 qcow2_cache_clean_unused(bs, s->refcount_block_cache); 496 496 timer_mod(s->cache_clean_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + ··· 499 499 500 500 static void cache_clean_timer_init(BlockDriverState *bs, AioContext *context) 501 501 { 502 - BDRVQcowState *s = bs->opaque; 502 + BDRVQcow2State *s = bs->opaque; 503 503 if (s->cache_clean_interval > 0) { 504 504 s->cache_clean_timer = aio_timer_new(context, QEMU_CLOCK_VIRTUAL, 505 505 SCALE_MS, cache_clean_timer_cb, ··· 511 511 512 512 static void cache_clean_timer_del(BlockDriverState *bs) 513 513 { 514 - BDRVQcowState *s = bs->opaque; 514 + BDRVQcow2State *s = bs->opaque; 515 515 if (s->cache_clean_timer) { 516 516 timer_del(s->cache_clean_timer); 517 517 timer_free(s->cache_clean_timer); ··· 534 534 uint64_t *l2_cache_size, 535 535 uint64_t *refcount_cache_size, Error **errp) 536 536 { 537 - BDRVQcowState *s = bs->opaque; 537 + BDRVQcow2State *s = bs->opaque; 538 538 uint64_t combined_cache_size; 539 539 bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; 540 540 ··· 589 589 } 590 590 } 591 591 592 + typedef struct Qcow2ReopenState { 593 + Qcow2Cache *l2_table_cache; 594 + Qcow2Cache *refcount_block_cache; 595 + bool use_lazy_refcounts; 596 + int overlap_check; 597 + bool discard_passthrough[QCOW2_DISCARD_MAX]; 598 + uint64_t cache_clean_interval; 599 + } Qcow2ReopenState; 600 + 601 + static int qcow2_update_options_prepare(BlockDriverState *bs, 602 + Qcow2ReopenState *r, 603 + QDict *options, int flags, 604 + Error **errp) 605 + { 606 + BDRVQcow2State *s = bs->opaque; 607 + QemuOpts *opts = NULL; 608 + const char *opt_overlap_check, *opt_overlap_check_template; 609 + int overlap_check_template = 0; 610 + uint64_t l2_cache_size, refcount_cache_size; 611 + int i; 612 + Error *local_err = NULL; 613 + int ret; 614 + 615 + opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort); 616 + qemu_opts_absorb_qdict(opts, options, &local_err); 617 + if (local_err) { 618 + error_propagate(errp, local_err); 619 + ret = -EINVAL; 620 + goto fail; 621 + } 622 + 623 + /* get L2 table/refcount block cache size from command line options */ 624 + read_cache_sizes(bs, opts, &l2_cache_size, &refcount_cache_size, 625 + &local_err); 626 + if (local_err) { 627 + error_propagate(errp, local_err); 628 + ret = -EINVAL; 629 + goto fail; 630 + } 631 + 632 + l2_cache_size /= s->cluster_size; 633 + if (l2_cache_size < MIN_L2_CACHE_SIZE) { 634 + l2_cache_size = MIN_L2_CACHE_SIZE; 635 + } 636 + if (l2_cache_size > INT_MAX) { 637 + error_setg(errp, "L2 cache size too big"); 638 + ret = -EINVAL; 639 + goto fail; 640 + } 641 + 642 + refcount_cache_size /= s->cluster_size; 643 + if (refcount_cache_size < MIN_REFCOUNT_CACHE_SIZE) { 644 + refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE; 645 + } 646 + if (refcount_cache_size > INT_MAX) { 647 + error_setg(errp, "Refcount cache size too big"); 648 + ret = -EINVAL; 649 + goto fail; 650 + } 651 + 652 + /* alloc new L2 table/refcount block cache, flush old one */ 653 + if (s->l2_table_cache) { 654 + ret = qcow2_cache_flush(bs, s->l2_table_cache); 655 + if (ret) { 656 + error_setg_errno(errp, -ret, "Failed to flush the L2 table cache"); 657 + goto fail; 658 + } 659 + } 660 + 661 + if (s->refcount_block_cache) { 662 + ret = qcow2_cache_flush(bs, s->refcount_block_cache); 663 + if (ret) { 664 + error_setg_errno(errp, -ret, 665 + "Failed to flush the refcount block cache"); 666 + goto fail; 667 + } 668 + } 669 + 670 + r->l2_table_cache = qcow2_cache_create(bs, l2_cache_size); 671 + r->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size); 672 + if (r->l2_table_cache == NULL || r->refcount_block_cache == NULL) { 673 + error_setg(errp, "Could not allocate metadata caches"); 674 + ret = -ENOMEM; 675 + goto fail; 676 + } 677 + 678 + /* New interval for cache cleanup timer */ 679 + r->cache_clean_interval = 680 + qemu_opt_get_number(opts, QCOW2_OPT_CACHE_CLEAN_INTERVAL, 681 + s->cache_clean_interval); 682 + if (r->cache_clean_interval > UINT_MAX) { 683 + error_setg(errp, "Cache clean interval too big"); 684 + ret = -EINVAL; 685 + goto fail; 686 + } 687 + 688 + /* lazy-refcounts; flush if going from enabled to disabled */ 689 + r->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS, 690 + (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS)); 691 + if (r->use_lazy_refcounts && s->qcow_version < 3) { 692 + error_setg(errp, "Lazy refcounts require a qcow2 image with at least " 693 + "qemu 1.1 compatibility level"); 694 + ret = -EINVAL; 695 + goto fail; 696 + } 697 + 698 + if (s->use_lazy_refcounts && !r->use_lazy_refcounts) { 699 + ret = qcow2_mark_clean(bs); 700 + if (ret < 0) { 701 + error_setg_errno(errp, -ret, "Failed to disable lazy refcounts"); 702 + goto fail; 703 + } 704 + } 705 + 706 + /* Overlap check options */ 707 + opt_overlap_check = qemu_opt_get(opts, QCOW2_OPT_OVERLAP); 708 + opt_overlap_check_template = qemu_opt_get(opts, QCOW2_OPT_OVERLAP_TEMPLATE); 709 + if (opt_overlap_check_template && opt_overlap_check && 710 + strcmp(opt_overlap_check_template, opt_overlap_check)) 711 + { 712 + error_setg(errp, "Conflicting values for qcow2 options '" 713 + QCOW2_OPT_OVERLAP "' ('%s') and '" QCOW2_OPT_OVERLAP_TEMPLATE 714 + "' ('%s')", opt_overlap_check, opt_overlap_check_template); 715 + ret = -EINVAL; 716 + goto fail; 717 + } 718 + if (!opt_overlap_check) { 719 + opt_overlap_check = opt_overlap_check_template ?: "cached"; 720 + } 721 + 722 + if (!strcmp(opt_overlap_check, "none")) { 723 + overlap_check_template = 0; 724 + } else if (!strcmp(opt_overlap_check, "constant")) { 725 + overlap_check_template = QCOW2_OL_CONSTANT; 726 + } else if (!strcmp(opt_overlap_check, "cached")) { 727 + overlap_check_template = QCOW2_OL_CACHED; 728 + } else if (!strcmp(opt_overlap_check, "all")) { 729 + overlap_check_template = QCOW2_OL_ALL; 730 + } else { 731 + error_setg(errp, "Unsupported value '%s' for qcow2 option " 732 + "'overlap-check'. Allowed are any of the following: " 733 + "none, constant, cached, all", opt_overlap_check); 734 + ret = -EINVAL; 735 + goto fail; 736 + } 737 + 738 + r->overlap_check = 0; 739 + for (i = 0; i < QCOW2_OL_MAX_BITNR; i++) { 740 + /* overlap-check defines a template bitmask, but every flag may be 741 + * overwritten through the associated boolean option */ 742 + r->overlap_check |= 743 + qemu_opt_get_bool(opts, overlap_bool_option_names[i], 744 + overlap_check_template & (1 << i)) << i; 745 + } 746 + 747 + r->discard_passthrough[QCOW2_DISCARD_NEVER] = false; 748 + r->discard_passthrough[QCOW2_DISCARD_ALWAYS] = true; 749 + r->discard_passthrough[QCOW2_DISCARD_REQUEST] = 750 + qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_REQUEST, 751 + flags & BDRV_O_UNMAP); 752 + r->discard_passthrough[QCOW2_DISCARD_SNAPSHOT] = 753 + qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_SNAPSHOT, true); 754 + r->discard_passthrough[QCOW2_DISCARD_OTHER] = 755 + qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false); 756 + 757 + ret = 0; 758 + fail: 759 + qemu_opts_del(opts); 760 + opts = NULL; 761 + return ret; 762 + } 763 + 764 + static void qcow2_update_options_commit(BlockDriverState *bs, 765 + Qcow2ReopenState *r) 766 + { 767 + BDRVQcow2State *s = bs->opaque; 768 + int i; 769 + 770 + if (s->l2_table_cache) { 771 + qcow2_cache_destroy(bs, s->l2_table_cache); 772 + } 773 + if (s->refcount_block_cache) { 774 + qcow2_cache_destroy(bs, s->refcount_block_cache); 775 + } 776 + s->l2_table_cache = r->l2_table_cache; 777 + s->refcount_block_cache = r->refcount_block_cache; 778 + 779 + s->overlap_check = r->overlap_check; 780 + s->use_lazy_refcounts = r->use_lazy_refcounts; 781 + 782 + for (i = 0; i < QCOW2_DISCARD_MAX; i++) { 783 + s->discard_passthrough[i] = r->discard_passthrough[i]; 784 + } 785 + 786 + if (s->cache_clean_interval != r->cache_clean_interval) { 787 + cache_clean_timer_del(bs); 788 + s->cache_clean_interval = r->cache_clean_interval; 789 + cache_clean_timer_init(bs, bdrv_get_aio_context(bs)); 790 + } 791 + } 792 + 793 + static void qcow2_update_options_abort(BlockDriverState *bs, 794 + Qcow2ReopenState *r) 795 + { 796 + if (r->l2_table_cache) { 797 + qcow2_cache_destroy(bs, r->l2_table_cache); 798 + } 799 + if (r->refcount_block_cache) { 800 + qcow2_cache_destroy(bs, r->refcount_block_cache); 801 + } 802 + } 803 + 804 + static int qcow2_update_options(BlockDriverState *bs, QDict *options, 805 + int flags, Error **errp) 806 + { 807 + Qcow2ReopenState r = {}; 808 + int ret; 809 + 810 + ret = qcow2_update_options_prepare(bs, &r, options, flags, errp); 811 + if (ret >= 0) { 812 + qcow2_update_options_commit(bs, &r); 813 + } else { 814 + qcow2_update_options_abort(bs, &r); 815 + } 816 + 817 + return ret; 818 + } 819 + 592 820 static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, 593 821 Error **errp) 594 822 { 595 - BDRVQcowState *s = bs->opaque; 823 + BDRVQcow2State *s = bs->opaque; 596 824 unsigned int len, i; 597 825 int ret = 0; 598 826 QCowHeader header; 599 - QemuOpts *opts = NULL; 600 827 Error *local_err = NULL; 601 828 uint64_t ext_end; 602 829 uint64_t l1_vm_state_index; 603 - const char *opt_overlap_check, *opt_overlap_check_template; 604 - int overlap_check_template = 0; 605 - uint64_t l2_cache_size, refcount_cache_size; 606 - uint64_t cache_clean_interval; 607 830 608 831 ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); 609 832 if (ret < 0) { ··· 851 1074 } 852 1075 } 853 1076 854 - /* get L2 table/refcount block cache size from command line options */ 855 - opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort); 856 - qemu_opts_absorb_qdict(opts, options, &local_err); 857 - if (local_err) { 858 - error_propagate(errp, local_err); 859 - ret = -EINVAL; 860 - goto fail; 861 - } 862 - 863 - read_cache_sizes(bs, opts, &l2_cache_size, &refcount_cache_size, 864 - &local_err); 865 - if (local_err) { 866 - error_propagate(errp, local_err); 867 - ret = -EINVAL; 868 - goto fail; 869 - } 870 - 871 - l2_cache_size /= s->cluster_size; 872 - if (l2_cache_size < MIN_L2_CACHE_SIZE) { 873 - l2_cache_size = MIN_L2_CACHE_SIZE; 874 - } 875 - if (l2_cache_size > INT_MAX) { 876 - error_setg(errp, "L2 cache size too big"); 877 - ret = -EINVAL; 878 - goto fail; 879 - } 880 - 881 - refcount_cache_size /= s->cluster_size; 882 - if (refcount_cache_size < MIN_REFCOUNT_CACHE_SIZE) { 883 - refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE; 884 - } 885 - if (refcount_cache_size > INT_MAX) { 886 - error_setg(errp, "Refcount cache size too big"); 887 - ret = -EINVAL; 1077 + /* Parse driver-specific options */ 1078 + ret = qcow2_update_options(bs, options, flags, errp); 1079 + if (ret < 0) { 888 1080 goto fail; 889 1081 } 890 1082 891 - /* alloc L2 table/refcount block cache */ 892 - s->l2_table_cache = qcow2_cache_create(bs, l2_cache_size); 893 - s->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size); 894 - if (s->l2_table_cache == NULL || s->refcount_block_cache == NULL) { 895 - error_setg(errp, "Could not allocate metadata caches"); 896 - ret = -ENOMEM; 897 - goto fail; 898 - } 899 - 900 - cache_clean_interval = 901 - qemu_opt_get_number(opts, QCOW2_OPT_CACHE_CLEAN_INTERVAL, 0); 902 - if (cache_clean_interval > UINT_MAX) { 903 - error_setg(errp, "Cache clean interval too big"); 904 - ret = -EINVAL; 905 - goto fail; 906 - } 907 - s->cache_clean_interval = cache_clean_interval; 908 - cache_clean_timer_init(bs, bdrv_get_aio_context(bs)); 909 - 910 1083 s->cluster_cache = g_malloc(s->cluster_size); 911 1084 /* one more sector for decompressed data alignment */ 912 1085 s->cluster_data = qemu_try_blockalign(bs->file, QCOW_MAX_CRYPT_CLUSTERS ··· 991 1164 } 992 1165 } 993 1166 994 - /* Enable lazy_refcounts according to image and command line options */ 995 - s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS, 996 - (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS)); 997 - 998 - s->discard_passthrough[QCOW2_DISCARD_NEVER] = false; 999 - s->discard_passthrough[QCOW2_DISCARD_ALWAYS] = true; 1000 - s->discard_passthrough[QCOW2_DISCARD_REQUEST] = 1001 - qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_REQUEST, 1002 - flags & BDRV_O_UNMAP); 1003 - s->discard_passthrough[QCOW2_DISCARD_SNAPSHOT] = 1004 - qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_SNAPSHOT, true); 1005 - s->discard_passthrough[QCOW2_DISCARD_OTHER] = 1006 - qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false); 1007 - 1008 - opt_overlap_check = qemu_opt_get(opts, QCOW2_OPT_OVERLAP); 1009 - opt_overlap_check_template = qemu_opt_get(opts, QCOW2_OPT_OVERLAP_TEMPLATE); 1010 - if (opt_overlap_check_template && opt_overlap_check && 1011 - strcmp(opt_overlap_check_template, opt_overlap_check)) 1012 - { 1013 - error_setg(errp, "Conflicting values for qcow2 options '" 1014 - QCOW2_OPT_OVERLAP "' ('%s') and '" QCOW2_OPT_OVERLAP_TEMPLATE 1015 - "' ('%s')", opt_overlap_check, opt_overlap_check_template); 1016 - ret = -EINVAL; 1017 - goto fail; 1018 - } 1019 - if (!opt_overlap_check) { 1020 - opt_overlap_check = opt_overlap_check_template ?: "cached"; 1021 - } 1022 - 1023 - if (!strcmp(opt_overlap_check, "none")) { 1024 - overlap_check_template = 0; 1025 - } else if (!strcmp(opt_overlap_check, "constant")) { 1026 - overlap_check_template = QCOW2_OL_CONSTANT; 1027 - } else if (!strcmp(opt_overlap_check, "cached")) { 1028 - overlap_check_template = QCOW2_OL_CACHED; 1029 - } else if (!strcmp(opt_overlap_check, "all")) { 1030 - overlap_check_template = QCOW2_OL_ALL; 1031 - } else { 1032 - error_setg(errp, "Unsupported value '%s' for qcow2 option " 1033 - "'overlap-check'. Allowed are either of the following: " 1034 - "none, constant, cached, all", opt_overlap_check); 1035 - ret = -EINVAL; 1036 - goto fail; 1037 - } 1038 - 1039 - s->overlap_check = 0; 1040 - for (i = 0; i < QCOW2_OL_MAX_BITNR; i++) { 1041 - /* overlap-check defines a template bitmask, but every flag may be 1042 - * overwritten through the associated boolean option */ 1043 - s->overlap_check |= 1044 - qemu_opt_get_bool(opts, overlap_bool_option_names[i], 1045 - overlap_check_template & (1 << i)) << i; 1046 - } 1047 - 1048 - qemu_opts_del(opts); 1049 - opts = NULL; 1050 - 1051 - if (s->use_lazy_refcounts && s->qcow_version < 3) { 1052 - error_setg(errp, "Lazy refcounts require a qcow2 image with at least " 1053 - "qemu 1.1 compatibility level"); 1054 - ret = -EINVAL; 1055 - goto fail; 1056 - } 1057 - 1058 1167 #ifdef DEBUG_ALLOC 1059 1168 { 1060 1169 BdrvCheckResult result = {0}; ··· 1064 1173 return ret; 1065 1174 1066 1175 fail: 1067 - qemu_opts_del(opts); 1068 1176 g_free(s->unknown_header_fields); 1069 1177 cleanup_unknown_header_ext(bs); 1070 1178 qcow2_free_snapshots(bs); ··· 1086 1194 1087 1195 static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) 1088 1196 { 1089 - BDRVQcowState *s = bs->opaque; 1197 + BDRVQcow2State *s = bs->opaque; 1090 1198 1091 1199 bs->bl.write_zeroes_alignment = s->cluster_sectors; 1092 1200 } 1093 1201 1094 1202 static int qcow2_set_key(BlockDriverState *bs, const char *key) 1095 1203 { 1096 - BDRVQcowState *s = bs->opaque; 1204 + BDRVQcow2State *s = bs->opaque; 1097 1205 uint8_t keybuf[16]; 1098 1206 int len, i; 1099 1207 Error *err = NULL; ··· 1126 1234 return 0; 1127 1235 } 1128 1236 1129 - /* We have no actual commit/abort logic for qcow2, but we need to write out any 1130 - * unwritten data if we reopen read-only. */ 1131 1237 static int qcow2_reopen_prepare(BDRVReopenState *state, 1132 1238 BlockReopenQueue *queue, Error **errp) 1133 1239 { 1240 + Qcow2ReopenState *r; 1134 1241 int ret; 1135 1242 1243 + r = g_new0(Qcow2ReopenState, 1); 1244 + state->opaque = r; 1245 + 1246 + ret = qcow2_update_options_prepare(state->bs, r, state->options, 1247 + state->flags, errp); 1248 + if (ret < 0) { 1249 + goto fail; 1250 + } 1251 + 1252 + /* We need to write out any unwritten data if we reopen read-only. */ 1136 1253 if ((state->flags & BDRV_O_RDWR) == 0) { 1137 1254 ret = bdrv_flush(state->bs); 1138 1255 if (ret < 0) { 1139 - return ret; 1256 + goto fail; 1140 1257 } 1141 1258 1142 1259 ret = qcow2_mark_clean(state->bs); 1143 1260 if (ret < 0) { 1144 - return ret; 1261 + goto fail; 1145 1262 } 1146 1263 } 1147 1264 1148 1265 return 0; 1266 + 1267 + fail: 1268 + qcow2_update_options_abort(state->bs, r); 1269 + g_free(r); 1270 + return ret; 1271 + } 1272 + 1273 + static void qcow2_reopen_commit(BDRVReopenState *state) 1274 + { 1275 + qcow2_update_options_commit(state->bs, state->opaque); 1276 + g_free(state->opaque); 1277 + } 1278 + 1279 + static void qcow2_reopen_abort(BDRVReopenState *state) 1280 + { 1281 + qcow2_update_options_abort(state->bs, state->opaque); 1282 + g_free(state->opaque); 1149 1283 } 1150 1284 1151 1285 static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs, 1152 1286 int64_t sector_num, int nb_sectors, int *pnum) 1153 1287 { 1154 - BDRVQcowState *s = bs->opaque; 1288 + BDRVQcow2State *s = bs->opaque; 1155 1289 uint64_t cluster_offset; 1156 1290 int index_in_cluster, ret; 1157 1291 int64_t status = 0; ··· 1198 1332 static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, 1199 1333 int remaining_sectors, QEMUIOVector *qiov) 1200 1334 { 1201 - BDRVQcowState *s = bs->opaque; 1335 + BDRVQcow2State *s = bs->opaque; 1202 1336 int index_in_cluster, n1; 1203 1337 int ret; 1204 1338 int cur_nr_sectors; /* number of sectors in current iteration */ ··· 1360 1494 int remaining_sectors, 1361 1495 QEMUIOVector *qiov) 1362 1496 { 1363 - BDRVQcowState *s = bs->opaque; 1497 + BDRVQcow2State *s = bs->opaque; 1364 1498 int index_in_cluster; 1365 1499 int ret; 1366 1500 int cur_nr_sectors; /* number of sectors in current iteration */ ··· 1506 1640 1507 1641 static void qcow2_close(BlockDriverState *bs) 1508 1642 { 1509 - BDRVQcowState *s = bs->opaque; 1643 + BDRVQcow2State *s = bs->opaque; 1510 1644 qemu_vfree(s->l1_table); 1511 1645 /* else pre-write overlap checks in cache_destroy may crash */ 1512 1646 s->l1_table = NULL; ··· 1552 1686 1553 1687 static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) 1554 1688 { 1555 - BDRVQcowState *s = bs->opaque; 1689 + BDRVQcow2State *s = bs->opaque; 1556 1690 int flags = s->flags; 1557 1691 QCryptoCipher *cipher = NULL; 1558 1692 QDict *options; ··· 1575 1709 return; 1576 1710 } 1577 1711 1578 - memset(s, 0, sizeof(BDRVQcowState)); 1712 + memset(s, 0, sizeof(BDRVQcow2State)); 1579 1713 options = qdict_clone_shallow(bs->options); 1580 1714 1581 1715 ret = qcow2_open(bs, options, flags, &local_err); ··· 1622 1756 */ 1623 1757 int qcow2_update_header(BlockDriverState *bs) 1624 1758 { 1625 - BDRVQcowState *s = bs->opaque; 1759 + BDRVQcow2State *s = bs->opaque; 1626 1760 QCowHeader *header; 1627 1761 char *buf; 1628 1762 size_t buflen = s->cluster_size; ··· 1791 1925 static int qcow2_change_backing_file(BlockDriverState *bs, 1792 1926 const char *backing_file, const char *backing_fmt) 1793 1927 { 1794 - BDRVQcowState *s = bs->opaque; 1928 + BDRVQcow2State *s = bs->opaque; 1795 1929 1796 1930 pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: ""); 1797 1931 pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: ""); ··· 1873 2007 QemuOpts *opts, int version, int refcount_order, 1874 2008 Error **errp) 1875 2009 { 2010 + int cluster_bits; 2011 + QDict *options; 2012 + 1876 2013 /* Calculate cluster_bits */ 1877 - int cluster_bits; 1878 2014 cluster_bits = ctz32(cluster_size); 1879 2015 if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS || 1880 2016 (1 << cluster_bits) != cluster_size) ··· 1973 2109 1974 2110 bs = NULL; 1975 2111 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 1976 - NULL, &local_err); 2112 + &local_err); 1977 2113 if (ret < 0) { 1978 2114 error_propagate(errp, local_err); 1979 2115 return ret; ··· 2032 2168 * refcount of the cluster that is occupied by the header and the refcount 2033 2169 * table) 2034 2170 */ 2035 - ret = bdrv_open(&bs, filename, NULL, NULL, 2171 + options = qdict_new(); 2172 + qdict_put(options, "driver", qstring_from_str("qcow2")); 2173 + ret = bdrv_open(&bs, filename, NULL, options, 2036 2174 BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, 2037 - &bdrv_qcow2, &local_err); 2175 + &local_err); 2038 2176 if (ret < 0) { 2039 2177 error_propagate(errp, local_err); 2040 2178 goto out; ··· 2070 2208 2071 2209 /* And if we're supposed to preallocate metadata, do that now */ 2072 2210 if (prealloc != PREALLOC_MODE_OFF) { 2073 - BDRVQcowState *s = bs->opaque; 2211 + BDRVQcow2State *s = bs->opaque; 2074 2212 qemu_co_mutex_lock(&s->lock); 2075 2213 ret = preallocate(bs); 2076 2214 qemu_co_mutex_unlock(&s->lock); ··· 2084 2222 bs = NULL; 2085 2223 2086 2224 /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */ 2087 - ret = bdrv_open(&bs, filename, NULL, NULL, 2225 + options = qdict_new(); 2226 + qdict_put(options, "driver", qstring_from_str("qcow2")); 2227 + ret = bdrv_open(&bs, filename, NULL, options, 2088 2228 BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING, 2089 - &bdrv_qcow2, &local_err); 2229 + &local_err); 2090 2230 if (local_err) { 2091 2231 error_propagate(errp, local_err); 2092 2232 goto out; ··· 2203 2343 int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) 2204 2344 { 2205 2345 int ret; 2206 - BDRVQcowState *s = bs->opaque; 2346 + BDRVQcow2State *s = bs->opaque; 2207 2347 2208 2348 /* Emulate misaligned zero writes */ 2209 2349 if (sector_num % s->cluster_sectors || nb_sectors % s->cluster_sectors) { ··· 2223 2363 int64_t sector_num, int nb_sectors) 2224 2364 { 2225 2365 int ret; 2226 - BDRVQcowState *s = bs->opaque; 2366 + BDRVQcow2State *s = bs->opaque; 2227 2367 2228 2368 qemu_co_mutex_lock(&s->lock); 2229 2369 ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS, ··· 2234 2374 2235 2375 static int qcow2_truncate(BlockDriverState *bs, int64_t offset) 2236 2376 { 2237 - BDRVQcowState *s = bs->opaque; 2377 + BDRVQcow2State *s = bs->opaque; 2238 2378 int64_t new_l1_size; 2239 2379 int ret; 2240 2380 ··· 2278 2418 static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, 2279 2419 const uint8_t *buf, int nb_sectors) 2280 2420 { 2281 - BDRVQcowState *s = bs->opaque; 2421 + BDRVQcow2State *s = bs->opaque; 2282 2422 z_stream strm; 2283 2423 int ret, out_len; 2284 2424 uint8_t *out_buf; ··· 2369 2509 2370 2510 static int make_completely_empty(BlockDriverState *bs) 2371 2511 { 2372 - BDRVQcowState *s = bs->opaque; 2512 + BDRVQcow2State *s = bs->opaque; 2373 2513 int ret, l1_clusters; 2374 2514 int64_t offset; 2375 2515 uint64_t *new_reftable = NULL; ··· 2517 2657 2518 2658 static int qcow2_make_empty(BlockDriverState *bs) 2519 2659 { 2520 - BDRVQcowState *s = bs->opaque; 2660 + BDRVQcow2State *s = bs->opaque; 2521 2661 uint64_t start_sector; 2522 2662 int sector_step = INT_MAX / BDRV_SECTOR_SIZE; 2523 2663 int l1_clusters, ret = 0; ··· 2558 2698 2559 2699 static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) 2560 2700 { 2561 - BDRVQcowState *s = bs->opaque; 2701 + BDRVQcow2State *s = bs->opaque; 2562 2702 int ret; 2563 2703 2564 2704 qemu_co_mutex_lock(&s->lock); ··· 2582 2722 2583 2723 static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 2584 2724 { 2585 - BDRVQcowState *s = bs->opaque; 2725 + BDRVQcow2State *s = bs->opaque; 2586 2726 bdi->unallocated_blocks_are_zero = true; 2587 2727 bdi->can_write_zeroes_with_unmap = (s->qcow_version >= 3); 2588 2728 bdi->cluster_size = s->cluster_size; ··· 2592 2732 2593 2733 static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs) 2594 2734 { 2595 - BDRVQcowState *s = bs->opaque; 2735 + BDRVQcow2State *s = bs->opaque; 2596 2736 ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1); 2597 2737 2598 2738 *spec_info = (ImageInfoSpecific){ ··· 2625 2765 #if 0 2626 2766 static void dump_refcounts(BlockDriverState *bs) 2627 2767 { 2628 - BDRVQcowState *s = bs->opaque; 2768 + BDRVQcow2State *s = bs->opaque; 2629 2769 int64_t nb_clusters, k, k1, size; 2630 2770 int refcount; 2631 2771 ··· 2646 2786 static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, 2647 2787 int64_t pos) 2648 2788 { 2649 - BDRVQcowState *s = bs->opaque; 2789 + BDRVQcow2State *s = bs->opaque; 2650 2790 int64_t total_sectors = bs->total_sectors; 2651 2791 bool zero_beyond_eof = bs->zero_beyond_eof; 2652 2792 int ret; ··· 2667 2807 static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf, 2668 2808 int64_t pos, int size) 2669 2809 { 2670 - BDRVQcowState *s = bs->opaque; 2810 + BDRVQcow2State *s = bs->opaque; 2671 2811 bool zero_beyond_eof = bs->zero_beyond_eof; 2672 2812 int ret; 2673 2813 ··· 2686 2826 static int qcow2_downgrade(BlockDriverState *bs, int target_version, 2687 2827 BlockDriverAmendStatusCB *status_cb) 2688 2828 { 2689 - BDRVQcowState *s = bs->opaque; 2829 + BDRVQcow2State *s = bs->opaque; 2690 2830 int current_version = s->qcow_version; 2691 2831 int ret; 2692 2832 ··· 2750 2890 static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, 2751 2891 BlockDriverAmendStatusCB *status_cb) 2752 2892 { 2753 - BDRVQcowState *s = bs->opaque; 2893 + BDRVQcow2State *s = bs->opaque; 2754 2894 int old_version = s->qcow_version, new_version = old_version; 2755 2895 uint64_t new_size = 0; 2756 2896 const char *backing_file = NULL, *backing_format = NULL; ··· 2897 3037 void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset, 2898 3038 int64_t size, const char *message_format, ...) 2899 3039 { 2900 - BDRVQcowState *s = bs->opaque; 3040 + BDRVQcow2State *s = bs->opaque; 2901 3041 const char *node_name; 2902 3042 char *message; 2903 3043 va_list ap; ··· 2998 3138 2999 3139 BlockDriver bdrv_qcow2 = { 3000 3140 .format_name = "qcow2", 3001 - .instance_size = sizeof(BDRVQcowState), 3141 + .instance_size = sizeof(BDRVQcow2State), 3002 3142 .bdrv_probe = qcow2_probe, 3003 3143 .bdrv_open = qcow2_open, 3004 3144 .bdrv_close = qcow2_close, 3005 3145 .bdrv_reopen_prepare = qcow2_reopen_prepare, 3146 + .bdrv_reopen_commit = qcow2_reopen_commit, 3147 + .bdrv_reopen_abort = qcow2_reopen_abort, 3006 3148 .bdrv_create = qcow2_create, 3007 3149 .bdrv_has_zero_init = bdrv_has_zero_init_1, 3008 3150 .bdrv_co_get_block_status = qcow2_co_get_block_status,
+13 -13
block/qcow2.h
··· 222 222 typedef void Qcow2SetRefcountFunc(void *refcount_array, 223 223 uint64_t index, uint64_t value); 224 224 225 - typedef struct BDRVQcowState { 225 + typedef struct BDRVQcow2State { 226 226 int cluster_bits; 227 227 int cluster_size; 228 228 int cluster_sectors; ··· 293 293 * override) */ 294 294 char *image_backing_file; 295 295 char *image_backing_format; 296 - } BDRVQcowState; 296 + } BDRVQcow2State; 297 297 298 298 struct QCowAIOCB; 299 299 ··· 405 405 406 406 #define REFT_OFFSET_MASK 0xfffffffffffffe00ULL 407 407 408 - static inline int64_t start_of_cluster(BDRVQcowState *s, int64_t offset) 408 + static inline int64_t start_of_cluster(BDRVQcow2State *s, int64_t offset) 409 409 { 410 410 return offset & ~(s->cluster_size - 1); 411 411 } 412 412 413 - static inline int64_t offset_into_cluster(BDRVQcowState *s, int64_t offset) 413 + static inline int64_t offset_into_cluster(BDRVQcow2State *s, int64_t offset) 414 414 { 415 415 return offset & (s->cluster_size - 1); 416 416 } 417 417 418 - static inline int size_to_clusters(BDRVQcowState *s, int64_t size) 418 + static inline uint64_t size_to_clusters(BDRVQcow2State *s, uint64_t size) 419 419 { 420 420 return (size + (s->cluster_size - 1)) >> s->cluster_bits; 421 421 } 422 422 423 - static inline int64_t size_to_l1(BDRVQcowState *s, int64_t size) 423 + static inline int64_t size_to_l1(BDRVQcow2State *s, int64_t size) 424 424 { 425 425 int shift = s->cluster_bits + s->l2_bits; 426 426 return (size + (1ULL << shift) - 1) >> shift; 427 427 } 428 428 429 - static inline int offset_to_l2_index(BDRVQcowState *s, int64_t offset) 429 + static inline int offset_to_l2_index(BDRVQcow2State *s, int64_t offset) 430 430 { 431 431 return (offset >> s->cluster_bits) & (s->l2_size - 1); 432 432 } ··· 437 437 return offset; 438 438 } 439 439 440 - static inline int64_t qcow2_vm_state_offset(BDRVQcowState *s) 440 + static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s) 441 441 { 442 442 return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); 443 443 } 444 444 445 - static inline uint64_t qcow2_max_refcount_clusters(BDRVQcowState *s) 445 + static inline uint64_t qcow2_max_refcount_clusters(BDRVQcow2State *s) 446 446 { 447 447 return QCOW_MAX_REFTABLE_SIZE >> s->cluster_bits; 448 448 } ··· 461 461 } 462 462 463 463 /* Check whether refcounts are eager or lazy */ 464 - static inline bool qcow2_need_accurate_refcounts(BDRVQcowState *s) 464 + static inline bool qcow2_need_accurate_refcounts(BDRVQcow2State *s) 465 465 { 466 466 return !(s->incompatible_features & QCOW2_INCOMPAT_DIRTY); 467 467 } ··· 509 509 enum qcow2_discard_type type); 510 510 511 511 int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size); 512 - int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, 513 - int nb_clusters); 512 + int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, 513 + int64_t nb_clusters); 514 514 int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size); 515 515 void qcow2_free_clusters(BlockDriverState *bs, 516 516 int64_t offset, int64_t size, ··· 537 537 int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); 538 538 void qcow2_l2_cache_reset(BlockDriverState *bs); 539 539 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); 540 - int qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num, 540 + int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, 541 541 uint8_t *out_buf, const uint8_t *in_buf, 542 542 int nb_sectors, bool enc, Error **errp); 543 543
+1 -1
block/qed.c
··· 583 583 584 584 bs = NULL; 585 585 ret = bdrv_open(&bs, filename, NULL, NULL, 586 - BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_PROTOCOL, NULL, 586 + BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_PROTOCOL, 587 587 &local_err); 588 588 if (ret < 0) { 589 589 error_propagate(errp, local_err);
+2 -3
block/sheepdog.c
··· 1554 1554 int ret; 1555 1555 1556 1556 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 1557 - NULL, errp); 1557 + errp); 1558 1558 if (ret < 0) { 1559 1559 goto out_with_err_set; 1560 1560 } ··· 1746 1746 } 1747 1747 1748 1748 bs = NULL; 1749 - ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL, 1750 - errp); 1749 + ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, errp); 1751 1750 if (ret < 0) { 1752 1751 goto out; 1753 1752 }
+1 -1
block/vdi.c
··· 764 764 goto exit; 765 765 } 766 766 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 767 - NULL, &local_err); 767 + &local_err); 768 768 if (ret < 0) { 769 769 error_propagate(errp, local_err); 770 770 goto exit;
+1 -1
block/vhdx.c
··· 1842 1842 1843 1843 bs = NULL; 1844 1844 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 1845 - NULL, &local_err); 1845 + &local_err); 1846 1846 if (ret < 0) { 1847 1847 error_propagate(errp, local_err); 1848 1848 goto exit;
+9 -6
block/vmdk.c
··· 1324 1324 1325 1325 write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE); 1326 1326 1327 - extent->next_cluster_sector = MAX(extent->next_cluster_sector, 1328 - write_end_sector); 1327 + if (extent->compressed) { 1328 + extent->next_cluster_sector = write_end_sector; 1329 + } else { 1330 + extent->next_cluster_sector = MAX(extent->next_cluster_sector, 1331 + write_end_sector); 1332 + } 1329 1333 1330 1334 if (ret != write_len) { 1331 1335 ret = ret < 0 ? ret : -EIO; ··· 1632 1636 1633 1637 assert(bs == NULL); 1634 1638 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 1635 - NULL, &local_err); 1639 + &local_err); 1636 1640 if (ret < 0) { 1637 1641 error_propagate(errp, local_err); 1638 1642 goto exit; ··· 1905 1909 ret = -ENOENT; 1906 1910 goto exit; 1907 1911 } 1908 - ret = bdrv_open(&bs, full_backing, NULL, NULL, BDRV_O_NO_BACKING, NULL, 1909 - errp); 1912 + ret = bdrv_open(&bs, full_backing, NULL, NULL, BDRV_O_NO_BACKING, errp); 1910 1913 g_free(full_backing); 1911 1914 if (ret != 0) { 1912 1915 goto exit; ··· 1977 1980 } 1978 1981 assert(new_bs == NULL); 1979 1982 ret = bdrv_open(&new_bs, filename, NULL, NULL, 1980 - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); 1983 + BDRV_O_RDWR | BDRV_O_PROTOCOL, &local_err); 1981 1984 if (ret < 0) { 1982 1985 error_propagate(errp, local_err); 1983 1986 goto exit;
+1 -1
block/vpc.c
··· 794 794 goto out; 795 795 } 796 796 ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, 797 - NULL, &local_err); 797 + &local_err); 798 798 if (ret < 0) { 799 799 error_propagate(errp, local_err); 800 800 goto out;
+6 -2
block/vvfat.c
··· 2926 2926 QemuOpts *opts = NULL; 2927 2927 int ret; 2928 2928 int size = sector2cluster(s, s->sector_count); 2929 + QDict *options; 2930 + 2929 2931 s->used_clusters = calloc(size, 1); 2930 2932 2931 2933 array_init(&(s->commits), sizeof(commit_t)); ··· 2956 2958 } 2957 2959 2958 2960 s->qcow = NULL; 2959 - ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL, 2961 + options = qdict_new(); 2962 + qdict_put(options, "driver", qstring_from_str("qcow")); 2963 + ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, options, 2960 2964 BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, 2961 - bdrv_qcow, errp); 2965 + errp); 2962 2966 if (ret < 0) { 2963 2967 goto err; 2964 2968 }
+28 -44
blockdev.c
··· 1422 1422 static void external_snapshot_prepare(BlkTransactionState *common, 1423 1423 Error **errp) 1424 1424 { 1425 - BlockDriver *drv; 1426 1425 int flags, ret; 1427 - QDict *options = NULL; 1426 + QDict *options; 1428 1427 Error *local_err = NULL; 1429 1428 bool has_device = false; 1430 1429 const char *device; ··· 1459 1458 } 1460 1459 1461 1460 /* start processing */ 1462 - drv = bdrv_find_format(format); 1463 - if (!drv) { 1464 - error_setg(errp, QERR_INVALID_BLOCK_FORMAT, format); 1465 - return; 1466 - } 1467 - 1468 1461 state->old_bs = bdrv_lookup_bs(has_device ? device : NULL, 1469 1462 has_node_name ? node_name : NULL, 1470 1463 &local_err); ··· 1523 1516 } 1524 1517 } 1525 1518 1519 + options = qdict_new(); 1526 1520 if (has_snapshot_node_name) { 1527 - options = qdict_new(); 1528 1521 qdict_put(options, "node-name", 1529 1522 qstring_from_str(snapshot_node_name)); 1530 1523 } 1524 + qdict_put(options, "driver", qstring_from_str(format)); 1531 1525 1532 1526 /* TODO Inherit bs->options or only take explicit options with an 1533 1527 * extended QMP command? */ 1534 1528 assert(state->new_bs == NULL); 1535 1529 ret = bdrv_open(&state->new_bs, new_image_file, NULL, options, 1536 - flags | BDRV_O_NO_BACKING, drv, &local_err); 1530 + flags | BDRV_O_NO_BACKING, &local_err); 1537 1531 /* We will manually add the backing_hd field to the bs later */ 1538 1532 if (ret != 0) { 1539 1533 error_propagate(errp, local_err); ··· 1895 1889 1896 1890 /* Assumes AioContext is held */ 1897 1891 static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, 1898 - int bdrv_flags, BlockDriver *drv, 1892 + int bdrv_flags, const char *format, 1899 1893 const char *password, Error **errp) 1900 1894 { 1901 1895 Error *local_err = NULL; 1896 + QDict *options = NULL; 1902 1897 int ret; 1903 1898 1904 - ret = bdrv_open(&bs, filename, NULL, NULL, bdrv_flags, drv, &local_err); 1899 + if (format) { 1900 + options = qdict_new(); 1901 + qdict_put(options, "driver", qstring_from_str(format)); 1902 + } 1903 + 1904 + ret = bdrv_open(&bs, filename, NULL, options, bdrv_flags, &local_err); 1905 1905 if (ret < 0) { 1906 1906 error_propagate(errp, local_err); 1907 1907 return; ··· 1916 1916 BlockBackend *blk; 1917 1917 BlockDriverState *bs; 1918 1918 AioContext *aio_context; 1919 - BlockDriver *drv = NULL; 1920 1919 int bdrv_flags; 1921 1920 Error *err = NULL; 1922 1921 ··· 1931 1930 aio_context = bdrv_get_aio_context(bs); 1932 1931 aio_context_acquire(aio_context); 1933 1932 1934 - if (format) { 1935 - drv = bdrv_find_whitelisted_format(format, bs->read_only); 1936 - if (!drv) { 1937 - error_setg(errp, QERR_INVALID_BLOCK_FORMAT, format); 1938 - goto out; 1939 - } 1940 - } 1941 - 1942 1933 eject_device(blk, 0, &err); 1943 1934 if (err) { 1944 1935 error_propagate(errp, err); ··· 1948 1939 bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR; 1949 1940 bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0; 1950 1941 1951 - qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp); 1942 + qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, format, NULL, errp); 1952 1943 1953 1944 out: 1954 1945 aio_context_release(aio_context); ··· 2466 2457 BlockDriverState *source = NULL; 2467 2458 BdrvDirtyBitmap *bmap = NULL; 2468 2459 AioContext *aio_context; 2469 - BlockDriver *drv = NULL; 2460 + QDict *options = NULL; 2470 2461 Error *local_err = NULL; 2471 2462 int flags; 2472 2463 int64_t size; ··· 2506 2497 if (!has_format) { 2507 2498 format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name; 2508 2499 } 2509 - if (format) { 2510 - drv = bdrv_find_format(format); 2511 - if (!drv) { 2512 - error_setg(errp, QERR_INVALID_BLOCK_FORMAT, format); 2513 - goto out; 2514 - } 2515 - } 2516 2500 2517 2501 /* Early check to avoid creating target */ 2518 2502 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) { ··· 2540 2524 } 2541 2525 2542 2526 if (mode != NEW_IMAGE_MODE_EXISTING) { 2543 - assert(format && drv); 2527 + assert(format); 2544 2528 if (source) { 2545 2529 bdrv_img_create(target, format, source->filename, 2546 2530 source->drv->format_name, NULL, ··· 2556 2540 goto out; 2557 2541 } 2558 2542 2543 + if (format) { 2544 + options = qdict_new(); 2545 + qdict_put(options, "driver", qstring_from_str(format)); 2546 + } 2547 + 2559 2548 target_bs = NULL; 2560 - ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err); 2549 + ret = bdrv_open(&target_bs, target, NULL, options, flags, &local_err); 2561 2550 if (ret < 0) { 2562 2551 error_propagate(errp, local_err); 2563 2552 goto out; ··· 2663 2652 BlockDriverState *bs; 2664 2653 BlockDriverState *source, *target_bs; 2665 2654 AioContext *aio_context; 2666 - BlockDriver *drv = NULL; 2667 2655 Error *local_err = NULL; 2668 - QDict *options = NULL; 2656 + QDict *options; 2669 2657 int flags; 2670 2658 int64_t size; 2671 2659 int ret; ··· 2721 2709 2722 2710 if (!has_format) { 2723 2711 format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name; 2724 - } 2725 - if (format) { 2726 - drv = bdrv_find_format(format); 2727 - if (!drv) { 2728 - error_setg(errp, QERR_INVALID_BLOCK_FORMAT, format); 2729 - goto out; 2730 - } 2731 2712 } 2732 2713 2733 2714 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR, errp)) { ··· 2783 2764 && mode != NEW_IMAGE_MODE_EXISTING) 2784 2765 { 2785 2766 /* create new image w/o backing file */ 2786 - assert(format && drv); 2767 + assert(format); 2787 2768 bdrv_img_create(target, format, 2788 2769 NULL, NULL, NULL, size, flags, &local_err, false); 2789 2770 } else { ··· 2807 2788 goto out; 2808 2789 } 2809 2790 2791 + options = qdict_new(); 2810 2792 if (has_node_name) { 2811 - options = qdict_new(); 2812 2793 qdict_put(options, "node-name", qstring_from_str(node_name)); 2794 + } 2795 + if (format) { 2796 + qdict_put(options, "driver", qstring_from_str(format)); 2813 2797 } 2814 2798 2815 2799 /* Mirroring takes care of copy-on-write using the source's backing ··· 2817 2801 */ 2818 2802 target_bs = NULL; 2819 2803 ret = bdrv_open(&target_bs, target, NULL, options, 2820 - flags | BDRV_O_NO_BACKING, drv, &local_err); 2804 + flags | BDRV_O_NO_BACKING, &local_err); 2821 2805 if (ret < 0) { 2822 2806 error_propagate(errp, local_err); 2823 2807 goto out;
+4 -5
include/block/block.h
··· 147 147 typedef struct BDRVReopenState { 148 148 BlockDriverState *bs; 149 149 int flags; 150 + QDict *options; 150 151 void *opaque; 151 152 } BDRVReopenState; 152 153 ··· 193 194 bool allow_protocol_prefix, 194 195 Error **errp); 195 196 BlockDriver *bdrv_find_format(const char *format_name); 196 - BlockDriver *bdrv_find_whitelisted_format(const char *format_name, 197 - bool readonly); 198 197 int bdrv_create(BlockDriver *drv, const char* filename, 199 198 QemuOpts *opts, Error **errp); 200 199 int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp); ··· 218 217 int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); 219 218 int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp); 220 219 int bdrv_open(BlockDriverState **pbs, const char *filename, 221 - const char *reference, QDict *options, int flags, 222 - BlockDriver *drv, Error **errp); 220 + const char *reference, QDict *options, int flags, Error **errp); 223 221 BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, 224 - BlockDriverState *bs, int flags); 222 + BlockDriverState *bs, 223 + QDict *options, int flags); 225 224 int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); 226 225 int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp); 227 226 int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
+90
qemu-io-cmds.c
··· 1979 1979 .oneline = "prints the allocated areas of a file", 1980 1980 }; 1981 1981 1982 + static void reopen_help(void) 1983 + { 1984 + printf( 1985 + "\n" 1986 + " Changes the open options of an already opened image\n" 1987 + "\n" 1988 + " Example:\n" 1989 + " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n" 1990 + "\n" 1991 + " -r, -- Reopen the image read-only\n" 1992 + " -c, -- Change the cache mode to the given value\n" 1993 + " -o, -- Changes block driver options (cf. 'open' command)\n" 1994 + "\n"); 1995 + } 1996 + 1997 + static int reopen_f(BlockBackend *blk, int argc, char **argv); 1998 + 1999 + static QemuOptsList reopen_opts = { 2000 + .name = "reopen", 2001 + .merge_lists = true, 2002 + .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head), 2003 + .desc = { 2004 + /* no elements => accept any params */ 2005 + { /* end of list */ } 2006 + }, 2007 + }; 2008 + 2009 + static const cmdinfo_t reopen_cmd = { 2010 + .name = "reopen", 2011 + .argmin = 0, 2012 + .argmax = -1, 2013 + .cfunc = reopen_f, 2014 + .args = "[-r] [-c cache] [-o options]", 2015 + .oneline = "reopens an image with new options", 2016 + .help = reopen_help, 2017 + }; 2018 + 2019 + static int reopen_f(BlockBackend *blk, int argc, char **argv) 2020 + { 2021 + BlockDriverState *bs = blk_bs(blk); 2022 + QemuOpts *qopts; 2023 + QDict *opts; 2024 + int c; 2025 + int flags = bs->open_flags; 2026 + 2027 + BlockReopenQueue *brq; 2028 + Error *local_err = NULL; 2029 + 2030 + while ((c = getopt(argc, argv, "c:o:r")) != -1) { 2031 + switch (c) { 2032 + case 'c': 2033 + if (bdrv_parse_cache_flags(optarg, &flags) < 0) { 2034 + error_report("Invalid cache option: %s", optarg); 2035 + return 0; 2036 + } 2037 + break; 2038 + case 'o': 2039 + if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) { 2040 + qemu_opts_reset(&reopen_opts); 2041 + return 0; 2042 + } 2043 + break; 2044 + case 'r': 2045 + flags &= ~BDRV_O_RDWR; 2046 + break; 2047 + default: 2048 + qemu_opts_reset(&reopen_opts); 2049 + return qemuio_command_usage(&reopen_cmd); 2050 + } 2051 + } 2052 + 2053 + if (optind != argc) { 2054 + qemu_opts_reset(&reopen_opts); 2055 + return qemuio_command_usage(&reopen_cmd); 2056 + } 2057 + 2058 + qopts = qemu_opts_find(&reopen_opts, NULL); 2059 + opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL; 2060 + qemu_opts_reset(&reopen_opts); 2061 + 2062 + brq = bdrv_reopen_queue(NULL, bs, opts, flags); 2063 + bdrv_reopen_multiple(brq, &local_err); 2064 + if (local_err) { 2065 + error_report_err(local_err); 2066 + } 2067 + 2068 + return 0; 2069 + } 2070 + 1982 2071 static int break_f(BlockBackend *blk, int argc, char **argv) 1983 2072 { 1984 2073 int ret; ··· 2266 2355 qemuio_add_command(&discard_cmd); 2267 2356 qemuio_add_command(&alloc_cmd); 2268 2357 qemuio_add_command(&map_cmd); 2358 + qemuio_add_command(&reopen_cmd); 2269 2359 qemuio_add_command(&break_cmd); 2270 2360 qemuio_add_command(&remove_break_cmd); 2271 2361 qemuio_add_command(&resume_cmd);
-1
qemu-io.c
··· 156 156 break; 157 157 case 'o': 158 158 if (!qemu_opts_parse_noisily(&empty_opts, optarg, false)) { 159 - printf("could not parse option list -- %s\n", optarg); 160 159 qemu_opts_reset(&empty_opts); 161 160 return 0; 162 161 }
+27
tests/qemu-iotests/039
··· 147 147 _check_test_img 148 148 TEST_IMG="$TEST_IMG".base _check_test_img 149 149 150 + echo 151 + echo "== Changing lazy_refcounts setting at runtime ==" 152 + 153 + IMGOPTS="compat=1.1,lazy_refcounts=off" 154 + _make_test_img $size 155 + 156 + $QEMU_IO -c "reopen -o lazy-refcounts=on" \ 157 + -c "write -P 0x5a 0 512" \ 158 + -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \ 159 + | _filter_qemu_io 160 + 161 + # The dirty bit must be set 162 + $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features 163 + _check_test_img 164 + 165 + IMGOPTS="compat=1.1,lazy_refcounts=on" 166 + _make_test_img $size 167 + 168 + $QEMU_IO -c "reopen -o lazy-refcounts=off" \ 169 + -c "write -P 0x5a 0 512" \ 170 + -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \ 171 + | _filter_qemu_io 172 + 173 + # The dirty bit must not be set 174 + $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features 175 + _check_test_img 176 + 150 177 151 178 # success, all done 152 179 echo "*** done"
+18
tests/qemu-iotests/039.out
··· 74 74 incompatible_features 0x0 75 75 No errors were found on the image. 76 76 No errors were found on the image. 77 + 78 + == Changing lazy_refcounts setting at runtime == 79 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 80 + wrote 512/512 bytes at offset 0 81 + 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 82 + ./common.config: Killed ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) 83 + incompatible_features 0x1 84 + ERROR cluster 5 refcount=0 reference=1 85 + ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0 86 + 87 + 2 errors were found on the image. 88 + Data may be corrupted, or further writes to the image may corrupt it. 89 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 90 + wrote 512/512 bytes at offset 0 91 + 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 92 + ./common.config: Killed ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) 93 + incompatible_features 0x0 94 + No errors were found on the image. 77 95 *** done
+145
tests/qemu-iotests/137
··· 1 + #!/bin/bash 2 + # 3 + # Test qcow2 reopen 4 + # 5 + # Copyright (C) 2015 Red Hat, Inc. 6 + # 7 + # This program is free software; you can redistribute it and/or modify 8 + # it under the terms of the GNU General Public License as published by 9 + # the Free Software Foundation; either version 2 of the License, or 10 + # (at your option) any later version. 11 + # 12 + # This program is distributed in the hope that it will be useful, 13 + # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + # GNU General Public License for more details. 16 + # 17 + # You should have received a copy of the GNU General Public License 18 + # along with this program. If not, see <http://www.gnu.org/licenses/>. 19 + # 20 + 21 + # creator 22 + owner=kwolf@redhat.com 23 + 24 + seq="$(basename $0)" 25 + echo "QA output created by $seq" 26 + 27 + here="$PWD" 28 + tmp=/tmp/$$ 29 + status=1 # failure is the default! 30 + 31 + _cleanup() 32 + { 33 + _cleanup_test_img 34 + } 35 + trap "_cleanup; exit \$status" 0 1 2 3 15 36 + 37 + # get standard environment, filters and checks 38 + . ./common.rc 39 + . ./common.filter 40 + . ./common.qemu 41 + 42 + _supported_fmt qcow2 43 + _supported_proto generic 44 + _supported_os Linux 45 + 46 + 47 + _make_test_img 64M 48 + 49 + echo === Try setting valid values for all options === 50 + echo 51 + 52 + # Try all options and then check that all of the basic I/O operations still 53 + # work on this image. 54 + $QEMU_IO \ 55 + -c "reopen -o lazy-refcounts=on,pass-discard-request=on" \ 56 + -c "reopen -o lazy-refcounts=off,pass-discard-request=off" \ 57 + -c "reopen -o pass-discard-snapshot=on,pass-discard-other=on" \ 58 + -c "reopen -o pass-discard-snapshot=off,pass-discard-other=off" \ 59 + -c "reopen -o overlap-check=all" \ 60 + -c "reopen -o overlap-check=none" \ 61 + -c "reopen -o overlap-check=cached" \ 62 + -c "reopen -o overlap-check=constant" \ 63 + -c "reopen -o overlap-check.template=all" \ 64 + -c "reopen -o overlap-check.template=none" \ 65 + -c "reopen -o overlap-check.template=cached" \ 66 + -c "reopen -o overlap-check.template=constant" \ 67 + -c "reopen -o overlap-check.main-header=on" \ 68 + -c "reopen -o overlap-check.main-header=off" \ 69 + -c "reopen -o overlap-check.active-l1=on" \ 70 + -c "reopen -o overlap-check.active-l1=off" \ 71 + -c "reopen -o overlap-check.active-l2=on" \ 72 + -c "reopen -o overlap-check.active-l2=off" \ 73 + -c "reopen -o overlap-check.refcount-table=on" \ 74 + -c "reopen -o overlap-check.refcount-table=off" \ 75 + -c "reopen -o overlap-check.refcount-block=on" \ 76 + -c "reopen -o overlap-check.refcount-block=off" \ 77 + -c "reopen -o overlap-check.snapshot-table=on" \ 78 + -c "reopen -o overlap-check.snapshot-table=off" \ 79 + -c "reopen -o overlap-check.inactive-l1=on" \ 80 + -c "reopen -o overlap-check.inactive-l1=off" \ 81 + -c "reopen -o overlap-check.inactive-l2=on" \ 82 + -c "reopen -o overlap-check.inactive-l2=off" \ 83 + -c "reopen -o cache-size=1M" \ 84 + -c "reopen -o l2-cache-size=512k" \ 85 + -c "reopen -o refcount-cache-size=128k" \ 86 + -c "reopen -o cache-clean-interval=5" \ 87 + -c "reopen -o cache-clean-interval=0" \ 88 + -c "reopen -o cache-clean-interval=10" \ 89 + \ 90 + -c "write -P 55 0 32M" \ 91 + -c "read -P 55 0 32M" \ 92 + -c "discard 0 32M" \ 93 + -c "write -z 0 32M" \ 94 + -c "read -P 0 0 32M" \ 95 + \ 96 + "$TEST_IMG" | _filter_qemu_io 97 + 98 + 99 + echo 100 + echo === Try setting some invalid values === 101 + echo 102 + 103 + $QEMU_IO \ 104 + -c "reopen -o lazy-refcounts=42" \ 105 + -c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \ 106 + -c "reopen -o cache-size=1M,l2-cache-size=2M" \ 107 + -c "reopen -o cache-size=1M,refcount-cache-size=2M" \ 108 + -c "reopen -o l2-cache-size=256T" \ 109 + -c "reopen -o refcount-cache-size=256T" \ 110 + -c "reopen -o overlap-check=constant,overlap-check.template=all" \ 111 + -c "reopen -o overlap-check=blubb" \ 112 + -c "reopen -o overlap-check.template=blubb" \ 113 + -c "reopen -o cache-clean-interval=-1" \ 114 + "$TEST_IMG" | _filter_qemu_io 115 + 116 + echo 117 + echo === Test transaction semantics === 118 + echo 119 + 120 + # Whether lazy-refcounts was actually enabled can easily be tested: Check if 121 + # the dirty bit is set after a crash 122 + $QEMU_IO \ 123 + -c "reopen -o lazy-refcounts=on,overlap-check=blubb" \ 124 + -c "write -P 0x5a 0 512" \ 125 + -c "sigraise $(kill -l KILL)" \ 126 + "$TEST_IMG" 2>&1 | _filter_qemu_io 127 + 128 + # The dirty bit must not be set 129 + $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features 130 + 131 + # Similarly we can test whether corruption detection has been enabled: 132 + # Create L1/L2, overwrite first entry in refcount block, allocate something. 133 + # Disabling the checks should fail, so the corruption must be detected. 134 + _make_test_img 64M 135 + $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io 136 + poke_file "$TEST_IMG" "$((0x20000))" "\x00\x00" 137 + $QEMU_IO \ 138 + -c "reopen -o overlap-check=none,lazy-refcounts=42" \ 139 + -c "write 64k 64k" \ 140 + "$TEST_IMG" 2>&1 | _filter_qemu_io 141 + 142 + # success, all done 143 + echo '*** done' 144 + rm -f $seq.full 145 + status=0
+42
tests/qemu-iotests/137.out
··· 1 + QA output created by 137 2 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 3 + === Try setting valid values for all options === 4 + 5 + wrote 33554432/33554432 bytes at offset 0 6 + 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 7 + read 33554432/33554432 bytes at offset 0 8 + 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 9 + discard 33554432/33554432 bytes at offset 0 10 + 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 11 + wrote 33554432/33554432 bytes at offset 0 12 + 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 13 + read 33554432/33554432 bytes at offset 0 14 + 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 15 + 16 + === Try setting some invalid values === 17 + 18 + Parameter 'lazy-refcounts' expects 'on' or 'off' 19 + cache-size, l2-cache-size and refcount-cache-size may not be set the same time 20 + l2-cache-size may not exceed cache-size 21 + refcount-cache-size may not exceed cache-size 22 + L2 cache size too big 23 + L2 cache size too big 24 + Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all') 25 + Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all 26 + Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all 27 + Cache clean interval too big 28 + 29 + === Test transaction semantics === 30 + 31 + Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all 32 + wrote 512/512 bytes at offset 0 33 + 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 34 + ./common.config: Killed ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) 35 + incompatible_features 0x0 36 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 37 + wrote 65536/65536 bytes at offset 0 38 + 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 39 + Parameter 'lazy-refcounts' expects 'on' or 'off' 40 + qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed 41 + write failed: Input/output error 42 + *** done
+73
tests/qemu-iotests/138
··· 1 + #!/bin/bash 2 + # 3 + # General test case for qcow2's image check 4 + # 5 + # Copyright (C) 2015 Red Hat, Inc. 6 + # 7 + # This program is free software; you can redistribute it and/or modify 8 + # it under the terms of the GNU General Public License as published by 9 + # the Free Software Foundation; either version 2 of the License, or 10 + # (at your option) any later version. 11 + # 12 + # This program is distributed in the hope that it will be useful, 13 + # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + # GNU General Public License for more details. 16 + # 17 + # You should have received a copy of the GNU General Public License 18 + # along with this program. If not, see <http://www.gnu.org/licenses/>. 19 + # 20 + 21 + # creator 22 + owner=mreitz@redhat.com 23 + 24 + seq="$(basename $0)" 25 + echo "QA output created by $seq" 26 + 27 + here="$PWD" 28 + tmp=/tmp/$$ 29 + status=1 # failure is the default! 30 + 31 + _cleanup() 32 + { 33 + _cleanup_test_img 34 + } 35 + trap "_cleanup; exit \$status" 0 1 2 3 15 36 + 37 + # get standard environment, filters and checks 38 + . ./common.rc 39 + . ./common.filter 40 + 41 + # This tests qocw2-specific low-level functionality 42 + _supported_fmt qcow2 43 + _supported_proto file 44 + _supported_os Linux 45 + 46 + echo 47 + echo '=== Check on an image with a multiple of 2^32 clusters ===' 48 + echo 49 + 50 + IMGOPTS=$(_optstr_add "$IMGOPTS" "cluster_size=512") \ 51 + _make_test_img 512 52 + 53 + # Allocate L2 table 54 + $QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 55 + 56 + # Put the data cluster at a multiple of 2 TB, resulting in the image apparently 57 + # having a multiple of 2^32 clusters 58 + # (To be more specific: It is at 32 PB) 59 + poke_file "$TEST_IMG" 2048 "\x80\x80\x00\x00\x00\x00\x00\x00" 60 + 61 + # An offset of 32 PB results in qemu-img check having to allocate an in-memory 62 + # refcount table of 128 TB (16 bit refcounts, 512 byte clusters). 63 + # This should be generally too much for any system and thus fail. 64 + # What this test is checking is that the qcow2 driver actually tries to allocate 65 + # such a large amount of memory (and is consequently aborting) instead of having 66 + # truncated the cluster count somewhere (which would result in much less memory 67 + # being allocated and then a segfault occurring). 68 + _check_test_img 69 + 70 + # success, all done 71 + echo "*** done" 72 + rm -f $seq.full 73 + status=0
+9
tests/qemu-iotests/138.out
··· 1 + QA output created by 138 2 + 3 + === Check on an image with a multiple of 2^32 clusters === 4 + 5 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512 6 + wrote 512/512 bytes at offset 0 7 + 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 8 + qemu-img: Check failed: Cannot allocate memory 9 + *** done
+2
tests/qemu-iotests/group
··· 134 134 132 rw auto quick 135 135 134 rw auto quick 136 136 135 rw auto 137 + 137 rw auto 138 + 138 rw auto quick