diff --git a/server/filestore.go b/server/filestore.go index c0c7361c00c..2ac494f853a 100644 --- a/server/filestore.go +++ b/server/filestore.go @@ -5086,10 +5086,15 @@ func (fs *fileStore) removeMsg(seq uint64, secure, viaLimits, needFSLock bool) ( // Grab record info, but use the pre-computed record length. ri, _, _, err := mb.slotInfo(int(seq - mb.cache.fseq)) if err != nil { + mb.finishedWithCache() + mb.mu.Unlock() + fsUnlock() return false, err } if err := mb.eraseMsg(seq, int(ri), int(msz), isLastBlock); err != nil { mb.finishedWithCache() + mb.mu.Unlock() + fsUnlock() return false, err } } diff --git a/server/filestore_test.go b/server/filestore_test.go index 80fafdec9c7..2d9c14e087f 100644 --- a/server/filestore_test.go +++ b/server/filestore_test.go @@ -10937,3 +10937,29 @@ func TestFileStoreDetectDeleteGapWithOnlySkipMsg(t *testing.T) { require_Len(t, mb.dmap.Size(), 0) }) } + +func TestFileStoreEraseMsgErr(t *testing.T) { + testFileStoreAllPermutations(t, func(t *testing.T, fcfg FileStoreConfig) { + cfg := StreamConfig{Name: "zzz", Subjects: []string{"foo"}, Storage: FileStorage} + created := time.Now() + fs, err := newFileStoreWithCreated(fcfg, cfg, created, prf(&fcfg), nil) + require_NoError(t, err) + defer fs.Stop() + + _, _, err = fs.StoreMsg("foo", nil, nil, 0) + require_NoError(t, err) + _, _, err = fs.StoreMsg("foo", nil, nil, 0) + require_NoError(t, err) + + mb := fs.getFirstBlock() + mb.mu.Lock() + if mb.cache == nil { + mb.mu.Unlock() + t.Fatal("Expected cache to be initialized") + } + // Set to a bogus value such that the file rename fails while performing the message erase. + mb.mfn = _EMPTY_ + mb.mu.Unlock() + fs.EraseMsg(2) + }) +}