From 8aa5a4edb4be1f8903e20942700f3bbf23050d9f Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Tue, 27 Apr 2021 15:40:14 +0100 Subject: [PATCH] Generalise `read` and `write`. This is also in preparation for adding support for `read_iter` and `write_iter`. An extra argument is being added to `write` for consistency with the other functions. Otherwise, this is a pure refactor. Signed-off-by: Wedson Almeida Filho --- rust/kernel/file_operations.rs | 33 ++++++++++++++++++++------------- samples/rust/rust_miscdev.rs | 10 +++++++--- samples/rust/rust_random.rs | 15 ++++++++++++--- samples/rust/rust_semaphore.rs | 9 +++++++-- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/rust/kernel/file_operations.rs b/rust/kernel/file_operations.rs index da13d4b6b0dbf7..49dcdc589f2a92 100644 --- a/rust/kernel/file_operations.rs +++ b/rust/kernel/file_operations.rs @@ -10,11 +10,13 @@ use core::{marker, mem, ops::Deref, pin::Pin, ptr}; use alloc::boxed::Box; use alloc::sync::Arc; -use crate::bindings; -use crate::c_types; -use crate::error::{Error, KernelResult}; -use crate::sync::{CondVar, Ref, RefCounted}; -use crate::user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter}; +use crate::{ + bindings, c_types, + error::{Error, KernelResult}, + io_buffer::{IoBufferReader, IoBufferWriter}, + sync::{CondVar, Ref, RefCounted}, + user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter}, +}; /// Wraps the kernel's `struct file`. /// @@ -166,7 +168,7 @@ unsafe extern "C" fn write_callback( let f = &*((*file).private_data as *const T); // No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63). // See discussion in https://github.com/fishinabarrel/linux-kernel-module-rust/pull/113 - let written = f.write(&mut data, (*offset).try_into()?)?; + let written = f.write(&File::from_ptr(file), &mut data, (*offset).try_into()?)?; (*offset) += bindings::loff_t::try_from(written).unwrap(); Ok(written as _) } @@ -548,22 +550,27 @@ pub trait FileOperations: Send + Sync + Sized { /// Corresponds to the `release` function pointer in `struct file_operations`. fn release(_obj: Self::Wrapper, _file: &File) {} - /// Reads data from this file to userspace. + /// Reads data from this file to the caller's buffer. /// - /// Corresponds to the `read` function pointer in `struct file_operations`. - fn read( + /// Corresponds to the `read` and `read_iter` function pointers in `struct file_operations`. + fn read( &self, _file: &File, - _data: &mut UserSlicePtrWriter, + _data: &mut T, _offset: u64, ) -> KernelResult { Err(Error::EINVAL) } - /// Writes data from userspace to this file. + /// Writes data from the caller's buffer to this file. /// - /// Corresponds to the `write` function pointer in `struct file_operations`. - fn write(&self, _data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult { + /// Corresponds to the `write` and `write_iter` function pointers in `struct file_operations`. + fn write( + &self, + _file: &File, + _data: &mut T, + _offset: u64, + ) -> KernelResult { Err(Error::EINVAL) } diff --git a/samples/rust/rust_miscdev.rs b/samples/rust/rust_miscdev.rs index 01f5c6d0e4e553..944da811f4c164 100644 --- a/samples/rust/rust_miscdev.rs +++ b/samples/rust/rust_miscdev.rs @@ -14,7 +14,6 @@ use kernel::{ io_buffer::{IoBufferReader, IoBufferWriter}, miscdev, sync::{CondVar, Mutex}, - user_ptr::{UserSlicePtrReader, UserSlicePtrWriter}, Error, }; @@ -74,7 +73,7 @@ impl FileOperations for Token { kernel::declare_file_operations!(read, write); - fn read(&self, _: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult { + fn read(&self, _: &File, data: &mut T, offset: u64) -> KernelResult { // Succeed if the caller doesn't provide a buffer or if not at the start. if data.is_empty() || offset != 0 { return Ok(0); @@ -102,7 +101,12 @@ impl FileOperations for Token { Ok(1) } - fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult { + fn write( + &self, + _: &File, + data: &mut T, + _offset: u64, + ) -> KernelResult { { let mut inner = self.shared.inner.lock(); diff --git a/samples/rust/rust_random.rs b/samples/rust/rust_random.rs index c4cc7d0f18027e..bc2335c854faf4 100644 --- a/samples/rust/rust_random.rs +++ b/samples/rust/rust_random.rs @@ -12,7 +12,6 @@ use kernel::{ file_operations::{File, FileOperations}, io_buffer::{IoBufferReader, IoBufferWriter}, prelude::*, - user_ptr::{UserSlicePtrReader, UserSlicePtrWriter}, }; #[derive(Default)] @@ -21,7 +20,12 @@ struct RandomFile; impl FileOperations for RandomFile { kernel::declare_file_operations!(read, write); - fn read(&self, file: &File, buf: &mut UserSlicePtrWriter, _offset: u64) -> KernelResult { + fn read( + &self, + file: &File, + buf: &mut T, + _offset: u64, + ) -> KernelResult { let total_len = buf.len(); let mut chunkbuf = [0; 256]; @@ -39,7 +43,12 @@ impl FileOperations for RandomFile { Ok(total_len) } - fn write(&self, buf: &mut UserSlicePtrReader, _offset: u64) -> KernelResult { + fn write( + &self, + _file: &File, + buf: &mut T, + _offset: u64, + ) -> KernelResult { let total_len = buf.len(); let mut chunkbuf = [0; 256]; while !buf.is_empty() { diff --git a/samples/rust/rust_semaphore.rs b/samples/rust/rust_semaphore.rs index 556c3eadb984ec..83b163f647f20c 100644 --- a/samples/rust/rust_semaphore.rs +++ b/samples/rust/rust_semaphore.rs @@ -84,7 +84,7 @@ impl FileOperations for FileState { declare_file_operations!(read, write, ioctl); - fn read(&self, _: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult { + fn read(&self, _: &File, data: &mut T, offset: u64) -> KernelResult { if data.is_empty() || offset > 0 { return Ok(0); } @@ -94,7 +94,12 @@ impl FileOperations for FileState { Ok(1) } - fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult { + fn write( + &self, + _: &File, + data: &mut T, + _offset: u64, + ) -> KernelResult { { let mut inner = self.shared.inner.lock(); inner.count = inner.count.saturating_add(data.len());