aboutsummaryrefslogtreecommitdiff
path: root/internal/fusefrontend_reverse/root_node.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/fusefrontend_reverse/root_node.go')
-rw-r--r--internal/fusefrontend_reverse/root_node.go24
1 files changed, 24 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go
index 8a2afd9..1a68ffd 100644
--- a/internal/fusefrontend_reverse/root_node.go
+++ b/internal/fusefrontend_reverse/root_node.go
@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync/atomic"
"syscall"
"github.com/rfjakob/gocryptfs/v2/internal/exitcodes"
@@ -45,6 +46,13 @@ type RootNode struct {
// If a file name length is shorter than shortNameMax, there is no need to
// hash it.
shortNameMax int
+ // gen is the node generation number. Normally, it is always set to 1,
+ // but reverse mode, like -sharestorage, uses an incrementing counter for new nodes.
+ // This makes each directory entry unique (even hard links),
+ // makes go-fuse hand out separate FUSE Node IDs for each, and prevents
+ // bizarre problems when inode numbers are reused behind our back,
+ // like this one: https://github.com/rfjakob/gocryptfs/issues/802
+ gen uint64
}
// NewRootNode returns an encrypted FUSE overlay filesystem.
@@ -149,3 +157,19 @@ func (rn *RootNode) excludeDirEntries(d *dirfdPlus, entries []fuse.DirEntry) (fi
}
return filtered
}
+
+// uniqueStableAttr returns a fs.StableAttr struct with a unique generation number,
+// preventing files to appear hard-linked, even when they have the same inode number.
+//
+// This is good because inode numbers can be reused behind our back, which could make
+// unrelated files appear hard-linked.
+// Example: https://github.com/rfjakob/gocryptfs/issues/802
+func (rn *RootNode) uniqueStableAttr(mode uint32, ino uint64) fs.StableAttr {
+ return fs.StableAttr{
+ Mode: mode,
+ Ino: ino,
+ // Make each directory entry a unique node by using a unique generation
+ // value. Also see the comment at RootNode.gen for details.
+ Gen: atomic.AddUint64(&rn.gen, 1),
+ }
+}