diff --git a/cmd/bb_virtual_tmp/main.go b/cmd/bb_virtual_tmp/main.go index ef34e51..8d24459 100644 --- a/cmd/bb_virtual_tmp/main.go +++ b/cmd/bb_virtual_tmp/main.go @@ -68,7 +68,7 @@ func main() { handleAllocator.New().AsStatelessDirectory( virtual.NewStaticDirectory(map[path.Component]virtual.DirectoryChild{ path.MustNewComponent("tmp"): virtual.DirectoryChild{}. - FromLeaf(handleAllocator.New().AsNativeLeaf(userSettableSymlink)), + FromLeaf(handleAllocator.New().AsLinkableLeaf(userSettableSymlink)), }))); err != nil { return util.StatusWrap(err, "Failed to expose virtual file system mount") } diff --git a/internal/mock/BUILD.bazel b/internal/mock/BUILD.bazel index cc77d39..3692a63 100644 --- a/internal/mock/BUILD.bazel +++ b/internal/mock/BUILD.bazel @@ -198,7 +198,7 @@ gomock( "HandleResolver", "InitialContentsFetcher", "Leaf", - "NativeLeaf", + "LinkableLeaf", "ResolvableHandleAllocation", "ResolvableHandleAllocator", "StatefulDirectoryHandle", diff --git a/pkg/filesystem/virtual/BUILD.bazel b/pkg/filesystem/virtual/BUILD.bazel index 879e1c1..25a53d8 100644 --- a/pkg/filesystem/virtual/BUILD.bazel +++ b/pkg/filesystem/virtual/BUILD.bazel @@ -22,7 +22,7 @@ go_library( "in_memory_prepopulated_directory.go", "initial_contents_fetcher.go", "leaf.go", - "native_leaf.go", + "linkable_leaf.go", "nfs_handle_allocator.go", "node.go", "permissions.go", diff --git a/pkg/filesystem/virtual/access_monitoring_initial_contents_fetcher_test.go b/pkg/filesystem/virtual/access_monitoring_initial_contents_fetcher_test.go index 30ab3b5..cd7ade8 100644 --- a/pkg/filesystem/virtual/access_monitoring_initial_contents_fetcher_test.go +++ b/pkg/filesystem/virtual/access_monitoring_initial_contents_fetcher_test.go @@ -43,7 +43,7 @@ func TestAccessMonitoringInitialContentsFetcher(t *testing.T) { // Reading the directory's contents should report it as being // read. It should return children that are wrapped as well. baseChildInitialContentsFetcher := mock.NewMockInitialContentsFetcher(ctrl) - baseChildFile := mock.NewMockNativeLeaf(ctrl) + baseChildFile := mock.NewMockLinkableLeaf(ctrl) baseChildFileReadMonitor := mock.NewMockFileReadMonitor(ctrl) baseFileReadMonitorFactory := mock.NewMockFileReadMonitorFactory(ctrl) baseFileReadMonitorFactory.EXPECT().Call(path.MustNewComponent("file")).Return(baseChildFileReadMonitor.Call) diff --git a/pkg/filesystem/virtual/base_symlink_factory.go b/pkg/filesystem/virtual/base_symlink_factory.go index 7c5e54e..8840ece 100644 --- a/pkg/filesystem/virtual/base_symlink_factory.go +++ b/pkg/filesystem/virtual/base_symlink_factory.go @@ -15,7 +15,7 @@ import ( type symlinkFactory struct{} -func (symlinkFactory) LookupSymlink(target []byte) NativeLeaf { +func (symlinkFactory) LookupSymlink(target []byte) LinkableLeaf { return symlink{target: target} } diff --git a/pkg/filesystem/virtual/blob_access_cas_file_factory.go b/pkg/filesystem/virtual/blob_access_cas_file_factory.go index aaf8d38..2ab09d9 100644 --- a/pkg/filesystem/virtual/blob_access_cas_file_factory.go +++ b/pkg/filesystem/virtual/blob_access_cas_file_factory.go @@ -35,7 +35,7 @@ func NewBlobAccessCASFileFactory(ctx context.Context, contentAddressableStorage } } -func (cff *blobAccessCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) NativeLeaf { +func (cff *blobAccessCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) LinkableLeaf { if readMonitor != nil { panic("The read monitor should have been set up by StatelessHandleAllocatingCASFileFactory") } diff --git a/pkg/filesystem/virtual/cas_file_factory.go b/pkg/filesystem/virtual/cas_file_factory.go index a25ccc9..576e6b2 100644 --- a/pkg/filesystem/virtual/cas_file_factory.go +++ b/pkg/filesystem/virtual/cas_file_factory.go @@ -7,5 +7,5 @@ import ( // CASFileFactory is a factory type for files whose contents correspond // with an object stored in the Content Addressable Storage (CAS). type CASFileFactory interface { - LookupFile(digest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) NativeLeaf + LookupFile(digest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) LinkableLeaf } diff --git a/pkg/filesystem/virtual/cas_initial_contents_fetcher.go b/pkg/filesystem/virtual/cas_initial_contents_fetcher.go index 6168165..6d33bca 100644 --- a/pkg/filesystem/virtual/cas_initial_contents_fetcher.go +++ b/pkg/filesystem/virtual/cas_initial_contents_fetcher.go @@ -74,7 +74,7 @@ func (icf *casInitialContentsFetcher) fetchContentsUnwrapped(fileReadMonitorFact } // Ensure that leaves are properly unlinked if this method fails. - leavesToUnlink := make([]NativeLeaf, 0, len(directory.Files)+len(directory.Symlinks)) + leavesToUnlink := make([]LinkableLeaf, 0, len(directory.Files)+len(directory.Symlinks)) defer func() { for _, leaf := range leavesToUnlink { leaf.Unlink() diff --git a/pkg/filesystem/virtual/cas_initial_contents_fetcher_test.go b/pkg/filesystem/virtual/cas_initial_contents_fetcher_test.go index dd227d6..a0dd2a7 100644 --- a/pkg/filesystem/virtual/cas_initial_contents_fetcher_test.go +++ b/pkg/filesystem/virtual/cas_initial_contents_fetcher_test.go @@ -105,7 +105,7 @@ func TestCASInitialContentsFetcherFetchContents(t *testing.T) { }, }, }, nil) - file1 := mock.NewMockNativeLeaf(ctrl) + file1 := mock.NewMockLinkableLeaf(ctrl) fileReadMonitor1 := mock.NewMockFileReadMonitor(ctrl) fileReadMonitorFactory.EXPECT().Call(path.MustNewComponent("file1")).Return(fileReadMonitor1.Call) casFileFactory.EXPECT().LookupFile( @@ -139,7 +139,7 @@ func TestCASInitialContentsFetcherFetchContents(t *testing.T) { }, }, }, nil) - file1 := mock.NewMockNativeLeaf(ctrl) + file1 := mock.NewMockLinkableLeaf(ctrl) fileReadMonitor1 := mock.NewMockFileReadMonitor(ctrl) fileReadMonitorFactory.EXPECT().Call(path.MustNewComponent("hello")).Return(fileReadMonitor1.Call) casFileFactory.EXPECT().LookupFile( @@ -195,7 +195,7 @@ func TestCASInitialContentsFetcherFetchContents(t *testing.T) { childDirectoryWalker := mock.NewMockDirectoryWalker(ctrl) directoryWalker.EXPECT().GetChild(digest.MustNewDigest("hello", remoteexecution.DigestFunction_MD5, "4b3b03436604cb9d831b91c71a8c1952", 123)). Return(childDirectoryWalker) - executableLeaf := mock.NewMockNativeLeaf(ctrl) + executableLeaf := mock.NewMockLinkableLeaf(ctrl) executableReadMonitor := mock.NewMockFileReadMonitor(ctrl) fileReadMonitorFactory.EXPECT().Call(path.MustNewComponent("executable")).Return(executableReadMonitor.Call) casFileFactory.EXPECT().LookupFile( @@ -203,7 +203,7 @@ func TestCASInitialContentsFetcherFetchContents(t *testing.T) { /* isExecutable = */ true, gomock.Any(), ).Return(executableLeaf) - fileLeaf := mock.NewMockNativeLeaf(ctrl) + fileLeaf := mock.NewMockLinkableLeaf(ctrl) fileReadMonitor := mock.NewMockFileReadMonitor(ctrl) fileReadMonitorFactory.EXPECT().Call(path.MustNewComponent("file")).Return(fileReadMonitor.Call) casFileFactory.EXPECT().LookupFile( @@ -211,7 +211,7 @@ func TestCASInitialContentsFetcherFetchContents(t *testing.T) { /* isExecutable = */ false, gomock.Any(), ).Return(fileLeaf) - symlinkLeaf := mock.NewMockNativeLeaf(ctrl) + symlinkLeaf := mock.NewMockLinkableLeaf(ctrl) symlinkFactory.EXPECT().LookupSymlink([]byte("target")).Return(symlinkLeaf) children, err := initialContentsFetcher.FetchContents(fileReadMonitorFactory.Call) diff --git a/pkg/filesystem/virtual/character_device_factory.go b/pkg/filesystem/virtual/character_device_factory.go index 844cdfa..c96c06f 100644 --- a/pkg/filesystem/virtual/character_device_factory.go +++ b/pkg/filesystem/virtual/character_device_factory.go @@ -13,12 +13,12 @@ import ( // Character devices are immutable files; it is not possible to change // the device after it has been created. type CharacterDeviceFactory interface { - LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) NativeLeaf + LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) LinkableLeaf } type baseCharacterDeviceFactory struct{} -func (baseCharacterDeviceFactory) LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) NativeLeaf { +func (baseCharacterDeviceFactory) LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) LinkableLeaf { return NewSpecialFile(filesystem.FileTypeCharacterDevice, &deviceNumber) } @@ -46,7 +46,7 @@ func NewHandleAllocatingCharacterDeviceFactory(base CharacterDeviceFactory, allo return cdf } -func (cdf *handleAllocatingCharacterDeviceFactory) LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) NativeLeaf { +func (cdf *handleAllocatingCharacterDeviceFactory) LookupCharacterDevice(deviceNumber filesystem.DeviceNumber) LinkableLeaf { // Convert the device number to a binary identifier. major, minor := deviceNumber.ToMajorMinor() var identifier [binary.MaxVarintLen32 * 2]byte @@ -55,7 +55,7 @@ func (cdf *handleAllocatingCharacterDeviceFactory) LookupCharacterDevice(deviceN return cdf.allocator. New(bytes.NewBuffer(identifier[:length])). - AsNativeLeaf(cdf.base.LookupCharacterDevice(deviceNumber)) + AsLinkableLeaf(cdf.base.LookupCharacterDevice(deviceNumber)) } func (cdf *handleAllocatingCharacterDeviceFactory) resolve(r io.ByteReader) (DirectoryChild, Status) { diff --git a/pkg/filesystem/virtual/character_device_factory_test.go b/pkg/filesystem/virtual/character_device_factory_test.go index 4590de6..b77e613 100644 --- a/pkg/filesystem/virtual/character_device_factory_test.go +++ b/pkg/filesystem/virtual/character_device_factory_test.go @@ -32,9 +32,9 @@ func TestHandleAllocatingCharacterDeviceFactory(t *testing.T) { t.Run("Lookup", func(t *testing.T) { // Look up /dev/null (on Linux: major 1, minor 3). deviceNumber := filesystem.NewDeviceNumberFromMajorMinor(1, 3) - underlyingLeaf := mock.NewMockNativeLeaf(ctrl) + underlyingLeaf := mock.NewMockLinkableLeaf(ctrl) baseCharacterDeviceFactory.EXPECT().LookupCharacterDevice(deviceNumber).Return(underlyingLeaf) - wrappedLeaf := mock.NewMockNativeLeaf(ctrl) + wrappedLeaf := mock.NewMockLinkableLeaf(ctrl) leafHandleAllocation := mock.NewMockResolvableHandleAllocation(ctrl) handleAllocator.EXPECT().New(gomock.Any()). DoAndReturn(func(id io.WriterTo) virtual.ResolvableHandleAllocation { @@ -45,7 +45,7 @@ func TestHandleAllocatingCharacterDeviceFactory(t *testing.T) { require.Equal(t, []byte{1, 3}, idBuf.Bytes()) return leafHandleAllocation }) - leafHandleAllocation.EXPECT().AsNativeLeaf(underlyingLeaf).Return(wrappedLeaf) + leafHandleAllocation.EXPECT().AsLinkableLeaf(underlyingLeaf).Return(wrappedLeaf) require.Equal(t, wrappedLeaf, characterDeviceFactory.LookupCharacterDevice(deviceNumber)) }) @@ -65,9 +65,9 @@ func TestHandleAllocatingCharacterDeviceFactory(t *testing.T) { t.Run("ResolverTwoNumbers", func(t *testing.T) { // Provided both a major and minor number. deviceNumber := filesystem.NewDeviceNumberFromMajorMinor(1, 3) - underlyingLeaf := mock.NewMockNativeLeaf(ctrl) + underlyingLeaf := mock.NewMockLinkableLeaf(ctrl) baseCharacterDeviceFactory.EXPECT().LookupCharacterDevice(deviceNumber).Return(underlyingLeaf) - wrappedLeaf := mock.NewMockNativeLeaf(ctrl) + wrappedLeaf := mock.NewMockLinkableLeaf(ctrl) leafHandleAllocation := mock.NewMockResolvableHandleAllocation(ctrl) handleAllocator.EXPECT().New(gomock.Any()). DoAndReturn(func(id io.WriterTo) virtual.ResolvableHandleAllocation { @@ -78,7 +78,7 @@ func TestHandleAllocatingCharacterDeviceFactory(t *testing.T) { require.Equal(t, []byte{1, 3}, idBuf.Bytes()) return leafHandleAllocation }) - leafHandleAllocation.EXPECT().AsNativeLeaf(underlyingLeaf).Return(wrappedLeaf) + leafHandleAllocation.EXPECT().AsLinkableLeaf(underlyingLeaf).Return(wrappedLeaf) actualChild, s := handleResolver(bytes.NewBuffer([]byte{1, 3})) require.Equal(t, virtual.StatusOK, s) diff --git a/pkg/filesystem/virtual/file_allocator.go b/pkg/filesystem/virtual/file_allocator.go index 2648bb7..035183a 100644 --- a/pkg/filesystem/virtual/file_allocator.go +++ b/pkg/filesystem/virtual/file_allocator.go @@ -7,5 +7,5 @@ package virtual // Files returned by this interface should have a link count of 1, and // are opened using the provided share access mask. type FileAllocator interface { - NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (NativeLeaf, Status) + NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (LinkableLeaf, Status) } diff --git a/pkg/filesystem/virtual/fuse_handle_allocator.go b/pkg/filesystem/virtual/fuse_handle_allocator.go index 0540488..5e95f7e 100644 --- a/pkg/filesystem/virtual/fuse_handle_allocator.go +++ b/pkg/filesystem/virtual/fuse_handle_allocator.go @@ -130,10 +130,10 @@ func (hn *fuseStatefulHandleAllocation) AsStatelessDirectory(directory Directory return d } -func (hn *fuseStatefulHandleAllocation) AsNativeLeaf(leaf NativeLeaf) NativeLeaf { - l := &fuseStatefulNativeLeaf{ - NativeLeaf: leaf, - inodeNumber: hn.options.randomNumberGenerator.Uint64(), +func (hn *fuseStatefulHandleAllocation) AsLinkableLeaf(leaf LinkableLeaf) LinkableLeaf { + l := &fuseStatefulLinkableLeaf{ + LinkableLeaf: leaf, + inodeNumber: hn.options.randomNumberGenerator.Uint64(), } l.linkCount.Store(1) *hn = fuseStatefulHandleAllocation{} @@ -189,10 +189,10 @@ func (hn *fuseStatelessHandleAllocation) AsStatelessDirectory(directory Director return d } -func (hn *fuseStatelessHandleAllocation) AsNativeLeaf(leaf NativeLeaf) NativeLeaf { - return &fuseStatelessNativeLeaf{ - NativeLeaf: leaf, - inodeNumber: hn.currentInodeNumber, +func (hn *fuseStatelessHandleAllocation) AsLinkableLeaf(leaf LinkableLeaf) LinkableLeaf { + return &fuseStatelessLinkableLeaf{ + LinkableLeaf: leaf, + inodeNumber: hn.currentInodeNumber, } } @@ -269,17 +269,17 @@ func (d *fuseStatelessDirectory) VirtualSetAttributes(ctx context.Context, in *A return StatusOK } -// fuseStatefulNativeLeaf is a decorator for NativeLeaf that augments +// fuseStatefulLinkableLeaf is a decorator for LinkableLeaf that augments // the results of VirtualGetAttributes() to contain an inode number and // link count. Link() and Unlink() calls are intercepted, and are only // forwarded if the link count drops to zero. -type fuseStatefulNativeLeaf struct { - NativeLeaf +type fuseStatefulLinkableLeaf struct { + LinkableLeaf inodeNumber uint64 linkCount atomic.Uint32 } -func (l *fuseStatefulNativeLeaf) Link() Status { +func (l *fuseStatefulLinkableLeaf) Link() Status { for { current := l.linkCount.Load() if current == 0 { @@ -292,13 +292,13 @@ func (l *fuseStatefulNativeLeaf) Link() Status { } } -func (l *fuseStatefulNativeLeaf) Unlink() { +func (l *fuseStatefulLinkableLeaf) Unlink() { if l.linkCount.Add(^uint32(0)) == 0 { - l.NativeLeaf.Unlink() + l.LinkableLeaf.Unlink() } } -func (l *fuseStatefulNativeLeaf) injectAttributes(attributes *Attributes) { +func (l *fuseStatefulLinkableLeaf) injectAttributes(attributes *Attributes) { attributes.SetInodeNumber(l.inodeNumber) attributes.SetLinkCount(l.linkCount.Load()) // The change ID should normally also be affected by the link @@ -306,66 +306,66 @@ func (l *fuseStatefulNativeLeaf) injectAttributes(attributes *Attributes) { // does not depend on it. } -func (l *fuseStatefulNativeLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { +func (l *fuseStatefulLinkableLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { if remaining := requested &^ (AttributesMaskInodeNumber | AttributesMaskLinkCount); remaining != 0 { - l.NativeLeaf.VirtualGetAttributes(ctx, remaining, attributes) + l.LinkableLeaf.VirtualGetAttributes(ctx, remaining, attributes) } l.injectAttributes(attributes) } -func (l *fuseStatefulNativeLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { +func (l *fuseStatefulLinkableLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { return s } l.injectAttributes(attributes) return StatusOK } -func (l *fuseStatefulNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { +func (l *fuseStatefulLinkableLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { return s } l.injectAttributes(attributes) return StatusOK } -// fuseStatelessNativeLeaf is a decorator for NativeLeaf that augments +// fuseStatelessLinkableLeaf is a decorator for LinkableLeaf that augments // the results of VirtualGetAttributes() to contain an inode number and // link count. For these kinds of files, the link count is just a // constant. -type fuseStatelessNativeLeaf struct { - NativeLeaf +type fuseStatelessLinkableLeaf struct { + LinkableLeaf inodeNumber uint64 } -func (l *fuseStatelessNativeLeaf) Link() Status { +func (l *fuseStatelessLinkableLeaf) Link() Status { return StatusOK } -func (l *fuseStatelessNativeLeaf) Unlink() {} +func (l *fuseStatelessLinkableLeaf) Unlink() {} -func (l *fuseStatelessNativeLeaf) injectAttributes(attributes *Attributes) { +func (l *fuseStatelessLinkableLeaf) injectAttributes(attributes *Attributes) { attributes.SetInodeNumber(l.inodeNumber) attributes.SetLinkCount(StatelessLeafLinkCount) } -func (l *fuseStatelessNativeLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { +func (l *fuseStatelessLinkableLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { if remaining := requested &^ (AttributesMaskInodeNumber | AttributesMaskLinkCount); remaining != 0 { - l.NativeLeaf.VirtualGetAttributes(ctx, remaining, attributes) + l.LinkableLeaf.VirtualGetAttributes(ctx, remaining, attributes) } l.injectAttributes(attributes) } -func (l *fuseStatelessNativeLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { +func (l *fuseStatelessLinkableLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { return s } l.injectAttributes(attributes) return StatusOK } -func (l *fuseStatelessNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { +func (l *fuseStatelessLinkableLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { return s } l.injectAttributes(attributes) diff --git a/pkg/filesystem/virtual/fuse_handle_allocator_test.go b/pkg/filesystem/virtual/fuse_handle_allocator_test.go index c06ad87..5043af2 100644 --- a/pkg/filesystem/virtual/fuse_handle_allocator_test.go +++ b/pkg/filesystem/virtual/fuse_handle_allocator_test.go @@ -75,17 +75,17 @@ func TestFUSEHandleAllocator(t *testing.T) { &attr) }) - t.Run("StatefulNativeLeaf", func(t *testing.T) { + t.Run("StatefulLinkableLeaf", func(t *testing.T) { // Create a stateful file and wrap it. A link count and // inode number should be added. - baseLeaf := mock.NewMockNativeLeaf(ctrl) + baseLeaf := mock.NewMockLinkableLeaf(ctrl) baseLeaf.EXPECT().VirtualGetAttributes(ctx, virtual.AttributesMaskSizeBytes, gomock.Any()). Do(func(ctx context.Context, attributesMask virtual.AttributesMask, attributes *virtual.Attributes) { attributes.SetSizeBytes(42) }).AnyTimes() randomNumberGenerator.EXPECT().Uint64().Return(uint64(0xf999bb2fd22421d8)) - wrappedLeaf := handleAllocator.New().AsNativeLeaf(baseLeaf) + wrappedLeaf := handleAllocator.New().AsLinkableLeaf(baseLeaf) var attr1 virtual.Attributes wrappedLeaf.VirtualGetAttributes(ctx, attributesMask, &attr1) @@ -142,7 +142,7 @@ func TestFUSEHandleAllocator(t *testing.T) { &attr4) }) - t.Run("StatelessNativeLeaf", func(t *testing.T) { + t.Run("StatelessLinkableLeaf", func(t *testing.T) { // Create a stateless file and wrap it. A link count and // inode number should be added. As the file is // stateless, the link count uses a placeholder value. @@ -150,7 +150,7 @@ func TestFUSEHandleAllocator(t *testing.T) { // The inode number of the leaf corresponds with the // FNV-1a hash of "Hello", using 0x6aae40a05f45b861 as // the offset basis. - baseLeaf := mock.NewMockNativeLeaf(ctrl) + baseLeaf := mock.NewMockLinkableLeaf(ctrl) baseLeaf.EXPECT().VirtualGetAttributes(ctx, virtual.AttributesMaskSizeBytes, gomock.Any()). Do(func(ctx context.Context, attributesMask virtual.AttributesMask, attributes *virtual.Attributes) { attributes.SetSizeBytes(123) @@ -161,7 +161,7 @@ func TestFUSEHandleAllocator(t *testing.T) { New(). AsStatelessAllocator(). New(bytes.NewBuffer([]byte("Hello"))). - AsNativeLeaf(baseLeaf) + AsLinkableLeaf(baseLeaf) var attr1 virtual.Attributes wrappedLeaf.VirtualGetAttributes(ctx, attributesMask, &attr1) diff --git a/pkg/filesystem/virtual/handle_allocating_file_allocator.go b/pkg/filesystem/virtual/handle_allocating_file_allocator.go index 97e5131..726e52a 100644 --- a/pkg/filesystem/virtual/handle_allocating_file_allocator.go +++ b/pkg/filesystem/virtual/handle_allocating_file_allocator.go @@ -16,10 +16,10 @@ func NewHandleAllocatingFileAllocator(base FileAllocator, allocator StatefulHand } } -func (fa *handleAllocatingFileAllocator) NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (NativeLeaf, Status) { +func (fa *handleAllocatingFileAllocator) NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (LinkableLeaf, Status) { leaf, s := fa.base.NewFile(isExecutable, size, shareAccess) if s != StatusOK { return nil, s } - return fa.allocator.New().AsNativeLeaf(leaf), StatusOK + return fa.allocator.New().AsLinkableLeaf(leaf), StatusOK } diff --git a/pkg/filesystem/virtual/handle_allocating_symlink_factory.go b/pkg/filesystem/virtual/handle_allocating_symlink_factory.go index 644f9f8..ab56eb2 100644 --- a/pkg/filesystem/virtual/handle_allocating_symlink_factory.go +++ b/pkg/filesystem/virtual/handle_allocating_symlink_factory.go @@ -21,8 +21,8 @@ func NewHandleAllocatingSymlinkFactory(base SymlinkFactory, allocation Stateless } } -func (sf *handleAllocatingSymlinkFactory) LookupSymlink(target []byte) NativeLeaf { +func (sf *handleAllocatingSymlinkFactory) LookupSymlink(target []byte) LinkableLeaf { return sf.allocator. New(ByteSliceID(target)). - AsNativeLeaf(sf.base.LookupSymlink(target)) + AsLinkableLeaf(sf.base.LookupSymlink(target)) } diff --git a/pkg/filesystem/virtual/handle_allocator.go b/pkg/filesystem/virtual/handle_allocator.go index 833ee91..ac4c958 100644 --- a/pkg/filesystem/virtual/handle_allocator.go +++ b/pkg/filesystem/virtual/handle_allocator.go @@ -107,7 +107,7 @@ type HandleResolver func(r io.ByteReader) (DirectoryChild, Status) type ResolvableHandleAllocation interface { AsResolvableAllocator(resolver HandleResolver) ResolvableHandleAllocator AsStatelessDirectory(directory Directory) Directory - AsNativeLeaf(leaf NativeLeaf) NativeLeaf + AsLinkableLeaf(leaf LinkableLeaf) LinkableLeaf AsLeaf(leaf Leaf) Leaf } diff --git a/pkg/filesystem/virtual/in_memory_prepopulated_directory.go b/pkg/filesystem/virtual/in_memory_prepopulated_directory.go index ae63869..37115c0 100644 --- a/pkg/filesystem/virtual/in_memory_prepopulated_directory.go +++ b/pkg/filesystem/virtual/in_memory_prepopulated_directory.go @@ -59,7 +59,7 @@ func (s *inMemorySubtree) createNewDirectory(initialContentsFetcher InitialConte // inMemoryDirectoryChild contains exactly one reference to an object // that's embedded in a parent directory. -type inMemoryDirectoryChild = Child[*inMemoryPrepopulatedDirectory, NativeLeaf, Node] +type inMemoryDirectoryChild = Child[*inMemoryPrepopulatedDirectory, LinkableLeaf, Node] // inMemoryDirectoryEntry is a directory entry for an object stored in // inMemoryDirectoryContents. @@ -249,7 +249,7 @@ func (c *inMemoryDirectoryContents) getDirectoriesAndLeavesCount(hiddenFilesMatc // locks (e.g., Rename() locking up to three directories), util.LockPile // is used for deadlock avoidance. To ensure consistency, locks on one // or more directories may be held when calling into the FileAllocator -// or NativeLeaf nodes. +// or LinkableLeaf nodes. type inMemoryPrepopulatedDirectory struct { subtree *inMemorySubtree handle StatefulDirectoryHandle @@ -606,7 +606,7 @@ func (i *inMemoryPrepopulatedDirectory) filterChildrenRecursive(childFilter Chil // Directory is already initialized. Gather the contents. type leafInfo struct { name path.Component - leaf NativeLeaf + leaf LinkableLeaf } directoriesCount, leavesCount := i.contents.getDirectoriesAndLeavesCount(i.subtree.filesystem.hiddenFilesMatcher) directories := make([]*inMemoryPrepopulatedDirectory, 0, directoriesCount) @@ -743,7 +743,7 @@ func (inMemoryPrepopulatedDirectory) VirtualApply(data any) bool { } func (i *inMemoryPrepopulatedDirectory) VirtualLink(ctx context.Context, name path.Component, leaf Leaf, requested AttributesMask, out *Attributes) (ChangeInfo, Status) { - child, ok := leaf.(NativeLeaf) + child, ok := leaf.(LinkableLeaf) if !ok { // The file is not the kind that can be embedded into // inMemoryPrepopulatedDirectory. @@ -855,7 +855,7 @@ func (i *inMemoryPrepopulatedDirectory) VirtualMknod(ctx context.Context, name p // therefore consider it to be stateful, like a writable file. child := i.subtree.filesystem.statefulHandleAllocator. New(). - AsNativeLeaf(NewSpecialFile(fileType, nil)) + AsLinkableLeaf(NewSpecialFile(fileType, nil)) changeIDBefore := contents.changeID contents.attach(i.subtree, name, inMemoryDirectoryChild{}.FromLeaf(child)) diff --git a/pkg/filesystem/virtual/in_memory_prepopulated_directory_test.go b/pkg/filesystem/virtual/in_memory_prepopulated_directory_test.go index 547183b..686db49 100644 --- a/pkg/filesystem/virtual/in_memory_prepopulated_directory_test.go +++ b/pkg/filesystem/virtual/in_memory_prepopulated_directory_test.go @@ -72,7 +72,7 @@ func TestInMemoryPrepopulatedDirectoryLookupChildFile(t *testing.T) { inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -148,8 +148,8 @@ func TestInMemoryPrepopulatedDirectoryLookupAllChildrenSuccess(t *testing.T) { d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) // Populate the directory with files and directories. - leaf1 := mock.NewMockNativeLeaf(ctrl) - leaf2 := mock.NewMockNativeLeaf(ctrl) + leaf1 := mock.NewMockLinkableLeaf(ctrl) + leaf2 := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("leaf1"): virtual.InitialNode{}.FromLeaf(leaf1), path.MustNewComponent("._leaf2"): virtual.InitialNode{}.FromLeaf(leaf2), @@ -187,8 +187,8 @@ func TestInMemoryPrepopulatedDirectoryReadDir(t *testing.T) { // Prepare file system. inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) - leaf1 := mock.NewMockNativeLeaf(ctrl) - leaf2 := mock.NewMockNativeLeaf(ctrl) + leaf1 := mock.NewMockLinkableLeaf(ctrl) + leaf2 := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("directory"): virtual.InitialNode{}.FromDirectory(virtual.EmptyInitialContentsFetcher), path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf1), @@ -263,7 +263,7 @@ func TestInMemoryPrepopulatedDirectoryRemoveDirectoryNotEmpty(t *testing.T) { require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("directory"): virtual.InitialNode{}.FromDirectory(initialContentsFetcher), }, false)) - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) initialContentsFetcher.EXPECT().FetchContents(gomock.Any()).Return(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf), }, nil) @@ -281,7 +281,7 @@ func TestInMemoryPrepopulatedDirectoryRemoveFile(t *testing.T) { dHandle := inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -307,7 +307,7 @@ func TestInMemoryPrepopulatedDirectoryCreateChildrenSuccess(t *testing.T) { // Merge another directory and file into it. inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) subdirectoryFetcher := mock.NewMockInitialContentsFetcher(ctrl) - topLevelFile := mock.NewMockNativeLeaf(ctrl) + topLevelFile := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("dir"): virtual.InitialNode{}.FromDirectory(subdirectoryFetcher), path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(topLevelFile), @@ -333,7 +333,7 @@ func TestInMemoryPrepopulatedDirectoryCreateChildrenSuccess(t *testing.T) { // Validate subdirectory listing. child, err := d.LookupChild(path.MustNewComponent("dir")) require.NoError(t, err) - subdirectoryFile := mock.NewMockNativeLeaf(ctrl) + subdirectoryFile := mock.NewMockLinkableLeaf(ctrl) subdirectoryFetcher.EXPECT().FetchContents(gomock.Any()).Return(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(subdirectoryFile), }, nil) @@ -455,8 +455,8 @@ func TestInMemoryPrepopulatedDirectoryFilterChildren(t *testing.T) { directory1 := mock.NewMockInitialContentsFetcher(ctrl) inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) directory2 := mock.NewMockInitialContentsFetcher(ctrl) - leaf1 := mock.NewMockNativeLeaf(ctrl) - leaf2 := mock.NewMockNativeLeaf(ctrl) + leaf1 := mock.NewMockLinkableLeaf(ctrl) + leaf2 := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("directory1"): virtual.InitialNode{}.FromDirectory(directory1), path.MustNewComponent("directory2"): virtual.InitialNode{}.FromDirectory(directory2), @@ -500,7 +500,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualOpenChildFileExists(t *testing.T) { d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) // Create a file at the desired target location. - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("target"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -609,7 +609,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualOpenChildSuccess(t *testing.T) { fileAllocator := mock.NewMockFileAllocator(ctrl) symlinkFactory := mock.NewMockSymlinkFactory(ctrl) - child := mock.NewMockNativeLeaf(ctrl) + child := mock.NewMockLinkableLeaf(ctrl) fileAllocator.EXPECT().NewFile(false, uint64(0), virtual.ShareMaskWrite). Return(child, virtual.StatusOK) child.EXPECT().VirtualGetAttributes( @@ -696,7 +696,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkExists(t *testing.T) { fileAllocator := mock.NewMockFileAllocator(ctrl) symlinkFactory := mock.NewMockSymlinkFactory(ctrl) - child := mock.NewMockNativeLeaf(ctrl) + child := mock.NewMockLinkableLeaf(ctrl) errorLogger := mock.NewMockErrorLogger(ctrl) handleAllocator := mock.NewMockStatefulHandleAllocator(ctrl) inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) @@ -717,7 +717,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkInRemovedDirectory(t *testing.T fileAllocator := mock.NewMockFileAllocator(ctrl) symlinkFactory := mock.NewMockSymlinkFactory(ctrl) - target := mock.NewMockNativeLeaf(ctrl) + target := mock.NewMockLinkableLeaf(ctrl) errorLogger := mock.NewMockErrorLogger(ctrl) handleAllocator := mock.NewMockStatefulHandleAllocator(ctrl) dHandle := inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) @@ -737,7 +737,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkInRemovedDirectory(t *testing.T require.Equal(t, virtual.StatusErrNoEnt, s) } -func TestInMemoryPrepopulatedDirectoryVirtualLinkNotNativeLeaf(t *testing.T) { +func TestInMemoryPrepopulatedDirectoryVirtualLinkNotLinkableLeaf(t *testing.T) { ctrl, ctx := gomock.WithContext(context.Background(), t) fileAllocator := mock.NewMockFileAllocator(ctrl) @@ -747,7 +747,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkNotNativeLeaf(t *testing.T) { inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) - // Trying to link a file that does not implement NativeLeaf is + // Trying to link a file that does not implement LinkableLeaf is // not possible. We can only store leaf nodes that implement // this interface. child := mock.NewMockVirtualLeaf(ctrl) @@ -768,7 +768,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkStale(t *testing.T) { // Attempting to link a file that has already been removed // should fail. - child := mock.NewMockNativeLeaf(ctrl) + child := mock.NewMockLinkableLeaf(ctrl) child.EXPECT().Link().Return(virtual.StatusErrStale) var attr virtual.Attributes @@ -781,7 +781,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLinkSuccess(t *testing.T) { fileAllocator := mock.NewMockFileAllocator(ctrl) symlinkFactory := mock.NewMockSymlinkFactory(ctrl) - child := mock.NewMockNativeLeaf(ctrl) + child := mock.NewMockLinkableLeaf(ctrl) child.EXPECT().Link() child.EXPECT().VirtualGetAttributes( ctx, @@ -820,7 +820,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualLookup(t *testing.T) { // Create an example directory and file that we'll try to look up. subdirHandle := inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) - file := mock.NewMockNativeLeaf(ctrl) + file := mock.NewMockLinkableLeaf(ctrl) clock.EXPECT().Now().Return(time.Unix(1001, 0)).Times(3) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("dir"): virtual.InitialNode{}.FromDirectory(virtual.EmptyInitialContentsFetcher), @@ -919,7 +919,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualMkdir(t *testing.T) { t.Run("FailureExist", func(t *testing.T) { // The operation should fail if a file or directory // already exists under the provided name. - existingFile := mock.NewMockNativeLeaf(ctrl) + existingFile := mock.NewMockLinkableLeaf(ctrl) clock.EXPECT().Now().Return(time.Unix(1002, 0)) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("existing_file"): virtual.InitialNode{}.FromLeaf(existingFile), @@ -992,8 +992,8 @@ func TestInMemoryPrepopulatedDirectoryVirtualMknodSuccess(t *testing.T) { // Create a FIFO and a UNIX domain socket. fifoHandleAllocation := mock.NewMockStatefulHandleAllocation(ctrl) handleAllocator.EXPECT().New().Return(fifoHandleAllocation) - fifoHandleAllocation.EXPECT().AsNativeLeaf(gomock.Any()). - DoAndReturn(func(leaf virtual.NativeLeaf) virtual.NativeLeaf { return leaf }) + fifoHandleAllocation.EXPECT().AsLinkableLeaf(gomock.Any()). + DoAndReturn(func(leaf virtual.LinkableLeaf) virtual.LinkableLeaf { return leaf }) var fifoAttr virtual.Attributes fifoNode, changeInfo, s := d.VirtualMknod(ctx, path.MustNewComponent("fifo"), filesystem.FileTypeFIFO, specialFileAttributesMask, &fifoAttr) require.Equal(t, virtual.StatusOK, s) @@ -1013,8 +1013,8 @@ func TestInMemoryPrepopulatedDirectoryVirtualMknodSuccess(t *testing.T) { socketHandleAllocation := mock.NewMockStatefulHandleAllocation(ctrl) handleAllocator.EXPECT().New().Return(socketHandleAllocation) - socketHandleAllocation.EXPECT().AsNativeLeaf(gomock.Any()). - DoAndReturn(func(leaf virtual.NativeLeaf) virtual.NativeLeaf { return leaf }) + socketHandleAllocation.EXPECT().AsLinkableLeaf(gomock.Any()). + DoAndReturn(func(leaf virtual.LinkableLeaf) virtual.LinkableLeaf { return leaf }) var socketAttr virtual.Attributes socketNode, changeInfo, s := d.VirtualMknod(ctx, path.MustNewComponent("socket"), filesystem.FileTypeSocket, specialFileAttributesMask, &socketAttr) require.Equal(t, virtual.StatusOK, s) @@ -1066,8 +1066,8 @@ func TestInMemoryPrepopulatedDirectoryVirtualReadDir(t *testing.T) { // uninitialized and a file. childDirectoryHandle := inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) childDirectory := mock.NewMockInitialContentsFetcher(ctrl) - childFile1 := mock.NewMockNativeLeaf(ctrl) - childFile2 := mock.NewMockNativeLeaf(ctrl) + childFile1 := mock.NewMockLinkableLeaf(ctrl) + childFile2 := mock.NewMockLinkableLeaf(ctrl) clock.EXPECT().Now().Return(time.Unix(1001, 0)).Times(4) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("directory"): virtual.InitialNode{}.FromDirectory(childDirectory), @@ -1166,7 +1166,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRenameSelfFile(t *testing.T) { inMemoryPrepopulatedDirectoryExpectMkdir(ctrl, handleAllocator) d := virtual.NewInMemoryPrepopulatedDirectory(fileAllocator, symlinkFactory, errorLogger, handleAllocator, sort.Sort, hiddenFilesPatternForTesting.MatchString, clock.SystemClock) - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("a"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -1272,7 +1272,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRenameFileInRemovedDirectory(t *tes require.NoError(t, d.Remove(path.MustNewComponent("removed"))) // Moving a file into it should fail with ENOENT. - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -1410,7 +1410,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRenameCrossDevice2(t *testing.T) { // completely safe. It's generally not useful to do this, but // even if we disallowed this explicitly, it would still be // possible to achieve this by hardlinking. - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d1.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("leaf"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -1458,7 +1458,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRemove(t *testing.T) { t.Run("NoLeafRemoval", func(t *testing.T) { // Attempting to remove a leaf, even though leaf removal // should not be performed. - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("no_file_removal"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -1490,7 +1490,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRemove(t *testing.T) { require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("non_empty_directory"): virtual.InitialNode{}.FromDirectory(initialContentsFetcher), }, false)) - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) initialContentsFetcher.EXPECT().FetchContents(gomock.Any()).Return(map[path.Component]virtual.InitialNode{ path.MustNewComponent("file"): virtual.InitialNode{}.FromLeaf(leaf), }, nil) @@ -1500,7 +1500,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualRemove(t *testing.T) { }) t.Run("SuccessFile", func(t *testing.T) { - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("success"): virtual.InitialNode{}.FromLeaf(leaf), }, false)) @@ -1523,8 +1523,8 @@ func TestInMemoryPrepopulatedDirectoryVirtualRemove(t *testing.T) { require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("directory_with_hidden_files"): virtual.InitialNode{}.FromDirectory(initialContentsFetcher), }, false)) - leaf1 := mock.NewMockNativeLeaf(ctrl) - leaf2 := mock.NewMockNativeLeaf(ctrl) + leaf1 := mock.NewMockLinkableLeaf(ctrl) + leaf2 := mock.NewMockLinkableLeaf(ctrl) initialContentsFetcher.EXPECT().FetchContents(gomock.Any()).Return(map[path.Component]virtual.InitialNode{ path.MustNewComponent("._hidden_file1"): virtual.InitialNode{}.FromLeaf(leaf1), path.MustNewComponent("._hidden_file2"): virtual.InitialNode{}.FromLeaf(leaf2), @@ -1582,7 +1582,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualSymlink(t *testing.T) { t.Run("FailureExist", func(t *testing.T) { // The operation should fail if a file or directory // already exists under the provided name. - existingFile := mock.NewMockNativeLeaf(ctrl) + existingFile := mock.NewMockLinkableLeaf(ctrl) require.NoError(t, d.CreateChildren(map[path.Component]virtual.InitialNode{ path.MustNewComponent("existing_file"): virtual.InitialNode{}.FromLeaf(existingFile), }, false)) @@ -1592,7 +1592,7 @@ func TestInMemoryPrepopulatedDirectoryVirtualSymlink(t *testing.T) { }) t.Run("Success", func(t *testing.T) { - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) symlinkFactory.EXPECT().LookupSymlink([]byte("target")).Return(leaf) leaf.EXPECT().VirtualGetAttributes( ctx, diff --git a/pkg/filesystem/virtual/initial_contents_fetcher.go b/pkg/filesystem/virtual/initial_contents_fetcher.go index 6e7f2f0..fd59a8e 100644 --- a/pkg/filesystem/virtual/initial_contents_fetcher.go +++ b/pkg/filesystem/virtual/initial_contents_fetcher.go @@ -10,7 +10,7 @@ import ( // InitialNode is the value type of the map of directory entries // returned by InitialContentsFetcher.FetchContents(). Either Directory // or Leaf is set, but not both. -type InitialNode = Child[InitialContentsFetcher, NativeLeaf, any] +type InitialNode = Child[InitialContentsFetcher, LinkableLeaf, any] // FileReadMonitor is used by the regular files created through the // InitialContentsFetcher to indicate that one or more calls against diff --git a/pkg/filesystem/virtual/native_leaf.go b/pkg/filesystem/virtual/linkable_leaf.go similarity index 74% rename from pkg/filesystem/virtual/native_leaf.go rename to pkg/filesystem/virtual/linkable_leaf.go index 2c058ac..51680c4 100644 --- a/pkg/filesystem/virtual/native_leaf.go +++ b/pkg/filesystem/virtual/linkable_leaf.go @@ -1,8 +1,8 @@ package virtual -// NativeLeaf objects are non-directory nodes that can be placed in a +// LinkableLeaf objects are non-directory nodes that can be placed in a // PrepopulatedDirectory. -type NativeLeaf interface { +type LinkableLeaf interface { Leaf // Operations called into by implementations of diff --git a/pkg/filesystem/virtual/nfs_handle_allocator.go b/pkg/filesystem/virtual/nfs_handle_allocator.go index a97b145..ea5cf69 100644 --- a/pkg/filesystem/virtual/nfs_handle_allocator.go +++ b/pkg/filesystem/virtual/nfs_handle_allocator.go @@ -44,8 +44,8 @@ type nfsHandlePool struct { lock sync.RWMutex randomNumberGenerator random.SingleThreadedGenerator directories map[uint64]Directory - statefulLeaves map[uint64]*nfsStatefulNativeLeaf - statelessLeaves map[uint64]*nfsStatelessNativeLeaf + statefulLeaves map[uint64]*nfsStatefulLinkableLeaf + statelessLeaves map[uint64]*nfsStatelessLinkableLeaf resolvers map[uint64]HandleResolver } @@ -111,8 +111,8 @@ func NewNFSHandleAllocator(randomNumberGenerator random.SingleThreadedGenerator) pool: &nfsHandlePool{ randomNumberGenerator: randomNumberGenerator, directories: map[uint64]Directory{}, - statefulLeaves: map[uint64]*nfsStatefulNativeLeaf{}, - statelessLeaves: map[uint64]*nfsStatelessNativeLeaf{}, + statefulLeaves: map[uint64]*nfsStatefulLinkableLeaf{}, + statelessLeaves: map[uint64]*nfsStatelessLinkableLeaf{}, resolvers: map[uint64]HandleResolver{}, }, } @@ -214,16 +214,16 @@ func (hn *nfsStatefulHandleAllocation) AsStatelessDirectory(underlyingDirectory return directory } -func (hn *nfsStatefulHandleAllocation) AsNativeLeaf(underlyingLeaf NativeLeaf) NativeLeaf { +func (hn *nfsStatefulHandleAllocation) AsLinkableLeaf(underlyingLeaf LinkableLeaf) LinkableLeaf { hp := hn.pool hp.lock.Lock() inodeNumber := hp.randomNumberGenerator.Uint64() fileHandle := inodeNumberToBaseFileHandle(inodeNumber) - leaf := &nfsStatefulNativeLeaf{ - NativeLeaf: underlyingLeaf, - pool: hp, - fileHandle: fileHandle[:], - linkCount: 1, + leaf := &nfsStatefulLinkableLeaf{ + LinkableLeaf: underlyingLeaf, + pool: hp, + fileHandle: fileHandle[:], + linkCount: 1, } hp.statefulLeaves[inodeNumber] = leaf hp.lock.Unlock() @@ -286,7 +286,7 @@ func (hn *nfsStatelessHandleAllocation) AsStatelessDirectory(underlyingDirectory return directory } -func (hn *nfsStatelessHandleAllocation) AsNativeLeaf(underlyingLeaf NativeLeaf) NativeLeaf { +func (hn *nfsStatelessHandleAllocation) AsLinkableLeaf(underlyingLeaf LinkableLeaf) LinkableLeaf { hp := hn.pool hp.lock.Lock() @@ -300,11 +300,11 @@ func (hn *nfsStatelessHandleAllocation) AsNativeLeaf(underlyingLeaf NativeLeaf) // None exists. Create a new one. fileHandle := inodeNumberToBaseFileHandle(hn.currentInodeNumber) - leaf := &nfsStatelessNativeLeaf{ - NativeLeaf: underlyingLeaf, - pool: hp, - fileHandle: fileHandle[:], - linkCount: 1, + leaf := &nfsStatelessLinkableLeaf{ + LinkableLeaf: underlyingLeaf, + pool: hp, + fileHandle: fileHandle[:], + linkCount: 1, } hp.statelessLeaves[hn.currentInodeNumber] = leaf hp.lock.Unlock() @@ -352,10 +352,10 @@ func (hn *nfsResolvableHandleAllocation) AsStatelessDirectory(underlyingDirector return directory } -func (hn *nfsResolvableHandleAllocation) AsNativeLeaf(underlyingLeaf NativeLeaf) NativeLeaf { - leaf := &nfsResolvableNativeLeaf{ - NativeLeaf: underlyingLeaf, - fileHandle: hn.currentFileHandle, +func (hn *nfsResolvableHandleAllocation) AsLinkableLeaf(underlyingLeaf LinkableLeaf) LinkableLeaf { + leaf := &nfsResolvableLinkableLeaf{ + LinkableLeaf: underlyingLeaf, + fileHandle: hn.currentFileHandle, } *hn = nfsResolvableHandleAllocation{} return leaf @@ -421,12 +421,12 @@ func (d *nfsStatelessDirectory) VirtualSetAttributes(ctx context.Context, in *At return StatusOK } -// nfsStatefulNativeLeaf is a decorator for NativeLeaf that augments +// nfsStatefulLinkableLeaf is a decorator for LinkableLeaf that augments // the results of VirtualGetAttributes() to contain a file handle, inode // number and link count. Link() and Unlink() calls are intercepted, and // are only forwarded if the link count drops to zero. -type nfsStatefulNativeLeaf struct { - NativeLeaf +type nfsStatefulLinkableLeaf struct { + LinkableLeaf pool *nfsHandlePool fileHandle []byte @@ -435,7 +435,7 @@ type nfsStatefulNativeLeaf struct { changeID uint64 } -func (l *nfsStatefulNativeLeaf) Link() Status { +func (l *nfsStatefulLinkableLeaf) Link() Status { hp := l.pool hp.lock.Lock() defer hp.lock.Unlock() @@ -448,7 +448,7 @@ func (l *nfsStatefulNativeLeaf) Link() Status { return StatusOK } -func (l *nfsStatefulNativeLeaf) Unlink() { +func (l *nfsStatefulLinkableLeaf) Unlink() { inodeNumber := fileHandleToInodeNumber(l.fileHandle) hp := l.pool @@ -461,13 +461,13 @@ func (l *nfsStatefulNativeLeaf) Unlink() { if l.linkCount == 0 { delete(hp.statefulLeaves, inodeNumber) hp.lock.Unlock() - l.NativeLeaf.Unlink() + l.LinkableLeaf.Unlink() } else { hp.lock.Unlock() } } -func (l *nfsStatefulNativeLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { +func (l *nfsStatefulLinkableLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { setAttributesForFileHandle(l.fileHandle, requested, attributes) if requested&(AttributesMaskChangeID|AttributesMaskLinkCount) != 0 { hp := l.pool @@ -480,30 +480,30 @@ func (l *nfsStatefulNativeLeaf) injectAttributes(requested AttributesMask, attri } } -func (l *nfsStatefulNativeLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { +func (l *nfsStatefulLinkableLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { if remaining := requested &^ (AttributesMaskFileHandle | AttributesMaskInodeNumber | AttributesMaskLinkCount); remaining != 0 { - l.NativeLeaf.VirtualGetAttributes(ctx, remaining, attributes) + l.LinkableLeaf.VirtualGetAttributes(ctx, remaining, attributes) } l.injectAttributes(requested, attributes) } -func (l *nfsStatefulNativeLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { +func (l *nfsStatefulLinkableLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) return StatusOK } -func (l *nfsStatefulNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { +func (l *nfsStatefulLinkableLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) return StatusOK } -// nfsStatelessNativeLeaf is a decorator for NativeLeaf that augments +// nfsStatelessLinkableLeaf is a decorator for LinkableLeaf that augments // the results of VirtualGetAttributes() to contain a file handle, inode // number and link count. // @@ -512,8 +512,8 @@ func (l *nfsStatefulNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess // from nfsHandlePool. We do report a constant link count back to the // user, both to prevent invalidation of the attributes and for // consistency with FUSE. -type nfsStatelessNativeLeaf struct { - NativeLeaf +type nfsStatelessLinkableLeaf struct { + LinkableLeaf pool *nfsHandlePool fileHandle []byte @@ -521,7 +521,7 @@ type nfsStatelessNativeLeaf struct { linkCount uint32 } -func (l *nfsStatelessNativeLeaf) Link() Status { +func (l *nfsStatelessLinkableLeaf) Link() Status { hp := l.pool hp.lock.Lock() defer hp.lock.Unlock() @@ -533,7 +533,7 @@ func (l *nfsStatelessNativeLeaf) Link() Status { return StatusOK } -func (l *nfsStatelessNativeLeaf) Unlink() { +func (l *nfsStatelessLinkableLeaf) Unlink() { inodeNumber := fileHandleToInodeNumber(l.fileHandle) hp := l.pool @@ -545,77 +545,77 @@ func (l *nfsStatelessNativeLeaf) Unlink() { if l.linkCount == 0 { delete(hp.statelessLeaves, inodeNumber) hp.lock.Unlock() - l.NativeLeaf.Unlink() + l.LinkableLeaf.Unlink() } else { hp.lock.Unlock() } } -func (l *nfsStatelessNativeLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { +func (l *nfsStatelessLinkableLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { setAttributesForFileHandle(l.fileHandle, requested, attributes) attributes.SetLinkCount(StatelessLeafLinkCount) } -func (l *nfsStatelessNativeLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { +func (l *nfsStatelessLinkableLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { if remaining := requested &^ (AttributesMaskFileHandle | AttributesMaskInodeNumber | AttributesMaskLinkCount); remaining != 0 { - l.NativeLeaf.VirtualGetAttributes(ctx, remaining, attributes) + l.LinkableLeaf.VirtualGetAttributes(ctx, remaining, attributes) } l.injectAttributes(requested, attributes) } -func (l *nfsStatelessNativeLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { +func (l *nfsStatelessLinkableLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) return StatusOK } -func (l *nfsStatelessNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { +func (l *nfsStatelessLinkableLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) return StatusOK } -// nfsResolvableNativeLeaf is a decorator for NativeLeaf that augments +// nfsResolvableLinkableLeaf is a decorator for LinkableLeaf that augments // the results of VirtualGetAttributes() to contain a file handle, inode // number and link count. For these kinds of files, the link count is // just a constant. -type nfsResolvableNativeLeaf struct { - NativeLeaf +type nfsResolvableLinkableLeaf struct { + LinkableLeaf fileHandle []byte } -func (l *nfsResolvableNativeLeaf) Link() Status { +func (l *nfsResolvableLinkableLeaf) Link() Status { return StatusOK } -func (l *nfsResolvableNativeLeaf) Unlink() {} +func (l *nfsResolvableLinkableLeaf) Unlink() {} -func (l *nfsResolvableNativeLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { +func (l *nfsResolvableLinkableLeaf) injectAttributes(requested AttributesMask, attributes *Attributes) { setAttributesForFileHandle(l.fileHandle, requested, attributes) attributes.SetLinkCount(StatelessLeafLinkCount) } -func (l *nfsResolvableNativeLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { +func (l *nfsResolvableLinkableLeaf) VirtualGetAttributes(ctx context.Context, requested AttributesMask, attributes *Attributes) { if remaining := requested &^ (AttributesMaskFileHandle | AttributesMaskInodeNumber | AttributesMaskLinkCount); remaining != 0 { - l.NativeLeaf.VirtualGetAttributes(ctx, remaining, attributes) + l.LinkableLeaf.VirtualGetAttributes(ctx, remaining, attributes) } l.injectAttributes(requested, attributes) } -func (l *nfsResolvableNativeLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { +func (l *nfsResolvableLinkableLeaf) VirtualSetAttributes(ctx context.Context, in *Attributes, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualSetAttributes(ctx, in, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) return StatusOK } -func (l *nfsResolvableNativeLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { - if s := l.NativeLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { +func (l *nfsResolvableLinkableLeaf) VirtualOpenSelf(ctx context.Context, shareAccess ShareMask, options *OpenExistingOptions, requested AttributesMask, attributes *Attributes) Status { + if s := l.LinkableLeaf.VirtualOpenSelf(ctx, shareAccess, options, requested, attributes); s != StatusOK { return s } l.injectAttributes(requested, attributes) diff --git a/pkg/filesystem/virtual/nfs_handle_allocator_test.go b/pkg/filesystem/virtual/nfs_handle_allocator_test.go index 97b1f23..b4a0cea 100644 --- a/pkg/filesystem/virtual/nfs_handle_allocator_test.go +++ b/pkg/filesystem/virtual/nfs_handle_allocator_test.go @@ -91,10 +91,10 @@ func TestNFSHandleAllocator(t *testing.T) { require.Equal(t, virtual.DirectoryChild{}.FromDirectory(wrappedDirectory), resolvedChild) }) - t.Run("StatefulNativeLeaf", func(t *testing.T) { + t.Run("StatefulLinkableLeaf", func(t *testing.T) { // Create a stateful file and wrap it. A file handle, link // count and inode number should be added. - baseLeaf := mock.NewMockNativeLeaf(ctrl) + baseLeaf := mock.NewMockLinkableLeaf(ctrl) baseLeaf.EXPECT().VirtualGetAttributes(ctx, virtual.AttributesMaskChangeID|virtual.AttributesMaskSizeBytes, gomock.Any()). Do(func(ctx context.Context, attributesMask virtual.AttributesMask, attributes *virtual.Attributes) { attributes.SetChangeID(7) @@ -102,7 +102,7 @@ func TestNFSHandleAllocator(t *testing.T) { }).AnyTimes() randomNumberGenerator.EXPECT().Uint64().Return(uint64(0xf999bb2fd22421d8)) - wrappedLeaf := handleAllocator.New().AsNativeLeaf(baseLeaf) + wrappedLeaf := handleAllocator.New().AsLinkableLeaf(baseLeaf) fileHandle := []byte{0xd8, 0x21, 0x24, 0xd2, 0x2f, 0xbb, 0x99, 0xf9} var attr1 virtual.Attributes @@ -177,7 +177,7 @@ func TestNFSHandleAllocator(t *testing.T) { &attr4) }) - t.Run("StatelessNativeLeaf", func(t *testing.T) { + t.Run("StatelessLinkableLeaf", func(t *testing.T) { // Create a stateless file and wrap it. A link count and // inode number should be added. As the file is // stateless, the reported link count uses a placeholder @@ -188,7 +188,7 @@ func TestNFSHandleAllocator(t *testing.T) { // The inode number of the leaf corresponds with the // FNV-1a hash of "Hello", using 0x6aae40a05f45b861 as // the offset basis. - baseLeaf := mock.NewMockNativeLeaf(ctrl) + baseLeaf := mock.NewMockLinkableLeaf(ctrl) baseLeaf.EXPECT().VirtualGetAttributes(ctx, virtual.AttributesMaskChangeID|virtual.AttributesMaskSizeBytes, gomock.Any()). Do(func(ctx context.Context, attributesMask virtual.AttributesMask, attributes *virtual.Attributes) { attributes.SetChangeID(0) @@ -200,7 +200,7 @@ func TestNFSHandleAllocator(t *testing.T) { New(). AsStatelessAllocator(). New(bytes.NewBuffer([]byte("Hello"))). - AsNativeLeaf(baseLeaf) + AsLinkableLeaf(baseLeaf) fileHandle := []byte{0x0f, 0x81, 0x5c, 0x1c, 0xc7, 0x04, 0xac, 0x2f} var attr1 virtual.Attributes diff --git a/pkg/filesystem/virtual/nfsv4/nfs40_program_test.go b/pkg/filesystem/virtual/nfsv4/nfs40_program_test.go index 51c60fa..bb82f81 100644 --- a/pkg/filesystem/virtual/nfsv4/nfs40_program_test.go +++ b/pkg/filesystem/virtual/nfsv4/nfs40_program_test.go @@ -6194,7 +6194,7 @@ func TestNFS40ProgramCompound_OP_SECINFO(t *testing.T) { }) t.Run("Success", func(t *testing.T) { - leaf := mock.NewMockNativeLeaf(ctrl) + leaf := mock.NewMockLinkableLeaf(ctrl) rootDirectory.EXPECT().VirtualLookup( gomock.Any(), path.MustNewComponent("Hello"), diff --git a/pkg/filesystem/virtual/pool_backed_file_allocator.go b/pkg/filesystem/virtual/pool_backed_file_allocator.go index 4a7827f..786e514 100644 --- a/pkg/filesystem/virtual/pool_backed_file_allocator.go +++ b/pkg/filesystem/virtual/pool_backed_file_allocator.go @@ -70,7 +70,7 @@ func NewPoolBackedFileAllocator(pool re_filesystem.FilePool, errorLogger util.Er } } -func (fa *poolBackedFileAllocator) NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (NativeLeaf, Status) { +func (fa *poolBackedFileAllocator) NewFile(isExecutable bool, size uint64, shareAccess ShareMask) (LinkableLeaf, Status) { file, err := fa.pool.NewFile() if err != nil { fa.errorLogger.Log(util.StatusWrapf(err, "Failed to create new file")) diff --git a/pkg/filesystem/virtual/prepopulated_directory.go b/pkg/filesystem/virtual/prepopulated_directory.go index 9e74f0c..df86619 100644 --- a/pkg/filesystem/virtual/prepopulated_directory.go +++ b/pkg/filesystem/virtual/prepopulated_directory.go @@ -34,16 +34,16 @@ type DirectoryPrepopulatedDirEntry struct { // LeafPrepopulatedDirEntry contains information about a leaf node that // is stored in a PrepopulatedDirectory. type LeafPrepopulatedDirEntry struct { - Child NativeLeaf + Child LinkableLeaf Name path.Component } // PrepopulatedDirectoryChild is either a PrepopulatedDirectory or a -// NativeLeaf, as returned by PrepopulatedDirectory.LookupChild(). -type PrepopulatedDirectoryChild = Child[PrepopulatedDirectory, NativeLeaf, Node] +// LinkableLeaf, as returned by PrepopulatedDirectory.LookupChild(). +type PrepopulatedDirectoryChild = Child[PrepopulatedDirectory, LinkableLeaf, Node] // PrepopulatedDirectory is a Directory that is writable and can contain -// files of type NativeLeaf. +// files of type LinkableLeaf. // // By making use of InitialContentsFetcher, it is possible to create // subdirectories that are prepopulated with files and directories. @@ -61,7 +61,7 @@ type PrepopulatedDirectory interface { // // TODO: Can't use PrepopulatedDirectoryChild in the return type // here, due to https://github.com/golang/go/issues/50259. - LookupChild(name path.Component) (Child[PrepopulatedDirectory, NativeLeaf, Node], error) + LookupChild(name path.Component) (Child[PrepopulatedDirectory, LinkableLeaf, Node], error) // LookupAllChildren() looks up all files and directories // contained in a PrepopulatedDirectory. This method is similar // to VirtualReadDir(), except that it returns the native types @@ -99,7 +99,7 @@ type PrepopulatedDirectory interface { // of FilePool. InstallHooks(fileAllocator FileAllocator, errorLogger util.ErrorLogger) // FilterChildren() can be used to traverse over all of the - // InitialContentsFetcher and NativeLeaf objects stored in this + // InitialContentsFetcher and LinkableLeaf objects stored in this // directory hierarchy. For each of the objects, a callback is // provided that can be used to remove the file or the contents // of the directory associated with this object. diff --git a/pkg/filesystem/virtual/resolvable_handle_allocating_cas_file_factory.go b/pkg/filesystem/virtual/resolvable_handle_allocating_cas_file_factory.go index f345850..a97f17b 100644 --- a/pkg/filesystem/virtual/resolvable_handle_allocating_cas_file_factory.go +++ b/pkg/filesystem/virtual/resolvable_handle_allocating_cas_file_factory.go @@ -30,7 +30,7 @@ func NewResolvableHandleAllocatingCASFileFactory(base CASFileFactory, allocation return cff } -func (cff *resolvableHandleAllocatingCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, fileReadMonitor FileReadMonitor) NativeLeaf { +func (cff *resolvableHandleAllocatingCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, fileReadMonitor FileReadMonitor) LinkableLeaf { if fileReadMonitor != nil { panic("Cannot monitor reads against CAS files with a resolvable handle, as the monitor would get lost across lookups") } @@ -45,7 +45,7 @@ func (cff *resolvableHandleAllocatingCASFileFactory) LookupFile(blobDigest diges return cff.resolve(blobDigest, r) }). New(bytes.NewBuffer(isExecutableField[:])). - AsNativeLeaf(cff.base.LookupFile(blobDigest, isExecutable, nil)) + AsLinkableLeaf(cff.base.LookupFile(blobDigest, isExecutable, nil)) } func (cff *resolvableHandleAllocatingCASFileFactory) resolve(blobDigest digest.Digest, remainder io.ByteReader) (DirectoryChild, Status) { diff --git a/pkg/filesystem/virtual/special_file.go b/pkg/filesystem/virtual/special_file.go index 62db1fb..ba359f3 100644 --- a/pkg/filesystem/virtual/special_file.go +++ b/pkg/filesystem/virtual/special_file.go @@ -19,7 +19,7 @@ type specialFile struct { // block device, FIFO or UNIX domain socket. Nodes of these types are // mere placeholders. The kernel is responsible for capturing calls to // open() and connect(). -func NewSpecialFile(fileType filesystem.FileType, deviceNumber *filesystem.DeviceNumber) NativeLeaf { +func NewSpecialFile(fileType filesystem.FileType, deviceNumber *filesystem.DeviceNumber) LinkableLeaf { return &specialFile{ fileType: fileType, deviceNumber: deviceNumber, diff --git a/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory.go b/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory.go index db7a50c..38b8a75 100644 --- a/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory.go +++ b/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory.go @@ -30,12 +30,12 @@ func NewStatelessHandleAllocatingCASFileFactory(base CASFileFactory, allocation return cff } -func (cff *statelessHandleAllocatingCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) NativeLeaf { +func (cff *statelessHandleAllocatingCASFileFactory) LookupFile(blobDigest digest.Digest, isExecutable bool, readMonitor FileReadMonitor) LinkableLeaf { leaf := cff.base.LookupFile(blobDigest, isExecutable, nil) if readMonitor != nil { - leaf = &readMonitoringNativeLeaf{ - NativeLeaf: leaf, - monitor: readMonitor, + leaf = &readMonitoringLinkableLeaf{ + LinkableLeaf: leaf, + monitor: readMonitor, } } return cff.allocator. @@ -43,7 +43,7 @@ func (cff *statelessHandleAllocatingCASFileFactory) LookupFile(blobDigest digest blobDigest: blobDigest, isExecutable: isExecutable, }). - AsNativeLeaf(leaf) + AsLinkableLeaf(leaf) } // casFileID is capable of converting the parameters that were used to @@ -67,20 +67,20 @@ func (id *casFileID) WriteTo(w io.Writer) (nTotal int64, err error) { return } -// readMonitoringNativeLeaf is a decorator for NativeLeaf that reports +// readMonitoringLinkableLeaf is a decorator for LinkableLeaf that reports // read operations against files to a FileReadMonitor. -type readMonitoringNativeLeaf struct { - NativeLeaf +type readMonitoringLinkableLeaf struct { + LinkableLeaf once sync.Once monitor FileReadMonitor } -func (l *readMonitoringNativeLeaf) reportRead() { +func (l *readMonitoringLinkableLeaf) reportRead() { l.monitor() l.monitor = nil } -func (l *readMonitoringNativeLeaf) VirtualRead(buf []byte, off uint64) (int, bool, Status) { +func (l *readMonitoringLinkableLeaf) VirtualRead(buf []byte, off uint64) (int, bool, Status) { l.once.Do(l.reportRead) - return l.NativeLeaf.VirtualRead(buf, off) + return l.LinkableLeaf.VirtualRead(buf, off) } diff --git a/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory_test.go b/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory_test.go index 94692de..f72302b 100644 --- a/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory_test.go +++ b/pkg/filesystem/virtual/stateless_handle_allocating_cas_file_factory_test.go @@ -25,13 +25,13 @@ func TestStatelessHandleAllocatingCASFileFactory(t *testing.T) { t.Run("NotExecutable", func(t *testing.T) { blobDigest := digest.MustNewDigest("hello", remoteexecution.DigestFunction_SHA256, "bc126902a442931481d7f89552a41b1891cf06dd8d3675062eede66d104d97b4", 123) - underlyingLeaf := mock.NewMockNativeLeaf(ctrl) + underlyingLeaf := mock.NewMockLinkableLeaf(ctrl) baseCASFileFactory.EXPECT().LookupFile( blobDigest, /* isExecutable = */ false, /* readMonitor = */ nil, ).Return(underlyingLeaf) - wrappedLeaf := mock.NewMockNativeLeaf(ctrl) + wrappedLeaf := mock.NewMockLinkableLeaf(ctrl) leafHandleAllocation := mock.NewMockStatelessHandleAllocation(ctrl) handleAllocator.EXPECT().New(gomock.Any()).DoAndReturn(func(id io.WriterTo) virtual.StatelessHandleAllocation { idBuf := bytes.NewBuffer(nil) @@ -47,20 +47,20 @@ func TestStatelessHandleAllocatingCASFileFactory(t *testing.T) { "\x00"), idBuf.Bytes()) return leafHandleAllocation }) - leafHandleAllocation.EXPECT().AsNativeLeaf(underlyingLeaf).Return(wrappedLeaf) + leafHandleAllocation.EXPECT().AsLinkableLeaf(underlyingLeaf).Return(wrappedLeaf) require.Equal(t, wrappedLeaf, casFileFactory.LookupFile(blobDigest, false, nil)) }) t.Run("Executable", func(t *testing.T) { blobDigest := digest.MustNewDigest("foobar", remoteexecution.DigestFunction_MD5, "c8a4ddfcd3a5a0caf4cc1d64883df421", 456) - underlyingLeaf := mock.NewMockNativeLeaf(ctrl) + underlyingLeaf := mock.NewMockLinkableLeaf(ctrl) baseCASFileFactory.EXPECT().LookupFile( blobDigest, /* isExecutable = */ true, /* readMonitor = */ nil, ).Return(underlyingLeaf) - wrappedLeaf := mock.NewMockNativeLeaf(ctrl) + wrappedLeaf := mock.NewMockLinkableLeaf(ctrl) leafHandleAllocation := mock.NewMockStatelessHandleAllocation(ctrl) handleAllocator.EXPECT().New(gomock.Any()).DoAndReturn(func(id io.WriterTo) virtual.StatelessHandleAllocation { idBuf := bytes.NewBuffer(nil) @@ -76,7 +76,7 @@ func TestStatelessHandleAllocatingCASFileFactory(t *testing.T) { "\x01"), idBuf.Bytes()) return leafHandleAllocation }) - leafHandleAllocation.EXPECT().AsNativeLeaf(underlyingLeaf).Return(wrappedLeaf) + leafHandleAllocation.EXPECT().AsLinkableLeaf(underlyingLeaf).Return(wrappedLeaf) require.Equal(t, wrappedLeaf, casFileFactory.LookupFile(blobDigest, true, nil)) }) @@ -87,13 +87,13 @@ func TestStatelessHandleAllocatingCASFileFactory(t *testing.T) { // twice: once to intercept VirtualRead() calls, and // once by the HandleAllocator. blobDigest := digest.MustNewDigest("foobar", remoteexecution.DigestFunction_MD5, "1234fc8071156282a346e0563ef92b6f", 123) - underlyingLeaf := mock.NewMockNativeLeaf(ctrl) + underlyingLeaf := mock.NewMockLinkableLeaf(ctrl) baseCASFileFactory.EXPECT().LookupFile( blobDigest, /* isExecutable = */ true, /* readMonitor = */ nil, ).Return(underlyingLeaf) - wrappedLeaf := mock.NewMockNativeLeaf(ctrl) + wrappedLeaf := mock.NewMockLinkableLeaf(ctrl) leafHandleAllocation := mock.NewMockStatelessHandleAllocation(ctrl) handleAllocator.EXPECT().New(gomock.Any()).DoAndReturn(func(id io.WriterTo) virtual.StatelessHandleAllocation { idBuf := bytes.NewBuffer(nil) @@ -109,8 +109,8 @@ func TestStatelessHandleAllocatingCASFileFactory(t *testing.T) { "\x01"), idBuf.Bytes()) return leafHandleAllocation }) - var monitoringLeaf virtual.NativeLeaf - leafHandleAllocation.EXPECT().AsNativeLeaf(gomock.Any()).DoAndReturn(func(leaf virtual.NativeLeaf) virtual.NativeLeaf { + var monitoringLeaf virtual.LinkableLeaf + leafHandleAllocation.EXPECT().AsLinkableLeaf(gomock.Any()).DoAndReturn(func(leaf virtual.LinkableLeaf) virtual.LinkableLeaf { monitoringLeaf = leaf return wrappedLeaf }) diff --git a/pkg/filesystem/virtual/symlink_factory.go b/pkg/filesystem/virtual/symlink_factory.go index c7673a4..54026d3 100644 --- a/pkg/filesystem/virtual/symlink_factory.go +++ b/pkg/filesystem/virtual/symlink_factory.go @@ -5,5 +5,5 @@ package virtual // replacing the node entirely (e.g., by first unlinking it from the // directory). type SymlinkFactory interface { - LookupSymlink(target []byte) NativeLeaf + LookupSymlink(target []byte) LinkableLeaf } diff --git a/pkg/filesystem/virtual/user_settable_symlink.go b/pkg/filesystem/virtual/user_settable_symlink.go index e1d69c8..3ec9d33 100644 --- a/pkg/filesystem/virtual/user_settable_symlink.go +++ b/pkg/filesystem/virtual/user_settable_symlink.go @@ -32,7 +32,7 @@ type UserSettableSymlink struct { } var ( - _ NativeLeaf = (*UserSettableSymlink)(nil) + _ LinkableLeaf = (*UserSettableSymlink)(nil) _ tmp_installer.TemporaryDirectoryInstallerServer = (*UserSettableSymlink)(nil) )