diff options
author | Jakob Unterwurzacher | 2020-04-12 17:15:03 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2020-04-13 14:54:04 +0200 |
commit | 488111ce390218806fca933b89279b766f7ff49c (patch) | |
tree | d75a8aac95f95767410027da14cd0231c17110a3 /internal/openfiletable | |
parent | 194030f18ae623fbf5b0bb805b780f81fe9ec7a7 (diff) |
inomap: split into separate package
inomap will also be used by fusefrontend_reverse
in the future. Split if off openfiletable to make
it independent.
Diffstat (limited to 'internal/openfiletable')
-rw-r--r-- | internal/openfiletable/inummap.go | 63 | ||||
-rw-r--r-- | internal/openfiletable/inummap_test.go | 81 | ||||
-rw-r--r-- | internal/openfiletable/open_file_table.go | 31 |
3 files changed, 6 insertions, 169 deletions
diff --git a/internal/openfiletable/inummap.go b/internal/openfiletable/inummap.go deleted file mode 100644 index d9f6862..0000000 --- a/internal/openfiletable/inummap.go +++ /dev/null @@ -1,63 +0,0 @@ -package openfiletable - -import ( - "sync" - "syscall" -) - -// UINT64_MAX = 18446744073709551615 -const inumTranslateBase = 10000000000000000000 - -// InumMap ... see NewInumMap() for description. -type InumMap struct { - sync.Mutex - baseDev uint64 - translate map[QIno]uint64 - translateNext uint64 -} - -// NewInumMap returns a new inumMap. -// -// inumMap translates (device uint64, inode uint64) pairs to unique uint64 -// inode numbers. -// Inode numbers on the "baseDev" are passed through unchanged (as long as they -// are not higher than inumTranslateBase). -// Inode numbers on other devices are remapped to the number space above -// 10000000000000000000. The mapping is stored in a simple Go map. Entries -// can only be added and are never removed. -func NewInumMap(baseDev uint64) *InumMap { - return &InumMap{ - baseDev: baseDev, - translate: make(map[QIno]uint64), - translateNext: inumTranslateBase, - } -} - -// Translate maps the passed-in (device, inode) pair to a unique inode number. -func (m *InumMap) Translate(in QIno) (out uint64) { - if in.Dev == m.baseDev && in.Ino < inumTranslateBase { - return in.Ino - } - m.Lock() - defer m.Unlock() - out = m.translate[in] - if out != 0 { - return out - } - out = m.translateNext - m.translate[in] = m.translateNext - m.translateNext++ - return out -} - -// TranslateStat translates the inode number contained in "st" if neccessary. -// Convience wrapper around Translate(). -func (m *InumMap) TranslateStat(st *syscall.Stat_t) { - in := QInoFromStat(st) - st.Ino = m.Translate(in) -} - -// Count returns the number of entries in the translation table. -func (m *InumMap) Count() int { - return len(m.translate) -} diff --git a/internal/openfiletable/inummap_test.go b/internal/openfiletable/inummap_test.go deleted file mode 100644 index 85438bd..0000000 --- a/internal/openfiletable/inummap_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package openfiletable - -import ( - "sync" - "testing" -) - -func TestTranslate(t *testing.T) { - const baseDev = 12345 - m := NewInumMap(baseDev) - - q := QIno{Dev: baseDev, Ino: 1} - out := m.Translate(q) - if out != 1 { - t.Errorf("expected 1, got %d", out) - } - q.Ino = inumTranslateBase - out = m.Translate(q) - if out < inumTranslateBase { - t.Errorf("got %d", out) - } - out2 := m.Translate(q) - if out2 != out { - t.Errorf("unstable mapping: %d %d", out2, out) - } -} - -func TestTranslateStress(t *testing.T) { - const baseDev = 12345 - m := NewInumMap(baseDev) - var wg sync.WaitGroup - wg.Add(4) - go func() { - q := QIno{Dev: baseDev} - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out != i { - t.Fail() - } - } - wg.Done() - }() - go func() { - q := QIno{Dev: baseDev} - for i := uint64(1); i <= 10000; i++ { - q.Ino = inumTranslateBase + i - out := m.Translate(q) - if out < inumTranslateBase { - t.Fail() - } - } - wg.Done() - }() - go func() { - q := QIno{Dev: 9999999} - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out < inumTranslateBase { - t.Fail() - } - } - wg.Done() - }() - go func() { - q := QIno{Dev: 4444444} - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out < inumTranslateBase { - t.Fail() - } - } - wg.Done() - }() - wg.Wait() - if m.Count() != 30000 { - t.Fail() - } -} diff --git a/internal/openfiletable/open_file_table.go b/internal/openfiletable/open_file_table.go index 4a8ce28..dfd9637 100644 --- a/internal/openfiletable/open_file_table.go +++ b/internal/openfiletable/open_file_table.go @@ -7,28 +7,9 @@ package openfiletable import ( "sync" "sync/atomic" - "syscall" -) - -// QIno = Qualified Inode number. -// Uniquely identifies a backing file through the device number, -// inode number pair. -type QIno struct { - // Stat_t.{Dev,Ino} is uint64 on 32- and 64-bit Linux - Dev uint64 - Ino uint64 -} -// QInoFromStat fills a new QIno struct with the passed Stat_t info. -func QInoFromStat(st *syscall.Stat_t) QIno { - return QIno{ - // There are some architectures that use 32-bit values here - // (darwin, freebsd-32, maybe others). Add and explicit cast to make - // this function work everywhere. - Dev: uint64(st.Dev), - Ino: uint64(st.Ino), - } -} + "github.com/rfjakob/gocryptfs/internal/inomap" +) // wlock - serializes write accesses to each file (identified by inode number) // Writing partial blocks means we have to do read-modify-write cycles. We @@ -38,7 +19,7 @@ func QInoFromStat(st *syscall.Stat_t) QIno { var t table func init() { - t.entries = make(map[QIno]*Entry) + t.entries = make(map[inomap.QIno]*Entry) } type table struct { @@ -52,7 +33,7 @@ type table struct { // Protects map access sync.Mutex // Table entries - entries map[QIno]*Entry + entries map[inomap.QIno]*Entry } // Entry is an entry in the open file table @@ -71,7 +52,7 @@ type Entry struct { // Register creates an open file table entry for "qi" (or incrementes the // reference count if the entry already exists) and returns the entry. -func Register(qi QIno) *Entry { +func Register(qi inomap.QIno) *Entry { t.Lock() defer t.Unlock() @@ -86,7 +67,7 @@ func Register(qi QIno) *Entry { // Unregister decrements the reference count for "qi" and deletes the entry from // the open file table if the reference count reaches 0. -func Unregister(qi QIno) { +func Unregister(qi inomap.QIno) { t.Lock() defer t.Unlock() |