@@ -3167,9 +3167,8 @@ func (m *baseMeta) Clone(ctx Context, srcParentIno, srcIno, parent Ino, name str
31673167 if concurrency < 1 {
31683168 concurrency = 1
31693169 }
3170- concurrent := make (chan struct {}, concurrency )
31713170 if attr .Typ == TypeDirectory {
3172- eno = m .cloneEntry (ctx , srcIno , parent , name , & dstIno , cmode , cumask , count , true , concurrent )
3171+ eno = m .cloneEntry (ctx , srcIno , parent , name , & dstIno , cmode , cumask , count , true , int ( concurrency ) )
31733172 if eno == 0 {
31743173 eno = m .en .doAttachDirNode (ctx , parent , dstIno , name )
31753174 }
@@ -3179,7 +3178,7 @@ func (m *baseMeta) Clone(ctx Context, srcParentIno, srcIno, parent Ino, name str
31793178 }
31803179 }
31813180 } else {
3182- eno = m .cloneEntry (ctx , srcIno , parent , name , nil , cmode , cumask , count , true , concurrent )
3181+ eno = m .cloneEntry (ctx , srcIno , parent , name , nil , cmode , cumask , count , true , int ( concurrency ) )
31833182 }
31843183 if eno == 0 {
31853184 m .updateDirStat (ctx , parent , int64 (attr .Length ), align4K (attr .Length ), 1 )
@@ -3188,7 +3187,7 @@ func (m *baseMeta) Clone(ctx Context, srcParentIno, srcIno, parent Ino, name str
31883187 return eno
31893188}
31903189
3191- func (m * baseMeta ) cloneEntry (ctx Context , srcIno Ino , parent Ino , name string , dstIno * Ino , cmode uint8 , cumask uint16 , count * uint64 , top bool , concurrent chan struct {} ) syscall.Errno {
3190+ func (m * baseMeta ) cloneEntry (ctx Context , srcIno Ino , parent Ino , name string , dstIno * Ino , cmode uint8 , cumask uint16 , count * uint64 , top bool , concurrency int ) syscall.Errno {
31923191 ino , err := m .nextInode ()
31933192 if err != nil {
31943193 return errno (err )
@@ -3221,10 +3220,11 @@ func (m *baseMeta) cloneEntry(ctx Context, srcIno Ino, parent Ino, name string,
32213220 defer handler .Close ()
32223221
32233222 var g errgroup.Group
3223+ g .SetLimit (concurrency )
32243224 var skipped uint32
32253225
32263226 cloneChild := func (e * Entry ) syscall.Errno {
3227- eno := m .cloneEntry (ctx , e .Inode , ino , string (e .Name ), nil , cmode , cumask , count , false , concurrent )
3227+ eno := m .cloneEntry (ctx , e .Inode , ino , string (e .Name ), nil , cmode , cumask , count , false , concurrency )
32283228 if eno == syscall .ENOENT {
32293229 logger .Warnf ("ignore deleted %s in dir %d" , string (e .Name ), srcIno )
32303230 if e .Attr .Typ == TypeDirectory {
@@ -3253,17 +3253,13 @@ func (m *baseMeta) cloneEntry(ctx Context, srcIno Ino, parent Ino, name string,
32533253 }
32543254
32553255 if e .Attr .Typ == TypeDirectory {
3256- select {
3257- case concurrent <- struct {}{}:
3258- entry := e
3259- g .Go (func () error {
3260- defer func () { <- concurrent }()
3261- if childEno := cloneChild (entry ); childEno != 0 {
3262- return childEno
3263- }
3264- return nil
3265- })
3266- default :
3256+ entry := e
3257+ if ! g .TryGo (func () error {
3258+ if childEno := cloneChild (entry ); childEno != 0 {
3259+ return childEno
3260+ }
3261+ return nil
3262+ }) {
32673263 // Synchronous fallback when concurrency limit reached
32683264 if childEno := cloneChild (e ); childEno != 0 {
32693265 eno = childEno
@@ -3289,17 +3285,13 @@ func (m *baseMeta) cloneEntry(ctx Context, srcIno Ino, parent Ino, name string,
32893285 if eno = m .BatchClone (ctx , srcIno , ino , nonDirEntries , cmode , cumask , count ); eno == syscall .ENOTSUP {
32903286 // Fallback: clone each file concurrently
32913287 for _ , e := range nonDirEntries {
3292- select {
3293- case concurrent <- struct {}{}:
3294- entry := e
3295- g .Go (func () error {
3296- defer func () { <- concurrent }()
3297- if childEno := cloneChild (entry ); childEno != 0 {
3298- return childEno
3299- }
3300- return nil
3301- })
3302- default :
3288+ entry := e
3289+ if ! g .TryGo (func () error {
3290+ if childEno := cloneChild (entry ); childEno != 0 {
3291+ return childEno
3292+ }
3293+ return nil
3294+ }) {
33033295 // Synchronous fallback when concurrency limit reached
33043296 if childEno := cloneChild (e ); childEno != 0 {
33053297 eno = childEno
0 commit comments