Commit e25cad69 authored by Markus Armbruster's avatar Markus Armbruster Committed by Kevin Wolf
Browse files

sheepdog: Fix error handling in sd_snapshot_delete()



As a bdrv_snapshot_delete() method, sd_snapshot_delete() must set an
error and return negative errno on failure.  It sometimes returns -1,
and sometimes neglects to set an error.  It also prints error messages
with error_report().  Fix all that.

Moreover, its handling of an attempt to delete a nonexistent snapshot
is wrong: it error_report()s and succeeds.  Fix it to set an error and
return -ENOENT instead.

Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent cbc488ee
Loading
Loading
Loading
Loading
+19 −22
Original line number Diff line number Diff line
@@ -2405,18 +2405,15 @@ out:

#define NR_BATCHED_DISCARD 128

static bool remove_objects(BDRVSheepdogState *s)
static int remove_objects(BDRVSheepdogState *s, Error **errp)
{
    int fd, i = 0, nr_objs = 0;
    Error *local_err = NULL;
    int ret = 0;
    bool result = true;
    int ret;
    SheepdogInode *inode = &s->inode;

    fd = connect_to_sdog(s, &local_err);
    fd = connect_to_sdog(s, errp);
    if (fd < 0) {
        error_report_err(local_err);
        return false;
        return fd;
    }

    nr_objs = count_data_objs(inode);
@@ -2446,15 +2443,15 @@ static bool remove_objects(BDRVSheepdogState *s)
                                    data_vdi_id[start_idx]),
                           false, s->cache_flags);
        if (ret < 0) {
            error_report("failed to discard snapshot inode.");
            result = false;
            error_setg(errp, "Failed to discard snapshot inode");
            goto out;
        }
    }

    ret = 0;
out:
    closesocket(fd);
    return result;
    return ret;
}

static int sd_snapshot_delete(BlockDriverState *bs,
@@ -2464,7 +2461,6 @@ static int sd_snapshot_delete(BlockDriverState *bs,
{
    unsigned long snap_id = 0;
    char snap_tag[SD_MAX_VDI_TAG_LEN];
    Error *local_err = NULL;
    int fd, ret;
    char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
    BDRVSheepdogState *s = bs->opaque;
@@ -2477,8 +2473,9 @@ static int sd_snapshot_delete(BlockDriverState *bs,
    };
    SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;

    if (!remove_objects(s)) {
        return -1;
    ret = remove_objects(s, errp);
    if (ret) {
        return ret;
    }

    memset(buf, 0, sizeof(buf));
@@ -2498,36 +2495,36 @@ static int sd_snapshot_delete(BlockDriverState *bs,
        pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag);
    }

    ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true,
                        &local_err);
    ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true, errp);
    if (ret) {
        return ret;
    }

    fd = connect_to_sdog(s, &local_err);
    fd = connect_to_sdog(s, errp);
    if (fd < 0) {
        error_report_err(local_err);
        return -1;
        return fd;
    }

    ret = do_req(fd, s->bs, (SheepdogReq *)&hdr,
                 buf, &wlen, &rlen);
    closesocket(fd);
    if (ret) {
        error_setg_errno(errp, -ret, "Couldn't send request to server");
        return ret;
    }

    switch (rsp->result) {
    case SD_RES_NO_VDI:
        error_report("%s was already deleted", s->name);
        error_setg(errp, "Can't find the snapshot");
        return -ENOENT;
    case SD_RES_SUCCESS:
        break;
    default:
        error_report("%s, %s", sd_strerror(rsp->result), s->name);
        return -1;
        error_setg(errp, "%s", sd_strerror(rsp->result));
        return -EIO;
    }

    return ret;
    return 0;
}

static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)