]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/9p/trans_virtio.c
ARM: dts: ls1021a: Add missing cooling device properties for CPUs
[mirror_ubuntu-bionic-kernel.git] / net / 9p / trans_virtio.c
index f3a4efcf1456422a6c6f036e8b7364f89b407bfd..e73fd647065a1a597a41fad86a256f6b19ff4fdf 100644 (file)
@@ -160,7 +160,8 @@ static void req_done(struct virtqueue *vq)
                spin_unlock_irqrestore(&chan->lock, flags);
                /* Wakeup if anyone waiting for VirtIO ring space. */
                wake_up(chan->vc_wq);
-               p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
+               if (len)
+                       p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
        }
 }
 
@@ -188,7 +189,7 @@ static int pack_sg_list(struct scatterlist *sg, int start,
                s = rest_of_page(data);
                if (s > count)
                        s = count;
-               BUG_ON(index > limit);
+               BUG_ON(index >= limit);
                /* Make sure we don't terminate early. */
                sg_unmark_end(&sg[index]);
                sg_set_buf(&sg[index++], data, s);
@@ -233,6 +234,7 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit,
                s = PAGE_SIZE - data_off;
                if (s > count)
                        s = count;
+               BUG_ON(index >= limit);
                /* Make sure we don't terminate early. */
                sg_unmark_end(&sg[index]);
                sg_set_page(&sg[index++], pdata[i++], s, data_off);
@@ -405,6 +407,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
        p9_debug(P9_DEBUG_TRANS, "virtio request\n");
 
        if (uodata) {
+               __le32 sz;
                int n = p9_get_mapped_pages(chan, &out_pages, uodata,
                                            outlen, &offs, &need_drop);
                if (n < 0)
@@ -415,6 +418,12 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
                        memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
                        outlen = n;
                }
+               /* The size field of the message must include the length of the
+                * header and the length of the data.  We didn't actually know
+                * the length of the data until this point so add it in now.
+                */
+               sz = cpu_to_le32(req->tc->size + outlen);
+               memcpy(&req->tc->sdata[0], &sz, sizeof(sz));
        } else if (uidata) {
                int n = p9_get_mapped_pages(chan, &in_pages, uidata,
                                            inlen, &offs, &need_drop);
@@ -562,7 +571,7 @@ static int p9_virtio_probe(struct virtio_device *vdev)
        chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
        if (IS_ERR(chan->vq)) {
                err = PTR_ERR(chan->vq);
-               goto out_free_vq;
+               goto out_free_chan;
        }
        chan->vq->vdev->priv = chan;
        spin_lock_init(&chan->lock);
@@ -615,6 +624,7 @@ out_free_tag:
        kfree(tag);
 out_free_vq:
        vdev->config->del_vqs(vdev);
+out_free_chan:
        kfree(chan);
 fail:
        return err;
@@ -642,6 +652,9 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
        int ret = -ENOENT;
        int found = 0;
 
+       if (devname == NULL)
+               return -EINVAL;
+
        mutex_lock(&virtio_9p_lock);
        list_for_each_entry(chan, &virtio_chan_list, chan_list) {
                if (!strncmp(devname, chan->tag, chan->tag_len) &&