Fix vfs.disconnectLocked() to get invariant checks passing.

There were two issues with disconnectLocked():
1. One of the invariant checks was wrong. It intended to check if the
   mount was already disconnected. But it was doing the opposite.
2. mountTable.Remove() had an undocumented precondition that the mount
   being removed should have a valid mount.key. This precondition was
   being violated in disconnectLocked().

PiperOrigin-RevId: 504375499
This commit is contained in:
Ayush Ranjan
2023-01-24 14:33:53 -08:00
committed by gVisor bot
parent cb5ecf817b
commit 0a580e0fbf
2 changed files with 6 additions and 5 deletions
+2 -2
View File
@@ -659,7 +659,7 @@ func (vfs *VirtualFilesystem) connectLocked(mnt *Mount, vd VirtualDentry, mntns
func (vfs *VirtualFilesystem) disconnectLocked(mnt *Mount) VirtualDentry {
vd := mnt.getKey()
if checkInvariants {
if vd.mount != nil {
if vd.mount == nil {
panic("VFS.disconnectLocked called on disconnected mount")
}
if mnt.ns.mountpoints[vd.dentry] == 0 {
@@ -669,7 +669,6 @@ func (vfs *VirtualFilesystem) disconnectLocked(mnt *Mount) VirtualDentry {
panic("VFS.disconnectLocked called on namespace with zero mounts.")
}
}
mnt.loadKey(VirtualDentry{})
delete(vd.mount.children, mnt)
vd.dentry.mounts.Add(math.MaxUint32) // -1
mnt.ns.mountpoints[vd.dentry]--
@@ -678,6 +677,7 @@ func (vfs *VirtualFilesystem) disconnectLocked(mnt *Mount) VirtualDentry {
delete(mnt.ns.mountpoints, vd.dentry)
}
vfs.mounts.removeSeqed(mnt)
mnt.loadKey(VirtualDentry{}) // Clear mnt.key.
vfsmpmounts := vfs.mountpoints[vd.dentry]
delete(vfsmpmounts, mnt)
if len(vfsmpmounts) == 0 {
+4 -3
View File
@@ -329,7 +329,9 @@ func mtInsertLocked(slots unsafe.Pointer, cap uintptr, value unsafe.Pointer, has
// Remove removes the given mount from mt.
//
// Preconditions: mt must contain mount.
// Preconditions:
// - mt must contain mount.
// - mount.key should be valid.
func (mt *mountTable) Remove(mount *Mount) {
mt.seq.BeginWrite()
mt.removeSeqed(mount)
@@ -338,9 +340,8 @@ func (mt *mountTable) Remove(mount *Mount) {
// removeSeqed removes the given mount from mt.
//
// Preconditions:
// Preconditions same as Remove() plus:
// - mt.seq must be in a writer critical section.
// - mt must contain mount.
func (mt *mountTable) removeSeqed(mount *Mount) {
hash := mount.key.hash()
tcap := uintptr(1) << (mt.size.RacyLoad() & mtSizeOrderMask)