diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-08-11 19:48:50 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-08-11 19:48:50 -0500 |
commit | 53810bab3acd73b9844807e53f02d867c1ad1d2a (patch) | |
tree | d39df6643c81aa0f9f6c3da3d549cb6bc56c2e4e /block | |
parent | 312942619af7bd81bda57769224a8280684dd1cf (diff) | |
parent | 166f3c7b7026f9cd55a7daeec3b3444ec41092ab (diff) |
Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony:
qemu-iotests: skip 039 with ./check -nocache
block: add BLOCK_O_CHECK for qemu-img check
qcow2: mark image clean after repair succeeds
qed: mark image clean after repair succeeds
blockdev: flip default cache mode from writethrough to writeback
virtio-blk: disable write cache if not negotiated
virtio-blk: support VIRTIO_BLK_F_CONFIG_WCE
qemu-iotests: Save some sed processes
ahci: Fix sglist memleak in ahci_dma_rw_buf()
ahci: Fix ahci cdrom read corruptions for reads > 128k
virtio-blk: fix use-after-free while handling scsi commands
Diffstat (limited to 'block')
-rw-r--r-- | block/qcow2.c | 32 | ||||
-rw-r--r-- | block/qed-check.c | 26 | ||||
-rw-r--r-- | block/qed.c | 11 | ||||
-rw-r--r-- | block/qed.h | 5 |
4 files changed, 50 insertions, 24 deletions
diff --git a/block/qcow2.c b/block/qcow2.c index fd5e214431..8f183f1465 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -270,6 +270,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 +484,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; } @@ -1568,13 +1577,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) { diff --git a/block/qed-check.c b/block/qed-check.c index 5edf60775b..b473dcd61f 100644 --- a/block/qed-check.c +++ b/block/qed-check.c @@ -194,6 +194,28 @@ static void qed_check_for_leaks(QEDCheck *check) } } +/** + * Mark an image clean once it passes check or has been repaired + */ +static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result) +{ + /* Skip if there were unfixable corruptions or I/O errors */ + if (result->corruptions > 0 || result->check_errors > 0) { + return; + } + + /* Skip if image is already marked clean */ + if (!(s->header.features & QED_F_NEED_CHECK)) { + return; + } + + /* Ensure fixes reach storage before clearing check bit */ + bdrv_flush(s->bs); + + s->header.features &= ~QED_F_NEED_CHECK; + qed_write_header_sync(s); +} + int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) { QEDCheck check = { @@ -215,6 +237,10 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) if (ret == 0) { /* Only check for leaks if entire image was scanned successfully */ qed_check_for_leaks(&check); + + if (fix) { + qed_check_mark_clean(s, result); + } } g_free(check.used_clusters); diff --git a/block/qed.c b/block/qed.c index 5f3eefa3af..a02dbfd72d 100644 --- a/block/qed.c +++ b/block/qed.c @@ -89,7 +89,7 @@ static void qed_header_cpu_to_le(const QEDHeader *cpu, QEDHeader *le) le->backing_filename_size = cpu_to_le32(cpu->backing_filename_size); } -static int qed_write_header_sync(BDRVQEDState *s) +int qed_write_header_sync(BDRVQEDState *s) { QEDHeader le; int ret; @@ -477,7 +477,7 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags) } /* If image was not closed cleanly, check consistency */ - if (s->header.features & QED_F_NEED_CHECK) { + if (!(flags & BDRV_O_CHECK) && (s->header.features & QED_F_NEED_CHECK)) { /* Read-only images cannot be fixed. There is no risk of corruption * since write operations are not possible. Therefore, allow * potentially inconsistent images to be opened read-only. This can @@ -491,13 +491,6 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags) if (ret) { goto out; } - if (!result.corruptions && !result.check_errors) { - /* Ensure fixes reach storage before clearing check bit */ - bdrv_flush(s->bs); - - s->header.features &= ~QED_F_NEED_CHECK; - qed_write_header_sync(s); - } } } diff --git a/block/qed.h b/block/qed.h index c716772ad7..a063bf70af 100644 --- a/block/qed.h +++ b/block/qed.h @@ -211,6 +211,11 @@ void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque); void gencb_complete(void *opaque, int ret); /** + * Header functions + */ +int qed_write_header_sync(BDRVQEDState *s); + +/** * L2 cache functions */ void qed_init_l2_cache(L2TableCache *l2_cache); |