github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/fsimpl/overlay/fstree.go (about)

     1  package overlay
     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  }