ANDROID: ashmem_rust: add llseek

Similarly to reading, we also forward seeking to the underlying file.

Bug: 370906207
Change-Id: Icba9b7416276211c71ca04b266d12523389ad733
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2024-09-13 13:40:45 +00:00
committed by Treehugger Robot
parent 700f668e3c
commit 00c67f121e
2 changed files with 43 additions and 3 deletions
+24 -3
View File
@@ -10,13 +10,13 @@
//! It is, in theory, a good memory allocator for low-memory devices, because it can discard shared
//! memory units when under memory pressure.
use core::pin::Pin;
use core::{ffi::c_int, pin::Pin};
use kernel::{
bindings, c_str,
error::Result,
fs::File,
fs::{File, LocalFile},
ioctl::_IOC_SIZE,
miscdevice::{IovIter, Kiocb, MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
miscdevice::{loff_t, IovIter, Kiocb, MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
mm::virt::{flags as vma_flags, VmAreaNew},
page::page_align,
prelude::*,
@@ -155,6 +155,27 @@ impl MiscDevice for Ashmem {
Ok(())
}
fn llseek(me: Pin<&Ashmem>, file: &LocalFile, offset: loff_t, whence: c_int) -> Result<loff_t> {
let asma_file = {
let asma = me.inner.lock();
if asma.size == 0 {
return Err(EINVAL);
}
match asma.file.as_ref() {
Some(asma_file) => asma_file.clone(),
None => return Err(EBADF),
}
};
let ret = asma_file.vfs_llseek(offset, whence)?;
// SAFETY: We protect the shmem file with the same mechanism as the ashmem file. We are in
// llseek, so our caller ensures that accessing f_pos is okay.
unsafe { shmem::file_set_fpos(file, shmem::file_get_fpos(asma_file.file())) };
Ok(ret)
}
fn read_iter(mut kiocb: Kiocb<'_, Self::Ptr>, iov: &mut IovIter) -> Result<usize> {
let me = kiocb.private_data();
let asma_file = {
+19
View File
@@ -21,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_get_fpos(file: &LocalFile) -> loff_t {
// SAFETY: Caller ensures that this is okay.
unsafe { (*file.as_ptr()).f_pos }
}
/// # Safety
///
/// Caller must ensure that access to the file position is properly synchronized.
@@ -78,6 +86,17 @@ impl ShmemFile {
&self.inner
}
pub(crate) fn vfs_llseek(&self, offset: loff_t, whence: c_int) -> Result<loff_t> {
// SAFETY: Just an FFI call. The file is valid.
let ret = unsafe { bindings::vfs_llseek(self.inner.as_ptr(), offset, whence) };
if ret < 0 {
Err(Error::from_errno(ret as i32))
} else {
Ok(ret)
}
}
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) };