@@ -7,6 +7,8 @@ use kernel::{
77 io_buffer:: IoBufferWriter ,
88 linked_list:: List ,
99 linked_list:: { GetLinks , Links } ,
10+ macros:: pinned_drop,
11+ new_spinlock,
1012 prelude:: * ,
1113 sync:: { Arc , SpinLock , UniqueArc } ,
1214 user_ptr:: UserSlicePtrWriter ,
@@ -26,7 +28,9 @@ struct TransactionInner {
2628 file_list : List < Box < FileInfo > > ,
2729}
2830
31+ #[ pin_project( PinnedDrop ) ]
2932pub ( crate ) struct Transaction {
33+ #[ pin]
3034 inner : SpinLock < TransactionInner > ,
3135 // TODO: Node should be released when the buffer is released.
3236 node_ref : Option < NodeRef > ,
@@ -55,26 +59,20 @@ impl Transaction {
5559 let data_address = alloc. ptr ;
5660 let file_list = alloc. take_file_list ( ) ;
5761 alloc. keep_alive ( ) ;
58- let mut tr = Pin :: from ( UniqueArc :: try_new ( Self {
59- // SAFETY: `spinlock_init` is called below.
60- inner : unsafe { SpinLock :: new ( TransactionInner { file_list } ) } ,
62+ let tr = UniqueArc :: pin_init :: < core:: convert:: Infallible > ( pin_init ! ( Self {
63+ inner: new_spinlock!( TransactionInner { file_list } , "Transaction::inner" ) ,
6164 node_ref: Some ( node_ref) ,
6265 stack_next,
6366 from: from. clone( ) ,
6467 to,
6568 code: tr. code,
6669 flags: tr. flags,
67- data_size : tr. data_size as _ ,
70+ data_size: tr. data_size as usize ,
6871 data_address,
69- offsets_size : tr. offsets_size as _ ,
72+ offsets_size: tr. offsets_size as usize ,
7073 links: Links :: new( ) ,
7174 free_allocation: AtomicBool :: new( true ) ,
72- } ) ?) ;
73-
74- // SAFETY: `inner` is pinned when `tr` is.
75- let pinned = unsafe { tr. as_mut ( ) . map_unchecked_mut ( |t| & mut t. inner ) } ;
76- kernel:: spinlock_init!( pinned, "Transaction::inner" ) ;
77-
75+ } ) ) ?;
7876 Ok ( tr. into ( ) )
7977 }
8078
@@ -88,26 +86,20 @@ impl Transaction {
8886 let data_address = alloc. ptr ;
8987 let file_list = alloc. take_file_list ( ) ;
9088 alloc. keep_alive ( ) ;
91- let mut tr = Pin :: from ( UniqueArc :: try_new ( Self {
92- // SAFETY: `spinlock_init` is called below.
93- inner : unsafe { SpinLock :: new ( TransactionInner { file_list } ) } ,
89+ let tr = UniqueArc :: pin_init :: < core:: convert:: Infallible > ( pin_init ! ( Self {
90+ inner: new_spinlock!( TransactionInner { file_list } , "Transaction::inner" ) ,
9491 node_ref: None ,
9592 stack_next: None ,
9693 from: from. clone( ) ,
9794 to,
9895 code: tr. code,
9996 flags: tr. flags,
100- data_size : tr. data_size as _ ,
97+ data_size: tr. data_size as usize ,
10198 data_address,
102- offsets_size : tr. offsets_size as _ ,
99+ offsets_size: tr. offsets_size as usize ,
103100 links: Links :: new( ) ,
104101 free_allocation: AtomicBool :: new( true ) ,
105- } ) ?) ;
106-
107- // SAFETY: `inner` is pinned when `tr` is.
108- let pinned = unsafe { tr. as_mut ( ) . map_unchecked_mut ( |t| & mut t. inner ) } ;
109- kernel:: spinlock_init!( pinned, "Transaction::inner" ) ;
110-
102+ } ) ) ?;
111103 Ok ( tr. into ( ) )
112104 }
113105
@@ -285,8 +277,9 @@ impl DeliverToRead for Transaction {
285277 }
286278}
287279
288- impl Drop for Transaction {
289- fn drop ( & mut self ) {
280+ #[ pinned_drop]
281+ impl PinnedDrop for Transaction {
282+ fn drop ( self : Pin < & mut Self > ) {
290283 if self . free_allocation . load ( Ordering :: Relaxed ) {
291284 self . to . buffer_get ( self . data_address ) ;
292285 }
0 commit comments