diff options
author | Jakob Unterwurzacher | 2020-05-03 15:22:10 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2020-05-03 15:22:10 +0200 |
commit | 518771e4e247762f60c5594de427a8c86f19bd57 (patch) | |
tree | 625aed59393508f8f3b61787963012a684b37d8e /internal/inomap | |
parent | db93a6c54cfd615561207f1bbcf7e665ebc296b6 (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.go | 16 | ||||
-rw-r--r-- | internal/inomap/inomap_test.go | 2 | ||||
-rw-r--r-- | internal/inomap/qino.go | 26 |
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)) +} |