From e52129efb429873368c17b60bc01318c72a31691 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Wed, 26 Feb 2020 10:46:10 +0100 Subject: [PATCH] vhost_user_fs: Process events from HIPRIO queue We weren't processing events arriving at the HIPRIO queue, which implied ignoring FUSE_INTERRUPT, FUSE_FORGET, and FUSE_BATCH_FORGET requests. One effect of this issue was that file descriptors weren't closed on the server, so it eventually hits RLIMIT_NOFILE. Additionally, the guest OS may hang while attempting to unmount the filesystem. Signed-off-by: Sergio Lopez --- src/bin/vhost_user_fs.rs | 42 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/bin/vhost_user_fs.rs b/src/bin/vhost_user_fs.rs index dd79988a0..3dc1329d6 100644 --- a/src/bin/vhost_user_fs.rs +++ b/src/bin/vhost_user_fs.rs @@ -183,32 +183,34 @@ impl VhostUserBackend for VhostUserFsBack return Err(Error::HandleEventNotEpollIn.into()); } - match device_event { + let mut vring = match device_event { HIPRIO_QUEUE_EVENT => { debug!("HIPRIO_QUEUE_EVENT"); + vrings[0].write().unwrap() } REQ_QUEUE_EVENT => { - debug!("REQ_QUEUE_EVENT"); - let mut vring = vrings[1].write().unwrap(); - if self.event_idx { - // vm-virtio's Queue implementation only checks avail_index - // once, so to properly support EVENT_IDX we need to keep - // calling process_queue() until it stops finding new - // requests on the queue. - loop { - vring.mut_queue().update_avail_event( - self.mem.as_ref().ok_or(Error::NoMemoryConfigured)?, - ); - if !self.process_queue(&mut vring)? { - break; - } - } - } else { - // Without EVENT_IDX, a single call is enough. - self.process_queue(&mut vring)?; - } + debug!("QUEUE_EVENT"); + vrings[1].write().unwrap() } _ => return Err(Error::HandleEventUnknownEvent.into()), + }; + + if self.event_idx { + // vm-virtio's Queue implementation only checks avail_index + // once, so to properly support EVENT_IDX we need to keep + // calling process_queue() until it stops finding new + // requests on the queue. + loop { + vring + .mut_queue() + .update_avail_event(self.mem.as_ref().unwrap()); + if !self.process_queue(&mut vring)? { + break; + } + } + } else { + // Without EVENT_IDX, a single call is enough. + self.process_queue(&mut vring)?; } Ok(false)