diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-08-10 17:15:27 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-08-10 17:16:38 -0700 |
commit | a2ec391dfbc5a03077b73078777a9347c372dece (patch) | |
tree | 037d59bfbb29c2bb4bee25678060be65139e8bb7 /pkg/sentry/fs/mount_overlay.go | |
parent | ae6f092fe117a738df34e072ef5ba01a41c89222 (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.go | 39 |
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. |