aboutsummaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-04-25 12:22:37 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-04-25 12:22:37 +0100
commit7931b05987564b07ada5a4467d8e78a786a3e7d4 (patch)
treec3cb42df6e17e3985c055637700dea279c5b7656 /block.c
parent0e96643c98eb22a5f2e11ac500852133032d38e4 (diff)
parent370e681629da587af7592a7b83ebc7ec4955461e (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches # gpg: Signature made Wed 23 Apr 2014 11:02:29 BST using RSA key ID C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" * remotes/kevin/tags/for-upstream: block/cloop: use PRIu32 format specifier for uint32_t vmdk: Fix "%x" to PRIx32 in format strings for cid qemu-img: Improve error messages qemu-iotests: Check common namespace for id and node-name block: Catch duplicate IDs in bdrv_new() qemu-img: Avoid duplicate block device IDs block: Add errp to bdrv_new() convert fprintf() calls to error_setg() in block/qed.c:bdrv_qed_create() block: Remove -errno return value from bdrv_assign_node_name curl: Replaced old error handling with error reporting API. block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap vmdk: Fix %d and %lld to PRI* in format strings block: Check bdrv_getlength() return value in bdrv_make_zero() block: Catch integer overflow in bdrv_rw_co() block: Limit size to INT_MAX in bdrv_check_byte_request() block: Fix nb_sectors check in bdrv_check_byte_request() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block.c')
-rw-r--r--block.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/block.c b/block.c
index 990a7542a9..fc2edd33ae 100644
--- a/block.c
+++ b/block.c
@@ -332,10 +332,21 @@ void bdrv_register(BlockDriver *bdrv)
}
/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name)
+BlockDriverState *bdrv_new(const char *device_name, Error **errp)
{
BlockDriverState *bs;
+ if (bdrv_find(device_name)) {
+ error_setg(errp, "Device with id '%s' already exists",
+ device_name);
+ return NULL;
+ }
+ if (bdrv_find_node(device_name)) {
+ error_setg(errp, "Device with node-name '%s' already exists",
+ device_name);
+ return NULL;
+ }
+
bs = g_malloc0(sizeof(BlockDriverState));
QLIST_INIT(&bs->dirty_bitmaps);
pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
@@ -788,38 +799,36 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
return open_flags;
}
-static int bdrv_assign_node_name(BlockDriverState *bs,
- const char *node_name,
- Error **errp)
+static void bdrv_assign_node_name(BlockDriverState *bs,
+ const char *node_name,
+ Error **errp)
{
if (!node_name) {
- return 0;
+ return;
}
/* empty string node name is invalid */
if (node_name[0] == '\0') {
error_setg(errp, "Empty node name");
- return -EINVAL;
+ return;
}
/* takes care of avoiding namespaces collisions */
if (bdrv_find(node_name)) {
error_setg(errp, "node-name=%s is conflicting with a device id",
node_name);
- return -EINVAL;
+ return;
}
/* takes care of avoiding duplicates node names */
if (bdrv_find_node(node_name)) {
error_setg(errp, "Duplicate node name");
- return -EINVAL;
+ return;
}
/* copy node name into the bs and insert it into the graph list */
pstrcpy(bs->node_name, sizeof(bs->node_name), node_name);
QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs, node_list);
-
- return 0;
}
/*
@@ -854,9 +863,10 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
node_name = qdict_get_try_str(options, "node-name");
- ret = bdrv_assign_node_name(bs, node_name, errp);
- if (ret < 0) {
- return ret;
+ bdrv_assign_node_name(bs, node_name, &local_err);
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+ return -EINVAL;
}
qdict_del(options, "node-name");
@@ -1221,7 +1231,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
qdict_put(snapshot_options, "file.filename",
qstring_from_str(tmp_filename));
- bs_snapshot = bdrv_new("");
+ bs_snapshot = bdrv_new("", &error_abort);
bs_snapshot->is_temporary = 1;
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
@@ -1288,7 +1298,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
if (*pbs) {
bs = *pbs;
} else {
- bs = bdrv_new("");
+ bs = bdrv_new("", &error_abort);
}
/* NULL means an empty set of options */
@@ -2581,6 +2591,10 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
{
int64_t len;
+ if (size > INT_MAX) {
+ return -EIO;
+ }
+
if (!bdrv_is_inserted(bs))
return -ENOMEDIUM;
@@ -2601,7 +2615,7 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
- if (nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
+ if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
return -EIO;
}
@@ -2686,6 +2700,10 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
};
+ if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
+ return -EINVAL;
+ }
+
qemu_iovec_init_external(&qiov, &iov, 1);
return bdrv_prwv_co(bs, sector_num << BDRV_SECTOR_BITS,
&qiov, is_write, flags);
@@ -2741,10 +2759,16 @@ int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
*/
int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)
{
- int64_t target_size = bdrv_getlength(bs) / BDRV_SECTOR_SIZE;
+ int64_t target_size;
int64_t ret, nb_sectors, sector_num = 0;
int n;
+ target_size = bdrv_getlength(bs);
+ if (target_size < 0) {
+ return target_size;
+ }
+ target_size /= BDRV_SECTOR_SIZE;
+
for (;;) {
nb_sectors = target_size - sector_num;
if (nb_sectors <= 0) {
@@ -5096,7 +5120,8 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return true;
}
-BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity)
+BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity,
+ Error **errp)
{
int64_t bitmap_size;
BdrvDirtyBitmap *bitmap;
@@ -5105,7 +5130,13 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity)
granularity >>= BDRV_SECTOR_BITS;
assert(granularity);
- bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
+ bitmap_size = bdrv_getlength(bs);
+ if (bitmap_size < 0) {
+ error_setg_errno(errp, -bitmap_size, "could not get length of device");
+ errno = -bitmap_size;
+ return NULL;
+ }
+ bitmap_size >>= BDRV_SECTOR_BITS;
bitmap = g_malloc0(sizeof(BdrvDirtyBitmap));
bitmap->bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);