summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-08-28 15:08:15 -0700
committerShentubot <shentubot@google.com>2018-08-28 15:09:17 -0700
commit515d9bf43b358cf7645d34dccdcc299f43dd8d74 (patch)
tree800c2b4860b4c76cdb311a874840bf0ae9613828 /pkg/sentry
parentd724863a313f5e08a043c8f2ccb4969e8ea23de1 (diff)
fs: Add tests for dirent ref counting with an overlay.
PiperOrigin-RevId: 210614669 Change-Id: I408365ff6d6c7765ed7b789446d30e7079cbfc67
Diffstat (limited to 'pkg/sentry')
-rw-r--r--pkg/sentry/fs/inode_overlay_test.go70
-rw-r--r--pkg/sentry/fs/mounts.go4
2 files changed, 72 insertions, 2 deletions
diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go
index a7be9d040..3ee4c9667 100644
--- a/pkg/sentry/fs/inode_overlay_test.go
+++ b/pkg/sentry/fs/inode_overlay_test.go
@@ -299,6 +299,76 @@ func TestLookupRevalidation(t *testing.T) {
}
}
+func TestCacheFlush(t *testing.T) {
+ ctx := contexttest.Context(t)
+
+ // Upper and lower each have a file.
+ upperFileName := "file-from-upper"
+ lowerFileName := "file-from-lower"
+ upper := newTestRamfsDir(ctx, []dirContent{{name: upperFileName}}, nil)
+ lower := newTestRamfsDir(ctx, []dirContent{{name: lowerFileName}}, nil)
+
+ overlay := fs.NewTestOverlayDir(ctx, upper, lower, true /* revalidate */)
+
+ mns, err := fs.NewMountNamespace(ctx, overlay)
+ if err != nil {
+ t.Fatalf("NewMountNamespace failed: %v", err)
+ }
+ root := mns.Root()
+ defer root.DecRef()
+
+ ctx = &rootContext{
+ Context: ctx,
+ root: root,
+ }
+
+ for _, fileName := range []string{upperFileName, lowerFileName} {
+ // Walk to the file.
+ dirent, err := mns.FindInode(ctx, root, nil, fileName, 0)
+ if err != nil {
+ t.Fatalf("FindInode(%q) failed: %v", fileName, err)
+ }
+
+ // Get a file from the dirent.
+ file, err := dirent.Inode.GetFile(ctx, dirent, fs.FileFlags{Read: true})
+ if err != nil {
+ t.Fatalf("GetFile() failed: %v", err)
+ }
+
+ // The dirent should have 3 refs, one from us, one from the
+ // file, and one from the dirent cache.
+ // dirent cache.
+ if got, want := dirent.ReadRefs(), 3; int(got) != want {
+ t.Errorf("dirent.ReadRefs() got %d want %d", got, want)
+ }
+
+ // Drop the file reference.
+ file.DecRef()
+
+ // Dirent should have 2 refs left.
+ if got, want := dirent.ReadRefs(), 2; int(got) != want {
+ t.Errorf("dirent.ReadRefs() got %d want %d", got, want)
+ }
+
+ // Flush the dirent cache.
+ mns.FlushMountSourceRefs()
+
+ // Dirent should have 1 ref left from the dirent cache.
+ if got, want := dirent.ReadRefs(), 1; int(got) != want {
+ t.Errorf("dirent.ReadRefs() got %d want %d", got, want)
+ }
+
+ // Drop our ref.
+ dirent.DecRef()
+
+ // We should be back to zero refs.
+ if got, want := dirent.ReadRefs(), 0; int(got) != want {
+ t.Errorf("dirent.ReadRefs() got %d want %d", got, want)
+ }
+ }
+
+}
+
type dir struct {
fs.InodeOperations
diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go
index 144d3427d..0318f135d 100644
--- a/pkg/sentry/fs/mounts.go
+++ b/pkg/sentry/fs/mounts.go
@@ -348,10 +348,10 @@ func (mns *MountNamespace) Unmount(ctx context.Context, node *Dirent, detachOnly
// Precondition: the path must be non-empty.
func (mns *MountNamespace) FindLink(ctx context.Context, root, wd *Dirent, path string, maxTraversals uint) (*Dirent, error) {
if root == nil {
- panic("MountNamespace.FindInode: root must not be nil")
+ panic("MountNamespace.FindLink: root must not be nil")
}
if len(path) == 0 {
- panic("MountNamespace.FindInode: path is empty")
+ panic("MountNamespace.FindLink: path is empty")
}
// Split the path.