@@ -7,6 +7,7 @@ use crate::{
77 bindings,
88 error:: code:: * ,
99 error:: Result ,
10+ types:: { Opaque , Ownable , Owned } ,
1011 uaccess:: UserSliceReader ,
1112} ;
1213use core:: ptr:: { self , NonNull } ;
@@ -30,13 +31,10 @@ pub const fn page_align(addr: usize) -> usize {
3031 ( addr + ( PAGE_SIZE - 1 ) ) & PAGE_MASK
3132}
3233
33- /// A pointer to a page that owns the page allocation.
34- ///
35- /// # Invariants
36- ///
37- /// The pointer is valid, and has ownership over the page.
34+ /// A struct page.
35+ #[ repr( transparent) ]
3836pub struct Page {
39- page : NonNull < bindings:: page > ,
37+ page : Opaque < bindings:: page > ,
4038}
4139
4240// SAFETY: Pages have no logic that relies on them staying on a given thread, so moving them across
@@ -70,19 +68,20 @@ impl Page {
7068 /// # Ok::<(), kernel::alloc::AllocError>(())
7169 /// ```
7270 #[ inline]
73- pub fn alloc_page ( flags : Flags ) -> Result < Self , AllocError > {
71+ pub fn alloc_page ( flags : Flags ) -> Result < Owned < Self > , AllocError > {
7472 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it
7573 // is always safe to call this method.
7674 let page = unsafe { bindings:: alloc_pages ( flags. as_raw ( ) , 0 ) } ;
7775 let page = NonNull :: new ( page) . ok_or ( AllocError ) ?;
78- // INVARIANT: We just successfully allocated a page, so we now have ownership of the newly
79- // allocated page. We transfer that ownership to the new `Page` object.
80- Ok ( Self { page } )
76+ // SAFETY: We just successfully allocated a page, so we now have ownership of the newly
77+ // allocated page. We transfer that ownership to the new `Owned<Page>` object.
78+ // Since `Page` is transparent, we can cast the pointer directly.
79+ Ok ( unsafe { Owned :: from_raw ( page. cast ( ) ) } )
8180 }
8281
8382 /// Returns a raw pointer to the page.
8483 pub fn as_ptr ( & self ) -> * mut bindings:: page {
85- self . page . as_ptr ( )
84+ Opaque :: raw_get ( & self . page )
8685 }
8786
8887 /// Runs a piece of code with this page mapped to an address.
@@ -251,10 +250,12 @@ impl Page {
251250 }
252251}
253252
254- impl Drop for Page {
253+ // SAFETY: See below.
254+ unsafe impl Ownable for Page {
255255 #[ inline]
256- fn drop ( & mut self ) {
256+ unsafe fn release ( this : NonNull < Self > ) {
257257 // SAFETY: By the type invariants, we have ownership of the page and can free it.
258- unsafe { bindings:: __free_pages ( self . page . as_ptr ( ) , 0 ) } ;
258+ // Since Page is transparent, we can cast the raw pointer directly.
259+ unsafe { bindings:: __free_pages ( this. cast ( ) . as_ptr ( ) , 0 ) } ;
259260 }
260261}
0 commit comments