diff options
author | Michael Pratt <mpratt@google.com> | 2019-06-21 16:26:26 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-06-21 16:27:26 -0700 |
commit | 6f933a934f715f4bcd4f4e4430d4040b6cf61032 (patch) | |
tree | 4402c27bcb692270850cffe6d7c5b862b3321b6d /pkg/p9/handlers.go | |
parent | ae4ef32b8c77a067229c593af784fbfa3098fd97 (diff) |
Remove O(n) lookup on unlink/rename
Currently, the path tracking in the gofer involves an O(n) lookup of
child fidRefs. This causes a significant overhead on unlinks in
directories with lots of child fidRefs (<4k).
In this transition, pathNode moves from sync.Map to normal synchronized
maps. There is a small chance of contention in walk, but the lock is
held for a very short time (and sync.Map also had a chance of requiring
locking).
OTOH, sync.Map makes it very difficult to add a fidRef reverse map.
PiperOrigin-RevId: 254489952
Diffstat (limited to 'pkg/p9/handlers.go')
-rw-r--r-- | pkg/p9/handlers.go | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index 9e622227b..999b4f684 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -224,7 +224,7 @@ func (t *Tattach) handle(cs *connState) message { file: sf, refs: 1, mode: attr.Mode.FileType(), - pathNode: &cs.server.pathTree, + pathNode: cs.server.pathTree, } defer root.DecRef() @@ -552,8 +552,8 @@ func (t *Tunlinkat) handle(cs *connState) message { // since we always acquire deeper in the hierarchy, we know // that we are free of lock cycles. childPathNode := ref.pathNode.pathNodeFor(t.Name) - childPathNode.mu.Lock() - defer childPathNode.mu.Unlock() + childPathNode.opMu.Lock() + defer childPathNode.opMu.Unlock() // Do the unlink. err = ref.file.UnlinkAt(t.Name, t.Flags) |