diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-06-19 11:09:20 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-06-19 11:10:11 -0700 |
commit | 9db7cfad93abff181c59d61892d32b9b05f4234f (patch) | |
tree | 51e3f4b6fa836a52f317dca62e01bf13143c8c05 /pkg/sentry/fs/gofer/file.go | |
parent | 5581256f879f4249de5ebffddaf0626fcb39eebd (diff) |
Add a new cache policy FSCACHE_WRITETHROUGH.
The new policy is identical to FSCACHE (which caches everything in memory), but
it also flushes writes to the backing fs agent immediately.
All gofer cache policy decisions have been moved into the cachePolicy type.
Previously they were sprinkled around the codebase.
There are many different things that we cache (page cache, negative dirents,
dirent LRU, unstable attrs, readdir results....), and I don't think we should
have individual flags to control each of these. Instead, we should have a few
high-level cache policies that are consistent and useful to users. This
refactoring makes it easy to add more such policies.
PiperOrigin-RevId: 201206937
Change-Id: I6e225c382b2e5e1b0ad4ccf8ca229873f4cd389d
Diffstat (limited to 'pkg/sentry/fs/gofer/file.go')
-rw-r--r-- | pkg/sentry/fs/gofer/file.go | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 07c9bf01d..69cee7026 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -93,7 +93,7 @@ func (f *fileOperations) Readdir(ctx context.Context, file *fs.File, serializer DirCursor: &f.dirCursor, } n, err := fs.DirentReaddir(ctx, file.Dirent, f, root, dirCtx, file.Offset()) - if f.inodeOperations.session().cachePolicy != cacheNone { + if f.inodeOperations.session().cachePolicy.cacheUAttrs(file.Dirent.Inode) { f.inodeOperations.cachingInodeOps.TouchAccessTime(ctx, file.Dirent.Inode) } return n, err @@ -105,7 +105,7 @@ func (f *fileOperations) IterateDir(ctx context.Context, dirCtx *fs.DirCtx, offs defer f.inodeOperations.readdirMu.Unlock() // Fetch directory entries if needed. - if f.inodeOperations.readdirCache == nil || f.inodeOperations.session().cachePolicy == cacheNone { + if !f.inodeOperations.session().cachePolicy.cacheReaddir() || f.inodeOperations.readdirCache == nil { entries, err := f.readdirAll(ctx) if err != nil { return offset, err @@ -183,13 +183,20 @@ func (f *fileOperations) Write(ctx context.Context, file *fs.File, src usermem.I // Not all remote file systems enforce this so this client does. return 0, syserror.EISDIR } + cp := f.inodeOperations.session().cachePolicy + if cp.usePageCache(file.Dirent.Inode) { + n, err := f.inodeOperations.cachingInodeOps.Write(ctx, src, offset) + if err != nil { + return n, err + } + if cp.writeThrough(file.Dirent.Inode) { + // Write out the file. + err = f.inodeOperations.cachingInodeOps.WriteOut(ctx, file.Dirent.Inode) + } + return n, err - // Do cached IO for regular files only. Some character devices expect no caching. - isFile := fs.IsFile(file.Dirent.Inode.StableAttr) - if f.inodeOperations.session().cachePolicy == cacheNone || !isFile { - return src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset)) } - return f.inodeOperations.cachingInodeOps.Write(ctx, src, offset) + return src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset)) } // Read implements fs.FileOperations.Read. @@ -199,12 +206,10 @@ func (f *fileOperations) Read(ctx context.Context, file *fs.File, dst usermem.IO return 0, syserror.EISDIR } - // Do cached IO for regular files only. Some character devices expect no caching. - isFile := fs.IsFile(file.Dirent.Inode.StableAttr) - if f.inodeOperations.session().cachePolicy == cacheNone || !isFile { - return dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset)) + if f.inodeOperations.session().cachePolicy.usePageCache(file.Dirent.Inode) { + return f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset) } - return f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset) + return dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset)) } // Fsync implements fs.FileOperations.Fsync. @@ -243,7 +248,7 @@ func (f *fileOperations) Flush(ctx context.Context, file *fs.File) error { // ConfigureMMap implements fs.FileOperations.ConfigureMMap. func (f *fileOperations) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.MMapOpts) error { - if !isFileCachable(f.inodeOperations.session(), file.Dirent.Inode) { + if !f.inodeOperations.session().cachePolicy.usePageCache(file.Dirent.Inode) { return syserror.ENODEV } return fsutil.GenericConfigureMMap(file, f.inodeOperations.cachingInodeOps, opts) |