261021.24 · e6a571cefd9377bad7daa04fcae550796e746185
Fix the issues a review of the server found
- --persist on a server's only tree removed the plain lock before
joining, so the server looked gone and the start failed with E98.
The lock now goes only once the new link is in place.
- Each join makes a registry link of a new name, so the server tells a
re-join from its own link even when the new link reuses the inode.
The name is cut short to stay under NAME_MAX, so deep directories
can be served, and a link that fails to register is removed.
- A share's search no longer names dot entries its listing hides.
- serve waits for its loop and signal handler before closing the
registry, which they may still lock or unlock: a data race that
could release another registry's flock. The git cache is reset in
place rather than replaced under an earlier server's goroutines.
- A persistent lock counts as served only if the running server wrote
it, so a lock kept from before a reboot no longer reports a URL that
another tree has taken.
- A secret token spelled with escapes no longer reaches the log.
- A share's DNS lookup runs before the registry is locked, so it holds
up no other www.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
reading declarations
Changes to cache.go. All files
@@ -66,6 +66,17 @@ func (c *cache) put(key string, val any, size int64) { } } +// reset empties c and gives it a new budget. A server resets the cache+// it shares with what is left of an earlier server in the same process,+// as in tests, rather than replace it under that server's goroutines.+func (c *cache) reset(max int64) {+ c.mu.Lock()+ defer c.mu.Unlock()+ c.max, c.used = max, 0+ c.order.Init()+ clear(c.items)+}+ func (c *cache) drop(key string) { c.mu.Lock() defer c.mu.Unlock()