github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/fsimpl/gofer/fstree.go (about) 1 package gofer 2 3 import ( 4 "github.com/metacubex/gvisor/pkg/fspath" 5 "github.com/metacubex/gvisor/pkg/sentry/vfs" 6 ) 7 8 // We need to define an interface instead of using atomic.Pointer because 9 // the Dentry type gets removed during code generation and the compiler 10 // complains about the unused sync/atomic type. 11 type genericatomicptr interface { 12 Load() *dentry 13 } 14 15 // IsAncestorDentry returns true if d is an ancestor of d2; that is, d is 16 // either d2's parent or an ancestor of d2's parent. 17 func genericIsAncestorDentry(d, d2 *dentry) bool { 18 for d2 != nil { 19 parent := d2.parent.Load() 20 if parent == d { 21 return true 22 } 23 if parent == d2 { 24 return false 25 } 26 d2 = parent 27 } 28 return false 29 } 30 31 // IsDescendant returns true if vd is a descendant of vfsroot or if vd and 32 // vfsroot are the same dentry. 33 func genericIsDescendant(vfsroot *vfs.Dentry, d *dentry) bool { 34 for d != nil && &d.vfsd != vfsroot { 35 d = d.parent.Load() 36 } 37 return d != nil 38 } 39 40 // ParentOrSelf returns d.parent. If d.parent is nil, ParentOrSelf returns d. 41 func genericParentOrSelf(d *dentry) *dentry { 42 if parent := d.parent.Load(); parent != nil { 43 return parent 44 } 45 return d 46 } 47 48 // PrependPath is a generic implementation of FilesystemImpl.PrependPath(). 49 func genericPrependPath(vfsroot vfs.VirtualDentry, mnt *vfs.Mount, d *dentry, b *fspath.Builder) error { 50 for { 51 if mnt == vfsroot.Mount() && &d.vfsd == vfsroot.Dentry() { 52 return vfs.PrependPathAtVFSRootError{} 53 } 54 if mnt != nil && &d.vfsd == mnt.Root() { 55 return nil 56 } 57 parent := d.parent.Load() 58 if parent == nil { 59 return vfs.PrependPathAtNonMountRootError{} 60 } 61 b.PrependComponent(d.name) 62 d = parent 63 } 64 } 65 66 // DebugPathname returns a pathname to d relative to its filesystem root. 67 // DebugPathname does not correspond to any Linux function; it's used to 68 // generate dentry pathnames for debugging. 69 func genericDebugPathname(d *dentry) string { 70 var b fspath.Builder 71 _ = genericPrependPath(vfs.VirtualDentry{}, nil, d, &b) 72 return b.String() 73 }