From 9cb7dc7204c7e561ffc068d89b7db298c97bbe3b Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 10 Aug 2026 00:31:16 -0700 Subject: [PATCH] filer: repack keeps the entry TTL and notifies subscribers New chunks were assigned with the TTL the request query implied while the entry kept its own, so repacking a permanent file with ?ttl= made its chunks expire under permanent metadata. Force the entry TTL onto the storage option instead. Filer.UpdateEntry only writes the store, so metadata subscribers never heard about the new chunk ids while the old ones were queued for deletion. Emit the update event the way the gRPC UpdateEntry path does. --- weed/server/filer_server_format.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/weed/server/filer_server_format.go b/weed/server/filer_server_format.go index 442d60379..b89c153a1 100644 --- a/weed/server/filer_server_format.go +++ b/weed/server/filer_server_format.go @@ -262,6 +262,10 @@ func (fs *FilerServer) formatRepack(ctx context.Context, w http.ResponseWriter, } } + // Repack rewrites where bytes are cut, never their lifetime: new chunks + // must carry the entry's TTL, not whatever the request query implies. + so.TtlSeconds = entry.TtlSec + size := int64(entry.FileSize) lookup := fs.filer.MasterClient.GetLookupFileIdFunction() chunkViews := filer.ViewFromChunks(ctx, lookup, oldChunks, 0, size) @@ -343,6 +347,9 @@ func (fs *FilerServer) formatRepack(ctx context.Context, w http.ResponseWriter, return } fs.filer.DeleteChunks(context.WithoutCancel(ctx), fullPath, oldChunks) + // Filer.UpdateEntry only writes the store; notify subscribers (sync, + // backup, replication) of the new chunk ids like the gRPC path does. + fs.filer.NotifyUpdateEvent(ctx, entry, &newEntry, true, false, nil) writeJsonQuiet(w, r, http.StatusOK, map[string]interface{}{ "name": entry.Name(), "size": size, "extents": len(layout.ExtentSizes), })