Skip to content

Commit 529fe3b

Browse files
wangyan0507Fei Xu
authored andcommitted
vhost-user-fs: fix the process of negotiation
If VHOST_USER_F_PROTOCOL_FEATURES has been negotiated, it should call set_vring_enable to enable vring. Otherwise, the ring is enabled by default. Currently, only vhost-user-blk device support negotiation of VHOST_USER_F_PROTOCOL_FEATURES. So, fix the negotiation process of vhost-user-fs. Signed-off-by: Yan Wang <[email protected]>
1 parent 9156089 commit 529fe3b

File tree

2 files changed

+69
-46
lines changed

2 files changed

+69
-46
lines changed

vhost_user_fs/src/virtio_fs.rs

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use util::loop_context::{
4040
gen_delete_notifiers, read_fd, EventNotifier, EventNotifierHelper, NotifierCallback,
4141
NotifierOperation,
4242
};
43-
use virtio::vhost::user::RegionMemInfo;
4443
use virtio::{
45-
Queue, QueueConfig, QUEUE_TYPE_SPLIT_VRING, VIRTIO_F_RING_EVENT_IDX,
44+
vhost::user::RegionMemInfo, virtio_has_feature, Queue, QueueConfig,
45+
VhostUser::VHOST_USER_F_PROTOCOL_FEATURES, QUEUE_TYPE_SPLIT_VRING, VIRTIO_F_RING_EVENT_IDX,
4646
VIRTIO_F_RING_INDIRECT_DESC, VIRTIO_F_VERSION_1,
4747
};
4848

@@ -246,6 +246,51 @@ impl VirtioFs {
246246

247247
bail!("Failed to find the guest address for addr: 0x{:X}", addr);
248248
}
249+
250+
fn register_fs_handler(&mut self, queue_index: usize) -> Result<()> {
251+
// Before setting up new notifiers, we should remove old ones.
252+
self.unregister_fs_handler(queue_index)?;
253+
254+
let driver_features = self.config.driver_features;
255+
let mut queue_info = self.config.get_mut_queue_config(queue_index)?;
256+
if queue_info.kick_evt.is_none() || queue_info.call_evt.is_none() {
257+
bail!(
258+
"The event for kicking {} or calling {} is none",
259+
queue_info.kick_evt.is_none(),
260+
queue_info.call_evt.is_none(),
261+
);
262+
}
263+
queue_info.config.ready = true;
264+
265+
let fs_handler = Arc::new(Mutex::new(
266+
FsIoHandler::new(
267+
queue_info.config,
268+
queue_info.kick_evt.as_ref().unwrap().clone(),
269+
queue_info.call_evt.as_ref().unwrap().clone(),
270+
&self.sys_mem,
271+
driver_features,
272+
self.fs.clone(),
273+
)
274+
.with_context(|| "Failed to create fs handler")?,
275+
));
276+
277+
self.fs_handlers[queue_index] = Some(fs_handler.clone());
278+
EventLoop::update_event(EventNotifierHelper::internal_notifiers(fs_handler), None)
279+
.with_context(|| "Failed to update event for queue status which is ready")?;
280+
281+
Ok(())
282+
}
283+
284+
fn unregister_fs_handler(&mut self, queue_index: usize) -> Result<()> {
285+
if let Some(fs_handler) = self.fs_handlers.get_mut(queue_index).unwrap().take() {
286+
EventLoop::update_event(fs_handler.lock().unwrap().delete_notifiers(), None)
287+
.with_context(|| "Failed to update event for queue status which is not ready")?;
288+
};
289+
let mut queue_info = self.config.get_mut_queue_config(queue_index)?;
290+
queue_info.config.ready = false;
291+
292+
Ok(())
293+
}
249294
}
250295

251296
impl VhostUserReqHandler for VirtioFs {
@@ -398,6 +443,11 @@ impl VhostUserReqHandler for VirtioFs {
398443
queue_info.call_evt = Some(Arc::new(call_evt));
399444
})
400445
.with_context(|| format!("Failed to set vring call, index: {}", index))?;
446+
447+
if !virtio_has_feature(self.config.driver_features, VHOST_USER_F_PROTOCOL_FEATURES) {
448+
self.register_fs_handler(queue_index)?;
449+
}
450+
401451
Ok(())
402452
}
403453

@@ -417,43 +467,11 @@ impl VhostUserReqHandler for VirtioFs {
417467
}
418468

419469
fn set_vring_enable(&mut self, queue_index: usize, status: u32) -> Result<()> {
420-
let driver_features = self.config.driver_features;
421-
422-
let mut queue_info = self.config.get_mut_queue_config(queue_index)?;
423-
queue_info.config.ready = status == 1;
424-
425-
// Before setting up new notifiers, we should remove old ones.
426-
if let Some(fs_handler) = self.fs_handlers.get_mut(queue_index).unwrap().take() {
427-
EventLoop::update_event(fs_handler.lock().unwrap().delete_notifiers(), None)
428-
.with_context(|| "Failed to update event for queue status which is not ready")?;
429-
};
430-
431470
if status == 1 {
432-
if queue_info.kick_evt.is_none() || queue_info.call_evt.is_none() {
433-
bail!(
434-
"The event for kicking {} or calling {} is none",
435-
queue_info.kick_evt.is_none(),
436-
queue_info.call_evt.is_none(),
437-
);
438-
}
439-
440-
let fs_handler = Arc::new(Mutex::new(
441-
FsIoHandler::new(
442-
queue_info.config,
443-
queue_info.kick_evt.as_ref().unwrap().clone(),
444-
queue_info.call_evt.as_ref().unwrap().clone(),
445-
&self.sys_mem,
446-
driver_features,
447-
self.fs.clone(),
448-
)
449-
.with_context(|| "Failed to create fs handler")?,
450-
));
451-
452-
self.fs_handlers[queue_index] = Some(fs_handler.clone());
453-
EventLoop::update_event(EventNotifierHelper::internal_notifiers(fs_handler), None)
454-
.with_context(|| "Failed to update event for queue status which is ready")?;
471+
self.register_fs_handler(queue_index)?;
472+
} else {
473+
self.unregister_fs_handler(queue_index)?;
455474
}
456-
457475
Ok(())
458476
}
459477
}

virtio/src/vhost/user/client.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -534,15 +534,20 @@ impl VhostUserClient {
534534
})?;
535535
}
536536

537-
for (queue_index, queue) in self.queues.iter().enumerate() {
538-
let enabled = queue.lock().unwrap().is_enabled();
539-
self.set_vring_enable(queue_index, enabled)
540-
.with_context(|| {
541-
format!(
542-
"Failed to set vring enable for vhost-user, index: {}",
543-
queue_index,
544-
)
545-
})?;
537+
if self.backend_type == VhostBackendType::TypeBlock {
538+
// If VHOST_USER_F_PROTOCOL_FEATURES has been negotiated, it should call
539+
// set_vring_enable to enable vring. Otherwise, the ring is enabled by default.
540+
// Currently, only vhost-user-blk device support negotiate VHOST_USER_F_PROTOCOL_FEATURES.
541+
for (queue_index, queue) in self.queues.iter().enumerate() {
542+
let enabled = queue.lock().unwrap().is_enabled();
543+
self.set_vring_enable(queue_index, enabled)
544+
.with_context(|| {
545+
format!(
546+
"Failed to set vring enable for vhost-user, index: {}",
547+
queue_index,
548+
)
549+
})?;
550+
}
546551
}
547552

548553
Ok(())

0 commit comments

Comments
 (0)