Don't hold gofer.filesystem.renameMu during dentry destruction.

PiperOrigin-RevId: 325546629
This commit is contained in:
Jamie Liu
2020-08-07 18:41:48 -07:00
committed by gVisor bot
parent 8f6d576afe
commit 343661770a
2 changed files with 17 additions and 5 deletions
+15 -5
View File
@@ -1158,7 +1158,8 @@ func (d *dentry) OnZeroWatches(ctx context.Context) {
// operation. One of the calls may destroy the dentry, so subsequent calls will
// do nothing.
//
// Preconditions: d.fs.renameMu must be locked for writing.
// Preconditions: d.fs.renameMu must be locked for writing; it may be
// temporarily unlocked.
func (d *dentry) checkCachingLocked(ctx context.Context) {
// Dentries with a non-zero reference count must be retained. (The only way
// to obtain a reference on a dentry with zero references is via path
@@ -1238,11 +1239,13 @@ func (d *dentry) checkCachingLocked(ctx context.Context) {
}
}
// destroyLocked destroys the dentry. It may flushes dirty pages from cache,
// close p9 file and remove reference on parent dentry.
// destroyLocked destroys the dentry.
//
// Preconditions: d.fs.renameMu must be locked for writing. d.refs == 0. d is
// not a child dentry.
// Preconditions:
// * d.fs.renameMu must be locked for writing; it may be temporarily unlocked.
// * d.refs == 0.
// * d.parent.children[d.name] != d, i.e. d is not reachable by path traversal
// from its former parent dentry.
func (d *dentry) destroyLocked(ctx context.Context) {
switch atomic.LoadInt64(&d.refs) {
case 0:
@@ -1254,6 +1257,10 @@ func (d *dentry) destroyLocked(ctx context.Context) {
panic("dentry.destroyLocked() called with references on the dentry")
}
// Allow the following to proceed without renameMu locked to improve
// scalability.
d.fs.renameMu.Unlock()
mf := d.fs.mfp.MemoryFile()
d.handleMu.Lock()
d.dataMu.Lock()
@@ -1315,6 +1322,9 @@ func (d *dentry) destroyLocked(ctx context.Context) {
delete(d.fs.syncableDentries, d)
d.fs.syncMu.Unlock()
}
d.fs.renameMu.Lock()
// Drop the reference held by d on its parent without recursively locking
// d.fs.renameMu.
if d.parent != nil {
+2
View File
@@ -52,6 +52,8 @@ func TestDestroyIdempotent(t *testing.T) {
}
parent.cacheNewChildLocked(child, "child")
fs.renameMu.Lock()
defer fs.renameMu.Unlock()
child.checkCachingLocked(ctx)
if got := atomic.LoadInt64(&child.refs); got != -1 {
t.Fatalf("child.refs=%d, want: -1", got)