summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/overlay.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs/overlay.go')
-rw-r--r--pkg/sentry/fs/overlay.go36
1 files changed, 27 insertions, 9 deletions
diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go
index db89a5f70..1d3ff39e0 100644
--- a/pkg/sentry/fs/overlay.go
+++ b/pkg/sentry/fs/overlay.go
@@ -19,11 +19,12 @@ import (
"strings"
"sync"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/pkg/sentry/context"
- "gvisor.googlesource.com/gvisor/pkg/sentry/memmap"
- "gvisor.googlesource.com/gvisor/pkg/sentry/usermem"
- "gvisor.googlesource.com/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/sentry/memmap"
+ "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/third_party/gvsync"
)
// The virtual filesystem implements an overlay configuration. For a high-level
@@ -104,7 +105,7 @@ func NewOverlayRoot(ctx context.Context, upper *Inode, lower *Inode, flags Mount
return nil, fmt.Errorf("cannot nest overlay in upper file of another overlay")
}
- msrc := newOverlayMountSource(upper.MountSource, lower.MountSource, flags)
+ msrc := newOverlayMountSource(ctx, upper.MountSource, lower.MountSource, flags)
overlay, err := newOverlayEntry(ctx, upper, lower, true)
if err != nil {
msrc.DecRef()
@@ -127,7 +128,7 @@ func NewOverlayRootFile(ctx context.Context, upperMS *MountSource, lower *Inode,
if !IsRegular(lower.StableAttr) {
return nil, fmt.Errorf("lower Inode is not a regular file")
}
- msrc := newOverlayMountSource(upperMS, lower.MountSource, flags)
+ msrc := newOverlayMountSource(ctx, upperMS, lower.MountSource, flags)
overlay, err := newOverlayEntry(ctx, nil, lower, true)
if err != nil {
msrc.DecRef()
@@ -140,9 +141,9 @@ func NewOverlayRootFile(ctx context.Context, upperMS *MountSource, lower *Inode,
func newOverlayInode(ctx context.Context, o *overlayEntry, msrc *MountSource) *Inode {
var inode *Inode
if o.upper != nil {
- inode = NewInode(nil, msrc, o.upper.StableAttr)
+ inode = NewInode(ctx, nil, msrc, o.upper.StableAttr)
} else {
- inode = NewInode(nil, msrc, o.lower.StableAttr)
+ inode = NewInode(ctx, nil, msrc, o.lower.StableAttr)
}
inode.overlay = o
return inode
@@ -196,6 +197,12 @@ type overlayEntry struct {
// these locks is sufficient to read upper; holding all three for writing
// is required to mutate it.
upper *Inode
+
+ // dirCacheMu protects dirCache.
+ dirCacheMu gvsync.DowngradableRWMutex `state:"nosave"`
+
+ // dirCache is cache of DentAttrs from upper and lower Inodes.
+ dirCache *SortedDentryMap
}
// newOverlayEntry returns a new overlayEntry.
@@ -258,6 +265,17 @@ func (o *overlayEntry) isMappableLocked() bool {
return o.inodeLocked().Mappable() != nil
}
+// markDirectoryDirty marks any cached data dirty for this directory. This is
+// necessary in order to ensure that this node does not retain stale state
+// throughout its lifetime across multiple open directory handles.
+//
+// Currently this means invalidating any readdir caches.
+func (o *overlayEntry) markDirectoryDirty() {
+ o.dirCacheMu.Lock()
+ o.dirCache = nil
+ o.dirCacheMu.Unlock()
+}
+
// AddMapping implements memmap.Mappable.AddMapping.
func (o *overlayEntry) AddMapping(ctx context.Context, ms memmap.MappingSpace, ar usermem.AddrRange, offset uint64, writable bool) error {
o.mapsMu.Lock()