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:
Fabricio Voznika
2019-12-23 17:32:46 -08:00
committed by gVisor bot
parent f45df7505b
commit 574e988f2b
2 changed files with 11 additions and 3 deletions
+1 -1
View File
@@ -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
}
+10 -2
View File
@@ -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