Commit 8c0c5e63 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

Merge remote-tracking branch 'mreitz/tags/pull-block-2018-01-23' into queue-block



Block patches

# gpg: Signature made Tue Jan 23 12:35:11 2018 CET
# gpg:                using RSA key F407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* mreitz/tags/pull-block-2018-01-23: (25 commits)
  iotests: Disable some tests for compat=0.10
  iotests: Split 177 into two parts for compat=0.10
  iotests: Make 059 pass on machines with little RAM
  iotests: Filter compat-dependent info in 198
  iotests: Make 191 work with qcow2 options
  iotests: Make 184 image-less
  iotests: Make 089 compatible with compat=0.10
  iotests: Fix 067 for compat=0.10
  iotests: Fix 059's reference output
  iotests: Fix 051 for compat=0.10
  iotests: Fix 020 for vmdk
  iotests: Skip 103 for refcount_bits=1
  iotests: Forbid 020 for non-file protocols
  iotests: Drop format-specific in _filter_img_info
  iotests: Fix _img_info for backslashes
  block/vmdk: Add blkdebug events
  block/qcow: Add blkdebug events
  qcow2: No persistent dirty bitmaps for compat=0.10
  block/vmdk: Fix , instead of ; at end of line
  qemu-iotests: Fix locking issue in 102
  ...

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parents 7c3a3028 94254c9b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ static int get_cluster_offset(BlockDriverState *bs,
        /* update the L1 entry */
        s->l1_table[l1_index] = l2_offset;
        tmp = cpu_to_be64(l2_offset);
        BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
        ret = bdrv_pwrite_sync(bs->file,
                               s->l1_table_offset + l1_index * sizeof(tmp),
                               &tmp, sizeof(tmp));
@@ -409,6 +410,7 @@ static int get_cluster_offset(BlockDriverState *bs,
        }
    }
    l2_table = s->l2_cache + (min_index << s->l2_bits);
    BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
    if (new_l2_table) {
        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
        ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
@@ -432,6 +434,7 @@ static int get_cluster_offset(BlockDriverState *bs,
        ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
        if (!allocate)
            return 0;
        BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
        /* allocate a new cluster */
        if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
            (n_end - n_start) < s->cluster_sectors) {
@@ -447,6 +450,7 @@ static int get_cluster_offset(BlockDriverState *bs,
            }
            cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size);
            /* write the cluster content */
            BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
            ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache,
                              s->cluster_size);
            if (ret < 0) {
@@ -486,6 +490,7 @@ static int get_cluster_offset(BlockDriverState *bs,
                                                      NULL) < 0) {
                                return -EIO;
                            }
                            BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
                            ret = bdrv_pwrite(bs->file,
                                              cluster_offset + i * 512,
                                              s->cluster_data, 512);
@@ -503,6 +508,11 @@ static int get_cluster_offset(BlockDriverState *bs,
        /* update L2 table */
        tmp = cpu_to_be64(cluster_offset);
        l2_table[l2_index] = tmp;
        if (allocate == 2) {
            BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
        } else {
            BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
        }
        ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
                               &tmp, sizeof(tmp));
        if (ret < 0) {
@@ -579,6 +589,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
    if (s->cluster_cache_offset != coffset) {
        csize = cluster_offset >> (63 - s->cluster_bits);
        csize &= (s->cluster_size - 1);
        BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
        ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize);
        if (ret != csize)
            return -1;
@@ -635,6 +646,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
                hd_iov.iov_len = n * 512;
                qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
                qemu_co_mutex_unlock(&s->lock);
                /* qcow2 emits this on bs->file instead of bs->backing */
                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov);
                qemu_co_mutex_lock(&s->lock);
                if (ret < 0) {
@@ -661,6 +674,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
            hd_iov.iov_len = n * 512;
            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
            qemu_co_mutex_unlock(&s->lock);
            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
            ret = bdrv_co_readv(bs->file,
                                (cluster_offset >> 9) + index_in_cluster,
                                n, &hd_qiov);
@@ -754,6 +768,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
        hd_iov.iov_len = n * 512;
        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
        qemu_co_mutex_unlock(&s->lock);
        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
        ret = bdrv_co_writev(bs->file,
                             (cluster_offset >> 9) + index_in_cluster,
                             n, &hd_qiov);
@@ -1048,6 +1063,7 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
        .iov_len    = out_len,
    };
    qemu_iovec_init_external(&hd_qiov, &iov, 1);
    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
    ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
    if (ret < 0) {
        goto fail;
+10 −0
Original line number Diff line number Diff line
@@ -1449,6 +1449,16 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
    bool found;
    Qcow2BitmapList *bm_list;

    if (s->qcow_version < 3) {
        /* Without autoclear_features, we would always have to assume
         * that a program without persistent dirty bitmap support has
         * accessed this qcow2 file when opening it, and would thus
         * have to drop all dirty bitmaps (defeating their purpose).
         */
        error_setg(errp, "Cannot store dirty bitmaps in qcow2 v2 files");
        goto fail;
    }

    if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) {
        goto fail;
    }
