send_forget_request() documents return value 1 as caller should wait;
virtio_fs_hiprio_dispatch_work() treats any non-zero return as a signal to
stop processing the rest of queued_reqs.

When virtqueue_add_outbuf() fails with a non-recoverable error we kfree the
forget but left ret negative, so the worker returned early and stranded
subsequent queued FORGETs.  Return 0 after dropping so the queue keeps
draining.

Signed-off-by: Li Wang <[email protected]>
---
 fs/fuse/virtio_fs.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 7e4c3fa6ab57..e5d3d58a760c 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -652,6 +652,12 @@ static int send_forget_request(struct virtio_fs_vq *fsvq,
                        kfree(forget);
                        if (in_flight)
                                dec_in_flight_req(fsvq);
+                       /*
+                        * send_forget_request() returns 1 to mean "stop 
draining
+                        * queued_reqs for now".  A negative value is also 
non-zero
+                        * and would stall the worker after one dropped forget.
+                        */
+                       ret = 0;
                }
                goto out;
        }
-- 
2.34.1


Reply via email to