summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs/vfs.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2019-11-25 15:20:25 -0800
committergVisor bot <gvisor-bot@google.com>2019-11-25 15:21:49 -0800
commit128948d6ae94009c6ad13a0bd96e03e45a560477 (patch)
tree73e3fd683075f8a1bf1a1e4d398aca22a2f1e4c4 /pkg/sentry/vfs/vfs.go
parentd92dc065fd98b5875a0945ccc062f91fc4d39190 (diff)
Implement basic umounting for vfs2.
This is required to test filesystems with a non-trivial implementation of FilesystemImpl.Release(). Propagation isn't handled yet, and umount isn't yet plumbed out to VirtualFilesystem.UmountAt(), but otherwise the implementation of umount is believed to be correct. - Move entering mountTable.seq writer critical sections to callers of mountTable.{insert,remove}Seqed. This is required since umount(2) must ensure that no new references are taken on the candidate mount after checking that it isn't busy, which is only possible by entering a vfs.mountTable.seq writer critical section before the check and remaining in it until after VFS.umountRecursiveLocked() is complete. (Linux does the same thing: fs/namespace.c:do_umount() => lock_mount_hash(), fs/pnode.c:propagate_mount_busy(), umount_tree(), unlock_mount_hash().) - It's not possible for dentry deletion to umount while only holding VFS.mountMu for reading, but it's also very unappealing to hold VFS.mountMu exclusively around e.g. gofer unlink RPCs. Introduce dentry.mu to avoid these problems. This means that VFS.mountMu is never acquired for reading, so change it to a sync.Mutex. PiperOrigin-RevId: 282444343
Diffstat (limited to 'pkg/sentry/vfs/vfs.go')
-rw-r--r--pkg/sentry/vfs/vfs.go11
1 files changed, 8 insertions, 3 deletions
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go
index 4a8a69540..88e865d86 100644
--- a/pkg/sentry/vfs/vfs.go
+++ b/pkg/sentry/vfs/vfs.go
@@ -16,9 +16,14 @@
//
// Lock order:
//
-// Filesystem implementation locks
+// FilesystemImpl/FileDescriptionImpl locks
// VirtualFilesystem.mountMu
+// Dentry.mu
+// Locks acquired by FilesystemImpls between Prepare{Delete,Rename}Dentry and Commit{Delete,Rename*}Dentry
// VirtualFilesystem.fsTypesMu
+//
+// Locking Dentry.mu in multiple Dentries requires holding
+// VirtualFilesystem.mountMu.
package vfs
import (
@@ -33,7 +38,7 @@ type VirtualFilesystem struct {
// mountMu serializes mount mutations.
//
// mountMu is analogous to Linux's namespace_sem.
- mountMu sync.RWMutex
+ mountMu sync.Mutex
// mounts maps (mount parent, mount point) pairs to mounts. (Since mounts
// are uniquely namespaced, including mount parent in the key correctly
@@ -52,7 +57,7 @@ type VirtualFilesystem struct {
// mountpoints maps mount points to mounts at those points in all
// namespaces. mountpoints is protected by mountMu.
//
- // mountpoints is used to find mounts that must be unmounted due to
+ // mountpoints is used to find mounts that must be umounted due to
// removal of a mount point Dentry from another mount namespace. ("A file
// or directory that is a mount point in one namespace that is not a mount
// point in another namespace, may be renamed, unlinked, or removed