summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/file_overlay.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-09-18 15:41:13 -0700
committerShentubot <shentubot@google.com>2018-09-18 15:42:22 -0700
commitfd222d62eda8b447fa0e11260f64fdb94e5e7084 (patch)
tree9d5522fd1ef87dfbe974c04cc18977f5619dbdd6 /pkg/sentry/fs/file_overlay.go
parent7967d8ecd57383f406d202f7e2f65e275bb36fc8 (diff)
Short-circuit Readdir calls on overlay files when the dirent is frozen.
If we have an overlay file whose corresponding Dirent is frozen, then we should not bother calling Readdir on the upper or lower files, since DirentReaddir will calculate children based on the frozen Dirent tree. A test was added that fails without this change. PiperOrigin-RevId: 213531215 Change-Id: I4d6c98f1416541a476a34418f664ba58f936a81d
Diffstat (limited to 'pkg/sentry/fs/file_overlay.go')
-rw-r--r--pkg/sentry/fs/file_overlay.go22
1 files changed, 15 insertions, 7 deletions
diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go
index 113962368..41e646ee8 100644
--- a/pkg/sentry/fs/file_overlay.go
+++ b/pkg/sentry/fs/file_overlay.go
@@ -163,6 +163,21 @@ func (f *overlayFileOperations) Seek(ctx context.Context, file *File, whence See
// Readdir implements FileOperations.Readdir.
func (f *overlayFileOperations) Readdir(ctx context.Context, file *File, serializer DentrySerializer) (int64, error) {
+ root := RootFromContext(ctx)
+ defer root.DecRef()
+ dirCtx := &DirCtx{
+ Serializer: serializer,
+ DirCursor: &f.dirCursor,
+ }
+
+ // If the directory dirent is frozen, then DirentReaddir will calculate
+ // the children based off the frozen dirent tree. There is no need to
+ // call readdir on the upper/lower layers.
+ if file.Dirent.frozen {
+ return DirentReaddir(ctx, file.Dirent, f, root, dirCtx, file.Offset())
+ }
+
+ // Otherwise proceed with usual overlay readdir.
o := file.Dirent.Inode.overlay
o.copyMu.RLock()
@@ -174,13 +189,6 @@ func (f *overlayFileOperations) Readdir(ctx context.Context, file *File, seriali
return file.Offset(), err
}
- root := RootFromContext(ctx)
- defer root.DecRef()
-
- dirCtx := &DirCtx{
- Serializer: serializer,
- DirCursor: &f.dirCursor,
- }
return DirentReaddir(ctx, file.Dirent, f, root, dirCtx, file.Offset())
}