ANDROID: ashmem_rust: add read_iter implementation
We just forward read calls to the underlying shmem file. Bug: 370906207 Change-Id: I14da5e4312c9c2807861c68f6cae0fa76a45f885 Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
52ffab963a
commit
700f668e3c
@@ -16,7 +16,7 @@ use kernel::{
|
||||
error::Result,
|
||||
fs::File,
|
||||
ioctl::_IOC_SIZE,
|
||||
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
|
||||
miscdevice::{IovIter, Kiocb, MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
|
||||
mm::virt::{flags as vma_flags, VmAreaNew},
|
||||
page::page_align,
|
||||
prelude::*,
|
||||
@@ -155,6 +155,29 @@ impl MiscDevice for Ashmem {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_iter(mut kiocb: Kiocb<'_, Self::Ptr>, iov: &mut IovIter) -> Result<usize> {
|
||||
let me = kiocb.private_data();
|
||||
let asma_file = {
|
||||
let asma = me.inner.lock();
|
||||
if asma.size == 0 {
|
||||
// If size is not set, or set to 0, always return EOF.
|
||||
return Ok(0);
|
||||
}
|
||||
match asma.file.as_ref() {
|
||||
Some(asma_file) => asma_file.clone(),
|
||||
None => return Err(EBADF),
|
||||
}
|
||||
};
|
||||
|
||||
let ret = asma_file.vfs_iter_read(iov, kiocb.ki_pos_mut())?;
|
||||
|
||||
// SAFETY: We protect the shmem file with the same mechanism as the ashmem file. We are in
|
||||
// read_iter, so our caller ensures that accessing f_pos is okay.
|
||||
unsafe { shmem::file_set_fpos(asma_file.file(), kiocb.ki_pos()) };
|
||||
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
fn ioctl(me: Pin<&Ashmem>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
|
||||
let size = _IOC_SIZE(cmd);
|
||||
match cmd {
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
use kernel::{
|
||||
bindings,
|
||||
error::{from_err_ptr, to_result, Result},
|
||||
fs::file::File,
|
||||
fs::file::{File, LocalFile},
|
||||
miscdevice::{loff_t, IovIter},
|
||||
mm::virt::{vm_flags_t, VmAreaNew},
|
||||
prelude::*,
|
||||
str::CStr,
|
||||
@@ -20,6 +21,14 @@ use core::{
|
||||
ptr::{addr_of_mut, NonNull},
|
||||
};
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Caller must ensure that access to the file position is properly synchronized.
|
||||
pub(crate) unsafe fn file_set_fpos(file: &LocalFile, pos: loff_t) {
|
||||
// SAFETY: Caller ensures that this is okay.
|
||||
unsafe { (*file.as_ptr()).f_pos = pos };
|
||||
}
|
||||
|
||||
pub(crate) fn vma_set_anonymous(vma: &VmAreaNew) {
|
||||
// SAFETY: The `VmAreaNew` type is only used when the vma is being set up, so this operation is
|
||||
// safe.
|
||||
@@ -68,6 +77,17 @@ impl ShmemFile {
|
||||
pub(crate) fn file(&self) -> &File {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub(crate) fn vfs_iter_read(&self, iov: &mut IovIter, pos: &mut loff_t) -> Result<loff_t> {
|
||||
// SAFETY: Just an FFI call. The file and iov is valid.
|
||||
let ret = unsafe { bindings::vfs_iter_read(self.inner.as_ptr(), iov.as_raw(), pos, 0) };
|
||||
|
||||
if ret < 0 {
|
||||
Err(Error::from_errno(ret as i32))
|
||||
} else {
|
||||
Ok(ret as loff_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fix the lockdep class of the shmem inode.
|
||||
|
||||
Reference in New Issue
Block a user