mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-15 16:28:30 +01:00
* mount: record a hard link's looked-up names on its inode Lookup mapped a second name of a hard-linked file to the existing inode without adding it to the inode's names, so GetAllPaths missed it and the final forget left it mapped to a released inode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * mount: keep an open file publishing when a peer unlinks one of its names A delete event from another client marked the inode's open handle deleted even when other names still held the hard-linked file, so every later fsync reported success without saving metadata. The delete event's entry carries the link count the filer decided on, so an alias delete now drops only that name, keeps the handle on a name this mount knows, and has the next flush read the survivor's stored entry before publishing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * mount: test peer unlinks of a hard link name held open Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * 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> * mount: read a pending link change before a periodic metadata flush Only flushMetadataToFiler applied linkRefresh. After a peer unlinked one name, the periodic flush kept publishing over the old link count, so the filer refused every one until a regular flush ran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * mount: test the periodic flush after a peer unlinks a hard link name Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
809 B
Go
32 lines
809 B
Go
//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")
|
|
}
|
|
}
|