+58 −12
Original line number Diff line number Diff line
@@ -1508,7 +1508,7 @@ enum {
static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
                              void **refcount_table,
                              int64_t *refcount_table_size, int64_t l2_offset,
                              int flags)
                              int flags, BdrvCheckMode fix)
{
    BDRVQcow2State *s = bs->opaque;
    uint64_t *l2_table, l2_entry;
@@ -1579,6 +1579,57 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
                next_contiguous_offset = offset + s->cluster_size;
            }

            /* Correct offsets are cluster aligned */
            if (offset_into_cluster(s, offset)) {
                if (qcow2_get_cluster_type(l2_entry) ==
                    QCOW2_CLUSTER_ZERO_ALLOC)
                {
                    fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero "
                            "cluster is not properly aligned; L2 entry "
                            "corrupted.\n",
                            fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR",
                            offset);
                    if (fix & BDRV_FIX_ERRORS) {
                        uint64_t l2e_offset =
                            l2_offset + (uint64_t)i * sizeof(uint64_t);

                        l2_entry = QCOW_OFLAG_ZERO;
                        l2_table[i] = cpu_to_be64(l2_entry);
                        ret = qcow2_pre_write_overlap_check(bs,
                                QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2,
                                l2e_offset, sizeof(uint64_t));
                        if (ret < 0) {
                            fprintf(stderr, "ERROR: Overlap check failed\n");
                            res->check_errors++;
                            /* Something is seriously wrong, so abort checking
                             * this L2 table */
                            goto fail;
                        }

                        ret = bdrv_pwrite_sync(bs->file, l2e_offset,
                                               &l2_table[i], sizeof(uint64_t));
                        if (ret < 0) {
                            fprintf(stderr, "ERROR: Failed to overwrite L2 "
                                    "table entry: %s\n", strerror(-ret));
                            res->check_errors++;
                            /* Do not abort, continue checking the rest of this
                             * L2 table's entries */
                        } else {
                            res->corruptions_fixed++;
                            /* Skip marking the cluster as used
                             * (it is unused now) */
                            continue;
                        }
                    } else {
                        res->corruptions++;
                    }
                } else {
                    fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is "
                        "not properly aligned; L2 entry corrupted.\n", offset);
                    res->corruptions++;
                }
            }

            /* Mark cluster as used */
            ret = qcow2_inc_refcounts_imrt(bs, res,
                                           refcount_table, refcount_table_size,
@@ -1586,13 +1637,6 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
            if (ret < 0) {
                goto fail;
            }

            /* Correct offsets are cluster aligned */
            if (offset_into_cluster(s, offset)) {
                fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "
                    "properly aligned; L2 entry corrupted.\n", offset);
                res->corruptions++;
            }
            break;
        }

@@ -1626,7 +1670,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
                              void **refcount_table,
                              int64_t *refcount_table_size,
                              int64_t l1_table_offset, int l1_size,
                              int flags)
                              int flags, BdrvCheckMode fix)
{
    BDRVQcow2State *s = bs->opaque;
    uint64_t *l1_table = NULL, l2_offset, l1_size2;
@@ -1681,7 +1725,8 @@ static int check_refcounts_l1(BlockDriverState *bs,

            /* Process and check L2 entries */
            ret = check_refcounts_l2(bs, res, refcount_table,
                                     refcount_table_size, l2_offset, flags);
                                     refcount_table_size, l2_offset, flags,
                                     fix);
            if (ret < 0) {
                goto fail;
            }
@@ -1957,7 +2002,8 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,

    /* current L1 table */
    ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
                             s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO);
                             s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO,
                             fix);
    if (ret < 0) {
        return ret;
    }
