From 2f278efffc8f1b45e0f7dce81a652cb1b7f2991e Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 5 Mar 2026 18:13:14 +0000 Subject: [PATCH] filer: serialise concurrent index read-modify-write in pending metadata deletion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add remoteMetadataDeletionIndexMu to Filer and acquire it for the full read→mutate→commit sequence in markRemoteMetadataDeletionPending and clearRemoteMetadataDeletionPending, preventing concurrent goroutines from overwriting each other's index updates. Made-with: Cursor --- weed/filer/filer.go | 3 ++- weed/filer/filer_delete_entry.go | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/weed/filer/filer.go b/weed/filer/filer.go index 8e52caf15..d2364b155 100644 --- a/weed/filer/filer.go +++ b/weed/filer/filer.go @@ -62,7 +62,8 @@ type Filer struct { deletionQuit chan struct{} DeletionRetryQueue *DeletionRetryQueue EmptyFolderCleaner *empty_folder_cleanup.EmptyFolderCleaner - remoteDeletionLoop sync.Once + remoteDeletionLoop sync.Once + remoteMetadataDeletionIndexMu sync.Mutex } func NewFiler(masters pb.ServerDiscovery, grpcDialOption grpc.DialOption, filerHost pb.ServerAddress, filerGroup string, collection string, replication string, dataCenter string, maxFilenameLength uint32, notifyFn func()) *Filer { diff --git a/weed/filer/filer_delete_entry.go b/weed/filer/filer_delete_entry.go index 0aba250cb..183897c40 100644 --- a/weed/filer/filer_delete_entry.go +++ b/weed/filer/filer_delete_entry.go @@ -253,6 +253,9 @@ func (f *Filer) reconcilePendingRemoteMetadataDeletions(ctx context.Context) err } func (f *Filer) markRemoteMetadataDeletionPending(ctx context.Context, path util.FullPath) error { + f.remoteMetadataDeletionIndexMu.Lock() + defer f.remoteMetadataDeletionIndexMu.Unlock() + txnCtx, beginErr := f.BeginTransaction(ctx) if beginErr != nil { return beginErr @@ -289,6 +292,9 @@ func (f *Filer) markRemoteMetadataDeletionPending(ctx context.Context, path util } func (f *Filer) clearRemoteMetadataDeletionPending(ctx context.Context, path util.FullPath) error { + f.remoteMetadataDeletionIndexMu.Lock() + defer f.remoteMetadataDeletionIndexMu.Unlock() + txnCtx, beginErr := f.BeginTransaction(ctx) if beginErr != nil { return beginErr