diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-04-25 12:22:37 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-04-25 12:22:37 +0100 |
commit | 7931b05987564b07ada5a4467d8e78a786a3e7d4 (patch) | |
tree | c3cb42df6e17e3985c055637700dea279c5b7656 /block.c | |
parent | 0e96643c98eb22a5f2e11ac500852133032d38e4 (diff) | |
parent | 370e681629da587af7592a7b83ebc7ec4955461e (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.c | 69 |
1 files changed, 50 insertions, 19 deletions
@@ -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); |