mirror of
https://github.com/minio/minio.git
synced 2025-11-09 05:34:56 -05:00
Fix concurrent map read/write (#13052)
Clones were not independent.
Fixes race:
```
WARNING: DATA RACE
Read at 0x00c002040cc0 by goroutine 50:
runtime.mapiterinit()
c:/go/src/runtime/map.go:802 +0x0
github.com/minio/minio/cmd.(*dataUsageCache).flatten()
d:/minio/minio/cmd/data-usage-cache.go:551 +0xad
github.com/minio/minio/cmd.(*dataUsageCache).dui()
d:/minio/minio/cmd/data-usage-cache.go:352 +0x144
github.com/minio/minio/cmd.(*erasureServerPools).NSScanner.func3.1()
d:/minio/minio/cmd/erasure-server-pool.go:542 +0x2a4
github.com/minio/minio/cmd.(*erasureServerPools).NSScanner.func3()
d:/minio/minio/cmd/erasure-server-pool.go:561 +0x24b
Previous write at 0x00c002040cc0 by goroutine 1391:
runtime.mapassign_faststr()
c:/go/src/runtime/map_faststr.go:202 +0x0
github.com/minio/minio/cmd.(*dataUsageEntry).addChild()
d:/minio/minio/cmd/data-usage-cache.go:231 +0x313
github.com/minio/minio/cmd.(*dataUsageCache).replace()
d:/minio/minio/cmd/data-usage-cache.go:383 +0x293
github.com/minio/minio/cmd.erasureObjects.nsScanner.func1()
d:/minio/minio/cmd/erasure.go:428 +0x3a6
```
This commit is contained in:
@@ -238,6 +238,24 @@ func (e *dataUsageEntry) removeChild(hash dataUsageHash) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a clone of the entry.
|
||||||
|
func (e dataUsageEntry) clone() dataUsageEntry {
|
||||||
|
// We operate on a copy from the receiver.
|
||||||
|
if e.Children != nil {
|
||||||
|
ch := make(dataUsageHashMap, len(e.Children))
|
||||||
|
for k, v := range e.Children {
|
||||||
|
ch[k] = v
|
||||||
|
}
|
||||||
|
e.Children = ch
|
||||||
|
}
|
||||||
|
if e.ReplicationStats != nil {
|
||||||
|
// Copy to new struct
|
||||||
|
r := *e.ReplicationStats
|
||||||
|
e.ReplicationStats = &r
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// find a path in the cache.
|
// find a path in the cache.
|
||||||
// Returns nil if not found.
|
// Returns nil if not found.
|
||||||
func (d *dataUsageCache) find(path string) *dataUsageEntry {
|
func (d *dataUsageCache) find(path string) *dataUsageEntry {
|
||||||
@@ -672,7 +690,7 @@ func (d *dataUsageCache) clone() dataUsageCache {
|
|||||||
Cache: make(map[string]dataUsageEntry, len(d.Cache)),
|
Cache: make(map[string]dataUsageEntry, len(d.Cache)),
|
||||||
}
|
}
|
||||||
for k, v := range d.Cache {
|
for k, v := range d.Cache {
|
||||||
clone.Cache[k] = v
|
clone.Cache[k] = v.clone()
|
||||||
}
|
}
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user