@@ -55,7 +55,7 @@ pub struct VirtualFile {
55
55
/// opened, in the VirtualFile::create() function, and strip the flag before
56
56
/// storing it here.
57
57
pub path : Utf8PathBuf ,
58
- open_options : tokio_epoll_uring :: ops :: open_at :: OpenOptions ,
58
+ open_options : OpenOptions ,
59
59
60
60
// These are strings becase we only use them for metrics, and those expect strings.
61
61
// It makes no sense for us to constantly turn the `TimelineId` and `TenantId` into
@@ -237,25 +237,24 @@ macro_rules! with_file {
237
237
impl VirtualFile {
238
238
/// Open a file in read-only mode. Like File::open.
239
239
pub async fn open ( path : & Utf8Path ) -> Result < VirtualFile , std:: io:: Error > {
240
- let mut options = tokio_epoll_uring:: ops:: open_at:: OpenOptions :: new ( ) ;
241
- options. read ( true ) ;
242
- Self :: open_with_options_async ( path, options) . await
240
+ Self :: open_with_options ( path, OpenOptions :: new ( ) . read ( true ) ) . await
243
241
}
244
242
245
243
/// Create a new file for writing. If the file exists, it will be truncated.
246
244
/// Like File::create.
247
245
pub async fn create ( path : & Utf8Path ) -> Result < VirtualFile , std:: io:: Error > {
248
- let mut options = tokio_epoll_uring:: ops:: open_at:: OpenOptions :: new ( ) ;
249
- options. write ( true ) . create ( true ) . truncate ( true ) ;
250
- Self :: open_with_options_async ( path, options) . await
246
+ Self :: open_with_options (
247
+ path,
248
+ OpenOptions :: new ( ) . write ( true ) . create ( true ) . truncate ( true ) ,
249
+ )
250
+ . await
251
251
}
252
252
253
253
/// Open a file with given options.
254
254
///
255
255
/// Note: If any custom flags were set in 'open_options' through OpenOptionsExt,
256
256
/// they will be applied also when the file is subsequently re-opened, not only
257
257
/// on the first time. Make sure that's sane!
258
- #[ cfg( test) ]
259
258
pub async fn open_with_options (
260
259
path : & Utf8Path ,
261
260
open_options : & OpenOptions ,
@@ -318,17 +317,16 @@ impl VirtualFile {
318
317
Err ( e) if e. kind ( ) == std:: io:: ErrorKind :: NotFound => { }
319
318
Err ( e) => return Err ( CrashsafeOverwriteError :: RemovePreviousTempfile ( e) ) ,
320
319
}
321
- let mut file = {
322
- let mut options = tokio_epoll_uring :: ops :: open_at :: OpenOptions :: new ( ) ;
323
- options
320
+ let mut file = Self :: open_with_options (
321
+ tmp_path ,
322
+ OpenOptions :: new ( )
324
323
. write ( true )
325
324
// Use `create_new` so that, if we race with ourselves or something else,
326
325
// we bail out instead of causing damage.
327
- . create_new ( true ) ;
328
- Self :: open_with_options_async ( tmp_path, options)
329
- . await
330
- . map_err ( CrashsafeOverwriteError :: CreateTempfile ) ?
331
- } ;
326
+ . create_new ( true ) ,
327
+ )
328
+ . await
329
+ . map_err ( CrashsafeOverwriteError :: CreateTempfile ) ?;
332
330
file. write_all ( content)
333
331
. await
334
332
. map_err ( CrashsafeOverwriteError :: WriteContents ) ?;
@@ -344,80 +342,17 @@ impl VirtualFile {
344
342
// the current `find_victim_slot` impl might pick the same slot for both
345
343
// VirtualFile., and it eventually does a blocking write lock instead of
346
344
// try_lock.
347
- let final_parent_dirfd = {
348
- let mut options = tokio_epoll_uring:: ops:: open_at:: OpenOptions :: new ( ) ;
349
- options. read ( true ) ;
350
- Self :: open_with_options_async ( final_path_parent, options)
345
+ let final_parent_dirfd =
346
+ Self :: open_with_options ( final_path_parent, OpenOptions :: new ( ) . read ( true ) )
351
347
. await
352
- . map_err ( CrashsafeOverwriteError :: OpenFinalPathParentDir ) ?
353
- } ;
348
+ . map_err ( CrashsafeOverwriteError :: OpenFinalPathParentDir ) ?;
354
349
final_parent_dirfd
355
350
. sync_all ( )
356
351
. await
357
352
. map_err ( CrashsafeOverwriteError :: SyncFinalPathParentDir ) ?;
358
353
Ok ( ( ) )
359
354
}
360
355
361
- /// Open a file with given options.
362
- ///
363
- /// Note: If any custom flags were set in 'open_options' through OpenOptionsExt,
364
- /// they will be applied also when the file is subsequently re-opened, not only
365
- /// on the first time. Make sure that's sane!
366
- pub async fn open_with_options_async (
367
- path : & Utf8Path ,
368
- open_options : tokio_epoll_uring:: ops:: open_at:: OpenOptions ,
369
- ) -> Result < VirtualFile , std:: io:: Error > {
370
- let path_str = path. to_string ( ) ;
371
- let parts = path_str. split ( '/' ) . collect :: < Vec < & str > > ( ) ;
372
- let tenant_id;
373
- let timeline_id;
374
- if parts. len ( ) > 5 && parts[ parts. len ( ) - 5 ] == "tenants" {
375
- tenant_id = parts[ parts. len ( ) - 4 ] . to_string ( ) ;
376
- timeline_id = parts[ parts. len ( ) - 2 ] . to_string ( ) ;
377
- } else {
378
- tenant_id = "*" . to_string ( ) ;
379
- timeline_id = "*" . to_string ( ) ;
380
- }
381
- let ( handle, mut slot_guard) = get_open_files ( ) . find_victim_slot ( ) . await ;
382
-
383
- let file = {
384
- let start = std:: time:: Instant :: now ( ) ;
385
- let system = tokio_epoll_uring:: thread_local_system ( ) . await ;
386
- let file: OwnedFd = system
387
- . open ( path, & open_options)
388
- . await
389
- . map_err ( |e| match e {
390
- tokio_epoll_uring:: Error :: Op ( e) => e,
391
- tokio_epoll_uring:: Error :: System ( system) => {
392
- std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , system)
393
- }
394
- } ) ?;
395
- let file = File :: from ( file) ;
396
- file
397
- } ;
398
-
399
- // Strip all options other than read and write.
400
- //
401
- // It would perhaps be nicer to check just for the read and write flags
402
- // explicitly, but OpenOptions doesn't contain any functions to read flags,
403
- // only to set them.
404
- let mut reopen_options = open_options;
405
- reopen_options. create ( false ) ;
406
- reopen_options. create_new ( false ) ;
407
- reopen_options. truncate ( false ) ;
408
-
409
- let vfile = VirtualFile {
410
- handle : RwLock :: new ( handle) ,
411
- pos : 0 ,
412
- path : path. to_path_buf ( ) ,
413
- open_options : reopen_options,
414
- tenant_id,
415
- timeline_id,
416
- } ;
417
-
418
- Ok ( vfile)
419
- }
420
-
421
356
/// Call File::sync_all() on the underlying File.
422
357
pub async fn sync_all ( & self ) -> Result < ( ) , Error > {
423
358
with_file ! ( self , StorageIoOperation :: Fsync , |file| file
@@ -480,21 +415,7 @@ impl VirtualFile {
480
415
let ( handle, mut slot_guard) = open_files. find_victim_slot ( ) . await ;
481
416
482
417
// Open the physical file
483
- let file = {
484
- let system = tokio_epoll_uring:: thread_local_system ( ) . await ;
485
- let file: OwnedFd =
486
- system
487
- . open ( & self . path , & self . open_options )
488
- . await
489
- . map_err ( |e| match e {
490
- tokio_epoll_uring:: Error :: Op ( e) => e,
491
- tokio_epoll_uring:: Error :: System ( system) => {
492
- std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , system)
493
- }
494
- } ) ?;
495
- let file = File :: from ( file) ;
496
- file
497
- } ;
418
+ let file = observe_duration ! ( StorageIoOperation :: Open , self . open_options. open( & self . path) ) ?;
498
419
499
420
// Store the File in the slot and update the handle in the VirtualFile
500
421
// to point to it.
0 commit comments