From 520795aaad701854e9ffe84de1108954cf2b77f8 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Mon, 12 Jul 2021 18:27:59 -0700 Subject: Fix deadlock in procfs Kernfs provides an internal mechanism to defer calls to `DecRef()` because on the last reference `Filesystem.mu` must be held and most places that need to call `DecRef()` are inside the lock. The same can be true for filesystems that extend kernfs. procfs needs to look up files and `DecRef()` them inside the `kernfs.Filesystem.mu`. If the files happen to be procfs files, it can deadlock trying to decrement if it's the last reference. This change extends the mechanism to external callers to defer DecRefs to `vfs.FileDescription` and `vfs.VirtualDentries`. PiperOrigin-RevId: 384361647 --- pkg/refsvfs2/refs.go | 5 +++++ pkg/refsvfs2/refs_template.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'pkg/refsvfs2') diff --git a/pkg/refsvfs2/refs.go b/pkg/refsvfs2/refs.go index ef8beb659..fe3e4a1ca 100644 --- a/pkg/refsvfs2/refs.go +++ b/pkg/refsvfs2/refs.go @@ -28,6 +28,11 @@ type RefCounter interface { // DecRef decrements the object's reference count. Users of refs_template.Refs // may specify a destructor to be called once the reference count reaches zero. DecRef(ctx context.Context) +} + +// TryRefCounter is like RefCounter but allow the ref increment to be tried. +type TryRefCounter interface { + RefCounter // TryIncRef attempts to increment the reference count, but may fail if all // references have already been dropped, in which case it returns false. If diff --git a/pkg/refsvfs2/refs_template.go b/pkg/refsvfs2/refs_template.go index 1102c8adc..55b0a60a1 100644 --- a/pkg/refsvfs2/refs_template.go +++ b/pkg/refsvfs2/refs_template.go @@ -101,7 +101,7 @@ func (r *Refs) IncRef() { } } -// TryIncRef implements refs.RefCounter.TryIncRef. +// TryIncRef implements refs.TryRefCounter.TryIncRef. // // To do this safely without a loop, a speculative reference is first acquired // on the object. This allows multiple concurrent TryIncRef calls to distinguish -- cgit v1.2.3