@@ -39,6 +39,7 @@ use std::{
3939use  anyhow:: { anyhow,  bail,  Context ,  Result } ; 
4040use  auto_hash_map:: { AutoMap ,  AutoSet } ; 
4141use  bitflags:: bitflags; 
42+ use  dashmap:: DashSet ; 
4243use  dunce:: simplified; 
4344use  glob:: Glob ; 
4445use  indexmap:: IndexSet ; 
@@ -227,6 +228,10 @@ struct DiskFileSystemInner {
227228#[ turbo_tasks( debug_ignore,  trace_ignore) ]  
228229    #[ serde( skip) ]  
229230    invalidation_lock :  RwLock < ( ) > , 
231+     /// A cache of already created directories to avoid creating them multiple times. 
232+ #[ turbo_tasks( debug_ignore,  trace_ignore) ]  
233+     #[ serde( skip) ]  
234+     created_directories :  DashSet < PathBuf > , 
230235    /// Semaphore to limit the maximum number of concurrent file operations. 
231236#[ turbo_tasks( debug_ignore,  trace_ignore) ]  
232237    #[ serde( skip,  default  = "create_semaphore" ) ]  
@@ -394,6 +399,27 @@ impl DiskFileSystemInner {
394399
395400        Ok ( ( ) ) 
396401    } 
402+ 
403+     async  fn  create_directory ( self :  & Arc < Self > ,  directory :  & Path )  -> Result < ( ) >  { 
404+         if  !self . created_directories . contains ( directory)  { 
405+             let  func = { 
406+                 let  inner = self . clone ( ) ; 
407+                 move  |p :  & Path | -> io:: Result < ( ) >  { 
408+                     std:: fs:: create_dir_all ( p) ?; 
409+                     inner. created_directories . insert ( p. to_path_buf ( ) ) ; 
410+                     Ok ( ( ) ) 
411+                 } 
412+             } ; 
413+             retry_blocking ( directory,  func) 
414+                 . concurrency_limited ( & self . semaphore ) 
415+                 . instrument ( tracing:: info_span!( 
416+                     "create directory" , 
417+                     path = display( directory. display( ) ) 
418+                 ) ) 
419+                 . await ?; 
420+         } 
421+         Ok ( ( ) ) 
422+     } 
397423} 
398424
399425#[ turbo_tasks:: value( cell = "new" ,  eq = "manual" ) ]  
@@ -500,6 +526,7 @@ impl DiskFileSystem {
500526                invalidation_lock :  Default :: default ( ) , 
501527                invalidator_map :  InvalidatorMap :: new ( ) , 
502528                dir_invalidator_map :  InvalidatorMap :: new ( ) , 
529+                 created_directories :  Default :: default ( ) , 
503530                semaphore :  create_semaphore ( ) , 
504531                watcher :  DiskWatcher :: new ( 
505532                    ignored_subpaths. into_iter ( ) . map ( PathBuf :: from) . collect ( ) , 
@@ -743,20 +770,13 @@ impl FileSystem for DiskFileSystem {
743770                    let  create_directory = compare == FileComparison :: Create ; 
744771                    if  create_directory { 
745772                        if  let  Some ( parent)  = full_path. parent ( )  { 
746-                             retry_blocking ( parent,  |p| std:: fs:: create_dir_all ( p) ) 
747-                                 . concurrency_limited ( & inner. semaphore ) 
748-                                 . instrument ( tracing:: info_span!( 
749-                                     "create directory" , 
750-                                     path = display( parent. display( ) ) 
751-                                 ) ) 
752-                                 . await 
753-                                 . with_context ( || { 
754-                                     format ! ( 
755-                                         "failed to create directory {} for write to {}" , 
756-                                         parent. display( ) , 
757-                                         full_path. display( ) 
758-                                     ) 
759-                                 } ) ?; 
773+                             inner. create_directory ( parent) . await . with_context ( || { 
774+                                 format ! ( 
775+                                     "failed to create directory {} for write to {}" , 
776+                                     parent. display( ) , 
777+                                     full_path. display( ) 
778+                                 ) 
779+                             } ) ?; 
760780                        } 
761781                    } 
762782                    let  full_path_to_write = full_path. clone ( ) ; 
@@ -879,20 +899,13 @@ impl FileSystem for DiskFileSystem {
879899                    let  create_directory = old_content. is_none ( ) ; 
880900                    if  create_directory { 
881901                        if  let  Some ( parent)  = full_path. parent ( )  { 
882-                             retry_blocking ( parent,  |path| std:: fs:: create_dir_all ( path) ) 
883-                                 . concurrency_limited ( & inner. semaphore ) 
884-                                 . instrument ( tracing:: info_span!( 
885-                                     "create directory" , 
886-                                     path = display( parent. display( ) ) 
887-                                 ) ) 
888-                                 . await 
889-                                 . with_context ( || { 
890-                                     format ! ( 
891-                                         "failed to create directory {} for write to {}" , 
892-                                         parent. display( ) , 
893-                                         full_path. display( ) 
894-                                     ) 
895-                                 } ) ?; 
902+                             inner. create_directory ( parent) . await . with_context ( || { 
903+                                 format ! ( 
904+                                     "failed to create directory {} for write link to {}" , 
905+                                     parent. display( ) , 
906+                                     full_path. display( ) 
907+                                 ) 
908+                             } ) ?; 
896909                        } 
897910                    } 
898911
0 commit comments