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/utils.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/utils.go')
-rw-r--r-- | pkg/sentry/fs/ext/utils.go | 43 |
1 files changed, 8 insertions, 35 deletions
diff --git a/pkg/sentry/fs/ext/utils.go b/pkg/sentry/fs/ext/utils.go index 7c33919e0..3d89d664d 100644 --- a/pkg/sentry/fs/ext/utils.go +++ b/pkg/sentry/fs/ext/utils.go @@ -15,55 +15,30 @@ package ext import ( - "encoding/binary" "io" + "gvisor.dev/gvisor/pkg/binary" "gvisor.dev/gvisor/pkg/sentry/fs/ext/disklayout" "gvisor.dev/gvisor/pkg/syserror" ) // readFromDisk performs a binary read from disk into the given struct from // the absolute offset provided. -// -// All disk reads should use this helper so we avoid reading from stale -// previously used offsets. This function forces the offset parameter. -// -// Precondition: Must hold the mutex of the filesystem containing dev. -func readFromDisk(dev io.ReadSeeker, abOff int64, v interface{}) error { - if _, err := dev.Seek(abOff, io.SeekStart); err != nil { - return syserror.EIO - } - - if err := binary.Read(dev, binary.LittleEndian, v); err != nil { +func readFromDisk(dev io.ReaderAt, abOff int64, v interface{}) error { + n := binary.Size(v) + buf := make([]byte, n) + if read, _ := dev.ReadAt(buf, abOff); read < int(n) { return syserror.EIO } + binary.Unmarshal(buf, binary.LittleEndian, v) return nil } -// readFull is a wrapper around io.ReadFull which enforces the absolute offset -// parameter so that we can ensure that we do not perform incorrect reads from -// stale previously used offsets. -// -// Precondition: Must hold the mutex of the filesystem containing dev. -func readFull(dev io.ReadSeeker, abOff int64, dst []byte) (int, error) { - if _, err := dev.Seek(abOff, io.SeekStart); err != nil { - return 0, syserror.EIO - } - - n, err := io.ReadFull(dev, dst) - if err != nil { - err = syserror.EIO - } - return n, err -} - // readSuperBlock reads the SuperBlock from block group 0 in the underlying // device. There are three versions of the superblock. This function identifies // and returns the correct version. -// -// Precondition: Must hold the mutex of the filesystem containing dev. -func readSuperBlock(dev io.ReadSeeker) (disklayout.SuperBlock, error) { +func readSuperBlock(dev io.ReaderAt) (disklayout.SuperBlock, error) { var sb disklayout.SuperBlock = &disklayout.SuperBlockOld{} if err := readFromDisk(dev, disklayout.SbOffset, sb); err != nil { return nil, err @@ -98,9 +73,7 @@ func blockGroupsCount(sb disklayout.SuperBlock) uint64 { // readBlockGroups reads the block group descriptor table from block group 0 in // the underlying device. -// -// Precondition: Must hold the mutex of the filesystem containing dev. -func readBlockGroups(dev io.ReadSeeker, sb disklayout.SuperBlock) ([]disklayout.BlockGroup, error) { +func readBlockGroups(dev io.ReaderAt, sb disklayout.SuperBlock) ([]disklayout.BlockGroup, error) { bgCount := blockGroupsCount(sb) bgdSize := uint64(sb.BgDescSize()) is64Bit := sb.IncompatibleFeatures().Is64Bit |