Commit eaa2410f authored by Kevin Wolf's avatar Kevin Wolf
Browse files

block: Require auto-read-only for existing fallbacks



Some block drivers have traditionally changed their node to read-only
mode without asking the user. This behaviour has been marked deprecated
since 2.11, expecting users to provide an explicit read-only=on option.

Now that we have auto-read-only=on, enable these drivers to make use of
the option.

This is the only use of bdrv_set_read_only(), so we can make it a bit
more specific and turn it into a bdrv_apply_auto_read_only() that is
more convenient for drivers to use.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent a51b9c48
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -266,29 +266,41 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
    return 0;
}

/* TODO Remove (deprecated since 2.11)
 * Block drivers are not supposed to automatically change bs->read_only.
 * Instead, they should just check whether they can provide what the user
 * explicitly requested and error out if read-write is requested, but they can
 * only provide read-only access. */
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
/*
 * Called by a driver that can only provide a read-only image.
 *
 * Returns 0 if the node is already read-only or it could switch the node to
 * read-only because BDRV_O_AUTO_RDONLY is set.
 *
 * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
 * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
 * is not NULL, it is used as the error message for the Error object.
 */
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
                              Error **errp)
{
    int ret = 0;

    ret = bdrv_can_set_read_only(bs, read_only, false, errp);
    if (ret < 0) {
        return ret;
    if (!(bs->open_flags & BDRV_O_RDWR)) {
        return 0;
    }
    if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
        goto fail;
    }

    bs->read_only = read_only;
    ret = bdrv_can_set_read_only(bs, true, false, NULL);
    if (ret < 0) {
        goto fail;
    }

    if (read_only) {
    bs->read_only = true;
    bs->open_flags &= ~BDRV_O_RDWR;
    } else {
        bs->open_flags |= BDRV_O_RDWR;
    }

    return 0;

fail:
    error_setg(errp, "%s", errmsg ?: "Image is read-only");
    return -EACCES;
}

void bdrv_get_full_backing_filename_from_filename(const char *backed,
+6 −11
Original line number Diff line number Diff line
@@ -105,23 +105,18 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
    struct bochs_header bochs;
    int ret;

    /* No write support yet */
    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
    if (ret < 0) {
        return ret;
    }

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    if (!bdrv_is_read_only(bs)) {
        error_report("Opening bochs images without an explicit read-only=on "
                     "option is deprecated. Future versions will refuse to "
                     "open the image instead of automatically marking the "
                     "image read-only.");
        ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
        if (ret < 0) {
            return ret;
        }
    }

    ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
    if (ret < 0) {
        return ret;
+5 −11
Original line number Diff line number Diff line
@@ -67,23 +67,17 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
    uint32_t offsets_size, max_compressed_block_size = 1, i;
    int ret;

    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
    if (ret < 0) {
        return ret;
    }

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    if (!bdrv_is_read_only(bs)) {
        error_report("Opening cloop images without an explicit read-only=on "
                     "option is deprecated. Future versions will refuse to "
                     "open the image instead of automatically marking the "
                     "image read-only.");
        ret = bdrv_set_read_only(bs, true, errp);
        if (ret < 0) {
            return ret;
        }
    }

    /* read header */
    ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
    if (ret < 0) {
+5 −11
Original line number Diff line number Diff line
@@ -413,23 +413,17 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
    int64_t offset;
    int ret;

    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
    if (ret < 0) {
        return ret;
    }

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    if (!bdrv_is_read_only(bs)) {
        error_report("Opening dmg images without an explicit read-only=on "
                     "option is deprecated. Future versions will refuse to "
                     "open the image instead of automatically marking the "
                     "image read-only.");
        ret = bdrv_set_read_only(bs, true, errp);
        if (ret < 0) {
            return ret;
        }
    }

    block_module_load_one("dmg-bz2");

    s->n_chunks = 0;
+4 −11
Original line number Diff line number Diff line
@@ -780,19 +780,12 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
    /* If we are using an rbd snapshot, we must be r/o, otherwise
     * leave as-is */
    if (s->snap != NULL) {
        if (!bdrv_is_read_only(bs)) {
            error_report("Opening rbd snapshots without an explicit "
                         "read-only=on option is deprecated. Future versions "
                         "will refuse to open the image instead of "
                         "automatically marking the image read-only.");
            r = bdrv_set_read_only(bs, true, &local_err);
        r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
        if (r < 0) {
            rbd_close(s->image);
                error_propagate(errp, local_err);
            goto failed_open;
        }
    }
    }

    r = 0;
    goto out;
Loading