[ARVADOS] updated: 2.1.0-930-gd6bbaafe9
Git user
git at public.arvados.org
Fri Jul 9 14:12:07 UTC 2021
Summary of changes:
sdk/go/arvados/fs_base.go | 46 ++++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
via d6bbaafe93600ac48fec642748ea2d303bcd1bd3 (commit)
from d14abaa117d6f93609d2ccd0ba9af3004585ef62 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit d6bbaafe93600ac48fec642748ea2d303bcd1bd3
Author: Tom Clegg <tom at curii.com>
Date: Mon Jul 5 14:32:39 2021 -0400
17853: Fix map write when only RLock held.
Update DebugLocksPanicMode to check RLock/Lock as appropriate.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/sdk/go/arvados/fs_base.go b/sdk/go/arvados/fs_base.go
index 65c207162..4dd8b53e1 100644
--- a/sdk/go/arvados/fs_base.go
+++ b/sdk/go/arvados/fs_base.go
@@ -36,17 +36,30 @@ type syncer interface {
Sync() error
}
-func debugPanicIfNotLocked(l sync.Locker) {
+func debugPanicIfNotLocked(l sync.Locker, writing bool) {
if !DebugLocksPanicMode {
return
}
race := false
- go func() {
- l.Lock()
- race = true
- l.Unlock()
- }()
- time.Sleep(10)
+ if rl, ok := l.(interface {
+ RLock()
+ RUnlock()
+ }); ok && writing {
+ go func() {
+ // Fail if we can grab the read lock during an
+ // operation that purportedly has write lock.
+ rl.RLock()
+ race = true
+ rl.RUnlock()
+ }()
+ } else {
+ go func() {
+ l.Lock()
+ race = true
+ l.Unlock()
+ }()
+ }
+ time.Sleep(100)
if race {
panic("bug: caller-must-have-lock func called, but nobody has lock")
}
@@ -288,7 +301,7 @@ func (n *treenode) IsDir() bool {
}
func (n *treenode) Child(name string, replace func(inode) (inode, error)) (child inode, err error) {
- debugPanicIfNotLocked(n)
+ debugPanicIfNotLocked(n, false)
child = n.inodes[name]
if name == "" || name == "." || name == ".." {
err = ErrInvalidArgument
@@ -302,8 +315,10 @@ func (n *treenode) Child(name string, replace func(inode) (inode, error)) (child
return
}
if newchild == nil {
+ debugPanicIfNotLocked(n, true)
delete(n.inodes, name)
} else if newchild != child {
+ debugPanicIfNotLocked(n, true)
n.inodes[name] = newchild
n.fileinfo.modTime = time.Now()
child = newchild
@@ -351,7 +366,7 @@ func (n *treenode) Sync() error {
func (n *treenode) MemorySize() (size int64) {
n.RLock()
defer n.RUnlock()
- debugPanicIfNotLocked(n)
+ debugPanicIfNotLocked(n, false)
for _, inode := range n.inodes {
size += inode.MemorySize()
}
@@ -414,13 +429,12 @@ func (fs *fileSystem) openFile(name string, flag int, perm os.FileMode) (*fileha
}
}
createMode := flag&os.O_CREATE != 0
- if createMode {
- parent.Lock()
- defer parent.Unlock()
- } else {
- parent.RLock()
- defer parent.RUnlock()
- }
+ // We always need to take Lock() here, not just RLock(). Even
+ // if we know we won't be creating a file, parent might be a
+ // lookupnode, which sometimes populates its inodes map during
+ // a Child() call.
+ parent.Lock()
+ defer parent.Unlock()
n, err := parent.Child(name, nil)
if err != nil {
return nil, err
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list