@@ -12,9 +12,9 @@ pub const MAX_LFS_FILESIZE: i64 = bindings::MAX_LFS_FILESIZE;
1212/// Read-only file systems.
1313pub mod ro {
1414 use crate :: error:: { code:: * , from_result, to_result, Error , Result } ;
15- use crate :: types:: Opaque ;
15+ use crate :: types:: { AlwaysRefCounted , Opaque } ;
1616 use crate :: { bindings, init:: PinInit , str:: CStr , try_pin_init, ThisModule } ;
17- use core:: { marker:: PhantomData , marker:: PhantomPinned , pin:: Pin } ;
17+ use core:: { marker:: PhantomData , marker:: PhantomPinned , pin:: Pin , ptr } ;
1818 use macros:: { pin_data, pinned_drop} ;
1919
2020 /// A read-only file system type.
@@ -93,6 +93,50 @@ pub mod ro {
9393 }
9494 }
9595
96+ /// Wraps the kernel's `struct inode`.
97+ ///
98+ /// # Invariants
99+ ///
100+ /// Instances of this type are always ref-counted, that is, a call to `ihold` ensures that the
101+ /// allocation remains valid at least until the matching call to `iput`.
102+ #[ repr( transparent) ]
103+ pub struct INode < T : Type + ?Sized > ( Opaque < bindings:: inode > , PhantomData < T > ) ;
104+
105+ impl < T : Type + ?Sized > INode < T > {
106+ /// Returns the number of the inode.
107+ pub fn ino ( & self ) -> u64 {
108+ // SAFETY: `i_ino` is immutable, and `self` is guaranteed to be valid by the existence
109+ // of a shared reference (&self) to it.
110+ unsafe { ( * self . 0 . get ( ) ) . i_ino }
111+ }
112+
113+ /// Returns the super-block that owns the inode.
114+ pub fn super_block ( & self ) -> & SuperBlock < T > {
115+ // SAFETY: `i_sb` is immutable, and `self` is guaranteed to be valid by the existence
116+ // of a shared reference (&self) to it.
117+ unsafe { & * ( * self . 0 . get ( ) ) . i_sb . cast ( ) }
118+ }
119+
120+ /// Returns the size of the inode contents.
121+ pub fn size ( & self ) -> i64 {
122+ // SAFETY: `self` is guaranteed to be valid by the existence of a shared reference.
123+ unsafe { bindings:: i_size_read ( self . 0 . get ( ) ) }
124+ }
125+ }
126+
127+ // SAFETY: The type invariants guarantee that `INode` is always ref-counted.
128+ unsafe impl < T : Type + ?Sized > AlwaysRefCounted for INode < T > {
129+ fn inc_ref ( & self ) {
130+ // SAFETY: The existence of a shared reference means that the refcount is nonzero.
131+ unsafe { bindings:: ihold ( self . 0 . get ( ) ) } ;
132+ }
133+
134+ unsafe fn dec_ref ( obj : ptr:: NonNull < Self > ) {
135+ // SAFETY: The safety requirements guarantee that the refcount is nonzero.
136+ unsafe { bindings:: iput ( obj. cast ( ) . as_ptr ( ) ) }
137+ }
138+ }
139+
96140 /// A file system super block.
97141 ///
98142 /// Wraps the kernel's `struct super_block`.
0 commit comments