diff options
author | Ayush Ranjan <ayushranjan@google.com> | 2019-07-29 20:11:24 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-07-29 20:12:37 -0700 |
commit | 8da9f8a12c51de41c4e048128a163fbb63679e4b (patch) | |
tree | 88dd537f92bf3b4d3e803bd7fdbf5b0693587607 /pkg/sentry/fs/ext/ext.go | |
parent | ddf25e3331a18a74d0e01d74fee7f82963fe778c (diff) |
Migrate from using io.ReadSeeker to io.ReaderAt.
This provides the following benefits:
- We can now use pkg/fd package which does not take ownership
of the file descriptor. So it does not close the fd when garbage collected.
This reduces scope of errors from unexpected garbage collection of io.File.
- It enforces the offset parameter in every read call.
It does not affect the fd offset nor is it affected by it. Hence reducing
scope of error of using stale offsets when reading.
- We do not need to serialize the usage of any global file descriptor anymore.
So this drops the mutual exclusion req hence reducing complexity and
congestion.
PiperOrigin-RevId: 260635174
Diffstat (limited to 'pkg/sentry/fs/ext/ext.go')
-rw-r--r-- | pkg/sentry/fs/ext/ext.go | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/pkg/sentry/fs/ext/ext.go b/pkg/sentry/fs/ext/ext.go index 2380f15da..d303dd122 100644 --- a/pkg/sentry/fs/ext/ext.go +++ b/pkg/sentry/fs/ext/ext.go @@ -19,9 +19,9 @@ import ( "errors" "fmt" "io" - "os" "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/sentry/context" "gvisor.dev/gvisor/pkg/sentry/fs/ext/disklayout" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" @@ -35,11 +35,11 @@ type filesystemType struct{} // Compiles only if filesystemType implements vfs.FilesystemType. var _ vfs.FilesystemType = (*filesystemType)(nil) -// getDeviceFd returns the read seeker to the underlying device. +// getDeviceFd returns an io.ReaderAt to the underlying device. // Currently there are two ways of mounting an ext(2/3/4) fs: // 1. Specify a mount with our internal special MountType in the OCI spec. // 2. Expose the device to the container and mount it from application layer. -func getDeviceFd(source string, opts vfs.NewFilesystemOptions) (io.ReadSeeker, error) { +func getDeviceFd(source string, opts vfs.NewFilesystemOptions) (io.ReaderAt, error) { if opts.InternalData == nil { // User mount call. // TODO(b/134676337): Open the device specified by `source` and return that. @@ -47,20 +47,19 @@ func getDeviceFd(source string, opts vfs.NewFilesystemOptions) (io.ReadSeeker, e } // NewFilesystem call originated from within the sentry. - fd, ok := opts.InternalData.(uintptr) + devFd, ok := opts.InternalData.(int) if !ok { - return nil, errors.New("internal data for ext fs must be a uintptr containing the file descriptor to device") + return nil, errors.New("internal data for ext fs must be an int containing the file descriptor to device") } - // We do not close this file because that would close the underlying device - // file descriptor (which is required for reading the fs from disk). - // TODO(b/134676337): Use pkg/fd instead. - deviceFile := os.NewFile(fd, source) - if deviceFile == nil { - return nil, fmt.Errorf("ext4 device file descriptor is not valid: %d", fd) + if devFd < 0 { + return nil, fmt.Errorf("ext device file descriptor is not valid: %d", devFd) } - return deviceFile, nil + // The fd.ReadWriter returned from fd.NewReadWriter() does not take ownership + // of the file descriptor and hence will not close it when it is garbage + // collected. + return fd.NewReadWriter(devFd), nil } // NewFilesystem implements vfs.FilesystemType.NewFilesystem. |