Blame 0035-virtiofsd-Keep-track-of-replies.patch

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