qcow2: check request on vmstate save/load path
We modify the request by adding an offset to vmstate. Let's check the modified request. It will help us to safely move .bdrv_co_preadv_part and .bdrv_co_pwritev_part to int64_t type of offset and bytes. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210903102807.27127-3-vsementsov@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
b984b2968b
commit
558902cc3d
@ -956,7 +956,7 @@ bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
|
|||||||
return waited;
|
return waited;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
|
int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -5227,24 +5227,55 @@ static int qcow2_has_zero_init(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the request to vmstate. On success return
|
||||||
|
* qcow2_vm_state_offset(bs) + @pos
|
||||||
|
*/
|
||||||
|
static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
|
||||||
|
QEMUIOVector *qiov, int64_t pos)
|
||||||
|
{
|
||||||
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
int64_t vmstate_offset = qcow2_vm_state_offset(s);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Incoming requests must be OK */
|
||||||
|
bdrv_check_qiov_request(pos, qiov->size, qiov, 0, &error_abort);
|
||||||
|
|
||||||
|
if (INT64_MAX - pos < vmstate_offset) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += vmstate_offset;
|
||||||
|
ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||||
int64_t pos)
|
int64_t pos)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||||
|
if (offset < 0) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
|
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
|
||||||
return bs->drv->bdrv_co_pwritev_part(bs, qcow2_vm_state_offset(s) + pos,
|
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
|
||||||
qiov->size, qiov, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||||
int64_t pos)
|
int64_t pos)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||||
|
if (offset < 0) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
|
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
|
||||||
return bs->drv->bdrv_co_preadv_part(bs, qcow2_vm_state_offset(s) + pos,
|
return bs->drv->bdrv_co_preadv_part(bs, offset, qiov->size, qiov, 0, 0);
|
||||||
qiov->size, qiov, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -94,6 +94,9 @@ typedef struct BdrvTrackedRequest {
|
|||||||
struct BdrvTrackedRequest *waiting_for;
|
struct BdrvTrackedRequest *waiting_for;
|
||||||
} BdrvTrackedRequest;
|
} BdrvTrackedRequest;
|
||||||
|
|
||||||
|
int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
|
Error **errp);
|
||||||
int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
|
int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
|
||||||
|
|
||||||
struct BlockDriver {
|
struct BlockDriver {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user