From fb2abc538035e47fd1615ab6cf754a5d1bb3e70e Mon Sep 17 00:00:00 2001 From: Pavel Kalinnikov Date: Wed, 22 Nov 2023 17:26:44 +0000 Subject: [PATCH 1/3] pebble: fix deadlock after MemFS.SetIgnoreSyncs Before this fix, if someone calls SetIgnoreSyncs() on a non-strict MemFS, it does not unlock the mutex before returning. This causes all other methods of MemFS to deadlock. --- vfs/mem_fs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vfs/mem_fs.go b/vfs/mem_fs.go index 7ccd8e71d69..19f6fc61247 100644 --- a/vfs/mem_fs.go +++ b/vfs/mem_fs.go @@ -117,11 +117,11 @@ func (y *MemFS) String() string { // SetIgnoreSyncs sets the MemFS.ignoreSyncs field. See the usage comment with NewStrictMem() for // details. func (y *MemFS) SetIgnoreSyncs(ignoreSyncs bool) { - y.mu.Lock() if !y.strict { // noop return } + y.mu.Lock() y.ignoreSyncs = ignoreSyncs y.mu.Unlock() } From 3c57d69b0788537f929c07aa2c748c7b92c24cde Mon Sep 17 00:00:00 2001 From: Pavel Kalinnikov Date: Wed, 22 Nov 2023 17:31:24 +0000 Subject: [PATCH 2/3] pebble: panic on incorrect strict MemFS methods use Strict MemFS methods can be used by mistake on a non-strict MemFS. Panic if this happens, instead of (previously) ignoring this silently. This saves a test writer time being confused if they mis-use the type. --- vfs/mem_fs.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vfs/mem_fs.go b/vfs/mem_fs.go index 19f6fc61247..56cc4741319 100644 --- a/vfs/mem_fs.go +++ b/vfs/mem_fs.go @@ -118,8 +118,7 @@ func (y *MemFS) String() string { // details. func (y *MemFS) SetIgnoreSyncs(ignoreSyncs bool) { if !y.strict { - // noop - return + panic("SetIgnoreSyncs can only be used on a strict MemFS") } y.mu.Lock() y.ignoreSyncs = ignoreSyncs @@ -130,8 +129,7 @@ func (y *MemFS) SetIgnoreSyncs(ignoreSyncs bool) { // NewStrictMem() for details. func (y *MemFS) ResetToSyncedState() { if !y.strict { - // noop - return + panic("ResetToSyncedState can only be used on a strict MemFS") } y.mu.Lock() y.root.resetToSyncedState() From f5319e5c5c4b4d8ce094b535ec41f79b84695f70 Mon Sep 17 00:00:00 2001 From: Pavel Kalinnikov Date: Wed, 22 Nov 2023 17:35:13 +0000 Subject: [PATCH 3/3] pebble: unindent MemFS.Sync() while here --- vfs/mem_fs.go | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/vfs/mem_fs.go b/vfs/mem_fs.go index 56cc4741319..fa44847b4f4 100644 --- a/vfs/mem_fs.go +++ b/vfs/mem_fs.go @@ -773,22 +773,23 @@ func (f *memFile) Stat() (os.FileInfo, error) { } func (f *memFile) Sync() error { - if f.fs != nil && f.fs.strict { - f.fs.mu.Lock() - defer f.fs.mu.Unlock() - if f.fs.ignoreSyncs { - return nil - } - if f.n.isDir { - f.n.syncedChildren = make(map[string]*memNode) - for k, v := range f.n.children { - f.n.syncedChildren[k] = v - } - } else { - f.n.mu.Lock() - f.n.mu.syncedData = slices.Clone(f.n.mu.data) - f.n.mu.Unlock() + if f.fs == nil || !f.fs.strict { + return nil + } + f.fs.mu.Lock() + defer f.fs.mu.Unlock() + if f.fs.ignoreSyncs { + return nil + } + if f.n.isDir { + f.n.syncedChildren = make(map[string]*memNode) + for k, v := range f.n.children { + f.n.syncedChildren[k] = v } + } else { + f.n.mu.Lock() + f.n.mu.syncedData = slices.Clone(f.n.mu.data) + f.n.mu.Unlock() } return nil }