diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-11-27 18:16:18 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-27 18:17:09 -0800 |
commit | 573622fdcaa5c016d3e047353c729ca73d211c0e (patch) | |
tree | 17a168bd7099ee85b8d00493521a07d19dee43ac /pkg/sentry/fs/gofer/inode.go | |
parent | 5bd02b224fd0eb81fc028644137a24d0bbf7dab5 (diff) |
Fix data race in fs.Async.
Replaces the WaitGroup with a RWMutex. Calls to Async hold the mutex for
reading, while AsyncBarrier takes the lock for writing. This ensures that all
executing Async work finishes before AsyncBarrier returns.
Also pushes the Async() call from Inode.Release into
gofer/InodeOperations.Release(). This removes a recursive Async call which
should not have been allowed in the first place. The gofer Release call is the
slow one (since it may make RPCs to the gofer), so putting the Async call there
makes sense.
PiperOrigin-RevId: 223093067
Change-Id: I116da7b20fce5ebab8d99c2ab0f27db7c89d890e
Diffstat (limited to 'pkg/sentry/fs/gofer/inode.go')
-rw-r--r-- | pkg/sentry/fs/gofer/inode.go | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 5811b8b12..7c6e5b025 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -333,8 +333,14 @@ func (i *inodeOperations) session() *session { // Release implements fs.InodeOperations.Release. func (i *inodeOperations) Release(ctx context.Context) { - i.fileState.Release(ctx) i.cachingInodeOps.Release() + + // Releasing the fileState may make RPCs to the gofer. There is + // no need to wait for those to return, so we can do this + // asynchronously. + fs.Async(func() { + i.fileState.Release(ctx) + }) } // Mappable implements fs.InodeOperations.Mappable. |