@@ -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
@@ -71,19 +69,20 @@ impl Page {
7169 /// let page = Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?;
7270 /// # Ok(()) }
7371 /// ```
74- pub fn alloc_page ( flags : Flags ) -> Result < Self , AllocError > {
72+ pub fn alloc_page ( flags : Flags ) -> Result < Owned < Self > , AllocError > {
7573 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it
7674 // is always safe to call this method.
7775 let page = unsafe { bindings:: alloc_pages ( flags. as_raw ( ) , 0 ) } ;
7876 let page = NonNull :: new ( page) . ok_or ( AllocError ) ?;
7977 // INVARIANT: We just successfully allocated a page, so we now have ownership of the newly
80- // allocated page. We transfer that ownership to the new `Page` object.
81- Ok ( Self { page } )
78+ // allocated page. We transfer that ownership to the new `Owned<Page>` object.
79+ // Since `Page` is transparent, we can cast the pointer directly.
80+ Ok ( unsafe { Owned :: from_raw ( page. cast ( ) ) } )
8281 }
8382
8483 /// Returns a raw pointer to the page.
8584 pub fn as_ptr ( & self ) -> * mut bindings:: page {
86- self . page . as_ptr ( )
85+ Opaque :: raw_get ( & self . page )
8786 }
8887
8988 /// Runs a piece of code with this page mapped to an address.
@@ -252,9 +251,11 @@ impl Page {
252251 }
253252}
254253
255- impl Drop for Page {
256- fn drop ( & mut self ) {
254+ // SAFETY: See below.
255+ unsafe impl Ownable for Page {
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