From 872fc096a082cbd061a0efe79410fc78e944ea9d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 08:56:49 +0200 Subject: [PATCH 1/6] dma-buf: Update lints Signed-off-by: Maxime Ripard --- Cargo.toml | 3 ++- src/lib.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c8e7d4b..c30bbd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ single_use_lifetimes = "warn" trivial_casts = "warn" trivial_numeric_casts = "warn" unreachable_pub = "warn" -# unsafe_code = "deny" +unsafe_code = "deny" unsafe_op_in_unsafe_fn = "warn" unused_crate_dependencies = "warn" unused_import_braces = "warn" @@ -68,6 +68,7 @@ as_pointer_underscore = "warn" assertions_on_result_states = "warn" dbg_macro = "warn" decimal_literal_representation = "warn" +empty_enum_variants_with_brackets = "warn" empty_drop = "warn" empty_structs_with_brackets = "warn" error_impl_error = "warn" diff --git a/src/lib.rs b/src/lib.rs index d42c6ff..4253bf5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,8 @@ // Licensed under the MIT License // See the LICENSE file or +#![allow(unsafe_code)] + #![cfg_attr( feature = "nightly", feature( From 3fe757b6253b657b7552a5bdbe54bfeb63b92cd9 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 09:39:19 +0200 Subject: [PATCH 2/6] dma-buf: Use no default-features for rustix Signed-off-by: Maxime Ripard --- Cargo.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c30bbd4..368fd1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,12 @@ categories = ["api-bindings", "os::linux-apis"] repository = "https://github.com/mripard/dma-buf/" [dependencies] -rustix = { version = "1.0.5", features = ["fs", "mm", "param"] } +rustix = { version = "1.0.5", default-features = false, features = [ + "fs", + "mm", + "param", + "std", +] } thiserror = "2.0.3" tracing = { version = "0.1.41", default-features = false, features = ["std"] } From 0b41aa8ea2cff59c11e3eccd8c5e1ed4435f4367 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 09:46:16 +0200 Subject: [PATCH 3/6] fixup! dma-buf: Update lints --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4253bf5..5e43d23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ // See the LICENSE file or #![allow(unsafe_code)] - #![cfg_attr( feature = "nightly", feature( From de2d5fc55ab6eabee44865a822f9ab341e9bf7cc Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 09:46:47 +0200 Subject: [PATCH 4/6] dma-buf: Import core::error and std::io modules Signed-off-by: Maxime Ripard --- src/lib.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5e43d23..db8f9d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,8 +23,11 @@ )] #![doc = include_str!("../README.md")] -use core::{ffi::c_void, fmt, num::TryFromIntError, ptr, slice}; -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}; +use core::{error, ffi::c_void, fmt, num::TryFromIntError, ptr, slice}; +use std::{ + io, + os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}, +}; use rustix::{ fs::fstat, @@ -51,7 +54,7 @@ pub enum MapError { reason: String, /// Source of the Error - source: std::io::Error, + source: io::Error, }, /// An Error occurred while mapping the buffer file descriptor @@ -61,7 +64,7 @@ pub enum MapError { reason: String, /// Source of the Error - source: std::io::Error, + source: io::Error, }, /// An Error occurred while converting between Integer types @@ -89,7 +92,7 @@ impl DmaBuf { let stat = fstat(&self.0).map_err(|e| MapError::FdAccess { reason: e.to_string(), - source: std::io::Error::from(e), + source: io::Error::from(e), })?; let len = usize::try_from(stat.st_size)?.next_multiple_of(page_size()); @@ -110,7 +113,7 @@ impl DmaBuf { .map(<*mut c_void>::cast::) .map_err(|e| MapError::MappingFailed { reason: e.to_string(), - source: std::io::Error::from(e), + source: io::Error::from(e), })?; trace!("Memory Mapping Done"); @@ -140,12 +143,12 @@ pub enum BufferError { reason: String, /// Source of the Error - source: std::io::Error, + source: io::Error, }, /// An Error occured in the closure #[error("The closure returned an error: {0}")] - Closure(Box), + Closure(Box), } impl MappedDmaBuf { @@ -176,7 +179,7 @@ impl MappedDmaBuf { /// Will return [Error] if the underlying ioctl or the closure fails pub fn read(&self, f: F, arg: Option) -> Result where - F: Fn(&[u8], Option) -> Result>, + F: Fn(&[u8], Option) -> Result>, { trace_span!("Buffer Read Access").in_scope(|| { trace_span!("dma-buf begin access ioctl") @@ -214,7 +217,7 @@ impl MappedDmaBuf { /// Will return [Error] if the underlying ioctl or the closure fails pub fn readwrite(&mut self, f: F, arg: Option) -> Result where - F: Fn(&mut [u8], Option) -> Result>, + F: Fn(&mut [u8], Option) -> Result>, { trace_span!("Buffer Read / Write Access").in_scope(|| { trace_span!("dma-buf begin access ioctl") @@ -251,7 +254,7 @@ impl MappedDmaBuf { /// Will return [Error] if the underlying ioctl or the closure fails pub fn write(&mut self, f: F, arg: Option) -> Result<(), BufferError> where - F: Fn(&mut [u8], Option) -> Result<(), Box>, + F: Fn(&mut [u8], Option) -> Result<(), Box>, { trace_span!("Buffer Write Access").in_scope(|| { trace_span!("dma-buf begin access ioctl") From a25b6346af3b453a41e3e15876eaead410771a90 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 09:42:47 +0200 Subject: [PATCH 5/6] dma-buf: Return io::Error in DmaBuf::memory_map Signed-off-by: Maxime Ripard --- src/lib.rs | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index db8f9d3..2917d3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ )] #![doc = include_str!("../README.md")] -use core::{error, ffi::c_void, fmt, num::TryFromIntError, ptr, slice}; +use core::{error, ffi::c_void, fmt, ptr, slice}; use std::{ io, os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}, @@ -43,35 +43,6 @@ use ioctl::{ dma_buf_end_cpu_write_access, }; -/// Error type to map a [`DmaBuf`] -#[non_exhaustive] -#[derive(thiserror::Error, Debug)] -pub enum MapError { - /// An Error occurred while accessing the buffer file descriptor - #[error("Could not access the buffer file descriptor: {reason}")] - FdAccess { - /// Description of the Error - reason: String, - - /// Source of the Error - source: io::Error, - }, - - /// An Error occurred while mapping the buffer file descriptor - #[error("Could not map the buffer file descriptor: {reason}")] - MappingFailed { - /// Description of the Error - reason: String, - - /// Source of the Error - source: io::Error, - }, - - /// An Error occurred while converting between Integer types - #[error("Integer Conversion Error")] - IntegerConversionFailed(#[from] TryFromIntError), -} - /// A DMA-Buf buffer #[derive(Debug)] pub struct DmaBuf(OwnedFd); @@ -87,15 +58,16 @@ impl DmaBuf { /// /// Will return an error if either the Buffer's length can't be retrieved, or if the mmap call /// fails. - pub fn memory_map(self) -> Result { + #[expect( + clippy::unwrap_in_result, + reason = "The kernel doesn't use the same types between stat and munmap, but it's not something one can recover from." + )] + pub fn memory_map(self) -> io::Result { debug!("Mapping DMA-Buf buffer with File Descriptor {:#?}", self.0); - let stat = fstat(&self.0).map_err(|e| MapError::FdAccess { - reason: e.to_string(), - source: io::Error::from(e), - })?; - - let len = usize::try_from(stat.st_size)?.next_multiple_of(page_size()); + let len = usize::try_from(fstat(&self.0)?.st_size) + .expect("Buffer size can't fit into mmap argument length") + .next_multiple_of(page_size()); trace!("Valid buffer, size {len}"); // SAFETY: It's unclear at this point what the exact safety requirements from mmap are, but @@ -110,11 +82,7 @@ impl DmaBuf { 0, ) } - .map(<*mut c_void>::cast::) - .map_err(|e| MapError::MappingFailed { - reason: e.to_string(), - source: io::Error::from(e), - })?; + .map(<*mut c_void>::cast::)?; trace!("Memory Mapping Done"); From e9650df7bef4a73a6d5b1bec06b2d7a2d4b91c21 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 May 2025 09:49:07 +0200 Subject: [PATCH 6/6] dma-buf: Implement Display and Error by hand, and drop thiserror Signed-off-by: Maxime Ripard --- Cargo.toml | 1 - src/lib.rs | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 368fd1c..21ba01b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ rustix = { version = "1.0.5", default-features = false, features = [ "param", "std", ] } -thiserror = "2.0.3" tracing = { version = "0.1.41", default-features = false, features = ["std"] } [features] diff --git a/src/lib.rs b/src/lib.rs index 2917d3f..032e75f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,10 +102,9 @@ pub struct MappedDmaBuf { } /// Error type to access a [`MappedDmaBuf`] -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum BufferError { /// An Error occured while accessing the buffer file descriptor - #[error("Could not access the buffer: {reason}")] FdAccess { /// Description of the Error reason: String, @@ -115,10 +114,31 @@ pub enum BufferError { }, /// An Error occured in the closure - #[error("The closure returned an error: {0}")] Closure(Box), } +impl fmt::Display for BufferError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + BufferError::FdAccess { reason, .. } => { + f.write_fmt(format_args!("Could not access the buffer: {reason}")) + } + BufferError::Closure(error) => { + f.write_fmt(format_args!("The closure returned an error: {error}")) + } + } + } +} + +impl error::Error for BufferError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + BufferError::FdAccess { source, .. } => Some(source), + BufferError::Closure(error) => Some(error.as_ref()), + } + } +} + impl MappedDmaBuf { fn as_slice(&self) -> &[u8] { // SAFETY: We know that the pointer is valid, and the buffer length is at least equal to