From 1bc1db620b061aabf59469a5eb4fb60e3e1701a3 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 31 Jul 2021 13:24:25 +0200 Subject: fusefrontend: -sharedstorage: present stable inode numbers Use the Gen field (inode generation) to distinguish hard links while passing the real inode numbers to userspace. Fixes https://github.com/rfjakob/gocryptfs/issues/584 --- internal/fusefrontend/node.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'internal/fusefrontend/node.go') diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go index 5d3c178..8a3cfa2 100644 --- a/internal/fusefrontend/node.go +++ b/internal/fusefrontend/node.go @@ -40,6 +40,24 @@ func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ch // Translate ciphertext size in `out.Attr.Size` to plaintext size n.translateSize(dirfd, cName, &out.Attr) + rn := n.rootNode() + if rn.args.SharedStorage { + // If we already have a child node that matches what we found on disk* + // (as reflected in `ch`), return it here. + // + // This keeps the Node ID for each directory entry stable + // (until forgotten). + // + // *We compare `name`, `Ino`, `Mode` (but not `Gen`!) + old := n.Inode.GetChild(name) + if old != nil && + old.StableAttr().Ino == ch.StableAttr().Ino && + // `Mode` has already been masked with syscall.S_IFMT by n.newChild() + old.StableAttr().Mode == ch.StableAttr().Mode { + return old, 0 + } + } + return ch, 0 } -- cgit v1.2.3