Commit 3d9442ee authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging



Block layer patches:

- qcow2: Allow overwriting multiple compressed clusters at once for
  better performance
- nfs: add support for nfs_umount
- file-posix: write_zeroes fixes
- qemu-io, blockdev-create, pr-manager: Fix crashes and memory leaks
- qcow2: Fix the calculation of the maximum L2 cache size
- vpc: Fix return code for vpc_co_create()
- blockjob: Code cleanup
- iotests improvements (e.g. for use with valgrind)

# gpg: Signature made Fri 13 Sep 2019 11:19:19 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (23 commits)
  qcow2: Stop overwriting compressed clusters one by one
  block/create: Do not abort if a block driver is not available
  qemu-io: Don't leak pattern file in error path
  iotests: extend sleeping time under Valgrind
  iotests: extended timeout under Valgrind
  iotests: Valgrind fails with nonexistent directory
  iotests: Add casenotrun report to bash tests
  iotests: exclude killed processes from running under Valgrind
  iotests: allow Valgrind checking all QEMU processes
  block/nfs: add support for nfs_umount
  block/nfs: tear down aio before nfs_close
  iotests: skip 232 when run tests as root
  iotests: Test blockdev-create for vpc
  iotests: Restrict nbd Python tests to nbd
  iotests: Restrict file Python tests to file
  iotests: Add supported protocols to execute_test()
  vpc: Return 0 from vpc_co_create() on success
  file-posix: Fix has_write_zeroes after NO_FALLBACK
  pr-manager: Fix invalid g_free() crash bug
  iotests: Test reverse sub-cluster qcow2 writes
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents cc9c8b82 bf3d78ae
Loading
Loading
Loading
Loading
+1 −18
Original line number Diff line number Diff line
@@ -425,21 +425,6 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
    bdrv_set_dirty_bitmap(backup_job->copy_bitmap, 0, backup_job->len);
}

static void backup_drain(BlockJob *job)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common);

    /* Need to keep a reference in case blk_drain triggers execution
     * of backup_complete...
     */
    if (s->target) {
        BlockBackend *target = s->target;
        blk_ref(target);
        blk_drain(target);
        blk_unref(target);
    }
}

static BlockErrorAction backup_error_action(BackupBlockJob *job,
                                            bool read, int error)
{
@@ -588,13 +573,11 @@ static const BlockJobDriver backup_job_driver = {
        .job_type               = JOB_TYPE_BACKUP,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .run                    = backup_run,
        .commit                 = backup_commit,
        .abort                  = backup_abort,
        .clean                  = backup_clean,
    },
    .drain                  = backup_drain,
    }
};

static int64_t backup_calculate_cluster_size(BlockDriverState *target,
+0 −1
Original line number Diff line number Diff line
@@ -216,7 +216,6 @@ static const BlockJobDriver commit_job_driver = {
        .job_type      = JOB_TYPE_COMMIT,
        .free          = block_job_free,
        .user_resume   = block_job_user_resume,
        .drain         = block_job_drain,
        .run           = commit_run,
        .prepare       = commit_prepare,
        .abort         = commit_abort,
+5 −1
Original line number Diff line number Diff line
@@ -64,9 +64,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
    const char *fmt = BlockdevDriver_str(options->driver);
    BlockDriver *drv = bdrv_find_format(fmt);

    if (!drv) {
        error_setg(errp, "Block driver '%s' not found or not supported", fmt);
        return;
    }

    /* If the driver is in the schema, we know that it exists. But it may not
     * be whitelisted. */
    assert(drv);
    if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
        error_setg(errp, "Driver is not whitelisted");
        return;
+4 −79
Original line number Diff line number Diff line
@@ -1459,59 +1459,6 @@ out:
    }
}

#ifdef CONFIG_XFS
static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
    int64_t len;
    struct xfs_flock64 fl;
    int err;

    len = lseek(s->fd, 0, SEEK_END);
    if (len < 0) {
        return -errno;
    }

    if (offset + bytes > len) {
        /* XFS_IOC_ZERO_RANGE does not increase the file length */
        if (ftruncate(s->fd, offset + bytes) < 0) {
            return -errno;
        }
    }

    memset(&fl, 0, sizeof(fl));
    fl.l_whence = SEEK_SET;
    fl.l_start = offset;
    fl.l_len = bytes;

    if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) {
        err = errno;
        trace_file_xfs_write_zeroes(strerror(errno));
        return -err;
    }

    return 0;
}

