summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/mount_overlay.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-08-10 17:15:27 -0700
committerShentubot <shentubot@google.com>2018-08-10 17:16:38 -0700
commita2ec391dfbc5a03077b73078777a9347c372dece (patch)
tree037d59bfbb29c2bb4bee25678060be65139e8bb7 /pkg/sentry/fs/mount_overlay.go
parentae6f092fe117a738df34e072ef5ba01a41c89222 (diff)
fs: Allow overlays to revalidate files from the upper fs.
Previously, an overlay would panic if either the upper or lower fs required revalidation for a given Dirent. Now, we allow revalidation from the upper file, but not the lower. If a cached overlay inode does need revalidation (because the upper needs revalidation), then the entire overlay Inode will be discarded and a new overlay Inode will be built with a fresh copy of the upper file. As a side effect of this change, Revalidate must take an Inode instead of a Dirent, since an overlay needs to revalidate individual Inodes. PiperOrigin-RevId: 208293638 Change-Id: Ic8f8d1ffdc09114721745661a09522b54420c5f1
Diffstat (limited to 'pkg/sentry/fs/mount_overlay.go')
-rw-r--r--pkg/sentry/fs/mount_overlay.go39
1 files changed, 28 insertions, 11 deletions
diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go
index d135e8a37..9fa87c10f 100644
--- a/pkg/sentry/fs/mount_overlay.go
+++ b/pkg/sentry/fs/mount_overlay.go
@@ -14,10 +14,13 @@
package fs
-import "gvisor.googlesource.com/gvisor/pkg/sentry/context"
+import (
+ "gvisor.googlesource.com/gvisor/pkg/sentry/context"
+)
// overlayMountSourceOperations implements MountSourceOperations for an overlay
-// mount point.
+// mount point. The upper filesystem determines the caching behavior of the
+// overlay.
//
// +stateify savable
type overlayMountSourceOperations struct {
@@ -34,19 +37,33 @@ func newOverlayMountSource(upper, lower *MountSource, flags MountSourceFlags) *M
}, &overlayFilesystem{}, flags)
}
-// Revalidate panics if the upper or lower MountSource require that dirent be
-// revalidated. Otherwise always returns false.
-func (o *overlayMountSourceOperations) Revalidate(ctx context.Context, dirent *Dirent) bool {
- if o.upper.Revalidate(ctx, dirent) || o.lower.Revalidate(ctx, dirent) {
- panic("an overlay cannot revalidate file objects")
+// Revalidate implements MountSourceOperations.Revalidate for an overlay by
+// delegating to the upper filesystem's Revalidate method. We cannot reload
+// files from the lower filesystem, so we panic if the lower filesystem's
+// Revalidate method returns true.
+func (o *overlayMountSourceOperations) Revalidate(ctx context.Context, inode *Inode) bool {
+ if inode.overlay == nil {
+ panic("overlay cannot revalidate inode that is not an overlay")
}
- return false
+
+ // Should we bother checking this, or just ignore?
+ if inode.overlay.lower != nil && o.lower.Revalidate(ctx, inode.overlay.lower) {
+ panic("an overlay cannot revalidate file objects from the lower fs")
+ }
+
+ if inode.overlay.upper == nil {
+ // Nothing to revalidate.
+ return false
+ }
+
+ // Does the upper require revalidation?
+ return o.upper.Revalidate(ctx, inode.overlay.upper)
}
-// Keep returns true if either upper or lower MountSource require that the
-// dirent be kept in memory.
+// Keep implements MountSourceOperations by delegating to the upper
+// filesystem's Keep method.
func (o *overlayMountSourceOperations) Keep(dirent *Dirent) bool {
- return o.upper.Keep(dirent) || o.lower.Keep(dirent)
+ return o.upper.Keep(dirent)
}
// ResetInodeMappings propagates the call to both upper and lower MountSource.