aboutsummaryrefslogtreecommitdiff
path: root/internal/openfiletable
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-04-12 17:15:03 +0200
committerJakob Unterwurzacher2020-04-13 14:54:04 +0200
commit488111ce390218806fca933b89279b766f7ff49c (patch)
treed75a8aac95f95767410027da14cd0231c17110a3 /internal/openfiletable
parent194030f18ae623fbf5b0bb805b780f81fe9ec7a7 (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.go63
-rw-r--r--internal/openfiletable/inummap_test.go81
-rw-r--r--internal/openfiletable/open_file_table.go31
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()