summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs/pathname.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/vfs/pathname.go')
-rw-r--r--pkg/sentry/vfs/pathname.go49
1 files changed, 46 insertions, 3 deletions
diff --git a/pkg/sentry/vfs/pathname.go b/pkg/sentry/vfs/pathname.go
index b318c681a..cd78d66bc 100644
--- a/pkg/sentry/vfs/pathname.go
+++ b/pkg/sentry/vfs/pathname.go
@@ -58,7 +58,7 @@ loop:
switch err.(type) {
case nil:
if vd.mount == vfsroot.mount && vd.mount.root == vfsroot.dentry {
- // GenericPrependPath() will have returned
+ // genericfstree.PrependPath() will have returned
// PrependPathAtVFSRootError in this case since it checks
// against vfsroot before mnt.root, but other implementations
// of FilesystemImpl.PrependPath() may return nil instead.
@@ -84,16 +84,59 @@ loop:
}
}
b.PrependByte('/')
- if origD.IsDisowned() {
+ if origD.IsDead() {
b.AppendString(" (deleted)")
}
return b.String(), nil
}
+// PathnameReachable returns an absolute pathname to vd, consistent with
+// Linux's __d_path() (as used by seq_path_root()). If vfsroot.Ok() and vd is
+// not reachable from vfsroot, such that seq_path_root() would return SEQ_SKIP
+// (causing the entire containing entry to be skipped), PathnameReachable
+// returns ("", nil).
+func (vfs *VirtualFilesystem) PathnameReachable(ctx context.Context, vfsroot, vd VirtualDentry) (string, error) {
+ b := getFSPathBuilder()
+ defer putFSPathBuilder(b)
+ haveRef := false
+ defer func() {
+ if haveRef {
+ vd.DecRef()
+ }
+ }()
+loop:
+ for {
+ err := vd.mount.fs.impl.PrependPath(ctx, vfsroot, vd, b)
+ switch err.(type) {
+ case nil:
+ if vd.mount == vfsroot.mount && vd.mount.root == vfsroot.dentry {
+ break loop
+ }
+ nextVD := vfs.getMountpointAt(vd.mount, vfsroot)
+ if !nextVD.Ok() {
+ return "", nil
+ }
+ if haveRef {
+ vd.DecRef()
+ }
+ vd = nextVD
+ haveRef = true
+ case PrependPathAtVFSRootError:
+ break loop
+ case PrependPathAtNonMountRootError, PrependPathSyntheticError:
+ return "", nil
+ default:
+ return "", err
+ }
+ }
+ b.PrependByte('/')
+ return b.String(), nil
+}
+
// PathnameForGetcwd returns an absolute pathname to vd, consistent with
// Linux's sys_getcwd().
func (vfs *VirtualFilesystem) PathnameForGetcwd(ctx context.Context, vfsroot, vd VirtualDentry) (string, error) {
- if vd.dentry.IsDisowned() {
+ if vd.dentry.IsDead() {
return "", syserror.ENOENT
}