summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/mount_overlay.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-08-27 14:25:21 -0700
committerShentubot <shentubot@google.com>2018-08-27 14:26:29 -0700
commit0b3bfe2ea30d491a6533f8ee74eb6e3cea707f06 (patch)
tree1be36b37d8d3f6d47fed0f17af901311eb51bb90 /pkg/sentry/fs/mount_overlay.go
parent5999767d53d6c00d7e0f1966700e2876879f490e (diff)
fs: Fix remote-revalidate cache policy.
When revalidating a Dirent, if the inode id is the same, then we don't need to throw away the entire Dirent. We can just update the unstable attributes in place. If the inode id has changed, then the remote file has been deleted or moved, and we have no choice but to throw away the dirent we have a look up another. In this case, we may still end up losing a mounted dirent that is a child of the revalidated dirent. However, that seems appropriate here because the entire mount point has been pulled out from underneath us. Because gVisor's overlay is at the Inode level rather than the Dirent level, we must pass the parent Inode and name along with the Inode that is being revalidated. PiperOrigin-RevId: 210431270 Change-Id: I705caef9c68900234972d5aac4ae3a78c61c7d42
Diffstat (limited to 'pkg/sentry/fs/mount_overlay.go')
-rw-r--r--pkg/sentry/fs/mount_overlay.go20
1 files changed, 13 insertions, 7 deletions
diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go
index 9fa87c10f..dbc608c7e 100644
--- a/pkg/sentry/fs/mount_overlay.go
+++ b/pkg/sentry/fs/mount_overlay.go
@@ -41,23 +41,29 @@ func newOverlayMountSource(upper, lower *MountSource, flags MountSourceFlags) *M
// 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 {
+func (o *overlayMountSourceOperations) Revalidate(ctx context.Context, name string, parent, child *Inode) bool {
+ if child.overlay == nil {
panic("overlay cannot revalidate inode that is not an overlay")
}
- // Should we bother checking this, or just ignore?
- if inode.overlay.lower != nil && o.lower.Revalidate(ctx, inode.overlay.lower) {
+ // Revalidate is never called on a mount point, so parent and child
+ // must be from the same mount, and thus must both be overlay inodes.
+ if parent.overlay == nil {
+ panic("trying to revalidate an overlay inode but the parent is not an overlay")
+ }
+
+ // We can't revalidate from the lower filesystem.
+ if child.overlay.lower != nil && o.lower.Revalidate(ctx, name, parent.overlay.lower, child.overlay.lower) {
panic("an overlay cannot revalidate file objects from the lower fs")
}
- if inode.overlay.upper == nil {
- // Nothing to revalidate.
+ // Do we have anything to revalidate?
+ if child.overlay.upper == nil {
return false
}
// Does the upper require revalidation?
- return o.upper.Revalidate(ctx, inode.overlay.upper)
+ return o.upper.Revalidate(ctx, name, parent.overlay.upper, child.overlay.upper)
}
// Keep implements MountSourceOperations by delegating to the upper