Skip to contentSkip to conversation

Block patches for stable-0.13

GIT PULL New Kevin Wolf 1 participant 7 messages Aug 30, 2010

lore
Share & tools
lore

Kevin Wolf

author
#0 lore raw

The following changes since commit 96638e706cd431528690cf611adcb04e1bc3255d:

ide: Avoid canceling IDE DMA (2010-08-03 16:39:54 +0200)

are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-stable-0.13

Andrew de Quincey (1):
posix-aio-compat: Fix async_conmtext for ioctl

Kevin Wolf (4):
virtio: Factor virtqueue_map_sg out
virtio-blk: Fix migration of queued requests
block: Fix image re-open in bdrv_commit qemu-img rebase: Open new backing file read-only

Loïc Minier (1):
vvfat: fat_chksum(): fix access above array bounds

 block.c            |   13 +++++++++----
 block/vvfat.c      |    2 +-
 hw/virtio-blk.c    |    5 +++++
 hw/virtio.c        |   38 ++++++++++++++++++++++++--------------
 hw/virtio.h        |    3 +++
 posix-aio-compat.c |    1 +
 qemu-img.c         |    2 +-
 7 files changed, 44 insertions(+), 20 deletions(-)
author
#1 lore raw

PATCH 1/6 virtio: Factor virtqueue_map_sg out

Separate the mapping of requests to host memory from the descriptor iteration. The next patch will make use of it in a different context.

(cherry picked from commit 42fb2e0720511fa1da2f8e751be393f851b71d80)
---
 hw/virtio.c |   38 ++++++++++++++++++++++++--------------
 hw/virtio.h |    3 +++
 2 files changed, 27 insertions(+), 14 deletions(-)
hw/virtio.c +24 -14
index 4475bb3..85312b3 100644
@@ -360,11 +360,26 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
     return 0;
 }
 
+void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
+    size_t num_sg, int is_write)
+{
+    unsigned int i;
+    target_phys_addr_t len;
+
+    for (i = 0; i < num_sg; i++) {
+        len = sg[i].iov_len;
+        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
+        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
+            fprintf(stderr, "virtio: trying to map MMIO memory\n");
+            exit(1);
+        }
+    }
+}
+
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 {
     unsigned int i, head, max;
     target_phys_addr_t desc_pa = vq->vring.desc;
-    target_phys_addr_t len;
 
     if (!virtqueue_num_heads(vq, vq->last_avail_idx))
         return 0;
@@ -388,28 +403,19 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
         i = 0;
     }
 
+    /* Collect all the descriptors */
     do {
         struct iovec *sg;
-        int is_write = 0;
 
         if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
             elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->in_sg[elem->in_num++];
-            is_write = 1;
-        } else
+        } else {
+            elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->out_sg[elem->out_num++];
+        }
 
-        /* Grab the first descriptor, and check it's OK. */
         sg->iov_len = vring_desc_len(desc_pa, i);
-        len = sg->iov_len;
-
-        sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i),
-                                               &len, is_write);
-
-        if (sg->iov_base == NULL || len != sg->iov_len) {
-            fprintf(stderr, "virtio: trying to map MMIO memory\n");
-            exit(1);
-        }
 
         /* If we've got too many, that implies a descriptor loop. */
         if ((elem->in_num + elem->out_num) > max) {
@@ -418,6 +424,10 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
         }
     } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
 
+    /* Now map what we have collected */
+    virtqueue_map_sg(elem->in_sg, elem->in_addr, elem->in_num, 1);
+    virtqueue_map_sg(elem->out_sg, elem->out_addr, elem->out_num, 0);
+
     elem->index = head;
 
     vq->inuse++;
hw/virtio.h +3 -0
index 30e472a..764970c 100644
@@ -81,6 +81,7 @@ typedef struct VirtQueueElement
     unsigned int out_num;
     unsigned int in_num;
     target_phys_addr_t in_addr[VIRTQUEUE_MAX_SIZE];
+    target_phys_addr_t out_addr[VIRTQUEUE_MAX_SIZE];
     struct iovec in_sg[VIRTQUEUE_MAX_SIZE];
     struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
 } VirtQueueElement;
@@ -142,6 +143,8 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count);
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
 
+void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
+    size_t num_sg, int is_write);
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
 int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
 
Signature · 1 line
1.7.2.2
author
#2 lore raw

PATCH 2/6 virtio-blk: Fix migration of queued requests

In reply to Kevin Wolf

in_sg[].iovec and out_sg[].ioved are pointer to (source) host memory and therefore invalid after migration. When loading the device state we must create a new mapping on the destination host.

