X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/d3da41e32bc6d6fac80d402aa1cc0f1d30539d98..c84649ca66a32aadba20a8202062b02247270ee5:/block/qcow2.c diff --git a/block/qcow2.c b/block/qcow2.c index fd5e214431..c1ff31f482 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -52,6 +52,7 @@ typedef struct { uint32_t magic; uint32_t len; } QCowExtension; + #define QCOW2_EXT_MAGIC_END 0 #define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA #define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857 @@ -270,6 +271,20 @@ static int qcow2_mark_clean(BlockDriverState *bs) return 0; } +static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result, + BdrvCheckMode fix) +{ + int ret = qcow2_check_refcounts(bs, result, fix); + if (ret < 0) { + return ret; + } + + if (fix && result->check_errors == 0 && result->corruptions == 0) { + return qcow2_mark_clean(bs); + } + return ret; +} + static int qcow2_open(BlockDriverState *bs, int flags) { BDRVQcowState *s = bs->opaque; @@ -470,16 +485,11 @@ static int qcow2_open(BlockDriverState *bs, int flags) qemu_co_mutex_init(&s->lock); /* Repair image if dirty */ - if ((s->incompatible_features & QCOW2_INCOMPAT_DIRTY) && - !bs->read_only) { + if (!(flags & BDRV_O_CHECK) && !bs->read_only && + (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) { BdrvCheckResult result = {0}; - ret = qcow2_check_refcounts(bs, &result, BDRV_FIX_ERRORS); - if (ret < 0) { - goto fail; - } - - ret = qcow2_mark_clean(bs); + ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS); if (ret < 0) { goto fail; } @@ -549,6 +559,14 @@ static int qcow2_set_key(BlockDriverState *bs, const char *key) return 0; } +/* We have nothing to do for QCOW2 reopen, stubs just return + * success */ +static int qcow2_reopen_prepare(BDRVReopenState *state, + BlockReopenQueue *queue, Error **errp) +{ + return 0; +} + static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { @@ -1078,6 +1096,7 @@ int qcow2_update_header(BlockDriverState *bs) goto fail; } + /* Using strncpy is ok here, since buf is not NUL-terminated. */ strncpy(buf, bs->backing_file, buflen); header->backing_file_offset = cpu_to_be64(buf - ((char*) header)); @@ -1568,13 +1587,6 @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return 0; } - -static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result, - BdrvCheckMode fix) -{ - return qcow2_check_refcounts(bs, result, fix); -} - #if 0 static void dump_refcounts(BlockDriverState *bs) { @@ -1677,6 +1689,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_probe = qcow2_probe, .bdrv_open = qcow2_open, .bdrv_close = qcow2_close, + .bdrv_reopen_prepare = qcow2_reopen_prepare, .bdrv_create = qcow2_create, .bdrv_co_is_allocated = qcow2_co_is_allocated, .bdrv_set_key = qcow2_set_key,