summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/inode_overlay.go
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2019-06-27 14:22:40 -0700
committergVisor bot <gvisor-bot@google.com>2019-06-27 14:24:03 -0700
commit085a907565921e84f59dfeb51da49af2d7c36c40 (patch)
treeaef4e9fef70d282291b8efeb5e675bd6085b22cc /pkg/sentry/fs/inode_overlay.go
parente2760839033618410cdea9aeab039e096cde54be (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/inode_overlay.go')
-rw-r--r--pkg/sentry/fs/inode_overlay.go38
1 files changed, 34 insertions, 4 deletions
diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go
index 920d86042..b247fa514 100644
--- a/pkg/sentry/fs/inode_overlay.go
+++ b/pkg/sentry/fs/inode_overlay.go
@@ -217,6 +217,9 @@ func overlayCreate(ctx context.Context, o *overlayEntry, parent *Dirent, name st
return nil, err
}
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+
// Take another reference on the upper file's inode, which will be
// owned by the overlay entry.
upperFile.Dirent.Inode.IncRef()
@@ -265,7 +268,12 @@ func overlayCreateDirectory(ctx context.Context, o *overlayEntry, parent *Dirent
if err := copyUpLockedForRename(ctx, parent); err != nil {
return err
}
- return o.upper.InodeOperations.CreateDirectory(ctx, o.upper, name, perm)
+ if err := o.upper.InodeOperations.CreateDirectory(ctx, o.upper, name, perm); err != nil {
+ return err
+ }
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+ return nil
}
func overlayCreateLink(ctx context.Context, o *overlayEntry, parent *Dirent, oldname string, newname string) error {
@@ -273,7 +281,12 @@ func overlayCreateLink(ctx context.Context, o *overlayEntry, parent *Dirent, old
if err := copyUpLockedForRename(ctx, parent); err != nil {
return err
}
- return o.upper.InodeOperations.CreateLink(ctx, o.upper, oldname, newname)
+ if err := o.upper.InodeOperations.CreateLink(ctx, o.upper, oldname, newname); err != nil {
+ return err
+ }
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+ return nil
}
func overlayCreateHardLink(ctx context.Context, o *overlayEntry, parent *Dirent, target *Dirent, name string) error {
@@ -285,7 +298,12 @@ func overlayCreateHardLink(ctx context.Context, o *overlayEntry, parent *Dirent,
if err := copyUpLockedForRename(ctx, target); err != nil {
return err
}
- return o.upper.InodeOperations.CreateHardLink(ctx, o.upper, target.Inode.overlay.upper, name)
+ if err := o.upper.InodeOperations.CreateHardLink(ctx, o.upper, target.Inode.overlay.upper, name); err != nil {
+ return err
+ }
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+ return nil
}
func overlayCreateFifo(ctx context.Context, o *overlayEntry, parent *Dirent, name string, perm FilePermissions) error {
@@ -293,7 +311,12 @@ func overlayCreateFifo(ctx context.Context, o *overlayEntry, parent *Dirent, nam
if err := copyUpLockedForRename(ctx, parent); err != nil {
return err
}
- return o.upper.InodeOperations.CreateFifo(ctx, o.upper, name, perm)
+ if err := o.upper.InodeOperations.CreateFifo(ctx, o.upper, name, perm); err != nil {
+ return err
+ }
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+ return nil
}
func overlayRemove(ctx context.Context, o *overlayEntry, parent *Dirent, child *Dirent) error {
@@ -318,6 +341,8 @@ func overlayRemove(ctx context.Context, o *overlayEntry, parent *Dirent, child *
if child.Inode.overlay.lowerExists {
return overlayCreateWhiteout(o.upper, child.name)
}
+ // We've removed from the directory so we must drop the cache.
+ o.markDirectoryDirty()
return nil
}
@@ -395,6 +420,8 @@ func overlayRename(ctx context.Context, o *overlayEntry, oldParent *Dirent, rena
if renamed.Inode.overlay.lowerExists {
return overlayCreateWhiteout(oldParent.Inode.overlay.upper, oldName)
}
+ // We've changed the directory so we must drop the cache.
+ o.markDirectoryDirty()
return nil
}
@@ -411,6 +438,9 @@ func overlayBind(ctx context.Context, o *overlayEntry, parent *Dirent, name stri
return nil, err
}
+ // We've added to the directory so we must drop the cache.
+ o.markDirectoryDirty()
+
// Grab the inode and drop the dirent, we don't need it.
inode := d.Inode
inode.IncRef()