@@ -959,7 +959,8 @@ impl Region {
959
959
}
960
960
} ;
961
961
962
- self . flush_extents ( & dirty_extents, flush_number, gen_number, job_id) ?;
962
+ self . flush_extents ( & dirty_extents, flush_number, gen_number, job_id)
963
+ . await ?;
963
964
cdt:: os__flush__done!( || job_id. 0 ) ;
964
965
965
966
// Now everything has succeeded, we can remove these extents from the
@@ -1039,7 +1040,8 @@ impl Region {
1039
1040
}
1040
1041
1041
1042
#[ cfg( not( feature = "omicron-build" ) ) ]
1042
- fn flush_extents (
1043
+ #[ allow( clippy:: unused_async) ]
1044
+ async fn flush_extents (
1043
1045
& mut self ,
1044
1046
dirty_extents : & BTreeSet < usize > ,
1045
1047
flush_number : u64 ,
@@ -1107,7 +1109,7 @@ impl Region {
1107
1109
/// region is backed by a ZFS dataset. Issue a _FIOFFS call, which
1108
1110
/// will result in a `zfs_sync` to the entire region dataset.
1109
1111
#[ cfg( feature = "omicron-build" ) ]
1110
- fn flush_extents (
1112
+ async fn flush_extents (
1111
1113
& mut self ,
1112
1114
dirty_extents : & BTreeSet < usize > ,
1113
1115
flush_number : u64 ,
@@ -1137,28 +1139,30 @@ impl Region {
1137
1139
// Send the ioctl!
1138
1140
use std:: os:: fd:: AsRawFd ;
1139
1141
// Open the region's mountpoint
1140
- let file = File :: open ( & self . dir ) ? ;
1142
+ let dir = self . dir . clone ( ) ;
1141
1143
// "file system flush", defined in illumos' sys/filio.h
1142
1144
const FIOFFS_MAGIC : u8 = b'f' ;
1143
1145
const FIOFFS_TYPE_MODE : u8 = 66 ;
1144
1146
nix:: ioctl_none!( zfs_fioffs, FIOFFS_MAGIC , FIOFFS_TYPE_MODE ) ;
1145
1147
1146
1148
// Do the flush in a worker thread if possible, to avoid blocking the
1147
1149
// main tokio thread pool.
1148
- let f = || unsafe { zfs_fioffs ( file. as_raw_fd ( ) ) } ;
1149
- let rc = if matches ! (
1150
- tokio:: runtime:: Handle :: try_current( ) . map( |r| r. runtime_flavor( ) ) ,
1151
- Ok ( tokio:: runtime:: RuntimeFlavor :: MultiThread )
1152
- ) {
1153
- tokio:: task:: block_in_place ( f)
1154
- } else {
1155
- f ( )
1156
- } ;
1157
-
1158
- if let Err ( e) = rc {
1159
- let e: std:: io:: Error = e. into ( ) ;
1160
- return Err ( CrucibleError :: from ( e) ) ;
1161
- }
1150
+ let handle = tokio:: task:: spawn_blocking (
1151
+ move || -> Result < ( ) , CrucibleError > {
1152
+ let file = File :: open ( & dir) ?;
1153
+ let rc = unsafe {
1154
+ zfs_fioffs ( file. as_raw_fd ( ) )
1155
+ } ;
1156
+ if let Err ( e) = rc {
1157
+ let e: std:: io:: Error = e. into ( ) ;
1158
+ Err ( CrucibleError :: from ( e) )
1159
+ } else {
1160
+ Ok ( ( ) )
1161
+ }
1162
+ } ,
1163
+ ) ;
1164
+ // Wait for the async work to finish
1165
+ handle. await . expect ( "could not join spawned task" ) ?;
1162
1166
1163
1167
// After the bits have been committed to durable storage, execute any
1164
1168
// post flush routine that needs to happen
0 commit comments