summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/fusefrontend/root_node.go12
-rw-r--r--internal/fusefrontend_reverse/root_node.go17
-rw-r--r--internal/inomap/inomap.go13
-rw-r--r--internal/inomap/inomap_test.go17
4 files changed, 39 insertions, 20 deletions
diff --git a/internal/fusefrontend/root_node.go b/internal/fusefrontend/root_node.go
index 7d37520..7221be6 100644
--- a/internal/fusefrontend/root_node.go
+++ b/internal/fusefrontend/root_node.go
@@ -62,18 +62,28 @@ type RootNode struct {
}
func NewRootNode(args Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *RootNode {
+ var rootDev uint64
+ var st syscall.Stat_t
+ if err := syscall.Stat(args.Cipherdir, &st); err != nil {
+ tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, err)
+ } else {
+ rootDev = uint64(st.Dev)
+ }
+
if len(args.Exclude) > 0 {
tlog.Warn.Printf("Forward mode does not support -exclude")
}
+
ivLen := nametransform.DirIVLen
if args.PlaintextNames {
ivLen = 0
}
+
rn := &RootNode{
args: args,
nameTransform: n,
contentEnc: c,
- inoMap: inomap.New(),
+ inoMap: inomap.New(rootDev),
dirCache: dirCache{ivLen: ivLen},
quirks: syscallcompat.DetectQuirks(args.Cipherdir),
}
diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go
index d4c1e37..e15ddb0 100644
--- a/internal/fusefrontend_reverse/root_node.go
+++ b/internal/fusefrontend_reverse/root_node.go
@@ -2,10 +2,13 @@ package fusefrontend_reverse
import (
"log"
+ "os"
"path/filepath"
"strings"
"syscall"
+ "github.com/rfjakob/gocryptfs/v2/internal/exitcodes"
+
"github.com/rfjakob/gocryptfs/v2/internal/tlog"
"golang.org/x/sys/unix"
@@ -46,12 +49,14 @@ type RootNode struct {
// ReverseFS provides an encrypted view.
func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *RootNode {
var rootDev uint64
- if args.OneFileSystem {
- var st syscall.Stat_t
- err := syscall.Stat(args.Cipherdir, &st)
- if err != nil {
- log.Panicf("Could not stat backing directory %q: %v", args.Cipherdir, err)
+ var st syscall.Stat_t
+ if err := syscall.Stat(args.Cipherdir, &st); err != nil {
+ tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, err)
+ if args.OneFileSystem {
+ tlog.Fatal.Printf("This is a fatal error in combination with -one-file-system")
+ os.Exit(exitcodes.CipherDir)
}
+ } else {
rootDev = uint64(st.Dev)
}
@@ -59,7 +64,7 @@ func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransf
args: args,
nameTransform: n,
contentEnc: c,
- inoMap: inomap.New(),
+ inoMap: inomap.New(rootDev),
rootDev: rootDev,
}
if len(args.Exclude) > 0 || len(args.ExcludeWildcard) > 0 || len(args.ExcludeFrom) > 0 {
diff --git a/internal/inomap/inomap.go b/internal/inomap/inomap.go
index 97f9b61..997ea9b 100644
--- a/internal/inomap/inomap.go
+++ b/internal/inomap/inomap.go
@@ -49,13 +49,22 @@ type InoMap struct {
}
// New returns a new InoMap.
-func New() *InoMap {
- return &InoMap{
+// Inode numbers on device `rootDev` will be passed through as-is.
+// If `rootDev` is zero, the first Translate() call decides the effective
+// rootDev.
+func New(rootDev uint64) *InoMap {
+ m := &InoMap{
namespaceMap: make(map[namespaceData]uint16),
namespaceNext: 0,
spillMap: make(map[QIno]uint64),
spillNext: 0,
}
+ if rootDev > 0 {
+ // Reserve namespace 0 for rootDev
+ m.namespaceMap[namespaceData{rootDev, 0}] = 0
+ m.namespaceNext = 1
+ }
+ return m
}
var spillWarn sync.Once
diff --git a/internal/inomap/inomap_test.go b/internal/inomap/inomap_test.go
index 6fbb4ef..9ec2932 100644
--- a/internal/inomap/inomap_test.go
+++ b/internal/inomap/inomap_test.go
@@ -6,7 +6,7 @@ import (
)
func TestTranslate(t *testing.T) {
- m := New()
+ m := New(0)
q := QIno{Ino: 1}
out := m.Translate(q)
if out != 1 {
@@ -25,12 +25,7 @@ func TestTranslate(t *testing.T) {
func TestTranslateStress(t *testing.T) {
const baseDev = 12345
- m := New()
-
- // Make sure baseDev gets namespace id zero
- var q QIno
- q.Dev = baseDev
- m.Translate(q)
+ m := New(baseDev)
var wg sync.WaitGroup
wg.Add(4)
@@ -100,7 +95,7 @@ func TestTranslateStress(t *testing.T) {
}
func TestSpill(t *testing.T) {
- m := New()
+ m := New(0)
var q QIno
q.Ino = maxPassthruIno + 1
out1 := m.Translate(q)
@@ -119,7 +114,7 @@ func TestSpill(t *testing.T) {
// TestUniqueness checks that unique (Dev, Flags, Ino) tuples get unique inode
// numbers
func TestUniqueness(t *testing.T) {
- m := New()
+ m := New(0)
var q QIno
outMap := make(map[uint64]struct{})
for q.Dev = 0; q.Dev < 10; q.Dev++ {
@@ -141,7 +136,7 @@ func TestUniqueness(t *testing.T) {
}
func BenchmarkTranslateSingleDev(b *testing.B) {
- m := New()
+ m := New(0)
var q QIno
for n := 0; n < b.N; n++ {
q.Ino = uint64(n % 1000)
@@ -150,7 +145,7 @@ func BenchmarkTranslateSingleDev(b *testing.B) {
}
func BenchmarkTranslateManyDevs(b *testing.B) {
- m := New()
+ m := New(0)
var q QIno
for n := 0; n < b.N; n++ {
q.Dev = uint64(n % 10)