@@ -12,7 +12,7 @@ use std::error::Error;
1212use  std:: fmt:: Display ; 
1313#[ cfg( not( windows) ) ]  
1414use  std:: fs:: Metadata ; 
15- use  std:: fs:: { self ,  File } ; 
15+ use  std:: fs:: { self ,  DirEntry ,   File } ; 
1616use  std:: io:: { BufRead ,  BufReader } ; 
1717#[ cfg( not( windows) ) ]  
1818use  std:: os:: unix:: fs:: MetadataExt ; 
@@ -138,7 +138,11 @@ struct Stat {
138138} 
139139
140140impl  Stat  { 
141-     fn  new ( path :  & Path ,  options :  & TraversalOptions )  -> std:: io:: Result < Self >  { 
141+     fn  new ( 
142+         path :  & Path , 
143+         dir_entry :  Option < & DirEntry > , 
144+         options :  & TraversalOptions , 
145+     )  -> std:: io:: Result < Self >  { 
142146        // Determine whether to dereference (follow) the symbolic link 
143147        let  should_dereference = match  & options. dereference  { 
144148            Deref :: All  => true , 
@@ -149,8 +153,11 @@ impl Stat {
149153        let  metadata = if  should_dereference { 
150154            // Get metadata, following symbolic links if necessary 
151155            fs:: metadata ( path) 
156+         }  else  if  let  Some ( dir_entry)  = dir_entry { 
157+             // Get metadata directly from the DirEntry, which is faster on Windows 
158+             dir_entry. metadata ( ) 
152159        }  else  { 
153-             // Get metadata without following symbolic links 
160+             // Get metadata from the filesystem  without following symbolic links 
154161            fs:: symlink_metadata ( path) 
155162        } ?; 
156163
@@ -319,7 +326,7 @@ fn du(
319326        ' file_loop:  for  f in  read { 
320327            match  f { 
321328                Ok ( entry)  => { 
322-                     match  Stat :: new ( & entry. path ( ) ,  options)  { 
329+                     match  Stat :: new ( & entry. path ( ) ,  Some ( & entry ) ,   options)  { 
323330                        Ok ( this_stat)  => { 
324331                            // We have an exclude list 
325332                            for  pattern in  & options. excludes  { 
@@ -765,7 +772,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
765772        } 
766773
767774        // Check existence of path provided in argument 
768-         if  let  Ok ( stat)  = Stat :: new ( & path,  & traversal_options)  { 
775+         if  let  Ok ( stat)  = Stat :: new ( & path,  None ,   & traversal_options)  { 
769776            // Kick off the computation of disk usage from the initial path 
770777            let  mut  seen_inodes:  HashSet < FileInfo >  = HashSet :: new ( ) ; 
771778            if  let  Some ( inode)  = stat. inode  { 
0 commit comments