mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Rust Binder exposes information about transactions that are sent in various ways: printing to the kernel log, tracepoints, files in binderfs, and the upcoming netlink support. Currently all these mechanisms use disparate ways of obtaining the same information, so let's introduce a single Info struct that collects all the required information in a single place, so that all of these different mechanisms can operate in a more uniform way. For now, the new info struct is only used to replace a few things: * The BinderTransactionDataSg struct that is passed as an argument to several methods is removed as the information is moved into the new info struct and passed down that way. * The oneway spam detection fields on Transaction and Allocation can be removed, as the information can be returned to the caller via the mutable info struct instead. But several other uses of the info struct are planned in follow-up patches. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Link: https://patch.msgid.link/20260306-transaction-info-v1-1-fda58fca558b@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
// Copyright (C) 2025 Google LLC.
|
|
|
|
use kernel::fmt;
|
|
use kernel::prelude::*;
|
|
|
|
use crate::defs::*;
|
|
|
|
pub(crate) type BinderResult<T = ()> = core::result::Result<T, BinderError>;
|
|
|
|
/// An error that will be returned to userspace via the `BINDER_WRITE_READ` ioctl rather than via
|
|
/// errno.
|
|
pub(crate) struct BinderError {
|
|
pub(crate) reply: u32,
|
|
pub(crate) source: Option<Error>,
|
|
}
|
|
|
|
impl BinderError {
|
|
pub(crate) fn new_dead() -> Self {
|
|
Self {
|
|
reply: BR_DEAD_REPLY,
|
|
source: None,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn new_frozen() -> Self {
|
|
Self {
|
|
reply: BR_FROZEN_REPLY,
|
|
source: None,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn new_frozen_oneway() -> Self {
|
|
Self {
|
|
reply: BR_TRANSACTION_PENDING_FROZEN,
|
|
source: None,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn is_dead(&self) -> bool {
|
|
self.reply == BR_DEAD_REPLY
|
|
}
|
|
}
|
|
|
|
/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
|
|
/// should be stored as the thread's extended error when given to userspace.
|
|
impl From<Error> for BinderError {
|
|
fn from(source: Error) -> Self {
|
|
Self {
|
|
reply: BR_FAILED_REPLY,
|
|
source: Some(source),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<kernel::fs::file::BadFdError> for BinderError {
|
|
fn from(source: kernel::fs::file::BadFdError) -> Self {
|
|
BinderError::from(Error::from(source))
|
|
}
|
|
}
|
|
|
|
impl From<kernel::alloc::AllocError> for BinderError {
|
|
fn from(_: kernel::alloc::AllocError) -> Self {
|
|
Self {
|
|
reply: BR_FAILED_REPLY,
|
|
source: Some(ENOMEM),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for BinderError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self.reply {
|
|
BR_FAILED_REPLY => match self.source.as_ref() {
|
|
Some(source) => f
|
|
.debug_struct("BR_FAILED_REPLY")
|
|
.field("source", source)
|
|
.finish(),
|
|
None => f.pad("BR_FAILED_REPLY"),
|
|
},
|
|
BR_DEAD_REPLY => f.pad("BR_DEAD_REPLY"),
|
|
BR_FROZEN_REPLY => f.pad("BR_FROZEN_REPLY"),
|
|
BR_TRANSACTION_PENDING_FROZEN => f.pad("BR_TRANSACTION_PENDING_FROZEN"),
|
|
BR_TRANSACTION_COMPLETE => f.pad("BR_TRANSACTION_COMPLETE"),
|
|
_ => f
|
|
.debug_struct("BinderError")
|
|
.field("reply", &self.reply)
|
|
.finish(),
|
|
}
|
|
}
|
|
}
|