From 76a96a91b48cdcd9006def608b384350cd1cda85 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 30 Jun 2026 10:52:12 +0100 Subject: [PATCH] mega: fix hard deleted files reappearing in listings - fixes #9554 The mega backend keeps the whole account as an in-memory tree. go-mega's Delete with destroy=true (hard_delete) removed the node from its lookup table but left it in its parent's children, so a hard deleted file kept showing up in directory listings until the tree was reloaded. In a long-running mount or serve the file reappeared once the VFS directory cache expired and re-read the backend. Update go-mega to pick up the fix, and let the ghost test exercise whichever delete mode the remote is configured with. (cherry picked from commit b59a17e5e83a08fd45caec5ff8aed0177fd630d9) --- backend/mega/mega_internal_test.go | 15 +++------------ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/backend/mega/mega_internal_test.go b/backend/mega/mega_internal_test.go index c39dfff4d..42fc41457 100644 --- a/backend/mega/mega_internal_test.go +++ b/backend/mega/mega_internal_test.go @@ -16,21 +16,12 @@ import ( // process disappears from listings straight away rather than lingering as a // ghost until go-mega's next event poll reconciles the in-memory tree. // -// The ghost is a race between the upload's server event being replayed and -// the delete, so it puts, removes and lists in a tight loop to make it show -// up reliably. +// It puts, removes and lists in a tight loop to make any lingering entry +// show up reliably, exercising whichever delete mode the remote is +// configured with (hard_delete or the default trash). func (f *Fs) InternalTestGhostAfterRemove(t *testing.T) { ctx := context.Background() - // Exercise the default soft-delete path - the hard_delete=true path - // hits a separate bug in go-mega's Delete which leaves the node in its - // parent's children regardless of what rclone does. - if f.opt.HardDelete { - oldHardDelete := f.opt.HardDelete - f.opt.HardDelete = false - defer func() { f.opt.HardDelete = oldHardDelete }() - } - dir := "ghost-test" require.NoError(t, f.Mkdir(ctx, dir)) defer func() { _ = f.Rmdir(ctx, dir) }() diff --git a/go.mod b/go.mod index 77994df88..f4387cb2e 100644 --- a/go.mod +++ b/go.mod @@ -82,7 +82,7 @@ require ( github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 - github.com/t3rm1n4l/go-mega v0.0.0-20251120131202-6845944c051c + github.com/t3rm1n4l/go-mega v0.0.0-20260630094356-4de2f127f34a github.com/unknwon/goconfig v1.0.0 github.com/willscott/go-nfs v0.0.4 github.com/winfsp/cgofuse v1.6.1-0.20260126094232-f2c4fccdb286 diff --git a/go.sum b/go.sum index 83604b46d..7d02d1636 100644 --- a/go.sum +++ b/go.sum @@ -666,8 +666,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/t3rm1n4l/go-mega v0.0.0-20251120131202-6845944c051c h1:dtcOwRimeiBFrlutmF6K94l0rxYFARNFMA+lSQ41C+M= -github.com/t3rm1n4l/go-mega v0.0.0-20251120131202-6845944c051c/go.mod h1:BF/l2jNyK+2h/BJZ7VLMAz6m/IWjA2F67gTjV1C/+Bo= +github.com/t3rm1n4l/go-mega v0.0.0-20260630094356-4de2f127f34a h1:VQ9CmpYeTgdFvg748N6tIOHBZn+hXjJe2xNuOJHW07E= +github.com/t3rm1n4l/go-mega v0.0.0-20260630094356-4de2f127f34a/go.mod h1:BF/l2jNyK+2h/BJZ7VLMAz6m/IWjA2F67gTjV1C/+Bo= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s= github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=