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