diff --git a/Cargo.toml b/Cargo.toml index b0d010dd..62b995db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,39 @@ members = [ "vhost-device-template", "vhost-device-vsock", ] + +[workspace.lints.rust] +unsafe_op_in_unsafe_fn = "deny" + +[workspace.lints.rustdoc] +broken_intra_doc_links = "deny" +redundant_explicit_links = "deny" + +[workspace.lints.clippy] +enum_glob_use = "deny" +# groups +correctness = { level = "deny", priority = -1 } +suspicious = { level = "deny", priority = -1 } +complexity = { level = "deny", priority = -1 } +perf = { level = "deny", priority = -1 } +style = { level = "deny", priority = -1 } +nursery = { level = "deny", priority = -1 } +# restriction +dbg_macro = "deny" +rc_buffer = "deny" +as_underscore = "deny" +assertions_on_result_states = "deny" +# pedantic +cast_lossless = "deny" +cast_possible_wrap = "deny" +cast_ptr_alignment = "deny" +naive_bytecount = "deny" +ptr_as_ptr = "deny" +bool_to_int_with_if = "deny" +borrow_as_ptr = "deny" +case_sensitive_file_extension_comparisons = "deny" +significant_drop_in_scrutinee = "allow" +significant_drop_tightening = "allow" +missing_safety_doc = "deny" +undocumented_unsafe_blocks = "deny" +option_if_let_else = "allow" diff --git a/staging/Cargo.toml b/staging/Cargo.toml index 88d41685..3989ddde 100644 --- a/staging/Cargo.toml +++ b/staging/Cargo.toml @@ -5,3 +5,39 @@ members = [ "vhost-device-can", "vhost-device-console", ] + +[workspace.lints.rust] +unsafe_op_in_unsafe_fn = "deny" + +[workspace.lints.rustdoc] +broken_intra_doc_links = "deny" +redundant_explicit_links = "deny" + +[workspace.lints.clippy] +enum_glob_use = "deny" +# groups +correctness = { level = "deny", priority = -1 } +suspicious = { level = "deny", priority = -1 } +complexity = { level = "deny", priority = -1 } +perf = { level = "deny", priority = -1 } +style = { level = "deny", priority = -1 } +nursery = { level = "deny", priority = -1 } +# restriction +dbg_macro = "deny" +rc_buffer = "deny" +as_underscore = "deny" +assertions_on_result_states = "deny" +# pedantic +cast_lossless = "deny" +cast_possible_wrap = "deny" +cast_ptr_alignment = "deny" +naive_bytecount = "deny" +ptr_as_ptr = "deny" +bool_to_int_with_if = "deny" +borrow_as_ptr = "deny" +case_sensitive_file_extension_comparisons = "deny" +significant_drop_in_scrutinee = "allow" +significant_drop_tightening = "allow" +missing_safety_doc = "deny" +undocumented_unsafe_blocks = "deny" +option_if_let_else = "allow" diff --git a/vhost-device-i2c/Cargo.toml b/vhost-device-i2c/Cargo.toml index 6193700b..c4b17ab1 100644 --- a/vhost-device-i2c/Cargo.toml +++ b/vhost-device-i2c/Cargo.toml @@ -9,6 +9,9 @@ keywords = ["i2c", "vhost", "virt", "backend"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" +[lints] +workspace = true + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] diff --git a/vhost-device-i2c/src/i2c.rs b/vhost-device-i2c/src/i2c.rs index e0f67f24..a4d778e5 100644 --- a/vhost-device-i2c/src/i2c.rs +++ b/vhost-device-i2c/src/i2c.rs @@ -27,9 +27,9 @@ type IoctlRequest = c_ulong; type Result = std::result::Result; -#[derive(Copy, Clone, Debug, PartialEq, ThisError)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, ThisError)] /// Errors related to low level i2c helpers -pub(crate) enum Error { +pub enum Error { #[error("Incorrect message length for {0} operation: {1}")] MessageLengthInvalid(&'static str, usize), #[error("Invalid SMBUS command: {0}")] @@ -56,8 +56,8 @@ pub(crate) enum Error { ParseFailure, } -/// Linux I2C/SMBUS definitions -/// IOCTL commands, refer Linux's Documentation/i2c/dev-interface.rst for further details. +// Linux I2C/SMBUS definitions +// IOCTL commands, refer Linux's Documentation/i2c/dev-interface.rst for further details. /// NOTE: Slave address is 7 or 10 bits, but 10-bit addresses are NOT supported! /// (due to code brokenness) @@ -66,7 +66,8 @@ const I2C_FUNCS: IoctlRequest = 0x0705; // Get the adapter functionality mask const I2C_RDWR: IoctlRequest = 0x0707; // Combined R/W transfer (one STOP only) const I2C_SMBUS: IoctlRequest = 0x0720; // SMBus transfer -/// Functions +// Functions + const I2C_FUNC_I2C: u64 = 0x00000001; const I2C_FUNC_SMBUS_READ_BYTE: u64 = 0x00020000; const I2C_FUNC_SMBUS_WRITE_BYTE: u64 = 0x00040000; @@ -83,13 +84,16 @@ const I2C_FUNC_SMBUS_WORD_DATA: u64 = const I2C_FUNC_SMBUS_ALL: u64 = I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA; -/// I2C protocol definitions -pub(crate) const I2C_M_RD: u16 = 0x0001; // read data, from slave to master +// I2C protocol definitions -/// Copied (partially) from Linux's include/uapi/linux/i2c.h +/// read data, from slave to master +pub const I2C_M_RD: u16 = 0x0001; + +/// `I2cMsg` - an I2C transaction segment beginning with `START` /// -/// I2cMsg - an I2C transaction segment beginning with START +/// Copied (partially) from Linux's include/uapi/linux/i2c.h /// +/// ```text /// @addr: Slave address, only 7 bit supported by virtio specification. /// /// @flags: @@ -107,14 +111,14 @@ pub(crate) const I2C_M_RD: u16 = 0x0001; // read data, from slave to master /// An I2cMsg is the low level representation of one segment of an I2C /// transaction. /// -/// Each transaction begins with a START. That is followed by the slave -/// address, and a bit encoding read versus write. Then follow all the -/// data bytes, possibly including a byte with SMBus PEC. The transfer +/// Each transaction begins with a START. That is followed by the slave +/// address, and a bit encoding read versus write. Then follow all the +/// data bytes, possibly including a byte with SMBus PEC. The transfer /// terminates with a NAK, or when all those bytes have been transferred -/// and ACKed. If this is the last message in a group, it is followed by -/// a STOP. Otherwise it is followed by the next @I2cMsg transaction +/// and ACKed. If this is the last message in a group, it is followed by +/// a STOP. Otherwise it is followed by the next @I2cMsg transaction /// segment, beginning with a (repeated) START. - +/// ``` #[repr(C)] struct I2cMsg { addr: u16, @@ -125,17 +129,19 @@ struct I2cMsg { /// This is the structure as used in the I2C_RDWR ioctl call #[repr(C)] -pub(crate) struct I2cRdwrIoctlData { +pub struct I2cRdwrIoctlData { msgs: *mut I2cMsg, nmsgs: u32, } -/// SMBUS protocol definitions -/// SMBUS read or write markers +// SMBUS protocol definitions +// SMBUS read or write markers + const I2C_SMBUS_WRITE: u8 = 0; const I2C_SMBUS_READ: u8 = 1; -/// SMBus transaction types (size parameter in the above functions) +// SMBus transaction types (size parameter in the above functions) + const I2C_SMBUS_QUICK: u32 = 0; const I2C_SMBUS_BYTE: u32 = 1; const I2C_SMBUS_BYTE_DATA: u32 = 2; @@ -154,27 +160,27 @@ union I2cSmbusData { } impl I2cSmbusData { - fn read_byte(&self) -> u8 { + const fn read_byte(&self) -> u8 { // SAFETY: Safe as we will only read the relevant bytes. unsafe { self.byte } } - fn read_word(&self) -> u16 { + const fn read_word(&self) -> u16 { // SAFETY: Safe as we will only read the relevant bytes. unsafe { self.word } } } -/// This is the structure as used in the I2C_SMBUS ioctl call +/// This is the structure as used in the `I2C_SMBUS` ioctl call #[repr(C)] -pub(crate) struct I2cSmbusIoctlData { +pub struct I2cSmbusIoctlData { read_write: u8, command: u8, size: u32, data: *mut I2cSmbusData, } -pub(crate) struct SmbusMsg { +pub struct SmbusMsg { read_write: u8, command: u8, size: u32, @@ -186,7 +192,7 @@ impl SmbusMsg { /// /// These smbus related functions try to reverse what Linux does, only /// support basic modes (up to word transfer). - fn new(reqs: &[I2cReq]) -> Result { + fn new(reqs: &[I2cReq]) -> Result { let mut data = I2cSmbusData { block: [0; I2C_SMBUS_BLOCK_MAX + 2], }; @@ -204,14 +210,14 @@ impl SmbusMsg { match reqs[0].len { // Special Read requests - 0 => Ok(SmbusMsg { + 0 => Ok(Self { read_write, command: 0, size: I2C_SMBUS_QUICK, data: None, }), - 1 => Ok(SmbusMsg { + 1 => Ok(Self { read_write, command: reqs[0].buf[0], size: I2C_SMBUS_BYTE, @@ -225,7 +231,7 @@ impl SmbusMsg { Err(Error::MessageLengthInvalid("read", 2)) } else { data.byte = reqs[0].buf[1]; - Ok(SmbusMsg { + Ok(Self { read_write, command: reqs[0].buf[0], size: I2C_SMBUS_BYTE_DATA, @@ -239,8 +245,9 @@ impl SmbusMsg { // Special Read requests, reqs[0].len can be 0 or 1 only. Err(Error::MessageLengthInvalid("read", 3)) } else { - data.word = reqs[0].buf[1] as u16 | ((reqs[0].buf[2] as u16) << 8); - Ok(SmbusMsg { + data.word = + u16::from(reqs[0].buf[1]) | (u16::from(reqs[0].buf[2]) << 8); + Ok(Self { read_write, command: reqs[0].buf[0], size: I2C_SMBUS_WORD_DATA, @@ -271,7 +278,7 @@ impl SmbusMsg { reqs[1].len, )) } else { - Ok(SmbusMsg { + Ok(Self { read_write: I2C_SMBUS_READ, command: reqs[0].buf[0], size: if reqs[1].len == 1 { @@ -294,7 +301,7 @@ impl SmbusMsg { } /// I2C definitions -pub(crate) struct I2cReq { +pub struct I2cReq { pub addr: u16, pub flags: u16, pub len: u16, @@ -307,7 +314,7 @@ pub(crate) struct I2cReq { /// be used outside of this crate. The purpose of this trait is to provide a /// mock implementation for the I2C driver so that we can test the I2C /// functionality without the need of a physical device. -pub(crate) trait I2cDevice { +pub trait I2cDevice { // Open the device specified by the adapter identifier, number or name. fn open(adapter_identifier: &AdapterIdentifier) -> Result where @@ -332,14 +339,14 @@ pub(crate) trait I2cDevice { /// A physical I2C device. This structure can only be initialized on hosts /// where `/dev/i2c-XX` is available. #[derive(Debug)] -pub(crate) struct PhysDevice { +pub struct PhysDevice { file: File, adapter_no: u32, } impl PhysDevice { fn open_with(device_path: &str, adapter_no: u32) -> Result { - Ok(PhysDevice { + Ok(Self { file: OpenOptions::new() .read(true) .write(true) @@ -376,7 +383,7 @@ impl PhysDevice { impl I2cDevice for PhysDevice { fn open(adapter_identifier: &AdapterIdentifier) -> Result { let adapter_no = match adapter_identifier { - AdapterIdentifier::Name(adapter_name) => PhysDevice::find_adapter(adapter_name)?, + AdapterIdentifier::Name(adapter_name) => Self::find_adapter(adapter_name)?, AdapterIdentifier::Number(no) => *no, }; let device_path = format!("/dev/i2c-{}", adapter_no); @@ -436,10 +443,7 @@ impl I2cDevice for PhysDevice { read_write: msg.read_write, command: msg.command, size: msg.size, - data: match &mut msg.data { - Some(data) => data, - _ => std::ptr::null_mut(), - }, + data: msg.data.as_mut().map_or(std::ptr::null_mut(), |data| data), }; // SAFETY: Safe as the file is a valid I2C adapter, the kernel will only @@ -470,7 +474,7 @@ impl I2cDevice for PhysDevice { } #[derive(Debug)] -pub(crate) struct I2cAdapter { +pub struct I2cAdapter { device: D, adapter_no: u32, smbus: bool, @@ -478,7 +482,7 @@ pub(crate) struct I2cAdapter { impl I2cAdapter { // Creates a new adapter corresponding to `device`. - fn new(mut device: D) -> Result> { + fn new(mut device: D) -> Result { let smbus; let func = device.funcs()?; @@ -490,7 +494,7 @@ impl I2cAdapter { return Err(Error::AdapterFunctionInvalid(func)); } - Ok(I2cAdapter { + Ok(Self { adapter_no: device.adapter_no(), device, smbus, @@ -527,11 +531,11 @@ impl I2cAdapter { Ok(()) } - fn adapter_no(&self) -> u32 { + const fn adapter_no(&self) -> u32 { self.adapter_no } - fn is_smbus(&self) -> bool { + const fn is_smbus(&self) -> bool { self.smbus } @@ -550,9 +554,9 @@ impl I2cAdapter { } /// I2C map and helpers -pub(crate) const MAX_I2C_VDEV: usize = 1 << 7; +pub const MAX_I2C_VDEV: usize = 1 << 7; -pub(crate) struct I2cMap { +pub struct I2cMap { adapters: Vec>, device_map: HashMap, } @@ -583,7 +587,7 @@ impl I2cMap { adapters.push(adapter); } - Ok(I2cMap { + Ok(Self { adapters, device_map, }) @@ -610,7 +614,7 @@ impl I2cMap { } #[cfg(test)] -pub(crate) mod tests { +pub mod tests { use super::*; use crate::DeviceConfig; use vmm_sys_util::tempfile::TempFile; @@ -639,7 +643,7 @@ pub(crate) mod tests { } impl DummyDevice { - fn find_adapter(_name: &str) -> Result { + const fn find_adapter(_name: &str) -> Result { Ok(11) } } @@ -662,11 +666,11 @@ pub(crate) mod tests { Self: Sized, { match adapter_identifier { - AdapterIdentifier::Name(adapter_name) => Ok(DummyDevice { - adapter_no: DummyDevice::find_adapter(adapter_name)?, + AdapterIdentifier::Name(adapter_name) => Ok(Self { + adapter_no: Self::find_adapter(adapter_name)?, ..Default::default() }), - AdapterIdentifier::Number(adapter_no) => Ok(DummyDevice { + AdapterIdentifier::Number(adapter_no) => Ok(Self { adapter_no: *adapter_no, ..Default::default() }), diff --git a/vhost-device-i2c/src/main.rs b/vhost-device-i2c/src/main.rs index e9bc9828..c912732d 100644 --- a/vhost-device-i2c/src/main.rs +++ b/vhost-device-i2c/src/main.rs @@ -28,7 +28,7 @@ type Result = std::result::Result; #[derive(Debug, ThisError)] /// Errors related to low level i2c helpers -pub(crate) enum Error { +enum Error { #[error("Invalid socket count: {0}")] SocketCountInvalid(usize), #[error("Failed while parsing adapter identifier")] @@ -79,8 +79,8 @@ enum AdapterIdentifier { impl fmt::Display for AdapterIdentifier { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - AdapterIdentifier::Name(name) => write!(f, "adapter_name: {}", name), - AdapterIdentifier::Number(no) => write!(f, "adapter_no:: {}", no), + Self::Name(name) => write!(f, "adapter_name: {}", name), + Self::Number(no) => write!(f, "adapter_no:: {}", no), } } } @@ -93,14 +93,14 @@ struct DeviceConfig { impl DeviceConfig { fn new_with_no(no: u32) -> Result { - Ok(DeviceConfig { + Ok(Self { adapter: AdapterIdentifier::Number(no), addr: Vec::new(), }) } fn new_with_name(name: &str) -> Result { - Ok(DeviceConfig { + Ok(Self { adapter: AdapterIdentifier::Name(name.trim().to_string()), addr: Vec::new(), }) @@ -121,14 +121,15 @@ impl DeviceConfig { } #[derive(Debug, PartialEq)] -pub(crate) struct AdapterConfig { +struct AdapterConfig { inner: Vec, } impl AdapterConfig { - fn new() -> Self { + const fn new() -> Self { Self { inner: Vec::new() } } + fn contains_adapter(&self, adapter: &DeviceConfig) -> bool { self.inner .iter() @@ -160,7 +161,7 @@ impl TryFrom<&str> for AdapterConfig { fn try_from(list: &str) -> Result { let adapter_identifiers: Vec<&str> = list.split(',').collect(); - let mut devices = AdapterConfig::new(); + let mut devices = Self::new(); for identifier_info in adapter_identifiers.iter() { let list: Vec<&str> = identifier_info.split(':').collect(); @@ -227,7 +228,7 @@ impl TryFrom for I2cConfiguration { } let devices = AdapterConfig::try_from(args.device_list.trim())?; - Ok(I2cConfiguration { + Ok(Self { socket_path: args.socket_path, socket_count: args.socket_count, devices, @@ -320,7 +321,7 @@ mod tests { impl DeviceConfig { pub fn new_with(adaper_id: AdapterIdentifier, addr: Vec) -> Self { - DeviceConfig { + Self { adapter: adaper_id, addr, } @@ -329,13 +330,13 @@ mod tests { impl AdapterConfig { pub fn new_with(devices: Vec) -> Self { - AdapterConfig { inner: devices } + Self { inner: devices } } } impl I2cArgs { - fn from_args(path: &str, devices: &str, count: usize) -> I2cArgs { - I2cArgs { + fn from_args(path: &str, devices: &str, count: usize) -> Self { + Self { socket_path: path.into(), socket_count: count, device_list: devices.to_string(), diff --git a/vhost-device-i2c/src/vhu_i2c.rs b/vhost-device-i2c/src/vhu_i2c.rs index 0ef9184e..701f5748 100644 --- a/vhost-device-i2c/src/vhu_i2c.rs +++ b/vhost-device-i2c/src/vhu_i2c.rs @@ -40,7 +40,7 @@ type Result = std::result::Result; #[derive(Copy, Clone, Debug, Eq, PartialEq, ThisError)] /// Errors related to vhost-device-i2c daemon. -pub(crate) enum Error { +pub enum Error { #[error("Failed to handle event, didn't match EPOLLIN")] HandleEventNotEpollIn, #[error("Failed to handle unknown event")] @@ -67,11 +67,11 @@ pub(crate) enum Error { impl convert::From for io::Error { fn from(e: Error) -> Self { - io::Error::new(io::ErrorKind::Other, e) + Self::new(io::ErrorKind::Other, e) } } -/// I2C definitions from Virtio Spec +// I2C definitions from Virtio Spec /// The final status written by the device const VIRTIO_I2C_MSG_OK: u8 = 0; @@ -100,7 +100,7 @@ struct VirtioI2cInHdr { // reading its content from byte array. unsafe impl ByteValued for VirtioI2cInHdr {} -pub(crate) struct VhostUserI2cBackend { +pub struct VhostUserI2cBackend { i2c_map: Arc>, event_idx: bool, pub exit_event: EventFd, @@ -111,7 +111,7 @@ type I2cDescriptorChain = DescriptorChain VhostUserI2cBackend { pub fn new(i2c_map: Arc>) -> Result { - Ok(VhostUserI2cBackend { + Ok(Self { i2c_map, event_idx: false, exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| Error::EventFdFailed)?, @@ -304,7 +304,7 @@ impl VhostUserBackendMut for VhostUserI2cB } fn set_event_idx(&mut self, enabled: bool) { - dbg!(self.event_idx = enabled); + self.event_idx = enabled; } fn update_memory(&mut self, mem: GuestMemoryAtomic) -> IoResult<()> { @@ -372,7 +372,7 @@ mod tests { // Prepares a single chain of descriptors fn prepare_desc_chain( start_addr: GuestAddress, - buf: &mut Vec, + buf: &mut [u8], flag: u32, client_addr: u16, ) -> I2cDescriptorChain { @@ -398,7 +398,7 @@ mod tests { mem.write_obj::(out_hdr, desc_out.addr()) .unwrap(); vq.desc_table().store(index, desc_out).unwrap(); - next_addr += desc_out.len() as u64; + next_addr += u64::from(desc_out.len()); index += 1; // Buf descriptor: optional @@ -419,7 +419,7 @@ mod tests { ); mem.write(buf, desc_buf.addr()).unwrap(); vq.desc_table().store(index, desc_buf).unwrap(); - next_addr += desc_buf.len() as u64; + next_addr += u64::from(desc_buf.len()); index += 1; } @@ -498,11 +498,7 @@ mod tests { }; f |= flag; - let offset = match addr { - Some(ref addr) => addr[i], - _ => 0x100, - }; - + let offset = addr.as_ref().map_or(0x100_u64, |addr| addr[i]); let desc = Descriptor::new(offset, len[i], f, (i + 1) as u16); vq.desc_table().store(i as u16, desc).unwrap(); } diff --git a/vhost-device-input/Cargo.toml b/vhost-device-input/Cargo.toml index dcbd5993..a07c6e96 100644 --- a/vhost-device-input/Cargo.toml +++ b/vhost-device-input/Cargo.toml @@ -10,6 +10,9 @@ categories = ["virtualization"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" +[lints] +workspace = true + [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] diff --git a/vhost-device-input/src/input.rs b/vhost-device-input/src/input.rs index a2b8f005..1bb8b6e5 100644 --- a/vhost-device-input/src/input.rs +++ b/vhost-device-input/src/input.rs @@ -33,19 +33,19 @@ pub trait InputDevice { impl InputDevice for Device { fn open(path: PathBuf) -> io::Result { - Device::open(path) + Self::open(path) } fn fetch_events(&mut self) -> io::Result> { - Device::fetch_events(self) + Self::fetch_events(self) } fn get_raw_fd(&self) -> RawFd { - Device::as_raw_fd(self) + Self::as_raw_fd(self) } fn input_id(&self) -> InputId { - Device::input_id(self) + Self::input_id(self) } } @@ -61,6 +61,9 @@ macro_rules! ioctl_read_buf { for item in data.iter_mut() { *item = $nr as u8; } + debug_assert!(!cfg!(target_pointer_width = "32")); + // We don't support 32bit platforms, so no wrap possible. + #[allow(clippy::cast_possible_wrap)] Ok(data.len() as i32) } ) diff --git a/vhost-device-input/src/main.rs b/vhost-device-input/src/main.rs index 4eb46fd8..1ed00a2d 100644 --- a/vhost-device-input/src/main.rs +++ b/vhost-device-input/src/main.rs @@ -182,8 +182,8 @@ mod tests { struct MockDevice; impl InputDevice for MockDevice { - fn open(_path: PathBuf) -> io::Result { - Ok(MockDevice {}) + fn open(_path: PathBuf) -> io::Result { + Ok(Self {}) } fn fetch_events(&mut self) -> io::Result> { @@ -241,7 +241,7 @@ mod tests { // An invalid socket path should trigger daemon failure. assert_matches!( - start_backend::(config.clone()).unwrap_err(), + start_backend::(config).unwrap_err(), Error::ServeFailed(_) ); } diff --git a/vhost-device-input/src/vhu_input.rs b/vhost-device-input/src/vhu_input.rs index 16551130..1e2b8678 100644 --- a/vhost-device-input/src/vhu_input.rs +++ b/vhost-device-input/src/vhu_input.rs @@ -45,7 +45,7 @@ const SYN_REPORT: u8 = 0x00; #[repr(C, packed)] #[derive(Copy, Clone, Debug)] -pub(crate) struct VuInputConfig { +pub struct VuInputConfig { select: u8, subsel: u8, size: u8, @@ -57,8 +57,8 @@ pub(crate) struct VuInputConfig { // thus it cannot meet the length VIRTIO_INPUT_CFG_SIZE (128) for the 'val' array. // Implement Default trait to accommodate array 'val'. impl Default for VuInputConfig { - fn default() -> VuInputConfig { - VuInputConfig { + fn default() -> Self { + Self { select: 0, subsel: 0, size: 0, @@ -74,7 +74,7 @@ unsafe impl ByteValued for VuInputConfig {} #[repr(C, packed)] #[derive(Copy, Clone, Debug, Default)] -pub(crate) struct VuInputEvent { +pub struct VuInputEvent { ev_type: u16, code: u16, value: u32, @@ -86,7 +86,7 @@ unsafe impl ByteValued for VuInputEvent {} #[derive(Debug, Eq, PartialEq, ThisError)] /// Errors related to vhost-device-input daemon. -pub(crate) enum VuInputError { +pub enum VuInputError { #[error("Notification send failed")] SendNotificationFailed, #[error("Can't create eventFd")] @@ -117,7 +117,7 @@ impl From for io::Error { } } -pub(crate) struct VuInputBackend { +pub struct VuInputBackend { event_idx: bool, ev_dev: T, pub exit_event: EventFd, @@ -129,7 +129,7 @@ pub(crate) struct VuInputBackend { impl VuInputBackend { pub fn new(ev_dev: T) -> std::result::Result { - Ok(VuInputBackend { + Ok(Self { event_idx: false, ev_dev, exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| VuInputError::EventFdError)?, @@ -144,7 +144,9 @@ impl VuInputBackend { let last_sync_index = self .ev_list .iter() - .rposition(|event| event.ev_type == EV_SYN as u16 && event.code == SYN_REPORT as u16) + .rposition(|event| { + event.ev_type == u16::from(EV_SYN) && event.code == u16::from(SYN_REPORT) + }) .unwrap_or(0); if last_sync_index == 0 { @@ -438,8 +440,8 @@ mod tests { struct MockDevice; impl InputDevice for MockDevice { - fn open(_path: PathBuf) -> io::Result { - Ok(MockDevice {}) + fn open(_path: PathBuf) -> io::Result { + Ok(Self {}) } fn fetch_events(&mut self) -> io::Result> { @@ -510,12 +512,7 @@ mod tests { // an error is generated. assert_eq!( backend - .handle_event( - EVENT_ID_IN_VRING_EPOLL as u16, - EventSet::OUT, - &[vring.clone()], - 0 - ) + .handle_event(EVENT_ID_IN_VRING_EPOLL as u16, EventSet::OUT, &[vring], 0) .unwrap_err() .kind(), io::ErrorKind::Other @@ -605,15 +602,15 @@ mod tests { .unwrap(); let ev_raw_data = VuInputEvent { - ev_type: EV_KEY as u16, - code: SYN_REPORT as u16, + ev_type: u16::from(EV_KEY), + code: u16::from(SYN_REPORT), value: 0, }; backend.ev_list.push_back(ev_raw_data); let ev_raw_data = VuInputEvent { - ev_type: EV_SYN as u16, - code: SYN_REPORT as u16, + ev_type: u16::from(EV_SYN), + code: u16::from(SYN_REPORT), value: 0, }; backend.ev_list.push_back(ev_raw_data); @@ -626,15 +623,15 @@ mod tests { assert_eq!(backend.ev_list.len(), 0); let ev_raw_data = VuInputEvent { - ev_type: EV_KEY as u16, - code: SYN_REPORT as u16, + ev_type: u16::from(EV_KEY), + code: u16::from(SYN_REPORT), value: 0, }; backend.ev_list.push_back(ev_raw_data); let ev_raw_data = VuInputEvent { - ev_type: EV_SYN as u16, - code: SYN_REPORT as u16, + ev_type: u16::from(EV_SYN), + code: u16::from(SYN_REPORT), value: 0, }; backend.ev_list.push_back(ev_raw_data); @@ -850,7 +847,7 @@ mod tests { assert_eq!(backend.queues_per_thread(), vec![0xffff_ffff]); assert_eq!(backend.get_config(0, 0), vec![]); - assert!(backend.update_memory(mem.clone()).is_ok()); + backend.update_memory(mem).unwrap(); backend.set_event_idx(true); assert!(backend.event_idx); diff --git a/vhost-device-rng/Cargo.toml b/vhost-device-rng/Cargo.toml index 77d5e729..9c601962 100644 --- a/vhost-device-rng/Cargo.toml +++ b/vhost-device-rng/Cargo.toml @@ -9,6 +9,9 @@ keywords = ["rng", "vhost", "virt", "backend"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" +[lints] +workspace = true + [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] diff --git a/vhost-device-rng/src/main.rs b/vhost-device-rng/src/main.rs index 37edbd13..8c6d7298 100644 --- a/vhost-device-rng/src/main.rs +++ b/vhost-device-rng/src/main.rs @@ -99,7 +99,7 @@ impl TryFrom for VuRngConfig { // to avoid overwhelming the HW. let max_bytes = max_bytes / socket_count as usize; - Ok(VuRngConfig { + Ok(Self { period_ms: period, max_bytes, count: socket_count, diff --git a/vhost-device-rng/src/vhu_rng.rs b/vhost-device-rng/src/vhu_rng.rs index 21f5ed19..6459664e 100644 --- a/vhost-device-rng/src/vhu_rng.rs +++ b/vhost-device-rng/src/vhu_rng.rs @@ -34,7 +34,7 @@ type RngDescriptorChain = DescriptorChain for io::Error { fn from(e: VuRngError) -> Self { - io::Error::new(io::ErrorKind::Other, e) + Self::new(io::ErrorKind::Other, e) } } #[derive(Clone, Debug, Eq, PartialEq)] -pub(crate) struct VuRngTimerConfig { +pub struct VuRngTimerConfig { period_ms: u128, period_start: Instant, max_bytes: usize, @@ -73,7 +73,7 @@ pub(crate) struct VuRngTimerConfig { impl VuRngTimerConfig { pub fn new(period_ms: u128, max_bytes: usize) -> Self { - VuRngTimerConfig { + Self { period_ms, period_start: Instant::now(), max_bytes, @@ -82,7 +82,7 @@ impl VuRngTimerConfig { } } -pub(crate) struct VuRngBackend { +pub struct VuRngBackend { event_idx: bool, timer: VuRngTimerConfig, rng_source: Arc>, @@ -97,7 +97,7 @@ impl VuRngBackend { period_ms: u128, max_bytes: usize, ) -> std::result::Result { - Ok(VuRngBackend { + Ok(Self { event_idx: false, rng_source, timer: VuRngTimerConfig::new(period_ms, max_bytes), @@ -228,7 +228,7 @@ impl VhostUserBackendMut for VuRngBacke } fn set_event_idx(&mut self, enabled: bool) { - dbg!(self.event_idx = enabled); + self.event_idx = enabled; } fn update_memory( @@ -325,8 +325,8 @@ mod tests { } impl MockRng { - fn new(permission_denied: bool) -> Self { - MockRng { permission_denied } + const fn new(permission_denied: bool) -> Self { + Self { permission_denied } } } @@ -359,7 +359,7 @@ mod tests { flags & !VRING_DESC_F_NEXT as u16 }; - let desc = Descriptor::new((0x100 * (i + 1)) as u64, 0x200, desc_flags, i + 1); + let desc = Descriptor::new(u64::from(0x100 * (i + 1)), 0x200, desc_flags, i + 1); vq.desc_table().store(i, desc).unwrap(); } @@ -561,7 +561,7 @@ mod tests { assert_eq!(backend.queues_per_thread(), vec![0xffff_ffff]); assert_eq!(backend.get_config(0, 0), vec![]); - assert!(backend.update_memory(mem).is_ok()); + backend.update_memory(mem).unwrap(); backend.set_event_idx(true); assert!(backend.event_idx); diff --git a/vhost-device-scmi/Cargo.toml b/vhost-device-scmi/Cargo.toml index 24e7b384..db37c549 100644 --- a/vhost-device-scmi/Cargo.toml +++ b/vhost-device-scmi/Cargo.toml @@ -9,6 +9,9 @@ keywords = ["scmi", "vhost", "virt", "backend"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" +[lints] +workspace = true + [dependencies] clap = { version = "4.5", features = ["derive"] } env_logger = "0.11" diff --git a/vhost-device-scmi/src/devices/iio.rs b/vhost-device-scmi/src/devices/iio.rs index 1c300af9..eae1f642 100644 --- a/vhost-device-scmi/src/devices/iio.rs +++ b/vhost-device-scmi/src/devices/iio.rs @@ -376,7 +376,7 @@ impl IIOSensor { custom_exponent } - fn add_axis(&mut self, axes: &mut Vec, path: &OsStr) { + fn add_axis(&self, axes: &mut Vec, path: &OsStr) { let unit_exponent = UNIT_MAPPING .iter() .find(|mapping| mapping.channel == self.channel) @@ -496,11 +496,11 @@ mod tests { } impl IIODirectory { - fn new(files: &[(&str, &str)]) -> IIODirectory { + fn new(files: &[(&str, &str)]) -> Self { let path = make_directory("_test"); - let directory = IIODirectory { path }; + let directory = Self { path }; for (file, content) in files.iter() { - fs::write(&directory.path.join(file), content).unwrap(); + fs::write(directory.path.join(file), content).unwrap(); } directory } diff --git a/vhost-device-scmi/src/scmi.rs b/vhost-device-scmi/src/scmi.rs index 36535287..8478147a 100644 --- a/vhost-device-scmi/src/scmi.rs +++ b/vhost-device-scmi/src/scmi.rs @@ -591,7 +591,7 @@ impl DeviceMap { // SENSOR_DESCRIPTION_GET supports -- the upper 16 bits of the response. const MAX_NUMBER_OF_PROTOCOL_DEVICES: usize = 0xFFFF; - fn insert(&mut self, device: Box) { + fn insert(&self, device: Box) { let mut device_map = self.0.lock().unwrap(); let devices = device_map.entry(device.protocol()).or_default(); if devices.len() >= Self::MAX_NUMBER_OF_PROTOCOL_DEVICES { @@ -653,7 +653,7 @@ impl ScmiHandler { self.handlers.get(request.protocol_id, request.message_id) } - pub fn handle(&mut self, request: ScmiRequest) -> ScmiResponse { + pub fn handle(&self, request: ScmiRequest) -> ScmiResponse { let response = match request.message_type { MessageType::Command => match self.request_handler(&request) { Some(info) => { @@ -720,7 +720,7 @@ impl ScmiHandler { .expect("Impossibly large number of SCMI protocols") } - pub fn register_device(&mut self, device: Box) { + pub fn register_device(&self, device: Box) { self.devices.insert(device); } @@ -961,7 +961,7 @@ mod tests { } fn make_handler() -> ScmiHandler { - let mut handler = ScmiHandler::new(); + let handler = ScmiHandler::new(); for i in 0..2 { let properties = DeviceProperties::new(vec![("name".to_owned(), format!("fake{i}"))]); let fake_sensor = FakeSensor::new_device(&properties).unwrap(); @@ -977,14 +977,13 @@ mod tests { result_code: ReturnStatus, result_values: Vec, ) { - let mut handler = make_handler(); test_message_with_handler( protocol_id, message_id, parameters, result_code, result_values, - &mut handler, + &make_handler(), ); } @@ -994,7 +993,7 @@ mod tests { parameters: Vec, result_code: ReturnStatus, result_values: Vec, - handler: &mut ScmiHandler, + handler: &ScmiHandler, ) { let mut request = make_request(protocol_id, message_id); let header = request.header; @@ -1280,7 +1279,7 @@ mod tests { ); } - fn check_enabled(sensor: u32, enabled: bool, handler: &mut ScmiHandler) { + fn check_enabled(sensor: u32, enabled: bool, handler: &ScmiHandler) { let enabled_flag = u32::from(enabled); let parameters = vec![MessageValue::Unsigned(sensor)]; let result = vec![MessageValue::Unsigned(enabled_flag)]; @@ -1296,11 +1295,11 @@ mod tests { #[test] fn test_sensor_config_get() { - let mut handler = make_handler(); - check_enabled(0, false, &mut handler); + let handler = make_handler(); + check_enabled(0, false, &handler); } - fn enable_sensor(sensor: u32, enable: bool, handler: &mut ScmiHandler) { + fn enable_sensor(sensor: u32, enable: bool, handler: &ScmiHandler) { let enable_flag = u32::from(enable); let parameters = vec![ MessageValue::Unsigned(sensor), @@ -1319,16 +1318,16 @@ mod tests { #[test] fn test_sensor_config_set() { - let mut handler = make_handler(); - enable_sensor(0, true, &mut handler); - check_enabled(0, true, &mut handler); - check_enabled(1, false, &mut handler); - enable_sensor(1, true, &mut handler); - check_enabled(1, true, &mut handler); - enable_sensor(0, true, &mut handler); - check_enabled(0, true, &mut handler); - enable_sensor(0, false, &mut handler); - check_enabled(0, false, &mut handler); + let handler = make_handler(); + enable_sensor(0, true, &handler); + check_enabled(0, true, &handler); + check_enabled(1, false, &handler); + enable_sensor(1, true, &handler); + check_enabled(1, true, &handler); + enable_sensor(0, true, &handler); + check_enabled(0, true, &handler); + enable_sensor(0, false, &handler); + check_enabled(0, false, &handler); } #[test] @@ -1345,9 +1344,9 @@ mod tests { #[test] fn test_sensor_reading_get() { - let mut handler = make_handler(); + let handler = make_handler(); for sensor in 0..2 { - enable_sensor(sensor, true, &mut handler); + enable_sensor(sensor, true, &handler); } for iteration in 0..2 { for sensor in 0..2 { @@ -1372,7 +1371,7 @@ mod tests { parameters, ReturnStatus::Success, result, - &mut handler, + &handler, ); } } diff --git a/vhost-device-scmi/src/vhu_scmi.rs b/vhost-device-scmi/src/vhu_scmi.rs index 9c509481..2888506a 100644 --- a/vhost-device-scmi/src/vhu_scmi.rs +++ b/vhost-device-scmi/src/vhu_scmi.rs @@ -98,7 +98,7 @@ pub struct VuScmiBackend { impl VuScmiBackend { pub fn new(config: &VuScmiConfig) -> Result { - let mut handler = ScmiHandler::new(); + let handler = ScmiHandler::new(); let device_mapping = available_devices(); for (name, properties) in config.devices.iter() { match device_mapping.get(name.as_str()) { @@ -133,7 +133,7 @@ impl VuScmiBackend { } pub fn process_requests( - &mut self, + &self, requests: Vec, vring: &VringRwLock, ) -> Result<()> { @@ -233,7 +233,7 @@ impl VuScmiBackend { Ok(()) } - fn process_command_queue(&mut self, vring: &VringRwLock) -> Result<()> { + fn process_command_queue(&self, vring: &VringRwLock) -> Result<()> { debug!("Processing command queue"); let requests: Vec<_> = vring .get_mut() @@ -595,7 +595,7 @@ mod tests { #[test] fn test_process_requests() { - let mut backend = make_backend(); + let backend = make_backend(); let mem = GuestMemoryAtomic::new( GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(), ); @@ -627,7 +627,7 @@ mod tests { #[test] fn test_process_requests_failure() { - let mut backend = make_backend(); + let backend = make_backend(); let mem = GuestMemoryAtomic::new( GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(), ); diff --git a/vhost-device-scsi/Cargo.toml b/vhost-device-scsi/Cargo.toml index 2b635680..3de46ca6 100644 --- a/vhost-device-scsi/Cargo.toml +++ b/vhost-device-scsi/Cargo.toml @@ -9,7 +9,8 @@ keywords = ["scsi", "vhost", "virt", "backend"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints] +workspace = true [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] @@ -31,4 +32,3 @@ vmm-sys-util = "0.12" [dev-dependencies] assert_matches = "1.5" tempfile = "3.12.0" - diff --git a/vhost-device-scsi/src/scsi/emulation/block_device.rs b/vhost-device-scsi/src/scsi/emulation/block_device.rs index 7ac4884a..63925646 100644 --- a/vhost-device-scsi/src/scsi/emulation/block_device.rs +++ b/vhost-device-scsi/src/scsi/emulation/block_device.rs @@ -22,16 +22,16 @@ use super::{ }; use crate::scsi::{sense, CmdError, CmdOutput, TaskAttr}; -pub(crate) enum MediumRotationRate { +pub enum MediumRotationRate { Unreported, NonRotating, } -#[derive(Clone, Copy, PartialEq, PartialOrd)] -pub(crate) struct ByteOffset(u64); +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd)] +pub struct ByteOffset(u64); impl From for ByteOffset { fn from(value: u64) -> Self { - ByteOffset(value) + Self(value) } } impl From for u64 { @@ -47,23 +47,23 @@ impl Div for ByteOffset { } } -#[derive(Clone, Copy, PartialEq, PartialOrd)] -pub(crate) struct BlockSize(NonZeroU32); +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd)] +pub struct BlockSize(NonZeroU32); impl From for u32 { fn from(value: BlockSize) -> Self { - u32::from(value.0) + Self::from(value.0) } } impl TryFrom for BlockSize { type Error = TryFromIntError; fn try_from(value: u32) -> Result { - Ok(BlockSize(NonZeroU32::try_from(value)?)) + Ok(Self(NonZeroU32::try_from(value)?)) } } -#[derive(Clone, Copy, PartialEq, PartialOrd)] -pub(crate) struct BlockOffset(u64); +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd)] +pub struct BlockOffset(u64); impl From for u64 { fn from(value: BlockOffset) -> Self { value.0 @@ -71,21 +71,21 @@ impl From for u64 { } impl From for BlockOffset { fn from(value: u64) -> Self { - BlockOffset(value) + Self(value) } } -impl Add for BlockOffset { - type Output = BlockOffset; +impl Add for BlockOffset { + type Output = Self; - fn add(self, rhs: BlockOffset) -> Self::Output { - BlockOffset(self.0 + rhs.0) + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) } } -impl Sub for BlockOffset { +impl Sub for BlockOffset { type Output = Self; - fn sub(self, rhs: BlockOffset) -> Self::Output { - BlockOffset(self.0 - rhs.0) + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) } } impl Mul for BlockOffset { @@ -96,7 +96,7 @@ impl Mul for BlockOffset { } } -pub(crate) trait BlockDeviceBackend: Send + Sync { +pub trait BlockDeviceBackend: Send + Sync { fn read_exact_at(&mut self, buf: &mut [u8], offset: ByteOffset) -> io::Result<()>; fn write_exact_at(&mut self, buf: &[u8], offset: ByteOffset) -> io::Result<()>; fn size_in_blocks(&mut self) -> io::Result; @@ -104,7 +104,7 @@ pub(crate) trait BlockDeviceBackend: Send + Sync { fn sync(&mut self) -> io::Result<()>; } -pub(crate) struct FileBackend { +pub struct FileBackend { file: File, block_size: BlockSize, } @@ -142,7 +142,7 @@ impl BlockDeviceBackend for FileBackend { } } -pub(crate) struct BlockDevice { +pub struct BlockDevice { backend: T, write_protected: bool, rotation_rate: MediumRotationRate, @@ -216,6 +216,7 @@ impl BlockDevice { } impl LogicalUnit for BlockDevice { + #[allow(clippy::cognitive_complexity)] fn execute_command( &mut self, data_in: &mut SilentlyTruncate<&mut dyn Write>, diff --git a/vhost-device-scsi/src/scsi/emulation/command.rs b/vhost-device-scsi/src/scsi/emulation/command.rs index 43cb0b40..7741e025 100644 --- a/vhost-device-scsi/src/scsi/emulation/command.rs +++ b/vhost-device-scsi/src/scsi/emulation/command.rs @@ -20,7 +20,7 @@ use crate::scsi::emulation::mode_page::ModePage; /// One of the modes supported by SCSI's REPORT LUNS command. #[derive(PartialEq, Eq, TryFromPrimitive, Debug, Copy, Clone)] #[repr(u8)] -pub(crate) enum ReportLunsSelectReport { +pub enum ReportLunsSelectReport { NoWellKnown = 0x0, WellKnownOnly = 0x1, All = 0x2, @@ -31,7 +31,7 @@ pub(crate) enum ReportLunsSelectReport { /// A type of "vital product data" page returned by SCSI's INQUIRY command. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -pub(crate) enum VpdPage { +pub enum VpdPage { Ascii(u8), Ata, // * BlockDeviceCharacteristics, // * @@ -63,7 +63,7 @@ pub(crate) enum VpdPage { #[derive(PartialEq, Eq, TryFromPrimitive, Debug, Copy, Clone)] #[repr(u8)] -pub(crate) enum ModeSensePageControl { +pub enum ModeSensePageControl { Current = 0b00, Changeable = 0b01, Default = 0b10, @@ -140,24 +140,24 @@ impl From for u8 { } #[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub(crate) enum SenseFormat { +pub enum SenseFormat { Fixed, Descriptor, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub(crate) enum ModePageSelection { +pub enum ModePageSelection { AllPageZeros, Single(ModePage), } #[derive(Debug)] -pub(crate) enum LunIndependentCommand { +pub enum LunIndependentCommand { ReportLuns(ReportLunsSelectReport), } #[derive(Debug)] -pub(crate) enum LunSpecificCommand { +pub enum LunSpecificCommand { Inquiry(Option), ModeSense6 { pc: ModeSensePageControl, @@ -201,13 +201,13 @@ pub(crate) enum LunSpecificCommand { } #[derive(Debug)] -pub(crate) enum Command { +pub enum Command { LunIndependentCommand(LunIndependentCommand), LunSpecificCommand(LunSpecificCommand), } #[derive(Clone, Copy, Debug)] -pub(crate) enum CommandType { +pub enum CommandType { Inquiry, ModeSense6, Read10, @@ -222,7 +222,7 @@ pub(crate) enum CommandType { SynchronizeCache10, } -pub(crate) const OPCODES: &[(CommandType, (u8, Option))] = &[ +pub const OPCODES: &[(CommandType, (u8, Option))] = &[ (CommandType::TestUnitReady, (0x0, None)), (CommandType::RequestSense, (0x3, None)), (CommandType::Inquiry, (0x12, None)), @@ -241,7 +241,7 @@ pub(crate) const OPCODES: &[(CommandType, (u8, Option))] = &[ ]; #[derive(Debug, Clone, Copy)] -pub(crate) struct UnparsedServiceAction(u8); +pub struct UnparsedServiceAction(u8); impl UnparsedServiceAction { pub fn parse(self, service_action: u16) -> Option { OPCODES @@ -253,7 +253,7 @@ impl UnparsedServiceAction { /// See `parse_opcode` #[derive(Debug, Clone, Copy)] -pub(crate) enum ParseOpcodeResult { +pub enum ParseOpcodeResult { /// The opcode represents a single command. Command(CommandType), /// The opcode requires a service action. @@ -280,7 +280,7 @@ pub(crate) enum ParseOpcodeResult { /// - `ServiceAction`: the opcode is the first byte of a service action; the /// caller needs to call .parse() on the `UnparsedServiceAction` we returned /// with the service action byte. -pub(crate) fn parse_opcode(opcode: u8) -> ParseOpcodeResult { +pub fn parse_opcode(opcode: u8) -> ParseOpcodeResult { let found = OPCODES.iter().find(|(_, (x, _))| *x == opcode); match found { Some(&(ty, (_, None))) => ParseOpcodeResult::Command(ty), @@ -464,14 +464,14 @@ impl CommandType { } #[derive(Debug)] -pub(crate) struct Cdb { +pub struct Cdb { pub command: Command, pub allocation_length: Option, pub naca: bool, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub(crate) enum ParseError { +pub enum ParseError { /// The opcode (specifically the first byte of the CDB) is unknown, i.e. we /// should respond with INVALID COMMAND OPERATION CODE InvalidCommand, @@ -483,7 +483,7 @@ pub(crate) enum ParseError { } #[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub(crate) enum ReportSupportedOpCodesMode { +pub enum ReportSupportedOpCodesMode { All, OneCommand(u8), OneServiceAction(u8, u16), diff --git a/vhost-device-scsi/src/scsi/emulation/missing_lun.rs b/vhost-device-scsi/src/scsi/emulation/missing_lun.rs index cb94baa8..f6a19db0 100644 --- a/vhost-device-scsi/src/scsi/emulation/missing_lun.rs +++ b/vhost-device-scsi/src/scsi/emulation/missing_lun.rs @@ -9,7 +9,7 @@ use super::{ }; use crate::scsi::{sense, CmdError, CmdError::DataIn, CmdOutput}; -pub(crate) struct MissingLun; +pub struct MissingLun; impl LogicalUnit for MissingLun { fn execute_command( diff --git a/vhost-device-scsi/src/scsi/emulation/mod.rs b/vhost-device-scsi/src/scsi/emulation/mod.rs index d697842e..6cccfc4e 100644 --- a/vhost-device-scsi/src/scsi/emulation/mod.rs +++ b/vhost-device-scsi/src/scsi/emulation/mod.rs @@ -1,11 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause -pub(crate) mod block_device; +pub mod block_device; mod command; -pub(crate) mod missing_lun; -pub(crate) mod mode_page; +pub mod missing_lun; +pub mod mode_page; mod response_data; -pub(crate) mod target; +pub mod target; #[cfg(test)] mod tests; diff --git a/vhost-device-scsi/src/scsi/emulation/mode_page.rs b/vhost-device-scsi/src/scsi/emulation/mode_page.rs index e0c30e76..b8402c2c 100644 --- a/vhost-device-scsi/src/scsi/emulation/mode_page.rs +++ b/vhost-device-scsi/src/scsi/emulation/mode_page.rs @@ -3,7 +3,7 @@ use std::io::{self, Write}; #[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub(crate) enum ModePage { +pub enum ModePage { Caching, } diff --git a/vhost-device-scsi/src/scsi/emulation/target.rs b/vhost-device-scsi/src/scsi/emulation/target.rs index 4ce1a347..9a376326 100644 --- a/vhost-device-scsi/src/scsi/emulation/target.rs +++ b/vhost-device-scsi/src/scsi/emulation/target.rs @@ -14,7 +14,7 @@ use super::{ }; use crate::scsi::{sense, CmdError, CmdOutput, Request, Target, TaskAttr}; -pub(crate) struct LunRequest { +pub struct LunRequest { pub _id: u64, pub task_attr: TaskAttr, pub crn: u8, @@ -24,7 +24,7 @@ pub(crate) struct LunRequest { } /// A single logical unit of an emulated SCSI device. -pub(crate) trait LogicalUnit: Send + Sync { +pub trait LogicalUnit: Send + Sync { /// Process a SCSI command sent to this logical unit. /// /// # Return value @@ -45,7 +45,7 @@ pub(crate) trait LogicalUnit: Send + Sync { } /// A SCSI target implemented by emulating a device within vhost-device-scsi. -pub(crate) struct EmulatedTarget { +pub struct EmulatedTarget { luns: Vec>, } @@ -58,7 +58,7 @@ impl EmulatedTarget { self.luns.push(logical_unit); } - pub(crate) fn luns(&self) -> impl Iterator + ExactSizeIterator + '_ { + pub(crate) fn luns(&self) -> impl ExactSizeIterator + '_ { // unwrap is safe: we limit LUNs at 256 self.luns .iter() diff --git a/vhost-device-scsi/src/vhu_scsi.rs b/vhost-device-scsi/src/vhu_scsi.rs index 6693693d..94449bef 100644 --- a/vhost-device-scsi/src/vhu_scsi.rs +++ b/vhost-device-scsi/src/vhu_scsi.rs @@ -33,7 +33,7 @@ const REQUEST_QUEUE: u16 = 2; type DescriptorChainWriter = virtio::DescriptorChainWriter>; type DescriptorChainReader = virtio::DescriptorChainReader>; -pub(crate) struct VhostUserScsiBackend { +pub struct VhostUserScsiBackend { event_idx: bool, mem: Option>, targets: Vec>, @@ -295,7 +295,7 @@ impl VhostUserBackendMut for VhostUserScsiBackend { // access up to the size of the struct. let config_slice = unsafe { slice::from_raw_parts( - &config as *const virtio_scsi_config as *const u8, + (&config as *const virtio_scsi_config).cast::(), mem::size_of::(), ) }; @@ -336,8 +336,7 @@ mod tests { }; use virtio_queue::{mock::MockSplitQueue, Descriptor}; use vm_memory::{ - Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, - GuestMemoryMmap, + ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap, }; use super::VhostUserScsiBackend; diff --git a/vhost-device-scsi/src/virtio.rs b/vhost-device-scsi/src/virtio.rs index 423c0aba..bdbf9ad0 100644 --- a/vhost-device-scsi/src/virtio.rs +++ b/vhost-device-scsi/src/virtio.rs @@ -20,12 +20,12 @@ use vm_memory::{Bytes, GuestAddress, GuestMemory}; /// virtio-scsi has its own format for LUNs, documented in 5.6.6.1 of virtio /// v1.1. This represents a LUN parsed from that format. #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub(crate) enum VirtioScsiLun { +pub enum VirtioScsiLun { ReportLuns, TargetLun(u8, u16), } -pub(crate) const REPORT_LUNS: [u8; 8] = [0xc1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]; +pub const REPORT_LUNS: [u8; 8] = [0xc1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]; impl VirtioScsiLun { pub(crate) const FLAT_SPACE_ADDRESSING_METHOD: u8 = 0b0100_0000; @@ -56,7 +56,7 @@ impl VirtioScsiLun { #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum ResponseCode { +pub enum ResponseCode { Ok = 0, Overrun = 1, BadTarget = 3, @@ -65,10 +65,10 @@ pub(crate) enum ResponseCode { // These are the defaults given in the virtio spec; QEMU doesn't let the driver // write to config space, so these will always be the correct values. -pub(crate) const SENSE_SIZE: usize = 96; -pub(crate) const CDB_SIZE: usize = 32; +pub const SENSE_SIZE: usize = 96; +pub const CDB_SIZE: usize = 32; -pub(crate) struct Request { +pub struct Request { pub id: u64, pub lun: VirtioScsiLun, pub prio: u8, @@ -78,7 +78,7 @@ pub(crate) struct Request { } #[derive(Debug)] -pub(crate) enum RequestParseError { +pub enum RequestParseError { CouldNotReadGuestMemory(io::Error), FailedParsingLun([u8; 8]), } @@ -108,7 +108,7 @@ impl Request { } #[derive(Debug, PartialEq, Eq)] -pub(crate) struct Response { +pub struct Response { pub response: ResponseCode, pub status: u8, pub status_qualifier: u16, diff --git a/vhost-device-sound/Cargo.toml b/vhost-device-sound/Cargo.toml index 47bffc1d..2a9ec019 100644 --- a/vhost-device-sound/Cargo.toml +++ b/vhost-device-sound/Cargo.toml @@ -10,6 +10,9 @@ categories = ["multimedia::audio", "virtualization"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2018" +[lints] +workspace = true + [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] default = ["alsa-backend", "pw-backend"] diff --git a/vhost-device-sound/src/audio_backends/pipewire/test_utils.rs b/vhost-device-sound/src/audio_backends/pipewire/test_utils.rs index f7321213..889f97b2 100644 --- a/vhost-device-sound/src/audio_backends/pipewire/test_utils.rs +++ b/vhost-device-sound/src/audio_backends/pipewire/test_utils.rs @@ -53,8 +53,10 @@ impl Drop for DbusSession { /// `PipewireTestHarness::new()`. #[non_exhaustive] pub struct PipewireTestHarness { + #[allow(dead_code)] pub dbus: DbusSession, pub pipewire_child: Child, + #[allow(dead_code)] pub tempdir: TempDir, } diff --git a/vhost-device-sound/src/main.rs b/vhost-device-sound/src/main.rs index a6f0047e..09bc498d 100644 --- a/vhost-device-sound/src/main.rs +++ b/vhost-device-sound/src/main.rs @@ -24,7 +24,7 @@ impl TryFrom for SoundConfig { fn try_from(cmd_args: SoundArgs) -> Result { let socket = cmd_args.socket.trim().to_string(); - Ok(SoundConfig::new(socket, false, cmd_args.backend)) + Ok(Self::new(socket, false, cmd_args.backend)) } } @@ -46,7 +46,7 @@ mod tests { impl SoundArgs { fn from_args(socket: &str) -> Self { - SoundArgs { + Self { socket: socket.to_string(), backend: BackendType::default(), } diff --git a/vhost-device-sound/src/stream.rs b/vhost-device-sound/src/stream.rs index 7e1cfbf6..d2d6f6b6 100644 --- a/vhost-device-sound/src/stream.rs +++ b/vhost-device-sound/src/stream.rs @@ -42,7 +42,7 @@ type Result = std::result::Result; /// - `SET PARAMETERS` /// /// The driver negotiates the stream parameters (format, transport, etc) with -/// the device. +/// the device. /// /// Possible valid transitions: `SET PARAMETERS`, `PREPARE`. /// @@ -51,7 +51,7 @@ type Result = std::result::Result; /// The device prepares the stream (allocates resources, etc). /// /// Possible valid transitions: `SET PARAMETERS`, `PREPARE`, `START`, -/// `RELEASE`. Output only: the driver transfers data for pre-buffing. +/// `RELEASE`. Output only: the driver transfers data for pre-buffing. /// /// - `START` /// @@ -156,21 +156,20 @@ impl PCMState { impl std::fmt::Display for PCMState { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - use PCMState::*; match *self { - SetParameters => { + Self::SetParameters => { write!(fmt, "VIRTIO_SND_R_PCM_SET_PARAMS") } - Prepare => { + Self::Prepare => { write!(fmt, "VIRTIO_SND_R_PCM_PREPARE") } - Release => { + Self::Release => { write!(fmt, "VIRTIO_SND_R_PCM_RELEASE") } - Start => { + Self::Start => { write!(fmt, "VIRTIO_SND_R_PCM_START") } - Stop => { + Self::Stop => { write!(fmt, "VIRTIO_SND_R_PCM_STOP") } } diff --git a/vhost-device-spi/Cargo.toml b/vhost-device-spi/Cargo.toml index 22d76523..82122b63 100644 --- a/vhost-device-spi/Cargo.toml +++ b/vhost-device-spi/Cargo.toml @@ -10,7 +10,8 @@ categories = ["virtualization"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints] +workspace = true [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] diff --git a/vhost-device-spi/src/linux_spi.rs b/vhost-device-spi/src/linux_spi.rs index c08c6044..c36c9475 100644 --- a/vhost-device-spi/src/linux_spi.rs +++ b/vhost-device-spi/src/linux_spi.rs @@ -53,11 +53,12 @@ ioctl_iow_nr!(SPI_IOC_WR_MODE32, 107, 5, u32); // Corresponds to the SPI_IOC_MESSAGE macro in Linux pub fn spi_ioc_message(n: u32) -> u64 { - let mut size: u32 = 0; - if n * 32 < (1 << _IOC_SIZEBITS) { - size = n * 32; - } - (SPI_IOC_MESSAGE_BASE | (size << _IOC_SIZESHIFT)) as u64 + let size = if n * 32 < (1 << _IOC_SIZEBITS) { + n * 32 + } else { + 0 + }; + u64::from(SPI_IOC_MESSAGE_BASE | (size << _IOC_SIZESHIFT)) } bitflags! { diff --git a/vhost-device-spi/src/main.rs b/vhost-device-spi/src/main.rs index ebd510f3..922968a8 100644 --- a/vhost-device-spi/src/main.rs +++ b/vhost-device-spi/src/main.rs @@ -71,7 +71,7 @@ struct SpiConfiguration { impl SpiConfiguration { fn from(args: SpiArgs) -> Result { - Ok(SpiConfiguration { + Ok(Self { socket_path: args.socket_path, socket_count: args.socket_count.get(), device: args.device, diff --git a/vhost-device-spi/src/spi.rs b/vhost-device-spi/src/spi.rs index a973e5ae..f7fe2d57 100644 --- a/vhost-device-spi/src/spi.rs +++ b/vhost-device-spi/src/spi.rs @@ -20,9 +20,9 @@ use crate::{linux_spi::*, vhu_spi::VirtioSpiConfig, virtio_spi::*}; type Result = std::result::Result; -#[derive(Copy, Clone, Debug, PartialEq, ThisError)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, ThisError)] /// Errors related to low level spi helpers -pub(crate) enum Error { +pub enum Error { #[error("Ioctl command failed for {0} operation: {1}")] IoctlFailure(&'static str, IoError), #[error("Failed to open spi controller")] @@ -30,7 +30,7 @@ pub(crate) enum Error { } /// SPI definitions -pub(crate) struct SpiTransReq { +pub struct SpiTransReq { pub tx_buf: Vec, pub rx_buf: Vec, pub trans_len: u32, @@ -51,7 +51,7 @@ pub(crate) struct SpiTransReq { /// be used outside of this crate. The purpose of this trait is to provide a /// mock implementation for the SPI driver so that we can test the SPI /// functionality without the need of a physical device. -pub(crate) trait SpiDevice { +pub trait SpiDevice { /// Open the device specified by the controller path. fn open(path: &Path) -> Result where @@ -85,13 +85,13 @@ pub(crate) trait SpiDevice { /// A physical SPI device. This structure can only be initialized on hosts /// where `/dev/spidevX.Y` is available. #[derive(Debug)] -pub(crate) struct PhysDevice { +pub struct PhysDevice { file: File, } impl SpiDevice for PhysDevice { fn open(path: &Path) -> Result { - Ok(PhysDevice { + Ok(Self { file: OpenOptions::new() .read(true) .write(true) @@ -206,6 +206,7 @@ impl SpiDevice for PhysDevice { } } + #[allow(clippy::cognitive_complexity)] fn detect_supported_features(&self) -> Result { // supported cs_max_number 1 // can't set cs timing from userland in Linux, reserve cs timing as 0 @@ -468,20 +469,20 @@ impl SpiDevice for PhysDevice { } #[derive(Debug)] -pub(crate) struct SpiController { +pub struct SpiController { device: D, config: VirtioSpiConfig, } impl SpiController { // Creates a new controller corresponding to `device`. - pub(crate) fn new(device: D) -> Result> { + pub(crate) fn new(device: D) -> Result { let config: VirtioSpiConfig = device.detect_supported_features()?; - Ok(SpiController { device, config }) + Ok(Self { device, config }) } - pub(crate) fn config(&self) -> &VirtioSpiConfig { + pub(crate) const fn config(&self) -> &VirtioSpiConfig { &self.config } diff --git a/vhost-device-spi/src/vhu_spi.rs b/vhost-device-spi/src/vhu_spi.rs index 9a10d86a..78bfc407 100644 --- a/vhost-device-spi/src/vhu_spi.rs +++ b/vhost-device-spi/src/vhu_spi.rs @@ -38,7 +38,7 @@ type Result = std::result::Result; #[derive(Copy, Clone, Debug, Eq, PartialEq, ThisError)] /// Errors related to vhost-device-spi daemon. -pub(crate) enum Error { +pub enum Error { #[error("TX length {0} and RX length {1} don't match")] TxRxTrnasLenNotEqual(u32, u32), #[error("TX length and RX length are both zero")] @@ -65,7 +65,7 @@ pub(crate) enum Error { impl From for io::Error { fn from(e: Error) -> Self { - io::Error::new(io::ErrorKind::Other, e) + Self::new(io::ErrorKind::Other, e) } } @@ -113,9 +113,9 @@ struct VirtioSpiTransferResult { unsafe impl ByteValued for VirtioSpiTransferResult {} /// Virtio SPI Configuration -#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[repr(C)] -pub(crate) struct VirtioSpiConfig { +pub struct VirtioSpiConfig { pub(crate) cs_max_number: u8, pub(crate) cs_change_supported: u8, pub(crate) tx_nbits_supported: u8, @@ -133,7 +133,7 @@ pub(crate) struct VirtioSpiConfig { // reading its content from byte array. unsafe impl ByteValued for VirtioSpiConfig {} -pub(crate) struct VhostUserSpiBackend { +pub struct VhostUserSpiBackend { spi_ctrl: Arc>, event_idx: bool, pub exit_event: EventFd, @@ -144,7 +144,7 @@ type SpiDescriptorChain = DescriptorChain VhostUserSpiBackend { pub fn new(spi_ctrl: Arc>) -> Result { - Ok(VhostUserSpiBackend { + Ok(Self { spi_ctrl, event_idx: false, exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| Error::EventFdFailed)?, @@ -352,7 +352,7 @@ impl VhostUserSpiBackend { status: ResponseStatus::TransErr as u8, }; - for desc_chain in requests.clone() { + for desc_chain in requests { let len = size_of::() as u32; let mem = atomic_mem.memory(); diff --git a/vhost-device-template/Cargo.toml b/vhost-device-template/Cargo.toml index 0632c9bf..a40d2532 100644 --- a/vhost-device-template/Cargo.toml +++ b/vhost-device-template/Cargo.toml @@ -12,6 +12,9 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints] +workspace = true + [features] xen = ["vm-memory/xen", "vhost/xen", "vhost-user-backend/xen"] diff --git a/vhost-device-template/src/main.rs b/vhost-device-template/src/main.rs index 349d3671..a229a606 100644 --- a/vhost-device-template/src/main.rs +++ b/vhost-device-template/src/main.rs @@ -53,7 +53,7 @@ impl TryFrom for FooConfiguration { // Even though this try_from() conversion always succeeds, in cases where the device's // configuration type needs to validate arguments and/or make operations that can fail a // TryFrom<_> implementation will be necessary. - Ok(FooConfiguration { + Ok(Self { socket_path: args.socket_path, }) } @@ -65,7 +65,7 @@ pub(crate) struct FooInfo { } impl FooInfo { - pub fn new() -> Self { + pub const fn new() -> Self { Self { counter: 0 } } @@ -78,7 +78,7 @@ impl FooInfo { fn start_backend(args: FooArgs) -> Result<()> { let config = FooConfiguration::try_from(args).unwrap(); - let socket_path = config.socket_path.clone(); + let socket_path = config.socket_path; let info = FooInfo::new(); let handle: JoinHandle> = spawn(move || loop { @@ -119,8 +119,8 @@ mod tests { use super::*; impl FooArgs { - pub(crate) fn from_args(path: &Path) -> FooArgs { - FooArgs { + pub(crate) fn from_args(path: &Path) -> Self { + Self { socket_path: path.to_path_buf(), } } diff --git a/vhost-device-template/src/vhu_foo.rs b/vhost-device-template/src/vhu_foo.rs index 4bf52f39..1c9527be 100644 --- a/vhost-device-template/src/vhu_foo.rs +++ b/vhost-device-template/src/vhu_foo.rs @@ -32,7 +32,7 @@ type Result = std::result::Result; #[derive(Copy, Clone, Debug, Eq, PartialEq, ThisError)] /// Errors related to vhost-device-foo daemon. -pub(crate) enum Error { +pub enum Error { #[error("Failed to handle event, didn't match EPOLLIN")] HandleEventNotEpollIn, #[error("Failed to handle unknown event")] @@ -47,11 +47,11 @@ pub(crate) enum Error { impl convert::From for io::Error { fn from(e: Error) -> Self { - io::Error::new(io::ErrorKind::Other, e) + Self::new(io::ErrorKind::Other, e) } } -pub(crate) struct VhostUserFooBackend { +pub struct VhostUserFooBackend { info: FooInfo, event_idx: bool, pub exit_event: EventFd, @@ -62,7 +62,7 @@ type FooDescriptorChain = DescriptorChain Result { - Ok(VhostUserFooBackend { + Ok(Self { info, event_idx: false, exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| Error::EventFdFailed)?, @@ -85,7 +85,7 @@ impl VhostUserFooBackend { // // The layout of the various structures, to be read from and written into the descriptor // buffers, is defined in the Virtio specification for each protocol. - for desc_chain in requests.clone() { + for desc_chain in requests { let counter = self.info.counter(); let descriptors: Vec<_> = desc_chain.clone().collect(); @@ -266,7 +266,7 @@ mod tests { fn prepare_descriptors( mut next_addr: u64, mem: &GuestMemoryLoadGuard>, - buf: &mut Vec, + buf: &[u8], ) -> Vec { let mut descriptors = Vec::new(); let mut index = 0; @@ -284,7 +284,7 @@ mod tests { VRING_DESC_F_NEXT as u16, index + 1, ); - next_addr += desc_out.len() as u64; + next_addr += u64::from(desc_out.len()); index += 1; mem.write_obj::(out_hdr, desc_out.addr()) @@ -299,7 +299,7 @@ mod tests { (VRING_DESC_F_WRITE | VRING_DESC_F_NEXT) as u16, index + 1, ); - next_addr += desc_buf.len() as u64; + next_addr += u64::from(desc_buf.len()); mem.write(buf, desc_buf.addr()).unwrap(); descriptors.push(desc_buf); @@ -317,7 +317,7 @@ mod tests { } // Prepares a single chain of descriptors - fn prepare_desc_chain(buf: &mut Vec) -> (VhostUserFooBackend, VringRwLock) { + fn prepare_desc_chain(buf: &[u8]) -> (VhostUserFooBackend, VringRwLock) { let (mut backend, mem, vring) = init(); let mem_handle = mem.memory(); let vq = MockSplitQueue::new(&*mem_handle, 16); @@ -351,7 +351,7 @@ mod tests { // Prepares a chain of descriptors fn prepare_desc_chains( mem: &GuestMemoryAtomic, - buf: &mut Vec, + buf: &[u8], ) -> FooDescriptorChain { let mem_handle = mem.memory(); let vq = MockSplitQueue::new(&*mem_handle, 16); @@ -395,8 +395,8 @@ mod tests { #[test] fn process_request_single() { // Single valid descriptor - let mut buf: Vec = vec![0; 30]; - let (mut backend, vring) = prepare_desc_chain(&mut buf); + let buf: Vec = vec![0; 30]; + let (mut backend, vring) = prepare_desc_chain(&buf); backend.process_queue(&vring).unwrap(); } @@ -405,19 +405,17 @@ mod tests { // Multiple valid descriptors let (mut backend, mem, vring) = init(); - let mut bufs: Vec> = vec![vec![0; 30]; 6]; + let bufs: Vec> = vec![vec![0; 30]; 6]; let desc_chains = vec![ - prepare_desc_chains(&mem, &mut bufs[0]), - prepare_desc_chains(&mem, &mut bufs[1]), - prepare_desc_chains(&mem, &mut bufs[2]), - prepare_desc_chains(&mem, &mut bufs[3]), - prepare_desc_chains(&mem, &mut bufs[4]), - prepare_desc_chains(&mem, &mut bufs[5]), + prepare_desc_chains(&mem, &bufs[0]), + prepare_desc_chains(&mem, &bufs[1]), + prepare_desc_chains(&mem, &bufs[2]), + prepare_desc_chains(&mem, &bufs[3]), + prepare_desc_chains(&mem, &bufs[4]), + prepare_desc_chains(&mem, &bufs[5]), ]; - backend - .process_requests(desc_chains.clone(), &vring) - .unwrap(); + backend.process_requests(desc_chains, &vring).unwrap(); } #[test]