(cherry picked from commit b6a4805b55b409134dc712677fdc4f6a8795e965)
---
 hw/virtio-blk.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
hw/virtio-blk.c +5 -0
index 490cd41..251779c 100644
@@ -480,6 +480,11 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
         qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
         req->next = s->rq;
         s->rq = req;
+
+        virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
+            req->elem.in_num, 1);
+        virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
+            req->elem.out_num, 0);
     }
 
     return 0;
Signature · 1 line
1.7.2.2
author
#3 lore raw

PATCH 3/6 block: Fix image re-open in bdrv_commit

In reply to Kevin Wolf

Arguably we should re-open the backing file with the backing file format and not with the format of the snapshot image.

(cherry picked from commit ee1811965fd15e0b41f8d508b951a8ab826ae3a7)

Conflicts:

block.c

---
 block.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
block.c +9 -4
index 8014a5c..e6087f3 100644
@@ -743,6 +743,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 int bdrv_commit(BlockDriverState *bs)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriver *backing_drv;
     int64_t i, total_sectors;
     int n, j, ro, open_flags;
     int ret = 0, rw_ret = 0;
@@ -760,7 +761,8 @@ int bdrv_commit(BlockDriverState *bs)
     if (bs->backing_hd->keep_read_only) {
         return -EACCES;
     }
-    
+
+    backing_drv = bs->backing_hd->drv;
     ro = bs->backing_hd->read_only;
     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
     open_flags =  bs->backing_hd->open_flags;
@@ -770,12 +772,14 @@ int bdrv_commit(BlockDriverState *bs)
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_rw = bdrv_new("");
-        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, drv);
+        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
+            backing_drv);
         if (rw_ret < 0) {
             bdrv_delete(bs_rw);
             /* try to re-open read-only */
             bs_ro = bdrv_new("");
-            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
+            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
+                backing_drv);
             if (ret < 0) {
                 bdrv_delete(bs_ro);
                 /* drive not functional anymore */
@@ -827,7 +831,8 @@ ro_cleanup:
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_ro = bdrv_new("");
-        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
+        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
+            backing_drv);
         if (ret < 0) {
             bdrv_delete(bs_ro);
             /* drive not functional anymore */
Signature · 1 line
1.7.2.2
author
#4 lore raw

PATCH 4/6 qemu-img rebase: Open new backing file read-only

In reply to Kevin Wolf

We never write to a backing file, so opening rw is useless. It just means that you can't rebase on top of a file for which you don't have write permissions.

(cherry picked from commit cdbae85169c384d1641aa1ae86cdeefe16285745)
---
 qemu-img.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
qemu-img.c +1 -1
index e300f91..d2a978b 100644
@@ -1286,7 +1286,7 @@ static int img_rebase(int argc, char **argv)
         }
 
         bs_new_backing = bdrv_new("new_backing");
-        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS | BDRV_O_RDWR,
+        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
                         new_backing_drv);
         if (ret) {
             error("Could not open new backing file '%s'", out_baseimg);
Signature · 1 line
1.7.2.2
author
#5 lore raw

PATCH 5/6 vvfat: fat_chksum(): fix access above array bounds

In reply to Kevin Wolf

From: Loïc Minier <[email protected]>

(cherry picked from commit 2aa326be0d2039f51192707bdb2fc935d0e87c21)
---
 block/vvfat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
block/vvfat.c +1 -1
index 6d61c2e..365332a 100644
@@ -512,7 +512,7 @@ static inline uint8_t fat_chksum(const direntry_t* entry)
     for(i=0;i<11;i++) {
         unsigned char c;
 
-        c = (i <= 8) ? entry->name[i] : entry->extension[i-8];
+        c = (i < 8) ? entry->name[i] : entry->extension[i-8];
         chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
     }
 
Signature · 1 line
1.7.2.2
author
#6 lore raw

PATCH 6/6 posix-aio-compat: Fix async_conmtext for ioctl

In reply to Kevin Wolf

From: Andrew de Quincey <[email protected]>

Set the async_context_id field when queuing an async ioctl call

(cherry picked from commit 34cf0081294513bc734896c9051c20ca6c19c3db)
---
 posix-aio-compat.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
posix-aio-compat.c +1 -0
index a67ffe3..efc5968 100644
@@ -599,6 +599,7 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,
     acb->aio_type = QEMU_AIO_IOCTL;
     acb->aio_fildes = fd;
     acb->ev_signo = SIGUSR2;
+    acb->async_context_id = get_async_context_id();
     acb->aio_offset = 0;
     acb->aio_ioctl_buf = buf;
     acb->aio_ioctl_cmd = req;
Signature · 1 line
1.7.2.2