mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Hold a reference while calling p9.pathNode.removeWithName() callback.
This prevents a racing clunk() call from destroying the file while the callback is running, leading to potential data races. PiperOrigin-RevId: 426180506
This commit is contained in:
committed by
gVisor bot
parent
95d883a92e
commit
34f41dfcbf
+10
-1
@@ -216,8 +216,17 @@ func (p *pathNode) removeWithName(name string, fn func(ref *fidRef)) *pathNode {
|
||||
for ref := range m {
|
||||
delete(m, ref)
|
||||
delete(p.childRefNames, ref)
|
||||
if fn != nil {
|
||||
if fn == nil {
|
||||
// No callback provided.
|
||||
continue
|
||||
}
|
||||
// Attempt to hold a reference while calling fn() to
|
||||
// prevent concurrent destruction of the child, which
|
||||
// can lead to data races. If the child has already
|
||||
// been destroyed, then we can skip the callback.
|
||||
if ref.TryIncRef() {
|
||||
fn(ref)
|
||||
ref.DecRef()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,20 @@ func (f *fidRef) DecRef() {
|
||||
}
|
||||
}
|
||||
|
||||
// TryIncRef returns true if a new reference is taken on the fid, and false if
|
||||
// the fid has been destroyed.
|
||||
func (f *fidRef) TryIncRef() bool {
|
||||
for {
|
||||
r := atomic.LoadInt64(&f.refs)
|
||||
if r <= 0 {
|
||||
return false
|
||||
}
|
||||
if atomic.CompareAndSwapInt64(&f.refs, r, r+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// isDeleted returns true if this fidRef has been deleted.
|
||||
//
|
||||
// Precondition: this must be called via safelyRead, safelyWrite or
|
||||
|
||||
Reference in New Issue
Block a user