diff options
author | Michael Pratt <mpratt@google.com> | 2019-06-27 14:22:40 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-06-27 14:24:03 -0700 |
commit | 085a907565921e84f59dfeb51da49af2d7c36c40 (patch) | |
tree | aef4e9fef70d282291b8efeb5e675bd6085b22cc /pkg/sentry/fs/mount.go | |
parent | e2760839033618410cdea9aeab039e096cde54be (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.go | 42 |
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() {} |