From ac3b8a6a6ab105cc822824eb5baf2d421fa70b29 Mon Sep 17 00:00:00 2001
From: Wedson Almeida Filho <wedsonaf@google.com>
Date: Thu, 25 Mar 2021 21:56:40 +0000
Subject: [PATCH] Change `read` and `write` to return the number of bytes
 read/written.

---
 drivers/char/rust_example.rs   | 11 +++++------
 rust/kernel/file_operations.rs | 23 +++++++++++++----------
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs
index 836e99f6adb027..2c23cb4060a876 100644
--- a/drivers/char/rust_example.rs
+++ b/drivers/char/rust_example.rs
@@ -99,10 +99,10 @@ impl FileOperations for Token {
 
     kernel::declare_file_operations!(read, write);
 
-    fn read(&self, _file: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult {
+    fn read(&self, _: &File, data: &mut UserSlicePtrWriter, offset: u64) -> KernelResult<usize> {
         // Succeed if the caller doesn't provide a buffer or if not at the start.
         if data.is_empty() || offset != 0 {
-            return Ok(());
+            return Ok(0);
         }
 
         {
@@ -124,10 +124,10 @@ impl FileOperations for Token {
 
         // Write a one-byte 1 to the reader.
         data.write_slice(&[1u8; 1])?;
-        Ok(())
+        Ok(1)
     }
 
-    fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<isize> {
+    fn write(&self, data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
         {
             let mut inner = self.shared.inner.lock();
 
@@ -144,8 +144,7 @@ impl FileOperations for Token {
 
         // Notify a possible reader waiting.
         self.shared.state_changed.notify_all();
-        data.read_all()?;
-        Ok(0)
+        Ok(data.len())
     }
 }
 
diff --git a/rust/kernel/file_operations.rs b/rust/kernel/file_operations.rs
index 3c4c076dddca9c..9f7d3f524f003f 100644
--- a/rust/kernel/file_operations.rs
+++ b/rust/kernel/file_operations.rs
@@ -105,10 +105,9 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
         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
-        T::read(f, &File::from_ptr(file), &mut data, (*offset).try_into()?)?;
-        let written = len - data.len();
-        (*offset) += bindings::loff_t::try_from(written).unwrap();
-        Ok(written.try_into().unwrap())
+        let read = f.read(&File::from_ptr(file), &mut data, (*offset).try_into()?)?;
+        (*offset) += bindings::loff_t::try_from(read).unwrap();
+        Ok(read as _)
     }
 }
 
@@ -123,10 +122,9 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
         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
-        T::write(f, &mut data, (*offset).try_into()?)?;
-        let read = len - data.len();
-        (*offset) += bindings::loff_t::try_from(read).unwrap();
-        Ok(read.try_into().unwrap())
+        let written = f.write(&mut data, (*offset).try_into()?)?;
+        (*offset) += bindings::loff_t::try_from(written).unwrap();
+        Ok(written as _)
     }
 }
 
@@ -470,14 +468,19 @@ pub trait FileOperations: Send + Sync + Sized {
     /// Reads data from this file to userspace.
     ///
     /// Corresponds to the `read` function pointer in `struct file_operations`.
-    fn read(&self, _file: &File, _data: &mut UserSlicePtrWriter, _offset: u64) -> KernelResult {
+    fn read(
+        &self,
+        _file: &File,
+        _data: &mut UserSlicePtrWriter,
+        _offset: u64,
+    ) -> KernelResult<usize> {
         Err(Error::EINVAL)
     }
 
     /// Writes data from userspace to this file.
     ///
     /// Corresponds to the `write` function pointer in `struct file_operations`.
-    fn write(&self, _data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<isize> {
+    fn write(&self, _data: &mut UserSlicePtrReader, _offset: u64) -> KernelResult<usize> {
         Err(Error::EINVAL)
     }