Ensure fsimpl/gofer.dentryPlatformFile.hostFileMapper is initialized.

Fixes #1812. (The more direct cause of the deadlock is panic unsafety because
the historically high cost of defer means that we avoid it in hot paths,
including much of MM; defer is much cheaper as of Go 1.14, but still a
measurable overhead.)

PiperOrigin-RevId: 294560316
This commit is contained in:
gVisor bot
2020-02-11 17:38:57 -08:00
parent e07eacc99f
commit 6dced977ea
2 changed files with 16 additions and 6 deletions
+11 -6
View File
@@ -65,13 +65,18 @@ type mapping struct {
writable bool
}
// NewHostFileMapper returns a HostFileMapper with no references or cached
// mappings.
// Init must be called on zero-value HostFileMappers before first use.
func (f *HostFileMapper) Init() {
f.refs = make(map[uint64]int32)
f.mappings = make(map[uint64]mapping)
}
// NewHostFileMapper returns an initialized HostFileMapper allocated on the
// heap with no references or cached mappings.
func NewHostFileMapper() *HostFileMapper {
return &HostFileMapper{
refs: make(map[uint64]int32),
mappings: make(map[uint64]mapping),
}
f := &HostFileMapper{}
f.Init()
return f
}
// IncRefOn increments the reference count on all offsets in mr.
+5
View File
@@ -571,6 +571,8 @@ func (fd *regularFileFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpt
default:
panic(fmt.Sprintf("unknown InteropMode %v", d.fs.opts.interop))
}
// After this point, d may be used as a memmap.Mappable.
d.pf.hostFileMapperInitOnce.Do(d.pf.hostFileMapper.Init)
return vfs.GenericConfigureMMap(&fd.vfsfd, d, opts)
}
@@ -799,6 +801,9 @@ type dentryPlatformFile struct {
// If this dentry represents a regular file, and handle.fd >= 0,
// hostFileMapper caches mappings of handle.fd.
hostFileMapper fsutil.HostFileMapper
// hostFileMapperInitOnce is used to lazily initialize hostFileMapper.
hostFileMapperInitOnce sync.Once
}
// IncRef implements platform.File.IncRef.