mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add memmap.File.DataFD().
This is used in cl/674746696 to ensure that users of MemoryFile data wait until that data has been loaded. PiperOrigin-RevId: 679255898
This commit is contained in:
@@ -72,6 +72,11 @@ func (mf *frontendFDMemmapFile) IncRef(fr memmap.FileRange, memCgID uint32) {
|
||||
func (mf *frontendFDMemmapFile) DecRef(fr memmap.FileRange) {
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *frontendFDMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *frontendFDMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -85,6 +85,11 @@ func (mf *uvmFDMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.AccessTy
|
||||
return safemem.BlockSeq{}, memmap.BufferedIOFallbackErr{}
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *uvmFDMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *uvmFDMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -80,6 +80,11 @@ func (mf *accelFDMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.Access
|
||||
return safemem.BlockSeq{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *accelFDMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *accelFDMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -91,6 +91,11 @@ func (mf *pciDeviceFdMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.Ac
|
||||
return mf.pfm.MapInternal(fr, int(mf.fd.hostFD), at.Write)
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *pciDeviceFdMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *pciDeviceFdMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -80,6 +80,11 @@ func (mf *tpuFDMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.AccessTy
|
||||
return safemem.BlockSeq{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *tpuFDMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *tpuFDMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -80,6 +80,11 @@ func (mf *vfioFDMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.AccessT
|
||||
return safemem.BlockSeq{}, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *vfioFDMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *vfioFDMemmapFile) FD() int {
|
||||
return int(mf.fd.hostFD)
|
||||
|
||||
@@ -213,6 +213,11 @@ func (mf *imageMemmapFile) MapInternal(fr memmap.FileRange, at hostarch.AccessTy
|
||||
return safemem.BlockSeqOf(safemem.BlockFromSafeSlice(bytes)), nil
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (mf *imageMemmapFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return mf.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (mf *imageMemmapFile) FD() int {
|
||||
return mf.image.FD()
|
||||
|
||||
@@ -960,6 +960,11 @@ func (d *dentryPlatformFile) MapInternal(fr memmap.FileRange, at hostarch.Access
|
||||
return d.hostFileMapper.MapInternal(fr, int(d.mmapFD.RacyLoad()), at.Write)
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (d *dentryPlatformFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return d.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (d *dentryPlatformFile) FD() int {
|
||||
d.handleMu.RLock()
|
||||
|
||||
@@ -505,6 +505,11 @@ func (fd *specialFileFD) MapInternal(fr memmap.FileRange, at hostarch.AccessType
|
||||
return fd.hostFileMapper.MapInternal(fr, int(fd.handle.fd), at.Write)
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (fd *specialFileFD) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return fd.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (fd *specialFileFD) FD() int {
|
||||
fd.requireHostFD()
|
||||
|
||||
@@ -72,6 +72,11 @@ func (i *inodePlatformFile) MapInternal(fr memmap.FileRange, at hostarch.AccessT
|
||||
return i.fileMapper.MapInternal(fr, i.hostFD, at.Write)
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (i *inodePlatformFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return i.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (i *inodePlatformFile) FD() int {
|
||||
return i.hostFD
|
||||
|
||||
@@ -819,11 +819,15 @@ func (rw *regularFileReadWriter) writeToMF(fr memmap.FileRange, srcs safemem.Blo
|
||||
// causes a lot of context switching. Use write(2) host syscall instead,
|
||||
// which makes one context switch and faults all the pages that are touched
|
||||
// during the write.
|
||||
fd, err := rw.file.inode.fs.mf.DataFD(fr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return hostfd.Pwritev2(
|
||||
int32(rw.file.inode.fs.mf.FD()), // fd
|
||||
srcs.TakeFirst64(fr.Length()), // srcs
|
||||
int64(fr.Start), // offset
|
||||
0, // flags
|
||||
int32(fd), // fd
|
||||
srcs.TakeFirst64(fr.Length()), // srcs
|
||||
int64(fr.Start), // offset
|
||||
0, // flags
|
||||
)
|
||||
}
|
||||
// Get internal mappings.
|
||||
|
||||
@@ -440,6 +440,16 @@ type File interface {
|
||||
// reference is held on the mapped pages.
|
||||
MapInternal(fr FileRange, at hostarch.AccessType) (safemem.BlockSeq, error)
|
||||
|
||||
// DataFD blocks until offsets fr in the file contain valid data, then
|
||||
// returns the file descriptor represented by the File.
|
||||
//
|
||||
// Note that fr.Start and fr.End need not be page-aligned.
|
||||
//
|
||||
// Preconditions:
|
||||
// * fr.Length() > 0.
|
||||
// * At least one reference must be held on all pages in fr.
|
||||
DataFD(fr FileRange) (int, error)
|
||||
|
||||
// BufferReadAt reads len(dst) bytes from the file into dst, starting at
|
||||
// file offset off. It returns the number of bytes read. Like
|
||||
// io.ReaderAt.ReadAt(), it never returns a short read with a nil error.
|
||||
@@ -466,10 +476,10 @@ type File interface {
|
||||
// * At least one reference must be held on all written pages.
|
||||
BufferWriteAt(off uint64, src []byte) (uint64, error)
|
||||
|
||||
// FD returns the file descriptor represented by the File.
|
||||
//
|
||||
// The only permitted operation on the returned file descriptor is to map
|
||||
// pages from it consistent with the requirements of AddressSpace.MapFile.
|
||||
// FD returns the file descriptor represented by the File. The returned
|
||||
// file descriptor should not be used to implement
|
||||
// platform.AddressSpace.MapFile, since the contents of the File may not be
|
||||
// valid; use DataFD instead.
|
||||
FD() int
|
||||
}
|
||||
|
||||
|
||||
@@ -1751,6 +1751,11 @@ func (f *MemoryFile) File() *os.File {
|
||||
return f.file
|
||||
}
|
||||
|
||||
// DataFD implements memmap.File.DataFD.
|
||||
func (f *MemoryFile) DataFD(fr memmap.FileRange) (int, error) {
|
||||
return f.FD(), nil
|
||||
}
|
||||
|
||||
// FD implements memmap.File.FD.
|
||||
func (f *MemoryFile) FD() int {
|
||||
return int(f.file.Fd())
|
||||
|
||||
@@ -635,17 +635,21 @@ func (s *subprocess) syscall(sysno uintptr, args ...arch.SyscallArgument) (uintp
|
||||
|
||||
// MapFile implements platform.AddressSpace.MapFile.
|
||||
func (s *subprocess) MapFile(addr hostarch.Addr, f memmap.File, fr memmap.FileRange, at hostarch.AccessType, precommit bool) error {
|
||||
fd, err := f.DataFD(fr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var flags int
|
||||
if precommit {
|
||||
flags |= unix.MAP_POPULATE
|
||||
}
|
||||
_, err := s.syscall(
|
||||
_, err = s.syscall(
|
||||
unix.SYS_MMAP,
|
||||
arch.SyscallArgument{Value: uintptr(addr)},
|
||||
arch.SyscallArgument{Value: uintptr(fr.Length())},
|
||||
arch.SyscallArgument{Value: uintptr(at.Prot())},
|
||||
arch.SyscallArgument{Value: uintptr(flags | unix.MAP_SHARED | unix.MAP_FIXED)},
|
||||
arch.SyscallArgument{Value: uintptr(f.FD())},
|
||||
arch.SyscallArgument{Value: uintptr(fd)},
|
||||
arch.SyscallArgument{Value: uintptr(fr.Start)})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ type subprocess struct {
|
||||
// within the sentry address space.
|
||||
threadContextRegion uintptr
|
||||
|
||||
// memoryFile is used to allocate a sysmsg stack which is shared
|
||||
// between a stub process and the Sentry.
|
||||
// memoryFile is used to allocate a sysmsg stack which is shared between a
|
||||
// stub process and the Sentry.
|
||||
memoryFile *pgalloc.MemoryFile
|
||||
|
||||
// usertrap is the state of the usertrap table which contains syscall
|
||||
@@ -967,17 +967,21 @@ func (s *subprocess) syscall(sysno uintptr, args ...arch.SyscallArgument) (uintp
|
||||
|
||||
// MapFile implements platform.AddressSpace.MapFile.
|
||||
func (s *subprocess) MapFile(addr hostarch.Addr, f memmap.File, fr memmap.FileRange, at hostarch.AccessType, precommit bool) error {
|
||||
fd, err := f.DataFD(fr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var flags int
|
||||
if precommit {
|
||||
flags |= unix.MAP_POPULATE
|
||||
}
|
||||
_, err := s.syscall(
|
||||
_, err = s.syscall(
|
||||
unix.SYS_MMAP,
|
||||
arch.SyscallArgument{Value: uintptr(addr)},
|
||||
arch.SyscallArgument{Value: uintptr(fr.Length())},
|
||||
arch.SyscallArgument{Value: uintptr(at.Prot())},
|
||||
arch.SyscallArgument{Value: uintptr(flags | unix.MAP_SHARED | unix.MAP_FIXED)},
|
||||
arch.SyscallArgument{Value: uintptr(f.FD())},
|
||||
arch.SyscallArgument{Value: uintptr(fd)},
|
||||
arch.SyscallArgument{Value: uintptr(fr.Start)})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -304,8 +304,9 @@ type Systrap struct {
|
||||
platform.UseHostGlobalMemoryBarrier
|
||||
platform.DoesNotOwnPageTables
|
||||
|
||||
// memoryFile is used to create a stub sysmsg stack
|
||||
// which is shared with the Sentry.
|
||||
// memoryFile is used to create a stub sysmsg stack which is shared with
|
||||
// the Sentry. Since memoryFile is platform-private, it is never restored,
|
||||
// so it is safe to call memoryFile.FD() rather than memoryFile.DataFD().
|
||||
memoryFile *pgalloc.MemoryFile
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user