From 72e913e1e766649d204cb414665d6dbe6d20c2b4 Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Mon, 5 Nov 2018 16:11:34 -0800 Subject: [PATCH] libfuse: on macOS, delete a moved node from the `nodes` cache Otherwise, the kernel might still treat it as having the old parent ID. This shouldn't mess up any kernel caching or libkbfs garbage collection, since if the original node for the moved node is still in use, bazil.org would hold a reference to it. But it's definitely a little weird that the same node might have two inodes pointing into it. We should remove this once the osxfuse issue is fixed. Issue: #1881 Issue: KBFS-3576 Issue: osxfuse/osxfuse#553 --- libfuse/dir.go | 17 +++++++++++++++++ libfuse/mount_test.go | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libfuse/dir.go b/libfuse/dir.go index 486d63aa55..def3d6bb22 100644 --- a/libfuse/dir.go +++ b/libfuse/dir.go @@ -8,6 +8,7 @@ import ( "fmt" "math" "os" + "runtime" "strings" "sync" "syscall" @@ -731,6 +732,22 @@ func (d *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, switch e := err.(type) { case nil: + // Because of https://github.com/osxfuse/osxfuse/issues/553, a + // node that's moved to a different directory needs to get a + // new Node object (and inode) on the next lookup. The + // easiest way to do that is to remove the moved node from + // this folder's local cache. See KBFS-3576. + if runtime.GOOS == "darwin" && + d.node.GetID() != realNewDir.node.GetID() { + movedNode, _, err := d.folder.fs.config.KBFSOps().Lookup( + ctx, realNewDir.node, req.NewName) + if err == nil { + d.folder.nodesMu.Lock() + delete(d.folder.nodes, movedNode.GetID()) + d.folder.nodesMu.Unlock() + } + } + return nil case libkbfs.RenameAcrossDirsError: var execPathErr error diff --git a/libfuse/mount_test.go b/libfuse/mount_test.go index 14f2cd1a36..83159a9a56 100644 --- a/libfuse/mount_test.go +++ b/libfuse/mount_test.go @@ -3931,7 +3931,8 @@ func TestInodes(t *testing.T) { syncFilename(t, p2) inode2 := getInode(p2) - if inode != inode2 { + if runtime.GOOS != "darwin" && inode != inode2 { + // (See KBFS-3576 for the darwin restriction here.) t.Fatalf("Inode changed after rename: %d vs %d", inode, inode2) }