@@ -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
@@ -69,19 +67,20 @@ impl Page {
6967 /// let page = Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?;
7068 /// # Ok::<(), kernel::alloc::AllocError>(())
7169 /// ```
72- pub fn alloc_page ( flags : Flags ) -> Result < Self , AllocError > {
70+ pub fn alloc_page ( flags : Flags ) -> Result < Owned < Self > , AllocError > {
7371 // SAFETY: Depending on the value of `gfp_flags`, this call may sleep. Other than that, it
7472 // is always safe to call this method.
7573 let page = unsafe { bindings:: alloc_pages ( flags. as_raw ( ) , 0 ) } ;
7674 let page = NonNull :: new ( page) . ok_or ( AllocError ) ?;
77- // INVARIANT: We just successfully allocated a page, so we now have ownership of the newly
78- // allocated page. We transfer that ownership to the new `Page` object.
79- Ok ( Self { page } )
75+ // SAFETY: We just successfully allocated a page, so we now have ownership of the newly
76+ // allocated page. We transfer that ownership to the new `Owned<Page>` object.
77+ // Since `Page` is transparent, we can cast the pointer directly.
78+ Ok ( unsafe { Owned :: from_raw ( page. cast ( ) ) } )
8079 }
8180
8281 /// Returns a raw pointer to the page.
8382 pub fn as_ptr ( & self ) -> * mut bindings:: page {
84- self . page . as_ptr ( )
83+ Opaque :: raw_get ( & self . page )
8584 }
8685
8786 /// Runs a piece of code with this page mapped to an address.
@@ -250,9 +249,11 @@ impl Page {
250249 }
251250}
252251
253- impl Drop for Page {
254- fn drop ( & mut self ) {
252+ // SAFETY: See below.
253+ unsafe impl Ownable for Page {
254+ unsafe fn release ( this : NonNull < Self > ) {
255255 // SAFETY: By the type invariants, we have ownership of the page and can free it.
256- unsafe { bindings:: __free_pages ( self . page . as_ptr ( ) , 0 ) } ;
256+ // Since Page is transparent, we can cast the raw pointer directly.
257+ unsafe { bindings:: __free_pages ( this. cast ( ) . as_ptr ( ) , 0 ) } ;
257258 }
258259}
0 commit comments