[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 02/20] block: Handle failure for potentially large a
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 02/20] block: Handle failure for potentially large allocations |
Date: |
Wed, 21 May 2014 18:28:00 +0200 |
Some code in the block layer makes potentially huge allocations. Failure
is not completely unexpected there, so avoid aborting qemu and handle
out-of-memory situations gracefully.
This patch addresses bounce buffer allocations in block.c. While at it,
convert bdrv_commit() from plain g_malloc() to qemu_try_blockalign().
Signed-off-by: Kevin Wolf <address@hidden>
---
block.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index 5940d1b..c989ac1 100644
--- a/block.c
+++ b/block.c
@@ -2270,7 +2270,10 @@ int bdrv_commit(BlockDriverState *bs)
}
total_sectors = length >> BDRV_SECTOR_BITS;
- buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
+
+ /* qemu_try_blockalign() for bs will choose an alignment that works for
+ * bs->backing_hd as well, so no need to compare the alignment manually. */
+ buf = qemu_try_blockalign(bs, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
for (sector = 0; sector < total_sectors; sector += n) {
ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
@@ -2969,7 +2972,12 @@ static int coroutine_fn
bdrv_co_do_copy_on_readv(BlockDriverState *bs,
cluster_sector_num, cluster_nb_sectors);
iov.iov_len = cluster_nb_sectors * BDRV_SECTOR_SIZE;
- iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len);
+ iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);
+ if (bounce_buffer == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
qemu_iovec_init_external(&bounce_qiov, &iov, 1);
ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors,
@@ -3241,7 +3249,11 @@ static int coroutine_fn
bdrv_co_do_write_zeroes(BlockDriverState *bs,
/* Fall back to bounce buffer if write zeroes is unsupported */
iov.iov_len = num * BDRV_SECTOR_SIZE;
if (iov.iov_base == NULL) {
- iov.iov_base = qemu_blockalign(bs, num * BDRV_SECTOR_SIZE);
+ iov.iov_base = qemu_try_blockalign(bs, num * BDRV_SECTOR_SIZE);
+ if (iov.iov_base == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+ }
memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE);
}
qemu_iovec_init_external(&qiov, &iov, 1);
@@ -3261,6 +3273,7 @@ static int coroutine_fn
bdrv_co_do_write_zeroes(BlockDriverState *bs,
nb_sectors -= num;
}
+fail:
qemu_vfree(iov.iov_base);
return ret;
}
@@ -4569,8 +4582,9 @@ static void bdrv_aio_bh_cb(void *opaque)
{
BlockDriverAIOCBSync *acb = opaque;
- if (!acb->is_write)
+ if (!acb->is_write && acb->ret >= 0) {
qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
+ }
qemu_vfree(acb->bounce);
acb->common.cb(acb->common.opaque, acb->ret);
qemu_bh_delete(acb->bh);
@@ -4592,10 +4606,12 @@ static BlockDriverAIOCB
*bdrv_aio_rw_vector(BlockDriverState *bs,
acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque);
acb->is_write = is_write;
acb->qiov = qiov;
- acb->bounce = qemu_blockalign(bs, qiov->size);
+ acb->bounce = qemu_try_blockalign(bs, qiov->size);
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
- if (is_write) {
+ if (acb->bounce == NULL) {
+ acb->ret = -ENOMEM;
+ } else if (is_write) {
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce,
nb_sectors);
} else {
--
1.8.3.1
- [Qemu-devel] [PATCH 00/20] block: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 01/20] block: Introduce qemu_try_blockalign(), Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 03/20] bochs: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 04/20] cloop: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 02/20] block: Handle failure for potentially large allocations,
Kevin Wolf <=
- [Qemu-devel] [PATCH 05/20] curl: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 06/20] dmg: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 07/20] iscsi: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21
- [Qemu-devel] [PATCH 09/20] parallels: Handle failure for potentially large allocations, Kevin Wolf, 2014/05/21