Commit 69c98726 authored by Max Reitz's avatar Max Reitz Committed by Kevin Wolf
Browse files

qcow2: Add corrupt bit



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: default avatarMax Reitz <mreitz@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 449df706
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -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)
{
@@ -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",
@@ -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,
+6 −1
Original line number Diff line number Diff line
@@ -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 */
@@ -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 */
+6 −1
Original line number Diff line number Diff line
@@ -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
+6 −6
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ header_length 72

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

Header extension:
@@ -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
@@ -92,7 +92,7 @@ data 'host_device'

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

Header extension:
@@ -155,7 +155,7 @@ header_length 104

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

Header extension:
@@ -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
@@ -193,7 +193,7 @@ data 'host_device'

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

Header extension:
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ header_length 104

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

*** done