kernel/fs/
kiocb.rs

1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2024 Google LLC.
4
5//! Kernel IO callbacks.
6//!
7//! C headers: [`include/linux/fs.h`](srctree/include/linux/fs.h)
8
9use core::marker::PhantomData;
10use core::ptr::NonNull;
11use kernel::types::ForeignOwnable;
12
13/// Wrapper for the kernel's `struct kiocb`.
14///
15/// Currently this abstractions is incomplete and is essentially just a tuple containing a
16/// reference to a file and a file position.
17///
18/// The type `T` represents the filesystem or driver specific data associated with the file.
19///
20/// # Invariants
21///
22/// `inner` points at a valid `struct kiocb` whose file has the type `T` as its private data.
23pub struct Kiocb<'a, T> {
24    inner: NonNull<bindings::kiocb>,
25    _phantom: PhantomData<&'a T>,
26}
27
28impl<'a, T: ForeignOwnable> Kiocb<'a, T> {
29    /// Create a `Kiocb` from a raw pointer.
30    ///
31    /// # Safety
32    ///
33    /// The pointer must reference a valid `struct kiocb` for the duration of `'a`. The private
34    /// data of the file must be `T`.
35    pub unsafe fn from_raw(kiocb: *mut bindings::kiocb) -> Self {
36        Self {
37            // SAFETY: If a pointer is valid it is not null.
38            inner: unsafe { NonNull::new_unchecked(kiocb) },
39            _phantom: PhantomData,
40        }
41    }
42
43    /// Access the underlying `struct kiocb` directly.
44    pub fn as_raw(&self) -> *mut bindings::kiocb {
45        self.inner.as_ptr()
46    }
47
48    /// Get the filesystem or driver specific data associated with the file.
49    pub fn file(&self) -> <T as ForeignOwnable>::Borrowed<'a> {
50        // SAFETY: We have shared access to this kiocb and hence the underlying file, so we can
51        // read the file's private data.
52        let private = unsafe { (*(*self.as_raw()).ki_filp).private_data };
53        // SAFETY: The kiocb has shared access to the private data.
54        unsafe { <T as ForeignOwnable>::borrow(private) }
55    }
56
57    /// Gets the current value of `ki_pos`.
58    pub fn ki_pos(&self) -> i64 {
59        // SAFETY: We have shared access to the kiocb, so we can read its `ki_pos` field.
60        unsafe { (*self.as_raw()).ki_pos }
61    }
62
63    /// Gets a mutable reference to the `ki_pos` field.
64    pub fn ki_pos_mut(&mut self) -> &mut i64 {
65        // SAFETY: We have exclusive access to the kiocb, so we can write to `ki_pos`.
66        unsafe { &mut (*self.as_raw()).ki_pos }
67    }
68}