summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/gofer
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs/gofer')
-rw-r--r--pkg/sentry/fs/gofer/file.go43
1 files changed, 31 insertions, 12 deletions
diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go
index 7a6dabba8..631cc80ae 100644
--- a/pkg/sentry/fs/gofer/file.go
+++ b/pkg/sentry/fs/gofer/file.go
@@ -17,6 +17,7 @@ package gofer
import (
"fmt"
"syscall"
+ "time"
"gvisor.googlesource.com/gvisor/pkg/log"
"gvisor.googlesource.com/gvisor/pkg/metric"
@@ -32,11 +33,13 @@ import (
)
var (
- opensWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.")
- opens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a 9P file was opened from a gofer.")
- opensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a host file was opened from a gofer.")
- reads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.")
- readsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.")
+ opensWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.")
+ opens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a 9P file was opened from a gofer.")
+ opensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a host file was opened from a gofer.")
+ reads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.")
+ readWait9P = metric.MustCreateNewUint64Metric("/gofer/read_wait_9p", false /* sync */, "Time waiting on 9P file reads from a gofer, in nanoseconds.")
+ readsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.")
+ readWaitHost = metric.MustCreateNewUint64Metric("/gofer/read_wait_host", false /* sync */, "Time waiting on host file reads from a gofer, in nanoseconds.")
)
// fileOperations implements fs.FileOperations for a remote file system.
@@ -232,22 +235,38 @@ func (f *fileOperations) Write(ctx context.Context, file *fs.File, src usermem.I
return src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset))
}
+// incrementReadCounters increments the read counters for the read starting at the given time. We
+// use this function rather than using a defer in Read() to avoid the performance hit of defer.
+func (f *fileOperations) incrementReadCounters(start time.Time) {
+ if f.handles.Host != nil {
+ readsHost.Increment()
+ fs.IncrementWait(readWaitHost, start)
+ } else {
+ reads9P.Increment()
+ fs.IncrementWait(readWait9P, start)
+ }
+}
+
// Read implements fs.FileOperations.Read.
func (f *fileOperations) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) {
+ var start time.Time
+ if fs.RecordWaitTime {
+ start = time.Now()
+ }
if fs.IsDir(file.Dirent.Inode.StableAttr) {
// Not all remote file systems enforce this so this client does.
+ f.incrementReadCounters(start)
return 0, syserror.EISDIR
}
- if f.handles.Host != nil {
- readsHost.Increment()
- } else {
- reads9P.Increment()
- }
if f.inodeOperations.session().cachePolicy.useCachingInodeOps(file.Dirent.Inode) {
- return f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset)
+ n, err := f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset)
+ f.incrementReadCounters(start)
+ return n, err
}
- return dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset))
+ n, err := dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset))
+ f.incrementReadCounters(start)
+ return n, err
}
// Fsync implements fs.FileOperations.Fsync.