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 <slp@redhat.com>
This commit is contained in:
Sergio Lopez 2020-02-26 10:46:10 +01:00 committed by Samuel Ortiz
parent 0c5c470247
commit e52129efb4

View File

@ -183,32 +183,34 @@ impl<F: FileSystem + Send + Sync + 'static> 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)