rust/kernel/fs/file.rs
Source file repositories/reference/linux-study-clean/rust/kernel/fs/file.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/fs/file.rs- Extension
.rs- Size
- 19454 bytes
- Lines
- 474
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function inc_reffunction dec_reffunction dec_reffunction Okfunction drop
Annotated Snippet
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
unsafe { bindings::get_file(self.as_ptr()) };
}
#[inline]
unsafe fn dec_ref(obj: ptr::NonNull<File>) {
// SAFETY: To call this method, the caller passes us ownership of a normal refcount, so we
// may drop it. The cast is okay since `File` has the same representation as `struct file`.
unsafe { bindings::fput(obj.cast().as_ptr()) }
}
}
/// Wraps the kernel's `struct file`. Not thread safe.
///
/// This type represents a file that is not known to be safe to transfer across thread boundaries.
/// To obtain a thread-safe [`File`], use the [`assume_no_fdget_pos`] conversion.
///
/// See the documentation for [`File`] for more information.
///
/// # Invariants
///
/// * All instances of this type are refcounted using the `f_count` field.
/// * If there is an active call to `fdget_pos` that did not take the `f_pos_lock` mutex, then it
/// must be on the same thread as this file.
///
/// [`assume_no_fdget_pos`]: LocalFile::assume_no_fdget_pos
#[repr(transparent)]
pub struct LocalFile {
inner: Opaque<bindings::file>,
}
// SAFETY: The type invariants guarantee that `LocalFile` is always ref-counted. This implementation
// makes `ARef<LocalFile>` own a normal refcount.
unsafe impl AlwaysRefCounted for LocalFile {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
unsafe { bindings::get_file(self.as_ptr()) };
}
#[inline]
unsafe fn dec_ref(obj: ptr::NonNull<LocalFile>) {
// SAFETY: To call this method, the caller passes us ownership of a normal refcount, so we
// may drop it. The cast is okay since `LocalFile` has the same representation as
// `struct file`.
unsafe { bindings::fput(obj.cast().as_ptr()) }
}
}
impl LocalFile {
/// Constructs a new `struct file` wrapper from a file descriptor.
///
/// The file descriptor belongs to the current process, and there might be active local calls
/// to `fdget_pos` on the same file.
///
/// To obtain an `ARef<File>`, use the [`assume_no_fdget_pos`] function to convert.
///
/// [`assume_no_fdget_pos`]: LocalFile::assume_no_fdget_pos
#[inline]
pub fn fget(fd: u32) -> Result<ARef<LocalFile>, BadFdError> {
// SAFETY: FFI call, there are no requirements on `fd`.
let ptr = ptr::NonNull::new(unsafe { bindings::fget(fd) }).ok_or(BadFdError)?;
// SAFETY: `bindings::fget` created a refcount, and we pass ownership of it to the `ARef`.
//
// INVARIANT: This file is in the fd table on this thread, so either all `fdget_pos` calls
// are on this thread, or the file is shared, in which case `fdget_pos` calls took the
// `f_pos_lock` mutex.
Ok(unsafe { ARef::from_raw(ptr.cast()) })
}
/// Creates a reference to a [`LocalFile`] from a valid pointer.
///
/// # Safety
///
/// * The caller must ensure that `ptr` points at a valid file and that the file's refcount is
/// positive for the duration of `'a`.
/// * The caller must ensure that if there is an active call to `fdget_pos` that did not take
/// the `f_pos_lock` mutex, then that call is on the current thread.
#[inline]
pub unsafe fn from_raw_file<'a>(ptr: *const bindings::file) -> &'a LocalFile {
// SAFETY: The caller guarantees that the pointer is not dangling and stays valid for the
// duration of `'a`. The cast is okay because `LocalFile` is `repr(transparent)`.
//
// INVARIANT: The caller guarantees that there are no problematic `fdget_pos` calls.
unsafe { &*ptr.cast() }
}
/// Assume that there are no active `fdget_pos` calls that prevent us from sharing this file.
Annotation
- Detected declarations: `function inc_ref`, `function dec_ref`, `function dec_ref`, `function Ok`, `function drop`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.