aboutsummaryrefslogtreecommitdiff
path: root/internal/inomap
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-05-03 15:22:10 +0200
committerJakob Unterwurzacher2020-05-03 15:22:10 +0200
commit518771e4e247762f60c5594de427a8c86f19bd57 (patch)
tree625aed59393508f8f3b61787963012a684b37d8e /internal/inomap
parentdb93a6c54cfd615561207f1bbcf7e665ebc296b6 (diff)
fusefrontend_reverse: use inomap for inode number translation
Gets rid of static inode number value limitations. Fixes https://github.com/rfjakob/gocryptfs/issues/457
Diffstat (limited to 'internal/inomap')
-rw-r--r--internal/inomap/inomap.go16
-rw-r--r--internal/inomap/inomap_test.go2
-rw-r--r--internal/inomap/qino.go26
3 files changed, 30 insertions, 14 deletions
diff --git a/internal/inomap/inomap.go b/internal/inomap/inomap.go
index c277849..0ca43e4 100644
--- a/internal/inomap/inomap.go
+++ b/internal/inomap/inomap.go
@@ -15,6 +15,7 @@
package inomap
import (
+ "fmt"
"log"
"sync"
"syscall"
@@ -72,23 +73,30 @@ func (m *InoMap) spill(in QIno) (out uint64) {
func (m *InoMap) Translate(in QIno) (out uint64) {
m.Lock()
defer m.Unlock()
+ defer func() {
+ fmt.Printf("Translate: %v -> %d\n", in, out)
+ }()
if in.Ino > maxPassthruIno {
- return m.spill(in)
+ out = m.spill(in)
+ return out
}
ns, found := m.namespaceMap[in.namespaceData]
// Use existing namespace
if found {
- return uint64(ns)<<48 | in.Ino
+ out = uint64(ns)<<48 | in.Ino
+ return out
}
// No free namespace slots?
if m.namespaceNext >= maxNamespaceId {
- return m.spill(in)
+ out = m.spill(in)
+ return out
}
ns = m.namespaceNext
m.namespaceNext++
m.namespaceMap[in.namespaceData] = ns
- return uint64(ns)<<48 | in.Ino
+ out = uint64(ns)<<48 | in.Ino
+ return out
}
// TranslateStat translates the inode number contained in "st" if neccessary.
diff --git a/internal/inomap/inomap_test.go b/internal/inomap/inomap_test.go
index 8efc960..78cb405 100644
--- a/internal/inomap/inomap_test.go
+++ b/internal/inomap/inomap_test.go
@@ -106,7 +106,7 @@ func TestUniqueness(t *testing.T) {
var q QIno
outMap := make(map[uint64]struct{})
for q.Dev = 0; q.Dev < 10; q.Dev++ {
- for q.Flags = 0; q.Flags < 10; q.Flags++ {
+ for q.Tag = 0; q.Tag < 10; q.Tag++ {
// some go into spill
for q.Ino = maxPassthruIno - 100; q.Ino < maxPassthruIno+100; q.Ino++ {
out := m.Translate(q)
diff --git a/internal/inomap/qino.go b/internal/inomap/qino.go
index a74a96d..ed514e8 100644
--- a/internal/inomap/qino.go
+++ b/internal/inomap/qino.go
@@ -7,9 +7,11 @@ import (
type namespaceData struct {
// Stat_t.Dev is uint64 on 32- and 64-bit Linux
Dev uint64
- // Flags acts like an extension of the Dev field.
+ // Tag acts like an extension of the Dev field.
// It is used by reverse mode for virtual files.
- Flags uint8
+ // Normal (forward) mode does not use it and it
+ // stays always zero there.
+ Tag uint8
}
// QIno = Qualified Inode number.
@@ -21,15 +23,21 @@ type QIno struct {
Ino uint64
}
-// QInoFromStat fills a new QIno struct with the passed Stat_t info.
-func QInoFromStat(st *syscall.Stat_t) QIno {
+// NewQIno returns a filled QIno struct
+func NewQIno(dev uint64, tag uint8, ino uint64) QIno {
return QIno{
namespaceData: namespaceData{
- // There are some architectures that use 32-bit values here
- // (darwin, freebsd-32, maybe others). Add an explicit cast to make
- // this function work everywhere.
- Dev: uint64(st.Dev),
+ Dev: dev,
+ Tag: tag,
},
- Ino: uint64(st.Ino),
+ Ino: ino,
}
}
+
+// QInoFromStat fills a new QIno struct with the passed Stat_t info.
+func QInoFromStat(st *syscall.Stat_t) QIno {
+ // There are some architectures that use 32-bit values here
+ // (darwin, freebsd-32, maybe others). Add an explicit cast to make
+ // this function work everywhere.
+ return NewQIno(uint64(st.Dev), 0, uint64(st.Ino))
+}