@@ -2904,22 +2904,11 @@ func (m *baseMeta) cloneEntry(ctx Context, srcIno Ino, parent Ino, name string,
29042904 if eno = m .Access (ctx , srcIno , MODE_MASK_R | MODE_MASK_X , & attr ); eno != 0 {
29052905 return eno
29062906 }
2907- var entries []* Entry
2908- eno = m .en .doReaddir (ctx , srcIno , 0 , & entries , - 1 )
2909- if eno == syscall .ENOENT {
2910- eno = 0 // empty dir
2911- }
2907+ handler , eno := m .NewDirHandler (ctx , srcIno , false , nil )
29122908 if eno != 0 {
29132909 return eno
29142910 }
2915- // try directories first to increase parallel
2916- var dirs int
2917- for i , e := range entries {
2918- if e .Attr .Typ == TypeDirectory {
2919- entries [dirs ], entries [i ] = entries [i ], entries [dirs ]
2920- dirs ++
2921- }
2922- }
2911+ defer handler .Close ()
29232912
29242913 var wg sync.WaitGroup
29252914 var skipped uint32
@@ -2935,6 +2924,47 @@ func (m *baseMeta) cloneEntry(ctx Context, srcIno Ino, parent Ino, name string,
29352924 }
29362925 return eno
29372926 }
2927+
2928+ var dirEntries []* Entry
2929+ var fileEntries []* Entry
2930+ offset := 0
2931+ for {
2932+ ets , err := handler .List (ctx , offset )
2933+ if err != 0 {
2934+ if err == syscall .ENOENT {
2935+ err = 0 // empty dir
2936+ }
2937+ if err != 0 {
2938+ return err
2939+ }
2940+ break
2941+ }
2942+ if len (ets ) == 0 {
2943+ break
2944+ }
2945+ for _ , e := range ets {
2946+ if len (e .Name ) == 1 && e .Name [0 ] == '.' {
2947+ continue
2948+ }
2949+ if len (e .Name ) == 2 && e .Name [0 ] == '.' && e .Name [1 ] == '.' {
2950+ continue
2951+ }
2952+ if e .Attr .Typ == TypeDirectory {
2953+ dirEntries = append (dirEntries , e )
2954+ } else {
2955+ fileEntries = append (fileEntries , e )
2956+ }
2957+ }
2958+ offset += len (ets )
2959+ if ctx .Canceled () {
2960+ return syscall .EINTR
2961+ }
2962+ }
2963+
2964+ entries := make ([]* Entry , 0 , len (dirEntries )+ len (fileEntries ))
2965+ entries = append (entries , dirEntries ... )
2966+ entries = append (entries , fileEntries ... )
2967+
29382968LOOP:
29392969 for i , entry := range entries {
29402970 select {
0 commit comments