From 128948d6ae94009c6ad13a0bd96e03e45a560477 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Mon, 25 Nov 2019 15:20:25 -0800 Subject: 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 --- pkg/sentry/vfs/resolving_path.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'pkg/sentry/vfs/resolving_path.go') diff --git a/pkg/sentry/vfs/resolving_path.go b/pkg/sentry/vfs/resolving_path.go index 8d05c8583..61bce6426 100644 --- a/pkg/sentry/vfs/resolving_path.go +++ b/pkg/sentry/vfs/resolving_path.go @@ -269,11 +269,11 @@ func (rp *ResolvingPath) ResolveParent(d *Dentry) (*Dentry, error) { parent = d } else if d == rp.mount.root { // At mount root ... - mnt, mntpt := rp.vfs.getMountpointAt(rp.mount, rp.root) - if mnt != nil { + vd := rp.vfs.getMountpointAt(rp.mount, rp.root) + if vd.Ok() { // ... of non-root mount. - rp.nextMount = mnt - rp.nextStart = mntpt + rp.nextMount = vd.mount + rp.nextStart = vd.dentry return nil, resolveMountRootError{} } // ... of root mount. -- cgit v1.2.3