mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix deadlock in kernfs.Filesystem.revalidateChildLocked
It was calling Dentry.InsertChild with the dentry's mutex already locked. Updates #1035 PiperOrigin-RevId: 286962742
This commit is contained in:
committed by
gVisor bot
parent
f45df7505b
commit
574e988f2b
@@ -122,7 +122,7 @@ func (fs *Filesystem) revalidateChildLocked(ctx context.Context, vfsObj *vfs.Vir
|
||||
return nil, err
|
||||
}
|
||||
// Reference on childVFSD dropped by a corresponding Valid.
|
||||
parent.InsertChild(name, childVFSD)
|
||||
parent.insertChildLocked(name, childVFSD)
|
||||
}
|
||||
return childVFSD.Impl().(*Dentry), nil
|
||||
}
|
||||
|
||||
@@ -239,14 +239,22 @@ func (d *Dentry) destroy() {
|
||||
//
|
||||
// Precondition: d must represent a directory inode.
|
||||
func (d *Dentry) InsertChild(name string, child *vfs.Dentry) {
|
||||
d.dirMu.Lock()
|
||||
d.insertChildLocked(name, child)
|
||||
d.dirMu.Unlock()
|
||||
}
|
||||
|
||||
// insertChildLocked is equivalent to InsertChild, with additional
|
||||
// preconditions.
|
||||
//
|
||||
// Precondition: d.dirMu must be locked.
|
||||
func (d *Dentry) insertChildLocked(name string, child *vfs.Dentry) {
|
||||
if !d.isDir() {
|
||||
panic(fmt.Sprintf("InsertChild called on non-directory Dentry: %+v.", d))
|
||||
}
|
||||
vfsDentry := d.VFSDentry()
|
||||
vfsDentry.IncRef() // DecRef in child's Dentry.destroy.
|
||||
d.dirMu.Lock()
|
||||
vfsDentry.InsertChild(child, name)
|
||||
d.dirMu.Unlock()
|
||||
}
|
||||
|
||||
// The Inode interface maps filesystem-level operations that operate on paths to
|
||||
|
||||
Reference in New Issue
Block a user