mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Move platform.File in memmap
The subsequent systrap changes will need to import memmap from the platform package. PiperOrigin-RevId: 323409486
This commit is contained in:
@@ -8,7 +8,6 @@ go_template_instance(
|
||||
out = "dirty_set_impl.go",
|
||||
imports = {
|
||||
"memmap": "gvisor.dev/gvisor/pkg/sentry/memmap",
|
||||
"platform": "gvisor.dev/gvisor/pkg/sentry/platform",
|
||||
},
|
||||
package = "fsutil",
|
||||
prefix = "Dirty",
|
||||
@@ -25,14 +24,14 @@ go_template_instance(
|
||||
name = "frame_ref_set_impl",
|
||||
out = "frame_ref_set_impl.go",
|
||||
imports = {
|
||||
"platform": "gvisor.dev/gvisor/pkg/sentry/platform",
|
||||
"memmap": "gvisor.dev/gvisor/pkg/sentry/memmap",
|
||||
},
|
||||
package = "fsutil",
|
||||
prefix = "FrameRef",
|
||||
template = "//pkg/segment:generic_set",
|
||||
types = {
|
||||
"Key": "uint64",
|
||||
"Range": "platform.FileRange",
|
||||
"Range": "memmap.FileRange",
|
||||
"Value": "uint64",
|
||||
"Functions": "FrameRefSetFunctions",
|
||||
},
|
||||
@@ -43,7 +42,6 @@ go_template_instance(
|
||||
out = "file_range_set_impl.go",
|
||||
imports = {
|
||||
"memmap": "gvisor.dev/gvisor/pkg/sentry/memmap",
|
||||
"platform": "gvisor.dev/gvisor/pkg/sentry/platform",
|
||||
},
|
||||
package = "fsutil",
|
||||
prefix = "FileRange",
|
||||
@@ -86,7 +84,6 @@ go_library(
|
||||
"//pkg/sentry/kernel/time",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/pgalloc",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/state",
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
@@ -159,7 +158,7 @@ func (ds *DirtySet) AllowClean(mr memmap.MappableRange) {
|
||||
// repeatedly until all bytes have been written. max is the true size of the
|
||||
// cached object; offsets beyond max will not be passed to writeAt, even if
|
||||
// they are marked dirty.
|
||||
func SyncDirty(ctx context.Context, mr memmap.MappableRange, cache *FileRangeSet, dirty *DirtySet, max uint64, mem platform.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
func SyncDirty(ctx context.Context, mr memmap.MappableRange, cache *FileRangeSet, dirty *DirtySet, max uint64, mem memmap.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
var changedDirty bool
|
||||
defer func() {
|
||||
if changedDirty {
|
||||
@@ -194,7 +193,7 @@ func SyncDirty(ctx context.Context, mr memmap.MappableRange, cache *FileRangeSet
|
||||
// successful partial write, SyncDirtyAll will call it repeatedly until all
|
||||
// bytes have been written. max is the true size of the cached object; offsets
|
||||
// beyond max will not be passed to writeAt, even if they are marked dirty.
|
||||
func SyncDirtyAll(ctx context.Context, cache *FileRangeSet, dirty *DirtySet, max uint64, mem platform.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
func SyncDirtyAll(ctx context.Context, cache *FileRangeSet, dirty *DirtySet, max uint64, mem memmap.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
dseg := dirty.FirstSegment()
|
||||
for dseg.Ok() {
|
||||
if err := syncDirtyRange(ctx, dseg.Range(), cache, max, mem, writeAt); err != nil {
|
||||
@@ -210,7 +209,7 @@ func SyncDirtyAll(ctx context.Context, cache *FileRangeSet, dirty *DirtySet, max
|
||||
}
|
||||
|
||||
// Preconditions: mr must be page-aligned.
|
||||
func syncDirtyRange(ctx context.Context, mr memmap.MappableRange, cache *FileRangeSet, max uint64, mem platform.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
func syncDirtyRange(ctx context.Context, mr memmap.MappableRange, cache *FileRangeSet, max uint64, mem memmap.File, writeAt func(ctx context.Context, srcs safemem.BlockSeq, offset uint64) (uint64, error)) error {
|
||||
for cseg := cache.LowerBoundSegment(mr.Start); cseg.Ok() && cseg.Start() < mr.End; cseg = cseg.NextSegment() {
|
||||
wbr := cseg.Range().Intersect(mr)
|
||||
if max < wbr.Start {
|
||||
|
||||
@@ -23,13 +23,12 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// FileRangeSet maps offsets into a memmap.Mappable to offsets into a
|
||||
// platform.File. It is used to implement Mappables that store data in
|
||||
// memmap.File. It is used to implement Mappables that store data in
|
||||
// sparsely-allocated memory.
|
||||
//
|
||||
// type FileRangeSet <generated by go_generics>
|
||||
@@ -65,20 +64,20 @@ func (FileRangeSetFunctions) Split(mr memmap.MappableRange, frstart uint64, spli
|
||||
}
|
||||
|
||||
// FileRange returns the FileRange mapped by seg.
|
||||
func (seg FileRangeIterator) FileRange() platform.FileRange {
|
||||
func (seg FileRangeIterator) FileRange() memmap.FileRange {
|
||||
return seg.FileRangeOf(seg.Range())
|
||||
}
|
||||
|
||||
// FileRangeOf returns the FileRange mapped by mr.
|
||||
//
|
||||
// Preconditions: seg.Range().IsSupersetOf(mr). mr.Length() != 0.
|
||||
func (seg FileRangeIterator) FileRangeOf(mr memmap.MappableRange) platform.FileRange {
|
||||
func (seg FileRangeIterator) FileRangeOf(mr memmap.MappableRange) memmap.FileRange {
|
||||
frstart := seg.Value() + (mr.Start - seg.Start())
|
||||
return platform.FileRange{frstart, frstart + mr.Length()}
|
||||
return memmap.FileRange{frstart, frstart + mr.Length()}
|
||||
}
|
||||
|
||||
// Fill attempts to ensure that all memmap.Mappable offsets in required are
|
||||
// mapped to a platform.File offset, by allocating from mf with the given
|
||||
// mapped to a memmap.File offset, by allocating from mf with the given
|
||||
// memory usage kind and invoking readAt to store data into memory. (If readAt
|
||||
// returns a successful partial read, Fill will call it repeatedly until all
|
||||
// bytes have been read.) EOF is handled consistently with the requirements of
|
||||
@@ -141,7 +140,7 @@ func (frs *FileRangeSet) Fill(ctx context.Context, required, optional memmap.Map
|
||||
}
|
||||
|
||||
// Drop removes segments for memmap.Mappable offsets in mr, freeing the
|
||||
// corresponding platform.FileRanges.
|
||||
// corresponding memmap.FileRanges.
|
||||
//
|
||||
// Preconditions: mr must be page-aligned.
|
||||
func (frs *FileRangeSet) Drop(mr memmap.MappableRange, mf *pgalloc.MemoryFile) {
|
||||
@@ -154,7 +153,7 @@ func (frs *FileRangeSet) Drop(mr memmap.MappableRange, mf *pgalloc.MemoryFile) {
|
||||
}
|
||||
|
||||
// DropAll removes all segments in mr, freeing the corresponding
|
||||
// platform.FileRanges.
|
||||
// memmap.FileRanges.
|
||||
func (frs *FileRangeSet) DropAll(mf *pgalloc.MemoryFile) {
|
||||
for seg := frs.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
|
||||
mf.DecRef(seg.FileRange())
|
||||
|
||||
@@ -17,7 +17,7 @@ package fsutil
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ func (FrameRefSetFunctions) ClearValue(val *uint64) {
|
||||
}
|
||||
|
||||
// Merge implements segment.Functions.Merge.
|
||||
func (FrameRefSetFunctions) Merge(_ platform.FileRange, val1 uint64, _ platform.FileRange, val2 uint64) (uint64, bool) {
|
||||
func (FrameRefSetFunctions) Merge(_ memmap.FileRange, val1 uint64, _ memmap.FileRange, val2 uint64) (uint64, bool) {
|
||||
if val1 != val2 {
|
||||
return 0, false
|
||||
}
|
||||
@@ -47,13 +47,13 @@ func (FrameRefSetFunctions) Merge(_ platform.FileRange, val1 uint64, _ platform.
|
||||
}
|
||||
|
||||
// Split implements segment.Functions.Split.
|
||||
func (FrameRefSetFunctions) Split(_ platform.FileRange, val uint64, _ uint64) (uint64, uint64) {
|
||||
func (FrameRefSetFunctions) Split(_ memmap.FileRange, val uint64, _ uint64) (uint64, uint64) {
|
||||
return val, val
|
||||
}
|
||||
|
||||
// IncRefAndAccount adds a reference on the range fr. All newly inserted segments
|
||||
// are accounted as host page cache memory mappings.
|
||||
func (refs *FrameRefSet) IncRefAndAccount(fr platform.FileRange) {
|
||||
func (refs *FrameRefSet) IncRefAndAccount(fr memmap.FileRange) {
|
||||
seg, gap := refs.Find(fr.Start)
|
||||
for {
|
||||
switch {
|
||||
@@ -74,7 +74,7 @@ func (refs *FrameRefSet) IncRefAndAccount(fr platform.FileRange) {
|
||||
|
||||
// DecRefAndAccount removes a reference on the range fr and untracks segments
|
||||
// that are removed from memory accounting.
|
||||
func (refs *FrameRefSet) DecRefAndAccount(fr platform.FileRange) {
|
||||
func (refs *FrameRefSet) DecRefAndAccount(fr memmap.FileRange) {
|
||||
seg := refs.FindSegment(fr.Start)
|
||||
|
||||
for seg.Ok() && seg.Start() < fr.End {
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
@@ -126,7 +125,7 @@ func (f *HostFileMapper) DecRefOn(mr memmap.MappableRange) {
|
||||
// offsets in fr or until the next call to UnmapAll.
|
||||
//
|
||||
// Preconditions: The caller must hold a reference on all offsets in fr.
|
||||
func (f *HostFileMapper) MapInternal(fr platform.FileRange, fd int, write bool) (safemem.BlockSeq, error) {
|
||||
func (f *HostFileMapper) MapInternal(fr memmap.FileRange, fd int, write bool) (safemem.BlockSeq, error) {
|
||||
chunks := ((fr.End + chunkMask) >> chunkShift) - (fr.Start >> chunkShift)
|
||||
f.mapsMu.Lock()
|
||||
defer f.mapsMu.Unlock()
|
||||
@@ -146,7 +145,7 @@ func (f *HostFileMapper) MapInternal(fr platform.FileRange, fd int, write bool)
|
||||
}
|
||||
|
||||
// Preconditions: f.mapsMu must be locked.
|
||||
func (f *HostFileMapper) forEachMappingBlockLocked(fr platform.FileRange, fd int, write bool, fn func(safemem.Block)) error {
|
||||
func (f *HostFileMapper) forEachMappingBlockLocked(fr memmap.FileRange, fd int, write bool, fn func(safemem.Block)) error {
|
||||
prot := syscall.PROT_READ
|
||||
if write {
|
||||
prot |= syscall.PROT_WRITE
|
||||
|
||||
@@ -21,18 +21,17 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// HostMappable implements memmap.Mappable and platform.File over a
|
||||
// HostMappable implements memmap.Mappable and memmap.File over a
|
||||
// CachedFileObject.
|
||||
//
|
||||
// Lock order (compare the lock order model in mm/mm.go):
|
||||
// truncateMu ("fs locks")
|
||||
// mu ("memmap.Mappable locks not taken by Translate")
|
||||
// ("platform.File locks")
|
||||
// ("memmap.File locks")
|
||||
// backingFile ("CachedFileObject locks")
|
||||
//
|
||||
// +stateify savable
|
||||
@@ -124,24 +123,24 @@ func (h *HostMappable) NotifyChangeFD() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MapInternal implements platform.File.MapInternal.
|
||||
func (h *HostMappable) MapInternal(fr platform.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
// MapInternal implements memmap.File.MapInternal.
|
||||
func (h *HostMappable) MapInternal(fr memmap.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
return h.hostFileMapper.MapInternal(fr, h.backingFile.FD(), at.Write)
|
||||
}
|
||||
|
||||
// FD implements platform.File.FD.
|
||||
// FD implements memmap.File.FD.
|
||||
func (h *HostMappable) FD() int {
|
||||
return h.backingFile.FD()
|
||||
}
|
||||
|
||||
// IncRef implements platform.File.IncRef.
|
||||
func (h *HostMappable) IncRef(fr platform.FileRange) {
|
||||
// IncRef implements memmap.File.IncRef.
|
||||
func (h *HostMappable) IncRef(fr memmap.FileRange) {
|
||||
mr := memmap.MappableRange{Start: fr.Start, End: fr.End}
|
||||
h.hostFileMapper.IncRefOn(mr)
|
||||
}
|
||||
|
||||
// DecRef implements platform.File.DecRef.
|
||||
func (h *HostMappable) DecRef(fr platform.FileRange) {
|
||||
// DecRef implements memmap.File.DecRef.
|
||||
func (h *HostMappable) DecRef(fr memmap.FileRange) {
|
||||
mr := memmap.MappableRange{Start: fr.Start, End: fr.End}
|
||||
h.hostFileMapper.DecRefOn(mr)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
@@ -934,7 +933,7 @@ func maxFillRange(required, optional memmap.MappableRange) memmap.MappableRange
|
||||
|
||||
// InvalidateUnsavable implements memmap.Mappable.InvalidateUnsavable.
|
||||
func (c *CachingInodeOperations) InvalidateUnsavable(ctx context.Context) error {
|
||||
// Whether we have a host fd (and consequently what platform.File is
|
||||
// Whether we have a host fd (and consequently what memmap.File is
|
||||
// mapped) can change across save/restore, so invalidate all translations
|
||||
// unconditionally.
|
||||
c.mapsMu.Lock()
|
||||
@@ -999,10 +998,10 @@ func (c *CachingInodeOperations) Evict(ctx context.Context, er pgalloc.Evictable
|
||||
}
|
||||
}
|
||||
|
||||
// IncRef implements platform.File.IncRef. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the platform.File
|
||||
// IncRef implements memmap.File.IncRef. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the memmap.File
|
||||
// during translation.
|
||||
func (c *CachingInodeOperations) IncRef(fr platform.FileRange) {
|
||||
func (c *CachingInodeOperations) IncRef(fr memmap.FileRange) {
|
||||
// Hot path. Avoid defers.
|
||||
c.dataMu.Lock()
|
||||
seg, gap := c.refs.Find(fr.Start)
|
||||
@@ -1024,10 +1023,10 @@ func (c *CachingInodeOperations) IncRef(fr platform.FileRange) {
|
||||
}
|
||||
}
|
||||
|
||||
// DecRef implements platform.File.DecRef. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the platform.File
|
||||
// DecRef implements memmap.File.DecRef. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the memmap.File
|
||||
// during translation.
|
||||
func (c *CachingInodeOperations) DecRef(fr platform.FileRange) {
|
||||
func (c *CachingInodeOperations) DecRef(fr memmap.FileRange) {
|
||||
// Hot path. Avoid defers.
|
||||
c.dataMu.Lock()
|
||||
seg := c.refs.FindSegment(fr.Start)
|
||||
@@ -1046,15 +1045,15 @@ func (c *CachingInodeOperations) DecRef(fr platform.FileRange) {
|
||||
c.dataMu.Unlock()
|
||||
}
|
||||
|
||||
// MapInternal implements platform.File.MapInternal. This is used when we
|
||||
// MapInternal implements memmap.File.MapInternal. This is used when we
|
||||
// directly map an underlying host fd and CachingInodeOperations is used as the
|
||||
// platform.File during translation.
|
||||
func (c *CachingInodeOperations) MapInternal(fr platform.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
// memmap.File during translation.
|
||||
func (c *CachingInodeOperations) MapInternal(fr memmap.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
return c.hostFileMapper.MapInternal(fr, c.backingFile.FD(), at.Write)
|
||||
}
|
||||
|
||||
// FD implements platform.File.FD. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the platform.File
|
||||
// FD implements memmap.File.FD. This is used when we directly map an
|
||||
// underlying host fd and CachingInodeOperations is used as the memmap.File
|
||||
// during translation.
|
||||
func (c *CachingInodeOperations) FD() int {
|
||||
return c.backingFile.FD()
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
@@ -221,12 +220,12 @@ func (fd *regularFileFD) pwriteLocked(ctx context.Context, src usermem.IOSequenc
|
||||
return 0, syserror.EINVAL
|
||||
}
|
||||
mr := memmap.MappableRange{pgstart, pgend}
|
||||
var freed []platform.FileRange
|
||||
var freed []memmap.FileRange
|
||||
d.dataMu.Lock()
|
||||
cseg := d.cache.LowerBoundSegment(mr.Start)
|
||||
for cseg.Ok() && cseg.Start() < mr.End {
|
||||
cseg = d.cache.Isolate(cseg, mr)
|
||||
freed = append(freed, platform.FileRange{cseg.Value(), cseg.Value() + cseg.Range().Length()})
|
||||
freed = append(freed, memmap.FileRange{cseg.Value(), cseg.Value() + cseg.Range().Length()})
|
||||
cseg = d.cache.Remove(cseg).NextSegment()
|
||||
}
|
||||
d.dataMu.Unlock()
|
||||
@@ -821,7 +820,7 @@ func maxFillRange(required, optional memmap.MappableRange) memmap.MappableRange
|
||||
|
||||
// InvalidateUnsavable implements memmap.Mappable.InvalidateUnsavable.
|
||||
func (d *dentry) InvalidateUnsavable(ctx context.Context) error {
|
||||
// Whether we have a host fd (and consequently what platform.File is
|
||||
// Whether we have a host fd (and consequently what memmap.File is
|
||||
// mapped) can change across save/restore, so invalidate all translations
|
||||
// unconditionally.
|
||||
d.mapsMu.Lock()
|
||||
@@ -869,8 +868,8 @@ func (d *dentry) Evict(ctx context.Context, er pgalloc.EvictableRange) {
|
||||
}
|
||||
}
|
||||
|
||||
// dentryPlatformFile implements platform.File. It exists solely because dentry
|
||||
// cannot implement both vfs.DentryImpl.IncRef and platform.File.IncRef.
|
||||
// dentryPlatformFile implements memmap.File. It exists solely because dentry
|
||||
// cannot implement both vfs.DentryImpl.IncRef and memmap.File.IncRef.
|
||||
//
|
||||
// dentryPlatformFile is only used when a host FD representing the remote file
|
||||
// is available (i.e. dentry.handle.fd >= 0), and that FD is used for
|
||||
@@ -878,7 +877,7 @@ func (d *dentry) Evict(ctx context.Context, er pgalloc.EvictableRange) {
|
||||
type dentryPlatformFile struct {
|
||||
*dentry
|
||||
|
||||
// fdRefs counts references on platform.File offsets. fdRefs is protected
|
||||
// fdRefs counts references on memmap.File offsets. fdRefs is protected
|
||||
// by dentry.dataMu.
|
||||
fdRefs fsutil.FrameRefSet
|
||||
|
||||
@@ -890,29 +889,29 @@ type dentryPlatformFile struct {
|
||||
hostFileMapperInitOnce sync.Once
|
||||
}
|
||||
|
||||
// IncRef implements platform.File.IncRef.
|
||||
func (d *dentryPlatformFile) IncRef(fr platform.FileRange) {
|
||||
// IncRef implements memmap.File.IncRef.
|
||||
func (d *dentryPlatformFile) IncRef(fr memmap.FileRange) {
|
||||
d.dataMu.Lock()
|
||||
d.fdRefs.IncRefAndAccount(fr)
|
||||
d.dataMu.Unlock()
|
||||
}
|
||||
|
||||
// DecRef implements platform.File.DecRef.
|
||||
func (d *dentryPlatformFile) DecRef(fr platform.FileRange) {
|
||||
// DecRef implements memmap.File.DecRef.
|
||||
func (d *dentryPlatformFile) DecRef(fr memmap.FileRange) {
|
||||
d.dataMu.Lock()
|
||||
d.fdRefs.DecRefAndAccount(fr)
|
||||
d.dataMu.Unlock()
|
||||
}
|
||||
|
||||
// MapInternal implements platform.File.MapInternal.
|
||||
func (d *dentryPlatformFile) MapInternal(fr platform.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
// MapInternal implements memmap.File.MapInternal.
|
||||
func (d *dentryPlatformFile) MapInternal(fr memmap.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
d.handleMu.RLock()
|
||||
bs, err := d.hostFileMapper.MapInternal(fr, int(d.handle.fd), at.Write)
|
||||
d.handleMu.RUnlock()
|
||||
return bs, err
|
||||
}
|
||||
|
||||
// FD implements platform.File.FD.
|
||||
// FD implements memmap.File.FD.
|
||||
func (d *dentryPlatformFile) FD() int {
|
||||
d.handleMu.RLock()
|
||||
fd := d.handle.fd
|
||||
|
||||
@@ -34,7 +34,6 @@ go_library(
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/socket/control",
|
||||
"//pkg/sentry/socket/unix",
|
||||
"//pkg/sentry/socket/unix/transport",
|
||||
|
||||
@@ -19,13 +19,12 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// inodePlatformFile implements platform.File. It exists solely because inode
|
||||
// cannot implement both kernfs.Inode.IncRef and platform.File.IncRef.
|
||||
// inodePlatformFile implements memmap.File. It exists solely because inode
|
||||
// cannot implement both kernfs.Inode.IncRef and memmap.File.IncRef.
|
||||
//
|
||||
// inodePlatformFile should only be used if inode.canMap is true.
|
||||
type inodePlatformFile struct {
|
||||
@@ -34,7 +33,7 @@ type inodePlatformFile struct {
|
||||
// fdRefsMu protects fdRefs.
|
||||
fdRefsMu sync.Mutex
|
||||
|
||||
// fdRefs counts references on platform.File offsets. It is used solely for
|
||||
// fdRefs counts references on memmap.File offsets. It is used solely for
|
||||
// memory accounting.
|
||||
fdRefs fsutil.FrameRefSet
|
||||
|
||||
@@ -45,32 +44,32 @@ type inodePlatformFile struct {
|
||||
fileMapperInitOnce sync.Once
|
||||
}
|
||||
|
||||
// IncRef implements platform.File.IncRef.
|
||||
// IncRef implements memmap.File.IncRef.
|
||||
//
|
||||
// Precondition: i.inode.canMap must be true.
|
||||
func (i *inodePlatformFile) IncRef(fr platform.FileRange) {
|
||||
func (i *inodePlatformFile) IncRef(fr memmap.FileRange) {
|
||||
i.fdRefsMu.Lock()
|
||||
i.fdRefs.IncRefAndAccount(fr)
|
||||
i.fdRefsMu.Unlock()
|
||||
}
|
||||
|
||||
// DecRef implements platform.File.DecRef.
|
||||
// DecRef implements memmap.File.DecRef.
|
||||
//
|
||||
// Precondition: i.inode.canMap must be true.
|
||||
func (i *inodePlatformFile) DecRef(fr platform.FileRange) {
|
||||
func (i *inodePlatformFile) DecRef(fr memmap.FileRange) {
|
||||
i.fdRefsMu.Lock()
|
||||
i.fdRefs.DecRefAndAccount(fr)
|
||||
i.fdRefsMu.Unlock()
|
||||
}
|
||||
|
||||
// MapInternal implements platform.File.MapInternal.
|
||||
// MapInternal implements memmap.File.MapInternal.
|
||||
//
|
||||
// Precondition: i.inode.canMap must be true.
|
||||
func (i *inodePlatformFile) MapInternal(fr platform.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
func (i *inodePlatformFile) MapInternal(fr memmap.FileRange, at usermem.AccessType) (safemem.BlockSeq, error) {
|
||||
return i.fileMapper.MapInternal(fr, i.hostFD, at.Write)
|
||||
}
|
||||
|
||||
// FD implements platform.File.FD.
|
||||
// FD implements memmap.File.FD.
|
||||
func (i *inodePlatformFile) FD() int {
|
||||
return i.hostFD
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ go_library(
|
||||
"//pkg/sentry/kernel/time",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/pgalloc",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/usage",
|
||||
"//pkg/sync",
|
||||
"//pkg/syserror",
|
||||
|
||||
@@ -45,7 +45,6 @@ import (
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
@@ -370,7 +369,7 @@ type Shm struct {
|
||||
|
||||
// fr is the offset into mfp.MemoryFile() that backs this contents of this
|
||||
// segment. Immutable.
|
||||
fr platform.FileRange
|
||||
fr memmap.FileRange
|
||||
|
||||
// mu protects all fields below.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
|
||||
@@ -21,8 +21,8 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
sentrytime "gvisor.dev/gvisor/pkg/sentry/time"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
@@ -90,7 +90,7 @@ type Timekeeper struct {
|
||||
// NewTimekeeper does not take ownership of paramPage.
|
||||
//
|
||||
// SetClocks must be called on the returned Timekeeper before it is usable.
|
||||
func NewTimekeeper(mfp pgalloc.MemoryFileProvider, paramPage platform.FileRange) (*Timekeeper, error) {
|
||||
func NewTimekeeper(mfp pgalloc.MemoryFileProvider, paramPage memmap.FileRange) (*Timekeeper, error) {
|
||||
return &Timekeeper{
|
||||
params: NewVDSOParamPage(mfp, paramPage),
|
||||
}, nil
|
||||
|
||||
@@ -19,8 +19,8 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
@@ -58,7 +58,7 @@ type vdsoParams struct {
|
||||
type VDSOParamPage struct {
|
||||
// The parameter page is fr, allocated from mfp.MemoryFile().
|
||||
mfp pgalloc.MemoryFileProvider
|
||||
fr platform.FileRange
|
||||
fr memmap.FileRange
|
||||
|
||||
// seq is the current sequence count written to the page.
|
||||
//
|
||||
@@ -81,7 +81,7 @@ type VDSOParamPage struct {
|
||||
// * VDSOParamPage must be the only writer to fr.
|
||||
//
|
||||
// * mfp.MemoryFile().MapInternal(fr) must return a single safemem.Block.
|
||||
func NewVDSOParamPage(mfp pgalloc.MemoryFileProvider, fr platform.FileRange) *VDSOParamPage {
|
||||
func NewVDSOParamPage(mfp pgalloc.MemoryFileProvider, fr memmap.FileRange) *VDSOParamPage {
|
||||
return &VDSOParamPage{mfp: mfp, fr: fr}
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -28,9 +28,21 @@ go_template_instance(
|
||||
},
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "file_range",
|
||||
out = "file_range.go",
|
||||
package = "memmap",
|
||||
prefix = "File",
|
||||
template = "//pkg/segment:generic_range",
|
||||
types = {
|
||||
"T": "uint64",
|
||||
},
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "memmap",
|
||||
srcs = [
|
||||
"file_range.go",
|
||||
"mappable_range.go",
|
||||
"mapping_set.go",
|
||||
"mapping_set_impl.go",
|
||||
@@ -40,7 +52,7 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/context",
|
||||
"//pkg/log",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/safemem",
|
||||
"//pkg/syserror",
|
||||
"//pkg/usermem",
|
||||
],
|
||||
|
||||
@@ -19,12 +19,12 @@ import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// Mappable represents a memory-mappable object, a mutable mapping from uint64
|
||||
// offsets to (platform.File, uint64 File offset) pairs.
|
||||
// offsets to (File, uint64 File offset) pairs.
|
||||
//
|
||||
// See mm/mm.go for Mappable's place in the lock order.
|
||||
//
|
||||
@@ -74,7 +74,7 @@ type Mappable interface {
|
||||
// Translations are valid until invalidated by a callback to
|
||||
// MappingSpace.Invalidate or until the caller removes its mapping of the
|
||||
// translated range. Mappable implementations must ensure that at least one
|
||||
// reference is held on all pages in a platform.File that may be the result
|
||||
// reference is held on all pages in a File that may be the result
|
||||
// of a valid Translation.
|
||||
//
|
||||
// Preconditions: required.Length() > 0. optional.IsSupersetOf(required).
|
||||
@@ -100,7 +100,7 @@ type Translation struct {
|
||||
Source MappableRange
|
||||
|
||||
// File is the mapped file.
|
||||
File platform.File
|
||||
File File
|
||||
|
||||
// Offset is the offset into File at which this Translation begins.
|
||||
Offset uint64
|
||||
@@ -110,9 +110,9 @@ type Translation struct {
|
||||
Perms usermem.AccessType
|
||||
}
|
||||
|
||||
// FileRange returns the platform.FileRange represented by t.
|
||||
func (t Translation) FileRange() platform.FileRange {
|
||||
return platform.FileRange{t.Offset, t.Offset + t.Source.Length()}
|
||||
// FileRange returns the FileRange represented by t.
|
||||
func (t Translation) FileRange() FileRange {
|
||||
return FileRange{t.Offset, t.Offset + t.Source.Length()}
|
||||
}
|
||||
|
||||
// CheckTranslateResult returns an error if (ts, terr) does not satisfy all
|
||||
@@ -361,3 +361,49 @@ type MMapOpts struct {
|
||||
// TODO(jamieliu): Replace entirely with MappingIdentity?
|
||||
Hint string
|
||||
}
|
||||
|
||||
// File represents a host file that may be mapped into an platform.AddressSpace.
|
||||
type File interface {
|
||||
// All pages in a File are reference-counted.
|
||||
|
||||
// IncRef increments the reference count on all pages in fr.
|
||||
//
|
||||
// Preconditions: fr.Start and fr.End must be page-aligned. fr.Length() >
|
||||
// 0. At least one reference must be held on all pages in fr. (The File
|
||||
// interface does not provide a way to acquire an initial reference;
|
||||
// implementors may define mechanisms for doing so.)
|
||||
IncRef(fr FileRange)
|
||||
|
||||
// DecRef decrements the reference count on all pages in fr.
|
||||
//
|
||||
// Preconditions: fr.Start and fr.End must be page-aligned. fr.Length() >
|
||||
// 0. At least one reference must be held on all pages in fr.
|
||||
DecRef(fr FileRange)
|
||||
|
||||
// MapInternal returns a mapping of the given file offsets in the invoking
|
||||
// process' address space for reading and writing.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Postconditions: The returned mapping is valid as long as at least one
|
||||
// reference is held on the mapped pages.
|
||||
MapInternal(fr FileRange, at usermem.AccessType) (safemem.BlockSeq, 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() int
|
||||
}
|
||||
|
||||
// FileRange represents a range of uint64 offsets into a File.
|
||||
//
|
||||
// type FileRange <generated using go_generics>
|
||||
|
||||
// String implements fmt.Stringer.String.
|
||||
func (fr FileRange) String() string {
|
||||
return fmt.Sprintf("[%#x, %#x)", fr.Start, fr.End)
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,14 +7,14 @@ go_template_instance(
|
||||
name = "file_refcount_set",
|
||||
out = "file_refcount_set.go",
|
||||
imports = {
|
||||
"platform": "gvisor.dev/gvisor/pkg/sentry/platform",
|
||||
"memmap": "gvisor.dev/gvisor/pkg/sentry/memmap",
|
||||
},
|
||||
package = "mm",
|
||||
prefix = "fileRefcount",
|
||||
template = "//pkg/segment:generic_set",
|
||||
types = {
|
||||
"Key": "uint64",
|
||||
"Range": "platform.FileRange",
|
||||
"Range": "memmap.FileRange",
|
||||
"Value": "int32",
|
||||
"Functions": "fileRefcountSetFunctions",
|
||||
},
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
@@ -243,7 +242,7 @@ type aioMappable struct {
|
||||
refs.AtomicRefCount
|
||||
|
||||
mfp pgalloc.MemoryFileProvider
|
||||
fr platform.FileRange
|
||||
fr memmap.FileRange
|
||||
}
|
||||
|
||||
var aioRingBufferSize = uint64(usermem.Addr(linux.AIORingSize).MustRoundUp())
|
||||
|
||||
+5
-5
@@ -25,7 +25,7 @@
|
||||
// Locks taken by memmap.Mappable.Translate
|
||||
// mm.privateRefs.mu
|
||||
// platform.AddressSpace locks
|
||||
// platform.File locks
|
||||
// memmap.File locks
|
||||
// mm.aioManager.mu
|
||||
// mm.AIOContext.mu
|
||||
//
|
||||
@@ -396,7 +396,7 @@ type pma struct {
|
||||
// file is the file mapped by this pma. Only pmas for which file ==
|
||||
// MemoryManager.mfp.MemoryFile() may be saved. pmas hold a reference to
|
||||
// the corresponding file range while they exist.
|
||||
file platform.File `state:"nosave"`
|
||||
file memmap.File `state:"nosave"`
|
||||
|
||||
// off is the offset into file at which this pma begins.
|
||||
//
|
||||
@@ -436,7 +436,7 @@ type pma struct {
|
||||
private bool
|
||||
|
||||
// If internalMappings is not empty, it is the cached return value of
|
||||
// file.MapInternal for the platform.FileRange mapped by this pma.
|
||||
// file.MapInternal for the memmap.FileRange mapped by this pma.
|
||||
internalMappings safemem.BlockSeq `state:"nosave"`
|
||||
}
|
||||
|
||||
@@ -469,10 +469,10 @@ func (fileRefcountSetFunctions) MaxKey() uint64 {
|
||||
func (fileRefcountSetFunctions) ClearValue(_ *int32) {
|
||||
}
|
||||
|
||||
func (fileRefcountSetFunctions) Merge(_ platform.FileRange, rc1 int32, _ platform.FileRange, rc2 int32) (int32, bool) {
|
||||
func (fileRefcountSetFunctions) Merge(_ memmap.FileRange, rc1 int32, _ memmap.FileRange, rc2 int32) (int32, bool) {
|
||||
return rc1, rc1 == rc2
|
||||
}
|
||||
|
||||
func (fileRefcountSetFunctions) Split(_ platform.FileRange, rc int32, _ uint64) (int32, int32) {
|
||||
func (fileRefcountSetFunctions) Split(_ memmap.FileRange, rc int32, _ uint64) (int32, int32) {
|
||||
return rc, rc
|
||||
}
|
||||
|
||||
+12
-13
@@ -21,7 +21,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/safecopy"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform"
|
||||
"gvisor.dev/gvisor/pkg/sentry/usage"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
@@ -604,7 +603,7 @@ func (mm *MemoryManager) invalidateLocked(ar usermem.AddrRange, invalidatePrivat
|
||||
}
|
||||
}
|
||||
|
||||
// Pin returns the platform.File ranges currently mapped by addresses in ar in
|
||||
// Pin returns the memmap.File ranges currently mapped by addresses in ar in
|
||||
// mm, acquiring a reference on the returned ranges which the caller must
|
||||
// release by calling Unpin. If not all addresses are mapped, Pin returns a
|
||||
// non-nil error. Note that Pin may return both a non-empty slice of
|
||||
@@ -674,15 +673,15 @@ type PinnedRange struct {
|
||||
Source usermem.AddrRange
|
||||
|
||||
// File is the mapped file.
|
||||
File platform.File
|
||||
File memmap.File
|
||||
|
||||
// Offset is the offset into File at which this PinnedRange begins.
|
||||
Offset uint64
|
||||
}
|
||||
|
||||
// FileRange returns the platform.File offsets mapped by pr.
|
||||
func (pr PinnedRange) FileRange() platform.FileRange {
|
||||
return platform.FileRange{pr.Offset, pr.Offset + uint64(pr.Source.Length())}
|
||||
// FileRange returns the memmap.File offsets mapped by pr.
|
||||
func (pr PinnedRange) FileRange() memmap.FileRange {
|
||||
return memmap.FileRange{pr.Offset, pr.Offset + uint64(pr.Source.Length())}
|
||||
}
|
||||
|
||||
// Unpin releases the reference held by prs.
|
||||
@@ -857,7 +856,7 @@ func (mm *MemoryManager) vecInternalMappingsLocked(ars usermem.AddrRangeSeq) saf
|
||||
}
|
||||
|
||||
// incPrivateRef acquires a reference on private pages in fr.
|
||||
func (mm *MemoryManager) incPrivateRef(fr platform.FileRange) {
|
||||
func (mm *MemoryManager) incPrivateRef(fr memmap.FileRange) {
|
||||
mm.privateRefs.mu.Lock()
|
||||
defer mm.privateRefs.mu.Unlock()
|
||||
refSet := &mm.privateRefs.refs
|
||||
@@ -878,8 +877,8 @@ func (mm *MemoryManager) incPrivateRef(fr platform.FileRange) {
|
||||
}
|
||||
|
||||
// decPrivateRef releases a reference on private pages in fr.
|
||||
func (mm *MemoryManager) decPrivateRef(fr platform.FileRange) {
|
||||
var freed []platform.FileRange
|
||||
func (mm *MemoryManager) decPrivateRef(fr memmap.FileRange) {
|
||||
var freed []memmap.FileRange
|
||||
|
||||
mm.privateRefs.mu.Lock()
|
||||
refSet := &mm.privateRefs.refs
|
||||
@@ -951,7 +950,7 @@ func (pmaSetFunctions) Merge(ar1 usermem.AddrRange, pma1 pma, ar2 usermem.AddrRa
|
||||
|
||||
// Discard internal mappings instead of trying to merge them, since merging
|
||||
// them requires an allocation and getting them again from the
|
||||
// platform.File might not.
|
||||
// memmap.File might not.
|
||||
pma1.internalMappings = safemem.BlockSeq{}
|
||||
return pma1, true
|
||||
}
|
||||
@@ -1012,12 +1011,12 @@ func (pseg pmaIterator) getInternalMappingsLocked() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pseg pmaIterator) fileRange() platform.FileRange {
|
||||
func (pseg pmaIterator) fileRange() memmap.FileRange {
|
||||
return pseg.fileRangeOf(pseg.Range())
|
||||
}
|
||||
|
||||
// Preconditions: pseg.Range().IsSupersetOf(ar). ar.Length != 0.
|
||||
func (pseg pmaIterator) fileRangeOf(ar usermem.AddrRange) platform.FileRange {
|
||||
func (pseg pmaIterator) fileRangeOf(ar usermem.AddrRange) memmap.FileRange {
|
||||
if checkInvariants {
|
||||
if !pseg.Ok() {
|
||||
panic("terminal pma iterator")
|
||||
@@ -1032,5 +1031,5 @@ func (pseg pmaIterator) fileRangeOf(ar usermem.AddrRange) platform.FileRange {
|
||||
|
||||
pma := pseg.ValuePtr()
|
||||
pstart := pseg.Start()
|
||||
return platform.FileRange{pma.off + uint64(ar.Start-pstart), pma.off + uint64(ar.End-pstart)}
|
||||
return memmap.FileRange{pma.off + uint64(ar.Start-pstart), pma.off + uint64(ar.End-pstart)}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user