Skip to content

Commit

Permalink
qcow2: Add corrupt bit
Browse files Browse the repository at this point in the history
This adds an incompatible bit indicating corruption to qcow2. Any image
with this bit set may not be written to unless for repairing (and
subsequently clearing the bit if the repair has been successful).

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
XanClic authored and kevmw committed Aug 30, 2013
1 parent 449df70 commit 69c9872
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 9 deletions.
47 changes: 47 additions & 0 deletions block/qcow2.c
Expand Up @@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
return 0;
}

/*
* Marks the image as corrupt.
*/
int qcow2_mark_corrupt(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;

s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
return qcow2_update_header(bs);
}

/*
* Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
* before if necessary.
*/
int qcow2_mark_consistent(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;

if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
int ret = bdrv_flush(bs);
if (ret < 0) {
return ret;
}

s->incompatible_features &= ~QCOW2_INCOMPAT_CORRUPT;
return qcow2_update_header(bs);
}
return 0;
}

static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
Expand Down Expand Up @@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
goto fail;
}

if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
/* Corrupt images may not be written to unless they are being repaired
*/
if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
error_report("qcow2: Image is corrupt; cannot be opened "
"read/write.");
ret = -EACCES;
goto fail;
}
}

/* Check support for various header values */
if (header.refcount_order != 4) {
report_unsupported(bs, "%d bit reference counts",
Expand Down Expand Up @@ -1129,6 +1171,11 @@ int qcow2_update_header(BlockDriverState *bs)
.bit = QCOW2_INCOMPAT_DIRTY_BITNR,
.name = "dirty bit",
},
{
.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
.bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
.name = "corrupt bit",
},
{
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
Expand Down
7 changes: 6 additions & 1 deletion block/qcow2.h
Expand Up @@ -119,9 +119,12 @@ enum {
/* Incompatible feature bits */
enum {
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,

QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY,
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
| QCOW2_INCOMPAT_CORRUPT,
};

/* Compatible feature bits */
Expand Down Expand Up @@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
int64_t sector_num, int nb_sectors);

int qcow2_mark_dirty(BlockDriverState *bs);
int qcow2_mark_corrupt(BlockDriverState *bs);
int qcow2_mark_consistent(BlockDriverState *bs);
int qcow2_update_header(BlockDriverState *bs);

/* qcow2-refcount.c functions */
Expand Down
7 changes: 6 additions & 1 deletion docs/specs/qcow2.txt
Expand Up @@ -80,7 +80,12 @@ in the description of a field.
tables to repair refcounts before accessing the
image.

Bits 1-63: Reserved (set to 0)
Bit 1: Corrupt bit. If this bit is set then any data
structure may be corrupt and the image must not
be written to (unless for regaining
consistency).

Bits 2-63: Reserved (set to 0)

80 - 87: compatible_features
Bitmask of compatible features. An implementation can
Expand Down
12 changes: 6 additions & 6 deletions tests/qemu-iotests/031.out
Expand Up @@ -54,7 +54,7 @@ header_length 72

Header extension:
magic 0x6803f857
length 96
length 144
data <binary>

Header extension:
Expand All @@ -68,7 +68,7 @@ No errors were found on the image.

magic 0x514649fb
version 2
backing_file_offset 0xf8
backing_file_offset 0x128
backing_file_size 0x17
cluster_bits 16
size 67108864
Expand All @@ -92,7 +92,7 @@ data 'host_device'

Header extension:
magic 0x6803f857
length 96
length 144
data <binary>

Header extension:
Expand Down Expand Up @@ -155,7 +155,7 @@ header_length 104

Header extension:
magic 0x6803f857
length 96
length 144
data <binary>

Header extension:
Expand All @@ -169,7 +169,7 @@ No errors were found on the image.

magic 0x514649fb
version 3
backing_file_offset 0x118
backing_file_offset 0x148
backing_file_size 0x17
cluster_bits 16
size 67108864
Expand All @@ -193,7 +193,7 @@ data 'host_device'

Header extension:
magic 0x6803f857
length 96
length 144
data <binary>

Header extension:
Expand Down
2 changes: 1 addition & 1 deletion tests/qemu-iotests/036.out
Expand Up @@ -46,7 +46,7 @@ header_length 104

Header extension:
magic 0x6803f857
length 96
length 144
data <binary>

*** done

0 comments on commit 69c9872

Please sign in to comment.