block: refactor bdrv_check_request: add errp

It's better to pass &error_abort than just assert that result is 0: on
crash, we'll immediately see the reason in the backtrace.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20201211183934.169161-2-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[eblake: fix iotest 206 fallout]
Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2020-12-11 21:39:19 +03:00 committed by Eric Blake
parent c930831446
commit 69b55e03f7
5 changed files with 28 additions and 12 deletions

View File

@ -2969,7 +2969,7 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
req->bytes = BDRV_MAX_LENGTH - req->offset;
assert(bdrv_check_request(req->offset, req->bytes) == 0);
bdrv_check_request(req->offset, req->bytes, &error_abort);
bdrv_make_request_serialising(req, bs->bl.request_alignment);
}

View File

@ -920,17 +920,34 @@ bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
return waited;
}
int bdrv_check_request(int64_t offset, int64_t bytes)
int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp)
{
if (offset < 0 || bytes < 0) {
if (offset < 0) {
error_setg(errp, "offset is negative: %" PRIi64, offset);
return -EIO;
}
if (bytes < 0) {
error_setg(errp, "bytes is negative: %" PRIi64, bytes);
return -EIO;
}
if (bytes > BDRV_MAX_LENGTH) {
error_setg(errp, "bytes(%" PRIi64 ") exceeds maximum(%" PRIi64 ")",
bytes, BDRV_MAX_LENGTH);
return -EIO;
}
if (offset > BDRV_MAX_LENGTH) {
error_setg(errp, "offset(%" PRIi64 ") exceeds maximum(%" PRIi64 ")",
offset, BDRV_MAX_LENGTH);
return -EIO;
}
if (offset > BDRV_MAX_LENGTH - bytes) {
error_setg(errp, "sum of offset(%" PRIi64 ") and bytes(%" PRIi64 ") "
"exceeds maximum(%" PRIi64 ")", offset, bytes,
BDRV_MAX_LENGTH);
return -EIO;
}
@ -939,7 +956,7 @@ int bdrv_check_request(int64_t offset, int64_t bytes)
static int bdrv_check_request32(int64_t offset, int64_t bytes)
{
int ret = bdrv_check_request(offset, bytes);
int ret = bdrv_check_request(offset, bytes, NULL);
if (ret < 0) {
return ret;
}
@ -2847,7 +2864,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
return -EPERM;
}
ret = bdrv_check_request(offset, bytes);
ret = bdrv_check_request(offset, bytes, NULL);
if (ret < 0) {
return ret;
}
@ -3249,10 +3266,8 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
return -EINVAL;
}
ret = bdrv_check_request(offset, 0);
ret = bdrv_check_request(offset, 0, errp);
if (ret < 0) {
error_setg(errp, "Required too big image size, it must be not greater "
"than %" PRId64, BDRV_MAX_LENGTH);
return ret;
}

View File

@ -93,7 +93,7 @@ typedef struct BdrvTrackedRequest {
struct BdrvTrackedRequest *waiting_for;
} BdrvTrackedRequest;
int bdrv_check_request(int64_t offset, int64_t bytes);
int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
struct BlockDriver {
const char *format_name;

View File

@ -180,7 +180,7 @@ Job failed: Could not resize image: Image size cannot be negative
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775296}}}
{"return": {}}
Job failed: Could not resize image: Required too big image size, it must be not greater than 9223372035781033984
Job failed: Could not resize image: offset(9223372036854775296) exceeds maximum(9223372035781033984)
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}

View File

@ -7,6 +7,7 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/write-threshold.h"
@ -64,7 +65,7 @@ static void test_threshold_not_trigger(void)
req.offset = 1024;
req.bytes = 1024;
assert(bdrv_check_request(req.offset, req.bytes) == 0);
bdrv_check_request(req.offset, req.bytes, &error_abort);
bdrv_write_threshold_set(&bs, threshold);
amount = bdrv_write_threshold_exceeded(&bs, &req);
@ -84,7 +85,7 @@ static void test_threshold_trigger(void)
req.offset = (4 * 1024 * 1024) - 1024;
req.bytes = 2 * 1024;
assert(bdrv_check_request(req.offset, req.bytes) == 0);
bdrv_check_request(req.offset, req.bytes, &error_abort);
bdrv_write_threshold_set(&bs, threshold);
amount = bdrv_write_threshold_exceeded(&bs, &req);