mount: leave an unlinked file out of the periodic metadata flush

flushFileMetadata did not check the handle's delete mark. A file
unlinked while open before its deferred create reached the filer was
created again by the next periodic flush, which expects no entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris LuandClaude Opus 5.5 committed 2026-11-13 02:58:08 -08:00
1 parent df02ea508e
commit 30a90ab1ed
2 files changed
+35

No files matched your search

+4
View File
@@ -99,6 +99,10 @@ func (wfs *WFS) flushFileMetadata(fh *FileHandle) error {
if !fh.dirtyMetadata {
return nil
}
// Unlink marks under this lock; publishing would recreate the name.
if fh.isDeleted {
return nil
}
fileFullPath := fh.FullPath()
dir, name := fileFullPath.DirAndName()
@@ -0,0 +1,31 @@
//go:build !freebsd
package mount
import (
"testing"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
)
// A file unlinked while open, before its deferred create reached the filer,
// must not be created by the periodic metadata flush.
func TestPeriodicFlushSkipsUnlinkedHandle(t *testing.T) {
wfs, fake, fh, inode := openLinkTestFile(t)
fake.mu.Lock()
delete(fake.records, "tmp")
fake.mu.Unlock()
fh.baseEntry.Store(nil)
wfs.markHandleDeleted(inode)
fh.UpdateEntry(func(e *filer_pb.Entry) {
e.Chunks = append(e.Chunks, linkHandleChunk(2, 100))
e.Attributes.FileSize = 200
})
fh.dirtyMetadata = true
if err := wfs.flushFileMetadata(fh); err != nil {
t.Fatalf("periodic flush: %v", err)
}
if fake.stored("tmp") != nil {
t.Fatal("the periodic flush recreated the unlinked name")
}
}