Skip to content

Commit 4e2d67e

Browse files
authored
Merge pull request #230 from wedsonaf/read-write
Generalise `read` and `write`.
2 parents d2a231a + 8aa5a4e commit 4e2d67e

File tree

4 files changed

+46
-21
lines changed

4 files changed

+46
-21
lines changed

rust/kernel/file_operations.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ use core::{marker, mem, ops::Deref, pin::Pin, ptr};
1010
use alloc::boxed::Box;
1111
use alloc::sync::Arc;
1212

13-
use crate::bindings;
14-
use crate::c_types;
15-
use crate::error::{Error, KernelResult};
16-
use crate::sync::{CondVar, Ref, RefCounted};
17-
use crate::user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter};
13+
use crate::{
14+
bindings, c_types,
15+
error::{Error, KernelResult},
16+
io_buffer::{IoBufferReader, IoBufferWriter},
17+
sync::{CondVar, Ref, RefCounted},
18+
user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter},
19+
};
1820

1921
/// Wraps the kernel's `struct file`.
2022
///
@@ -166,7 +168,7 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
166168
let f = &*((*file).private_data as *const T);
167169
// No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63).
168170
// See discussion in https://github.com/fishinabarrel/linux-kernel-module-rust/pull/113
169-
let written = f.write(&mut data, (*offset).try_into()?)?;
171+
let written = f.write(&File::from_ptr(file), &mut data, (*offset).try_into()?)?;
170172
(*offset) += bindings::loff_t::try_from(written).unwrap();
171173
Ok(written as _)
172174
}
@@ -548,22 +550,27 @@ pub trait FileOperations: Send + Sync + Sized {
548550
/// Corresponds to the `release` function pointer in `struct file_operations`.
549551
fn release(_obj: Self::Wrapper, _file: &File) {}
550552

551-
/// Reads data from this file to userspace.
553+
/// Reads data from this file to the caller's buffer.
552554
///
553-
/// Corresponds to the `read` function pointer in `struct file_operations`.
554-
fn read(
555+
/// Corresponds to the `read` and `read_iter` function pointers in `struct file_operations`.
556+
fn read<T: IoBufferWriter>(
555557
&self,
556558
_file: &File,
557-
_data: &mut UserSlicePtrWriter,
559+
_data: &mut T,
558560
_offset: u64,
559561
) -> KernelResult<usize> {
560562
Err(Error::EINVAL)
561563
}
562564

563-
/// Writes data from userspace to this file.
565+
/// Writes data from the caller's buffer to this file.
564566
///
565-
/// Corresponds to the `write` function pointer in `struct file_operations`.
566-
fn write(&self, _data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
567+
/// Corresponds to the `write` and `write_iter` function pointers in `struct file_operations`.
568+
fn write<T: IoBufferReader>(
569+
&self,
570+
_file: &File,
571+
_data: &mut T,
572+
_offset: u64,
573+
) -> KernelResult<usize> {
567574
Err(Error::EINVAL)
568575
}
569576

samples/rust/rust_miscdev.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use kernel::{
1414
io_buffer::{IoBufferReader, IoBufferWriter},
1515
miscdev,
1616
sync::{CondVar, Mutex},
17-
user_ptr::{UserSlicePtrReader, UserSlicePtrWriter},
1817
Error,
1918
};
2019

@@ -74,7 +73,7 @@ impl FileOperations for Token {
7473

7574
kernel::declare_file_operations!(read, write);
7675

77-
fn read(&self, _: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult<usize> {
76+
fn read<T: IoBufferWriter>(&self, _: &File, data: &mut T, offset: u64) -> KernelResult<usize> {
7877
// Succeed if the caller doesn't provide a buffer or if not at the start.
7978
if data.is_empty() || offset != 0 {
8079
return Ok(0);
@@ -102,7 +101,12 @@ impl FileOperations for Token {
102101
Ok(1)
103102
}
104103

105-
fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
104+
fn write<T: IoBufferReader>(
105+
&self,
106+
_: &File,
107+
data: &mut T,
108+
_offset: u64,
109+
) -> KernelResult<usize> {
106110
{
107111
let mut inner = self.shared.inner.lock();
108112

samples/rust/rust_random.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use kernel::{
1212
file_operations::{File, FileOperations},
1313
io_buffer::{IoBufferReader, IoBufferWriter},
1414
prelude::*,
15-
user_ptr::{UserSlicePtrReader, UserSlicePtrWriter},
1615
};
1716

1817
#[derive(Default)]
@@ -21,7 +20,12 @@ struct RandomFile;
2120
impl FileOperations for RandomFile {
2221
kernel::declare_file_operations!(read, write);
2322

24-
fn read(&self, file: &File, buf: &mut UserSlicePtrWriter, _offset: u64) -> KernelResult<usize> {
23+
fn read<T: IoBufferWriter>(
24+
&self,
25+
file: &File,
26+
buf: &mut T,
27+
_offset: u64,
28+
) -> KernelResult<usize> {
2529
let total_len = buf.len();
2630
let mut chunkbuf = [0; 256];
2731

@@ -39,7 +43,12 @@ impl FileOperations for RandomFile {
3943
Ok(total_len)
4044
}
4145

42-
fn write(&self, buf: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
46+
fn write<T: IoBufferReader>(
47+
&self,
48+
_file: &File,
49+
buf: &mut T,
50+
_offset: u64,
51+
) -> KernelResult<usize> {
4352
let total_len = buf.len();
4453
let mut chunkbuf = [0; 256];
4554
while !buf.is_empty() {

samples/rust/rust_semaphore.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl FileOperations for FileState {
8484

8585
declare_file_operations!(read, write, ioctl);
8686

87-
fn read(&self, _: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult<usize> {
87+
fn read<T: IoBufferWriter>(&self, _: &File, data: &mut T, offset: u64) -> KernelResult<usize> {
8888
if data.is_empty() || offset > 0 {
8989
return Ok(0);
9090
}
@@ -94,7 +94,12 @@ impl FileOperations for FileState {
9494
Ok(1)
9595
}
9696

97-
fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
97+
fn write<T: IoBufferReader>(
98+
&self,
99+
_: &File,
100+
data: &mut T,
101+
_offset: u64,
102+
) -> KernelResult<usize> {
98103
{
99104
let mut inner = self.shared.inner.lock();
100105
inner.count = inner.count.saturating_add(data.len());

0 commit comments

Comments
 (0)