aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-05-11 09:29:46 -0400
committerAvi Kivity <avi@redhat.com>2011-05-11 09:29:46 -0400
commitd32e8d0b8d9e0ef7cf7ab2e74548982972789dfc (patch)
tree78e2227555623d6f3121232925b8a78ef36d962c
parentf92dbe7878e00c350d97d85068d8beee2db00af5 (diff)
parent56a60dd6d619877e9957ba06b92d2f276e3c229d (diff)
Merge commit 'v0.14.1' into stable-0.14qemu-kvm-0.14.1stable-0.14
* commit 'v0.14.1': Version 0.14.1 virtio-blk: fail unaligned requests qed: Fix consistency check on 32-bit hosts exit if -drive specified is invalid instead of ignoring the "wrong" -drive vhost: fix dirty page handling Do not delete BlockDriverState when deleting the drive vnc: tight: Fix crash after 2GB of output lan9118: Ignore write to MAC_VLAN1 register Don't allow multiwrites against a block device without underlying medium Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--VERSION2
-rw-r--r--block.c22
-rw-r--r--block.h1
-rw-r--r--block/qed-check.c4
-rw-r--r--block/qed.h2
-rw-r--r--blockdev.c25
-rw-r--r--hw/lan9118.c6
-rw-r--r--hw/vhost.c4
-rw-r--r--hw/virtio-blk.c8
-rw-r--r--ui/vnc-enc-tight.c5
-rw-r--r--ui/vnc-enc-zlib.c4
-rw-r--r--vl.c4
12 files changed, 57 insertions, 30 deletions
diff --git a/VERSION b/VERSION
index a803cc227..930e3000b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.14.0
+0.14.1
diff --git a/block.c b/block.c
index b476479e0..b203875be 100644
--- a/block.c
+++ b/block.c
@@ -697,14 +697,22 @@ void bdrv_close_all(void)
}
}
+/* make a BlockDriverState anonymous by removing from bdrv_state list.
+ Also, NULL terminate the device_name to prevent double remove */
+void bdrv_make_anon(BlockDriverState *bs)
+{
+ if (bs->device_name[0] != '\0') {
+ QTAILQ_REMOVE(&bdrv_states, bs, list);
+ }
+ bs->device_name[0] = '\0';
+}
+
void bdrv_delete(BlockDriverState *bs)
{
assert(!bs->peer);
/* remove from list, if necessary */
- if (bs->device_name[0] != '\0') {
- QTAILQ_REMOVE(&bdrv_states, bs, list);
- }
+ bdrv_make_anon(bs);
bdrv_close(bs);
if (bs->file != NULL) {
@@ -2295,6 +2303,14 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
MultiwriteCB *mcb;
int i;
+ /* don't submit writes if we don't have a medium */
+ if (bs->drv == NULL) {
+ for (i = 0; i < num_reqs; i++) {
+ reqs[i].error = -ENOMEDIUM;
+ }
+ return -1;
+ }
+
if (num_reqs == 0) {
return 0;
}
diff --git a/block.h b/block.h
index 19f476887..097b78975 100644
--- a/block.h
+++ b/block.h
@@ -66,6 +66,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
QEMUOptionParameter *options);
int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
BlockDriverState *bdrv_new(const char *device_name);
+void bdrv_make_anon(BlockDriverState *bs);
void bdrv_delete(BlockDriverState *bs);
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
diff --git a/block/qed-check.c b/block/qed-check.c
index 4600932bf..474c847d1 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -18,7 +18,7 @@ typedef struct {
BdrvCheckResult *result;
bool fix; /* whether to fix invalid offsets */
- size_t nclusters;
+ uint64_t nclusters;
uint32_t *used_clusters; /* referenced cluster bitmap */
QEDRequest request;
@@ -176,7 +176,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
static void qed_check_for_leaks(QEDCheck *check)
{
BDRVQEDState *s = check->s;
- size_t i;
+ uint64_t i;
for (i = s->header.header_size; i < check->nclusters; i++) {
if (!qed_test_bit(check->used_clusters, i)) {
diff --git a/block/qed.h b/block/qed.h
index 2925e37b1..9f72ad549 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -251,7 +251,7 @@ static inline uint64_t qed_offset_into_cluster(BDRVQEDState *s, uint64_t offset)
return offset & (s->header.cluster_size - 1);
}
-static inline unsigned int qed_bytes_to_clusters(BDRVQEDState *s, size_t bytes)
+static inline uint64_t qed_bytes_to_clusters(BDRVQEDState *s, uint64_t bytes)
{
return qed_start_of_cluster(s, bytes + (s->header.cluster_size - 1)) /
(s->header.cluster_size - 1);
diff --git a/blockdev.c b/blockdev.c
index 335a77bab..5a97c09b8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -739,8 +739,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *id = qdict_get_str(qdict, "id");
BlockDriverState *bs;
- BlockDriverState **ptr;
- Property *prop;
bs = bdrv_find(id);
if (!bs) {
@@ -757,24 +755,17 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
bdrv_flush(bs);
bdrv_close(bs);
- /* clean up guest state from pointing to host resource by
- * finding and removing DeviceState "drive" property */
+ /* if we have a device associated with this BlockDriverState (bs->peer)
+ * then we need to make the drive anonymous until the device
+ * can be removed. If this is a drive with no device backing
+ * then we can just get rid of the block driver state right here.
+ */
if (bs->peer) {
- for (prop = bs->peer->info->props; prop && prop->name; prop++) {
- if (prop->info->type == PROP_TYPE_DRIVE) {
- ptr = qdev_get_prop_ptr(bs->peer, prop);
- if (*ptr == bs) {
- bdrv_detach(bs, bs->peer);
- *ptr = NULL;
- break;
- }
- }
- }
+ bdrv_make_anon(bs);
+ } else {
+ drive_uninit(drive_get_by_blockdev(bs));
}
- /* clean up host side */
- drive_uninit(drive_get_by_blockdev(bs));
-
return 0;
}
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 9cc7952b2..4ce9eb369 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -785,6 +785,12 @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
case MAC_FLOW:
s->mac_flow = val & 0xffff0000;
break;
+ case MAC_VLAN1:
+ /* Writing to this register changes a condition for
+ * FrameTooLong bit in rx_status. Since we do not set
+ * FrameTooLong anyway, just ignore write to this.
+ */
+ break;
default:
hw_error("lan9118: Unimplemented MAC register write: %d = 0x%x\n",
s->mac_cmd & 0xf, val);
diff --git a/hw/vhost.c b/hw/vhost.c
index 38cc3b365..6c194f0f8 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -47,8 +47,10 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
log = __sync_fetch_and_and(from, 0);
while ((bit = sizeof(log) > sizeof(int) ?
ffsll(log) : ffs(log))) {
+ ram_addr_t ram_addr;
bit -= 1;
- cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE);
+ ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
+ cpu_physical_memory_set_dirty(ram_addr);
log &= ~(0x1ull << bit);
}
addr += VHOST_LOG_CHUNK;
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index ffac5a4d8..114c63888 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -290,6 +290,10 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
virtio_blk_rw_complete(req, -EIO);
return;
}
+ if (req->qiov.size % req->dev->conf->logical_block_size) {
+ virtio_blk_rw_complete(req, -EIO);
+ return;
+ }
if (mrb->num_writes == 32) {
virtio_submit_multiwrite(req->dev->bs, mrb);
@@ -317,6 +321,10 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
virtio_blk_rw_complete(req, -EIO);
return;
}
+ if (req->qiov.size % req->dev->conf->logical_block_size) {
+ virtio_blk_rw_complete(req, -EIO);
+ return;
+ }
acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
req->qiov.size / BDRV_SECTOR_SIZE,
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index af45edd87..f9b982e3e 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -848,8 +848,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
zstream->avail_in = vs->tight.tight.offset;
zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
+ previous_out = zstream->avail_out;
zstream->data_type = Z_BINARY;
- previous_out = zstream->total_out;
/* start encoding */
if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -858,7 +858,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
}
vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
- bytes = zstream->total_out - previous_out;
+ /* ...how much data has actually been produced by deflate() */
+ bytes = previous_out - zstream->avail_out;
tight_send_compact_size(vs, bytes);
vnc_write(vs, vs->tight.zlib.buffer, bytes);
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index 3c6e6abf9..e32e4cd8a 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -103,8 +103,8 @@ static int vnc_zlib_stop(VncState *vs)
zstream->avail_in = vs->zlib.zlib.offset;
zstream->next_out = vs->output.buffer + vs->output.offset;
zstream->avail_out = vs->output.capacity - vs->output.offset;
+ previous_out = zstream->avail_out;
zstream->data_type = Z_BINARY;
- previous_out = zstream->total_out;
// start encoding
if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -113,7 +113,7 @@ static int vnc_zlib_stop(VncState *vs)
}
vs->output.offset = vs->output.capacity - zstream->avail_out;
- return zstream->total_out - previous_out;
+ return previous_out - zstream->avail_out;
}
int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
diff --git a/vl.c b/vl.c
index 85c36e3af..6da06bbe0 100644
--- a/vl.c
+++ b/vl.c
@@ -2090,7 +2090,9 @@ int main(int argc, char **argv, char **envp)
HD_OPTS);
break;
case QEMU_OPTION_drive:
- drive_def(optarg);
+ if (drive_def(optarg) == NULL) {
+ exit(1);
+ }
break;
case QEMU_OPTION_set:
if (qemu_set_option(optarg) != 0)