static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
    struct xfs_flock64 fl;
    int err;

    memset(&fl, 0, sizeof(fl));
    fl.l_whence = SEEK_SET;
    fl.l_start = offset;
    fl.l_len = bytes;

    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
        err = errno;
        trace_file_xfs_discard(strerror(errno));
        return -err;
    }

    return 0;
}
#endif

static int translate_err(int err)
{
    if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
@@ -1555,22 +1502,20 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
        } while (errno == EINTR);

        ret = translate_err(-errno);
    }
#endif

        if (ret == -ENOTSUP) {
            s->has_write_zeroes = false;
        }
    }
#endif

    return ret;
}

static int handle_aiocb_write_zeroes(void *opaque)
{
    RawPosixAIOData *aiocb = opaque;
#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
    BDRVRawState *s = aiocb->bs->opaque;
#endif
#ifdef CONFIG_FALLOCATE
    BDRVRawState *s = aiocb->bs->opaque;
    int64_t len;
#endif

@@ -1578,12 +1523,6 @@ static int handle_aiocb_write_zeroes(void *opaque)
        return handle_aiocb_write_zeroes_block(aiocb);
    }

#ifdef CONFIG_XFS
    if (s->is_xfs) {
        return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
    }
#endif

#ifdef CONFIG_FALLOCATE_ZERO_RANGE
    if (s->has_write_zeroes) {
        int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
@@ -1653,14 +1592,6 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
    }
#endif

#ifdef CONFIG_XFS
    if (s->is_xfs) {
        /* xfs_discard() guarantees that the discarded area reads as all-zero
         * afterwards, so we can use it here. */
        return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
    }
#endif

    /* If we couldn't manage to unmap while guaranteed that the area reads as
     * all-zero afterwards, just write zeroes without unmapping */
    ret = handle_aiocb_write_zeroes(aiocb);
@@ -1737,12 +1668,6 @@ static int handle_aiocb_discard(void *opaque)
        ret = -errno;
#endif
    } else {
#ifdef CONFIG_XFS
        if (s->is_xfs) {
            return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
        }
#endif

#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
        ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
                           aiocb->aio_offset, aiocb->aio_nbytes);
+3 −25
Original line number Diff line number Diff line
@@ -646,14 +646,11 @@ static int mirror_exit_common(Job *job)
    bdrv_ref(mirror_top_bs);
    bdrv_ref(target_bs);

    /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
    /*
     * Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
     * inserting target_bs at s->to_replace, where we might not be able to get
     * these permissions.
     *
     * Note that blk_unref() alone doesn't necessarily drop permissions because
     * we might be running nested inside mirror_drain(), which takes an extra
     * reference, so use an explicit blk_set_perm() first. */
    blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
     */
    blk_unref(s->target);
    s->target = NULL;

@@ -1149,28 +1146,12 @@ static bool mirror_drained_poll(BlockJob *job)
    return !!s->in_flight;
}

static void mirror_drain(BlockJob *job)
{
    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);

    /* Need to keep a reference in case blk_drain triggers execution
     * of mirror_complete...
     */
    if (s->target) {
        BlockBackend *target = s->target;
        blk_ref(target);
        blk_drain(target);
        blk_unref(target);
    }
}

static const BlockJobDriver mirror_job_driver = {
    .job_driver = {
        .instance_size          = sizeof(MirrorBlockJob),
        .job_type               = JOB_TYPE_MIRROR,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .run                    = mirror_run,
        .prepare                = mirror_prepare,
        .abort                  = mirror_abort,
@@ -1178,7 +1159,6 @@ static const BlockJobDriver mirror_job_driver = {
        .complete               = mirror_complete,
    },
    .drained_poll           = mirror_drained_poll,
    .drain                  = mirror_drain,
};

static const BlockJobDriver commit_active_job_driver = {
@@ -1187,7 +1167,6 @@ static const BlockJobDriver commit_active_job_driver = {
        .job_type               = JOB_TYPE_COMMIT,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .run                    = mirror_run,
        .prepare                = mirror_prepare,
        .abort                  = mirror_abort,
@@ -1195,7 +1174,6 @@ static const BlockJobDriver commit_active_job_driver = {
        .complete               = mirror_complete,
    },
    .drained_poll           = mirror_drained_poll,
    .drain                  = mirror_drain,
};

static void coroutine_fn
Loading