@@ -220,11 +220,18 @@ mod compat {
220
220
{
221
221
#[ cfg_attr( feature = "tracing" , tracing:: instrument( level = "trace" , skip( self ) ) ) ]
222
222
fn run ( & self , ( from, to) : ( Cow < Path > , Cow < Path > ) ) -> Result < ( ) , Error > {
223
+ let root_to_inode = {
224
+ let to_metadata = statx ( CWD , & * to, AtFlags :: SYMLINK_NOFOLLOW , StatxFlags :: INO )
225
+ . map_io_err ( || format ! ( "Failed to stat directory: {to:?}" ) ) ?;
226
+ to_metadata. stx_ino
227
+ } ;
228
+
223
229
let ( tasks, _) = & * self . scheduling ;
224
230
tasks
225
231
. send ( TreeNode {
226
232
from : path_buf_to_cstring ( from. into_owned ( ) ) ?,
227
233
to : path_buf_to_cstring ( to. into_owned ( ) ) ?,
234
+ root_to_inode,
228
235
messages : tasks. clone ( ) ,
229
236
} )
230
237
. map_err ( |_| Error :: Internal )
@@ -265,26 +272,9 @@ mod compat {
265
272
let mut threads = Vec :: with_capacity ( available_parallelism) ;
266
273
267
274
{
268
- let mut root_to_inode = None ;
269
275
let mut buf = [ MaybeUninit :: < u8 > :: uninit ( ) ; 8192 ] ;
270
276
let symlink_buf_cache = Cell :: new ( Vec :: new ( ) ) ;
271
277
for node in & tasks {
272
- let root_to_inode = if let Some ( root_to_inode) = root_to_inode {
273
- root_to_inode
274
- } else {
275
- let to_dir = openat (
276
- CWD ,
277
- & node. to ,
278
- OFlags :: RDONLY | OFlags :: DIRECTORY | OFlags :: PATH ,
279
- Mode :: empty ( ) ,
280
- )
281
- . map_io_err ( || format ! ( "Failed to open directory: {:?}" , node. to) ) ?;
282
- let to_metadata = statx ( to_dir, c"" , AtFlags :: EMPTY_PATH , StatxFlags :: INO )
283
- . map_io_err ( || format ! ( "Failed to stat directory: {:?}" , node. to) ) ?;
284
- root_to_inode = Some ( to_metadata. stx_ino ) ;
285
- to_metadata. stx_ino
286
- } ;
287
-
288
278
let mut maybe_spawn = || {
289
279
if available_parallelism > 0 && !tasks. is_empty ( ) {
290
280
#[ cfg( feature = "tracing" ) ]
@@ -297,21 +287,14 @@ mod compat {
297
287
available_parallelism -= 1 ;
298
288
threads. push ( scope. spawn ( {
299
289
let tasks = tasks. clone ( ) ;
300
- move || {
301
- worker_thread :: < HARD_LINK > (
302
- tasks,
303
- root_to_inode,
304
- follow_symlinks,
305
- )
306
- }
290
+ move || worker_thread :: < HARD_LINK > ( tasks, follow_symlinks)
307
291
} ) ) ;
308
292
}
309
293
} ;
310
294
maybe_spawn ( ) ;
311
295
312
296
copy_dir :: < HARD_LINK > (
313
297
node,
314
- root_to_inode,
315
298
follow_symlinks,
316
299
& mut buf,
317
300
& symlink_buf_cache,
@@ -330,22 +313,14 @@ mod compat {
330
313
#[ cfg_attr( feature = "tracing" , tracing:: instrument( level = "trace" , skip( tasks) ) ) ]
331
314
fn worker_thread < const HARD_LINK : bool > (
332
315
tasks : Receiver < TreeNode > ,
333
- root_to_inode : u64 ,
334
316
follow_symlinks : bool ,
335
317
) -> Result < ( ) , Error > {
336
318
unshare_files ( ) ?;
337
319
338
320
let mut buf = [ MaybeUninit :: < u8 > :: uninit ( ) ; 8192 ] ;
339
321
let symlink_buf_cache = Cell :: new ( Vec :: new ( ) ) ;
340
322
for node in tasks {
341
- copy_dir :: < HARD_LINK > (
342
- node,
343
- root_to_inode,
344
- follow_symlinks,
345
- & mut buf,
346
- & symlink_buf_cache,
347
- || { } ,
348
- ) ?;
323
+ copy_dir :: < HARD_LINK > ( node, follow_symlinks, & mut buf, & symlink_buf_cache, || { } ) ?;
349
324
}
350
325
Ok ( ( ) )
351
326
}
@@ -378,8 +353,12 @@ mod compat {
378
353
tracing:: instrument( level = "info" , skip( messages, buf, symlink_buf_cache, maybe_spawn) )
379
354
) ]
380
355
fn copy_dir < const HARD_LINK : bool > (
381
- TreeNode { from, to, messages } : TreeNode ,
382
- root_to_inode : u64 ,
356
+ TreeNode {
357
+ from,
358
+ to,
359
+ root_to_inode,
360
+ messages,
361
+ } : TreeNode ,
383
362
follow_symlinks : bool ,
384
363
buf : & mut [ MaybeUninit < u8 > ] ,
385
364
symlink_buf_cache : & Cell < Vec < u8 > > ,
@@ -437,6 +416,7 @@ mod compat {
437
416
. send ( TreeNode {
438
417
from,
439
418
to,
419
+ root_to_inode,
440
420
messages : messages. clone ( ) ,
441
421
} )
442
422
. map_err ( |_| Error :: Internal ) ?;
@@ -678,6 +658,7 @@ mod compat {
678
658
struct TreeNode {
679
659
from : CString ,
680
660
to : CString ,
661
+ root_to_inode : u64 ,
681
662
messages : Sender < TreeNode > ,
682
663
}
683
664
@@ -720,8 +701,20 @@ mod compat {
720
701
impl DirectoryOp < ( Cow < ' _ , Path > , Cow < ' _ , Path > ) > for Impl {
721
702
#[ cfg_attr( feature = "tracing" , tracing:: instrument( level = "trace" , skip( self ) ) ) ]
722
703
fn run ( & self , ( from, to) : ( Cow < Path > , Cow < Path > ) ) -> Result < ( ) , Error > {
723
- copy_dir ( & from, to, self . follow_symlinks , self . hard_link , None )
724
- . map_io_err ( || format ! ( "Failed to copy directory: {from:?}" ) )
704
+ copy_dir (
705
+ & from,
706
+ to,
707
+ self . follow_symlinks ,
708
+ self . hard_link ,
709
+ #[ cfg( unix) ]
710
+ {
711
+ use std:: os:: unix:: fs:: MetadataExt ;
712
+ fs:: metadata ( & * to)
713
+ . map_io_err ( || format ! ( "Failed to get inode: {to:?}" ) ) ?
714
+ . ino ( )
715
+ } ,
716
+ )
717
+ . map_io_err ( || format ! ( "Failed to copy directory: {from:?}" ) )
725
718
}
726
719
727
720
#[ cfg_attr( feature = "tracing" , tracing:: instrument( level = "trace" , skip( self ) ) ) ]
@@ -736,17 +729,13 @@ mod compat {
736
729
to : Q ,
737
730
follow_symlinks : bool ,
738
731
hard_link : bool ,
739
- root_to_inode : Option < u64 > ,
732
+ # [ cfg ( unix ) ] root_to_inode : u64 ,
740
733
) -> Result < ( ) , io:: Error > {
741
734
let to = to. as_ref ( ) ;
742
735
match fs:: create_dir ( to) {
743
736
Err ( e) if e. kind ( ) == io:: ErrorKind :: AlreadyExists => { }
744
737
r => r?,
745
738
}
746
- #[ cfg( unix) ]
747
- let root_to_inode = Some ( maybe_compute_root_to_inode ( to, root_to_inode) ?) ;
748
- #[ cfg( not( unix) ) ]
749
- let _ = root_to_inode;
750
739
751
740
from. as_ref ( )
752
741
. read_dir ( ) ?
@@ -776,6 +765,7 @@ mod compat {
776
765
to,
777
766
follow_symlinks,
778
767
hard_link,
768
+ #[ cfg( unix) ]
779
769
root_to_inode,
780
770
) ?;
781
771
} else if file_type. is_symlink ( ) {
@@ -801,18 +791,4 @@ mod compat {
801
791
Ok ( ( ) )
802
792
} )
803
793
}
804
-
805
- #[ cfg( unix) ]
806
- #[ cfg_attr( feature = "tracing" , tracing:: instrument( level = "trace" ) ) ]
807
- fn maybe_compute_root_to_inode < P : AsRef < Path > + Debug > (
808
- to : P ,
809
- root_to_inode : Option < u64 > ,
810
- ) -> Result < u64 , io:: Error > {
811
- Ok ( if let Some ( ino) = root_to_inode {
812
- ino
813
- } else {
814
- use std:: os:: unix:: fs:: MetadataExt ;
815
- fs:: metadata ( to) ?. ino ( )
816
- } )
817
- }
818
794
}
0 commit comments