From 5a2d4614ed75d4b32e0f45e93a225f8e1b7350c9 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 5 May 2024 22:25:19 +0200 Subject: inomap: export NextSpillIno() This will be used in reverse mode. Switch to atomic increment to avoid a "nextSpillInoUnlocked" helper. --- internal/inomap/inomap.go | 22 ++++++++++++++++------ internal/inomap/inomap_test.go | 8 ++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/internal/inomap/inomap.go b/internal/inomap/inomap.go index 1c012d9..b4dbf27 100644 --- a/internal/inomap/inomap.go +++ b/internal/inomap/inomap.go @@ -18,6 +18,7 @@ import ( "log" "math" "sync" + "sync/atomic" "syscall" "github.com/rfjakob/gocryptfs/v2/internal/tlog" @@ -68,19 +69,28 @@ func New(rootDev uint64) *InoMap { var spillWarn sync.Once +// NextSpillIno returns a fresh inode number from the spill pool without adding it to +// spillMap. +// Reverse mode NextSpillIno() for gocryptfs.longname.*.name files where a stable +// mapping is not needed. +func (m *InoMap) NextSpillIno() (out uint64) { + if m.spillNext == math.MaxUint64 { + log.Panicf("spillMap overflow: spillNext = 0x%x", m.spillNext) + } + return atomic.AddUint64(&m.spillNext, 1) - 1 +} + func (m *InoMap) spill(in QIno) (out uint64) { - spillWarn.Do(func() { tlog.Warn.Printf("InoMap: opening spillMap for %v", in) }) + spillWarn.Do(func() { tlog.Warn.Printf("InoMap: opening spillMap for %#v", in) }) out, found := m.spillMap[in] if found { return out } - if m.spillNext == math.MaxUint64 { - log.Panicf("spillMap overflow: spillNext = 0x%x", m.spillNext) - } - out = m.spillNext - m.spillNext++ + + out = m.NextSpillIno() m.spillMap[in] = out + return out } diff --git a/internal/inomap/inomap_test.go b/internal/inomap/inomap_test.go index 430ec94..ce5b880 100644 --- a/internal/inomap/inomap_test.go +++ b/internal/inomap/inomap_test.go @@ -107,6 +107,9 @@ func TestSpill(t *testing.T) { if out1&spillBit == 0 { t.Error("spill bit not set") } + if out1 != spillSpaceStart { + t.Errorf("unexpected first spill inode number %d", out1) + } out2 := m.Translate(q) if out2&spillBit == 0 { t.Error("spill bit not set") @@ -114,6 +117,11 @@ func TestSpill(t *testing.T) { if out1 != out2 { t.Errorf("unstable mapping: %d vs %d", out1, out2) } + q.Ino = maxPassthruIno + 2 + out3 := m.Translate(q) + if out3 != out1+1 { + t.Errorf("unexpected 2nd spill inode number %d", out1) + } } // TestUniqueness checks that unique (Dev, Flags, Ino) tuples get unique inode -- cgit v1.2.3