summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/mount.go
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2019-06-27 14:22:40 -0700
committergVisor bot <gvisor-bot@google.com>2019-06-27 14:24:03 -0700
commit085a907565921e84f59dfeb51da49af2d7c36c40 (patch)
treeaef4e9fef70d282291b8efeb5e675bd6085b22cc /pkg/sentry/fs/mount.go
parente2760839033618410cdea9aeab039e096cde54be (diff)
Cache directory entries in the overlay
Currently, the overlay dirCache is only used for a single logical use of getdents. i.e., it is discard when the FD is closed or seeked back to the beginning. But the initial work of getting the directory contents can be quite expensive (particularly sorting large directories), so we should keep it as long as possible. This is very similar to the readdirCache in fs/gofer. Since the upper filesystem does not have to allow caching readdir entries, the new CacheReaddir MountSourceOperations method controls this behavior. This caching should be trivially movable to all Inodes if desired, though that adds an additional copy step for non-overlay Inodes. (Overlay Inodes already do the extra copy). PiperOrigin-RevId: 255477592
Diffstat (limited to 'pkg/sentry/fs/mount.go')
-rw-r--r--pkg/sentry/fs/mount.go42
1 files changed, 29 insertions, 13 deletions
diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go
index 2eb6a9d82..912495528 100644
--- a/pkg/sentry/fs/mount.go
+++ b/pkg/sentry/fs/mount.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/context"
)
-// DirentOperations provide file systems greater control over how long a Dirent stays pinned
-// in core. Implementations must not take Dirent.mu.
+// DirentOperations provide file systems greater control over how long a Dirent
+// stays pinned in core. Implementations must not take Dirent.mu.
type DirentOperations interface {
// Revalidate is called during lookup each time we encounter a Dirent
// in the cache. Implementations may update stale properties of the
@@ -37,6 +37,12 @@ type DirentOperations interface {
// Keep returns true if the Dirent should be kept in memory for as long
// as possible beyond any active references.
Keep(dirent *Dirent) bool
+
+ // CacheReaddir returns true if directory entries returned by
+ // FileOperations.Readdir may be cached for future use.
+ //
+ // Postconditions: This method must always return the same value.
+ CacheReaddir() bool
}
// MountSourceOperations contains filesystem specific operations.
@@ -190,25 +196,28 @@ func (msrc *MountSource) SetDirentCacheLimiter(l *DirentCacheLimiter) {
// aggressively.
func NewCachingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource {
return NewMountSource(ctx, &SimpleMountSourceOperations{
- keep: true,
- revalidate: false,
+ keep: true,
+ revalidate: false,
+ cacheReaddir: true,
}, filesystem, flags)
}
// NewNonCachingMountSource returns a generic mount that will never cache dirents.
func NewNonCachingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource {
return NewMountSource(ctx, &SimpleMountSourceOperations{
- keep: false,
- revalidate: false,
+ keep: false,
+ revalidate: false,
+ cacheReaddir: false,
}, filesystem, flags)
}
// NewRevalidatingMountSource returns a generic mount that will cache dirents,
-// but will revalidate them on each lookup.
+// but will revalidate them on each lookup and always perform uncached readdir.
func NewRevalidatingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource {
return NewMountSource(ctx, &SimpleMountSourceOperations{
- keep: true,
- revalidate: true,
+ keep: true,
+ revalidate: true,
+ cacheReaddir: false,
}, filesystem, flags)
}
@@ -216,8 +225,9 @@ func NewRevalidatingMountSource(ctx context.Context, filesystem Filesystem, flag
// an actual filesystem. It is always non-caching.
func NewPseudoMountSource(ctx context.Context) *MountSource {
return NewMountSource(ctx, &SimpleMountSourceOperations{
- keep: false,
- revalidate: false,
+ keep: false,
+ revalidate: false,
+ cacheReaddir: false,
}, nil, MountSourceFlags{})
}
@@ -225,8 +235,9 @@ func NewPseudoMountSource(ctx context.Context) *MountSource {
//
// +stateify savable
type SimpleMountSourceOperations struct {
- keep bool
- revalidate bool
+ keep bool
+ revalidate bool
+ cacheReaddir bool
}
// Revalidate implements MountSourceOperations.Revalidate.
@@ -239,6 +250,11 @@ func (smo *SimpleMountSourceOperations) Keep(*Dirent) bool {
return smo.keep
}
+// CacheReaddir implements MountSourceOperations.CacheReaddir.
+func (smo *SimpleMountSourceOperations) CacheReaddir() bool {
+ return smo.cacheReaddir
+}
+
// ResetInodeMappings implements MountSourceOperations.ResetInodeMappings.
func (*SimpleMountSourceOperations) ResetInodeMappings() {}