902636
From c818a1cb603cad07aa5c49ce808aa09435667c7c Mon Sep 17 00:00:00 2001
902636
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
902636
Date: Mon, 27 Jan 2020 19:01:04 +0100
902636
Subject: [PATCH 033/116] virtiofsd: Keep track of replies
902636
MIME-Version: 1.0
902636
Content-Type: text/plain; charset=UTF-8
902636
Content-Transfer-Encoding: 8bit
902636
902636
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
902636
Message-id: <20200127190227.40942-30-dgilbert@redhat.com>
902636
Patchwork-id: 93481
902636
O-Subject: [RHEL-AV-8.2 qemu-kvm PATCH 029/112] virtiofsd: Keep track of replies
902636
Bugzilla: 1694164
902636
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
902636
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
902636
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
902636
902636
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
902636
902636
Keep track of whether we sent a reply to a request; this is a bit
902636
paranoid but it means:
902636
  a) We should always recycle an element even if there was an error
902636
     in the request
902636
  b) Never try and send two replies on one queue element
902636
902636
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
902636
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
902636
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
902636
(cherry picked from commit 2f65e69a7f22da8d20c747f34f339ebb40a0634f)
902636
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
902636
---
902636
 tools/virtiofsd/fuse_virtio.c | 23 ++++++++++++++++++++---
902636
 1 file changed, 20 insertions(+), 3 deletions(-)
902636
902636
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
902636
index 05d0e29..f1adeb6 100644
902636
--- a/tools/virtiofsd/fuse_virtio.c
902636
+++ b/tools/virtiofsd/fuse_virtio.c
902636
@@ -44,6 +44,7 @@ struct fv_QueueInfo {
902636
 
902636
     /* The element for the command currently being processed */
902636
     VuVirtqElement *qe;
902636
+    bool reply_sent;
902636
 };
902636
 
902636
 /*
902636
@@ -178,6 +179,7 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
902636
 {
902636
     VuVirtqElement *elem;
902636
     VuVirtq *q;
902636
+    int ret = 0;
902636
 
902636
     assert(count >= 1);
902636
     assert(iov[0].iov_len >= sizeof(struct fuse_out_header));
902636
@@ -191,6 +193,7 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
902636
     assert(out->unique);
902636
     /* For virtio we always have ch */
902636
     assert(ch);
902636
+    assert(!ch->qi->reply_sent);
902636
     elem = ch->qi->qe;
902636
     q = &ch->qi->virtio_dev->dev.vq[ch->qi->qidx];
902636
 
902636
@@ -208,19 +211,23 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
902636
     if (in_len < sizeof(struct fuse_out_header)) {
902636
         fuse_log(FUSE_LOG_ERR, "%s: elem %d too short for out_header\n",
902636
                  __func__, elem->index);
902636
-        return -E2BIG;
902636
+        ret = -E2BIG;
902636
+        goto err;
902636
     }
902636
     if (in_len < tosend_len) {
902636
         fuse_log(FUSE_LOG_ERR, "%s: elem %d too small for data len %zd\n",
902636
                  __func__, elem->index, tosend_len);
902636
-        return -E2BIG;
902636
+        ret = -E2BIG;
902636
+        goto err;
902636
     }
902636
 
902636
     copy_iov(iov, count, in_sg, in_num, tosend_len);
902636
     vu_queue_push(&se->virtio_dev->dev, q, elem, tosend_len);
902636
     vu_queue_notify(&se->virtio_dev->dev, q);
902636
+    ch->qi->reply_sent = true;
902636
 
902636
-    return 0;
902636
+err:
902636
+    return ret;
902636
 }
902636
 
902636
 /* Thread function for individual queues, created when a queue is 'started' */
902636
@@ -296,6 +303,9 @@ static void *fv_queue_thread(void *opaque)
902636
                 break;
902636
             }
902636
 
902636
+            qi->qe = elem;
902636
+            qi->reply_sent = false;
902636
+
902636
             if (!fbuf.mem) {
902636
                 fbuf.mem = malloc(se->bufsize);
902636
                 assert(fbuf.mem);
902636
@@ -331,6 +341,13 @@ static void *fv_queue_thread(void *opaque)
902636
             /* TODO: Add checks for fuse_session_exited */
902636
             fuse_session_process_buf_int(se, &fbuf, &ch);
902636
 
902636
+            if (!qi->reply_sent) {
902636
+                fuse_log(FUSE_LOG_DEBUG, "%s: elem %d no reply sent\n",
902636
+                         __func__, elem->index);
902636
+                /* I think we've still got to recycle the element */
902636
+                vu_queue_push(dev, q, elem, 0);
902636
+                vu_queue_notify(dev, q);
902636
+            }
902636
             qi->qe = NULL;
902636
             free(elem);
902636
             elem = NULL;
902636
-- 
902636
1.8.3.1
902636