@@ -41,11 +41,7 @@ use std::{
4141 atomic:: { AtomicU64 , Ordering } ,
4242 } ,
4343} ;
44- use tokio:: {
45- io:: { AsyncRead , AsyncWriteExt } ,
46- runtime,
47- sync:: RwLock ,
48- } ;
44+ use tokio:: { io:: AsyncRead , runtime, sync:: RwLock } ;
4945use tracing:: { error, info, info_span, instrument, trace, warn} ;
5046use tracing_futures:: Instrument as _;
5147use walkdir:: WalkDir ;
@@ -428,21 +424,35 @@ impl AsyncStorage {
428424 // remote/folder/and/x.zip.index
429425 let remote_index_path = format ! ( "{archive_path}.{ARCHIVE_INDEX_FILE_EXTENSION}" ) ;
430426
431- tokio:: fs:: create_dir_all (
432- local_index_path
433- . parent ( )
434- . ok_or_else ( || anyhow ! ( "index path without parent" ) ) ?,
435- )
427+ let parent = local_index_path
428+ . parent ( )
429+ . ok_or_else ( || anyhow ! ( "index path without parent" ) ) ?
430+ . to_path_buf ( ) ;
431+ tokio:: fs:: create_dir_all ( & parent) . await ?;
432+
433+ let mut temp_path = spawn_blocking ( {
434+ // this creates the tempfile and directly drops it again,
435+ // just to return a valid temp-path.
436+ // This could be optimized.
437+ let folder = self . config . local_archive_cache_path . clone ( ) ;
438+ move || Ok ( tempfile:: NamedTempFile :: new_in ( & folder) ?. into_temp_path ( ) )
439+ } )
436440 . await ?;
437441
438- {
439- let mut file = tokio:: fs:: File :: create ( & local_index_path) . await ?;
440- let mut stream = self . get_stream ( & remote_index_path) . await ?. content ;
442+ let mut file = tokio:: fs:: File :: create ( & temp_path) . await ?;
443+ let mut stream = self . get_stream ( & remote_index_path) . await ?. content ;
444+ tokio:: io:: copy ( & mut stream, & mut file) . await ?;
445+ file. sync_all ( ) . await ?;
441446
442- tokio:: io:: copy ( & mut stream, & mut file) . await ?;
447+ temp_path. disable_cleanup ( true ) ;
448+ tokio:: fs:: rename ( & temp_path, & local_index_path) . await ?;
443449
444- file. flush ( ) . await ?;
445- }
450+ // fsync parent dir to make rename durable (blocking)
451+ spawn_blocking ( move || {
452+ let dir = std:: fs:: File :: open ( parent) ?;
453+ dir. sync_all ( ) . map_err ( Into :: into)
454+ } )
455+ . await ?;
446456 }
447457
448458 _read_guard = _write_guard. downgrade ( ) ;
0 commit comments