ANDROID: ashmem_rust: add GET/SET_NAME
Add the first ioctl to the ashmem device. The `Ashmem` struct is augmented with a mutex to hold the name. The Rust bindings helper is updated to pull in constants from the existing C header. For now, only ASHMEM_NAME_LEN is needed, but later patches will need more stuff from the C header. Bug: 370906207 Change-Id: I7fbbce12e1fa7c4fb811fcb2561806795ba2bd0f Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
306f5648d8
commit
ad23cf4103
@@ -12,13 +12,18 @@
|
||||
|
||||
use core::pin::Pin;
|
||||
use kernel::{
|
||||
c_str,
|
||||
bindings, c_str,
|
||||
error::Result,
|
||||
fs::File,
|
||||
ioctl::_IOC_SIZE,
|
||||
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
|
||||
prelude::*,
|
||||
sync::{new_mutex, Mutex},
|
||||
uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
|
||||
};
|
||||
|
||||
const ASHMEM_NAME_LEN: usize = bindings::ASHMEM_NAME_LEN as usize;
|
||||
|
||||
module! {
|
||||
type: AshmemModule,
|
||||
name: "ashmem_rust",
|
||||
@@ -48,13 +53,81 @@ impl kernel::Module for AshmemModule {
|
||||
|
||||
/// Represents an open ashmem file.
|
||||
#[pin_data]
|
||||
struct Ashmem {}
|
||||
struct Ashmem {
|
||||
#[pin]
|
||||
inner: Mutex<AshmemInner>,
|
||||
}
|
||||
|
||||
struct AshmemInner {
|
||||
/// If set, then this holds the ashmem name without the dev/ashmem/ prefix. No zero terminator.
|
||||
name: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[vtable]
|
||||
impl MiscDevice for Ashmem {
|
||||
type Ptr = Pin<Box<Self>>;
|
||||
|
||||
fn open(_: &File, _: &MiscDeviceRegistration<Ashmem>) -> Result<Pin<Box<Self>>> {
|
||||
Box::try_pin_init(Ashmem {}, GFP_KERNEL)
|
||||
Box::try_pin_init(
|
||||
try_pin_init! {
|
||||
Ashmem {
|
||||
inner <- new_mutex!(AshmemInner {
|
||||
name: None,
|
||||
}),
|
||||
}
|
||||
},
|
||||
GFP_KERNEL,
|
||||
)
|
||||
}
|
||||
|
||||
fn ioctl(me: Pin<&Ashmem>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
|
||||
let size = _IOC_SIZE(cmd);
|
||||
match cmd {
|
||||
bindings::ASHMEM_SET_NAME => me.set_name(UserSlice::new(arg, size).reader()),
|
||||
bindings::ASHMEM_GET_NAME => me.get_name(UserSlice::new(arg, size).writer()),
|
||||
_ => Err(EINVAL),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ashmem {
|
||||
fn set_name(&self, mut reader: UserSliceReader) -> Result<isize> {
|
||||
let mut local_name = [0u8; ASHMEM_NAME_LEN];
|
||||
reader.read_slice(&mut local_name)?;
|
||||
|
||||
// Find the zero terminator. If the zero terminator is missing, the string is truncated to
|
||||
// `ASHMEM_NAME_LEN-1` so that `get_name` can return it and has enough space to add a zero
|
||||
// terminator.
|
||||
let len = local_name
|
||||
.iter()
|
||||
.position(|&c| c == 0)
|
||||
.unwrap_or(local_name.len() - 1);
|
||||
|
||||
let mut v = Vec::with_capacity(len, GFP_KERNEL)?;
|
||||
v.extend_from_slice(&local_name[..len], GFP_KERNEL)?;
|
||||
|
||||
let mut asma = self.inner.lock();
|
||||
// TODO: fail if `mmap` is already called
|
||||
asma.name = Some(v);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn get_name(&self, mut writer: UserSliceWriter) -> Result<isize> {
|
||||
let mut local_name = [0u8; ASHMEM_NAME_LEN];
|
||||
let asma = self.inner.lock();
|
||||
let name = asma.name.as_deref().unwrap_or(b"dev/ashmem");
|
||||
let len = name.len();
|
||||
let len_with_nul = len + 1;
|
||||
if local_name.len() <= len_with_nul {
|
||||
// This shouldn't happen in practice since `set_name` will refuse to store a string
|
||||
// that is too long.
|
||||
return Err(EINVAL);
|
||||
}
|
||||
local_name[..len].copy_from_slice(name);
|
||||
local_name[len_with_nul] = 0;
|
||||
drop(asma);
|
||||
|
||||
writer.write_slice(&local_name[..len_with_nul])?;
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,3 +45,7 @@ const gfp_t RUST_CONST_HELPER_GFP_NOWAIT = GFP_NOWAIT;
|
||||
const gfp_t RUST_CONST_HELPER___GFP_ZERO = __GFP_ZERO;
|
||||
const gfp_t RUST_CONST_HELPER___GFP_HIGHMEM = ___GFP_HIGHMEM;
|
||||
const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL;
|
||||
|
||||
#ifdef CONFIG_ASHMEM_RUST
|
||||
#include "../../drivers/staging/android/ashmem.h"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user