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