@@ -1966,7 +2012,7 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
    for (i = 0; i < s->nb_snapshots; i++) {
        sn = s->snapshots + i;
        ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
                                 sn->l1_table_offset, sn->l1_size, 0);
                                 sn->l1_table_offset, sn->l1_size, 0, fix);
        if (ret < 0) {
            return ret;
        }
+11 −3
Original line number Diff line number Diff line
@@ -302,9 +302,17 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
            }

            if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS)) {
                if (s->qcow_version < 3) {
                    /* Let's be a bit more specific */
                    warn_report("This qcow2 v2 image contains bitmaps, but "
                                "they may have been modified by a program "
                                "without persistent bitmap support; so now "
                                "they must all be considered inconsistent");
                } else {
                    warn_report("a program lacking bitmap support "
                                "modified this file, so all bitmaps are now "
                                "considered inconsistent");
                }
                error_printf("Some clusters may be leaked, "
                             "run 'qemu-img check -r' on the image "
                             "file to fix.");
+17 −1
Original line number Diff line number Diff line
@@ -1075,6 +1075,8 @@ static int get_whole_cluster(BlockDriverState *bs,
    /* Read backing data before skip range */
    if (skip_start_bytes > 0) {
        if (bs->backing) {
            /* qcow2 emits this on bs->file instead of bs->backing */
            BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
            ret = bdrv_pread(bs->backing, offset, whole_grain,
                             skip_start_bytes);
            if (ret < 0) {
@@ -1082,6 +1084,7 @@ static int get_whole_cluster(BlockDriverState *bs,
                goto exit;
            }
        }
        BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
        ret = bdrv_pwrite(extent->file, cluster_offset, whole_grain,
                          skip_start_bytes);
        if (ret < 0) {
@@ -1092,6 +1095,8 @@ static int get_whole_cluster(BlockDriverState *bs,
    /* Read backing data after skip range */
    if (skip_end_bytes < cluster_bytes) {
        if (bs->backing) {
            /* qcow2 emits this on bs->file instead of bs->backing */
            BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
            ret = bdrv_pread(bs->backing, offset + skip_end_bytes,
                             whole_grain + skip_end_bytes,
                             cluster_bytes - skip_end_bytes);
@@ -1100,6 +1105,7 @@ static int get_whole_cluster(BlockDriverState *bs,
                goto exit;
            }
        }
        BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
        ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes,
                          whole_grain + skip_end_bytes,
                          cluster_bytes - skip_end_bytes);
@@ -1120,6 +1126,7 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
{
    offset = cpu_to_le32(offset);
    /* update L2 table */
    BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE);
    if (bdrv_pwrite_sync(extent->file,
                ((int64_t)m_data->l2_offset * 512)
                    + (m_data->l2_index * sizeof(offset)),
@@ -1218,6 +1225,7 @@ static int get_cluster_offset(BlockDriverState *bs,
        }
    }
    l2_table = extent->l2_cache + (min_index * extent->l2_size);
    BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
    if (bdrv_pread(extent->file,
                (int64_t)l2_offset * 512,
                l2_table,
@@ -1393,12 +1401,16 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
            .iov_len    = n_bytes,
        };
        qemu_iovec_init_external(&local_qiov, &iov, 1);

        BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
    } else {
        qemu_iovec_init(&local_qiov, qiov->niov);
        qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes);

        BLKDBG_EVENT(extent->file, BLKDBG_WRITE_AIO);
    }

    write_offset = cluster_offset + offset_in_cluster,
    write_offset = cluster_offset + offset_in_cluster;
    ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
                          &local_qiov, 0);

@@ -1437,6 +1449,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,


    if (!extent->compressed) {
        BLKDBG_EVENT(extent->file, BLKDBG_READ_AIO);
        ret = bdrv_co_preadv(extent->file,
                             cluster_offset + offset_in_cluster, bytes,
                             qiov, 0);
@@ -1450,6 +1463,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
    buf_bytes = cluster_bytes * 2;
    cluster_buf = g_malloc(buf_bytes);
    uncomp_buf = g_malloc(cluster_bytes);
    BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
    ret = bdrv_pread(extent->file,
                cluster_offset,
                cluster_buf, buf_bytes);
@@ -1527,6 +1541,8 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
                qemu_iovec_reset(&local_qiov);
                qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

                /* qcow2 emits this on bs->file instead of bs->backing */
                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
                                     &local_qiov, 0);
                if (ret < 0) {
Loading