mirror of https://github.com/torvalds/linux.git
samples: rust_misc_device: Expand the sample to support read()ing from userspace
A userland application can now operate on the char device with read() in order to consume a locally held buffer. Memory for the buffer is to be provisioned and the buffer populated in its subsequently provided write() counterpart. Signed-off-by: Lee Jones <lee@kernel.org> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Co-developed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20250822-iov-iter-v5-5-6ce4819c2977@google.com
This commit is contained in:
parent
39c2745b37
commit
e5b0d7da94
|
|
@ -100,8 +100,9 @@
|
|||
use kernel::{
|
||||
c_str,
|
||||
device::Device,
|
||||
fs::File,
|
||||
fs::{File, Kiocb},
|
||||
ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
|
||||
iov::{IovIterDest, IovIterSource},
|
||||
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
|
||||
new_mutex,
|
||||
prelude::*,
|
||||
|
|
@ -144,6 +145,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
|
|||
|
||||
struct Inner {
|
||||
value: i32,
|
||||
buffer: KVVec<u8>,
|
||||
}
|
||||
|
||||
#[pin_data(PinnedDrop)]
|
||||
|
|
@ -165,7 +167,10 @@ fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Se
|
|||
KBox::try_pin_init(
|
||||
try_pin_init! {
|
||||
RustMiscDevice {
|
||||
inner <- new_mutex!( Inner{ value: 0_i32 } ),
|
||||
inner <- new_mutex!(Inner {
|
||||
value: 0_i32,
|
||||
buffer: KVVec::new(),
|
||||
}),
|
||||
dev: dev,
|
||||
}
|
||||
},
|
||||
|
|
@ -173,6 +178,33 @@ fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Se
|
|||
)
|
||||
}
|
||||
|
||||
fn read_iter(mut kiocb: Kiocb<'_, Self::Ptr>, iov: &mut IovIterDest<'_>) -> Result<usize> {
|
||||
let me = kiocb.file();
|
||||
dev_info!(me.dev, "Reading from Rust Misc Device Sample\n");
|
||||
|
||||
let inner = me.inner.lock();
|
||||
// Read the buffer contents, taking the file position into account.
|
||||
let read = iov.simple_read_from_buffer(kiocb.ki_pos_mut(), &inner.buffer)?;
|
||||
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
fn write_iter(mut kiocb: Kiocb<'_, Self::Ptr>, iov: &mut IovIterSource<'_>) -> Result<usize> {
|
||||
let me = kiocb.file();
|
||||
dev_info!(me.dev, "Writing to Rust Misc Device Sample\n");
|
||||
|
||||
let mut inner = me.inner.lock();
|
||||
|
||||
// Replace buffer contents.
|
||||
inner.buffer.clear();
|
||||
let len = iov.copy_from_iter_vec(&mut inner.buffer, GFP_KERNEL)?;
|
||||
|
||||
// Set position to zero so that future `read` calls will see the new contents.
|
||||
*kiocb.ki_pos_mut() = 0;
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
|
||||
dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue