xref: /linux/rust/kernel/fs/kiocb.rs (revision 6093a688a07da07808f0122f9aa2a3eed250d853)
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 
9 use core::marker::PhantomData;
10 use core::ptr::NonNull;
11 use 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.
23 pub struct Kiocb<'a, T> {
24     inner: NonNull<bindings::kiocb>,
25     _phantom: PhantomData<&'a T>,
26 }
27 
28 impl<'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 }
69