summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/gofer/handle.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2021-08-19 17:08:02 -0700
committergVisor bot <gvisor-bot@google.com>2021-08-19 17:10:46 -0700
commita77eaf2a9e0539326defc766d748b8eff1d89b0b (patch)
treea551af27c5ea3b702774f76ea66074b471568497 /pkg/sentry/fsimpl/gofer/handle.go
parent3b4bb947517d0d9010120aaa1c3989fd6abf278e (diff)
Use MM-mapped I/O instead of buffered copies in gofer.specialFileFD.
The rationale given for using buffered copies is still valid, but it's unclear whether holding MM locks or allocating buffers is better in practice, and the former is at least consistent with gofer.regularFileFD (and VFS1), making performance easier to reason about. PiperOrigin-RevId: 391877913
Diffstat (limited to 'pkg/sentry/fsimpl/gofer/handle.go')
-rw-r--r--pkg/sentry/fsimpl/gofer/handle.go41
1 files changed, 41 insertions, 0 deletions
diff --git a/pkg/sentry/fsimpl/gofer/handle.go b/pkg/sentry/fsimpl/gofer/handle.go
index 5c57f6fea..02540a754 100644
--- a/pkg/sentry/fsimpl/gofer/handle.go
+++ b/pkg/sentry/fsimpl/gofer/handle.go
@@ -20,6 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/p9"
"gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/hostfd"
+ "gvisor.dev/gvisor/pkg/sync"
)
// handle represents a remote "open file descriptor", consisting of an opened
@@ -130,3 +131,43 @@ func (h *handle) writeFromBlocksAt(ctx context.Context, srcs safemem.BlockSeq, o
}
return uint64(n), cperr
}
+
+type handleReadWriter struct {
+ ctx context.Context
+ h *handle
+ off uint64
+}
+
+var handleReadWriterPool = sync.Pool{
+ New: func() interface{} {
+ return &handleReadWriter{}
+ },
+}
+
+func getHandleReadWriter(ctx context.Context, h *handle, offset int64) *handleReadWriter {
+ rw := handleReadWriterPool.Get().(*handleReadWriter)
+ rw.ctx = ctx
+ rw.h = h
+ rw.off = uint64(offset)
+ return rw
+}
+
+func putHandleReadWriter(rw *handleReadWriter) {
+ rw.ctx = nil
+ rw.h = nil
+ handleReadWriterPool.Put(rw)
+}
+
+// ReadToBlocks implements safemem.Reader.ReadToBlocks.
+func (rw *handleReadWriter) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error) {
+ n, err := rw.h.readToBlocksAt(rw.ctx, dsts, rw.off)
+ rw.off += n
+ return n, err
+}
+
+// WriteFromBlocks implements safemem.Writer.WriteFromBlocks.
+func (rw *handleReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) {
+ n, err := rw.h.writeFromBlocksAt(rw.ctx, srcs, rw.off)
+ rw.off += n
+ return n, err
+}