diff options
author | Jakob Unterwurzacher | 2019-11-16 21:35:26 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2019-11-16 21:35:26 +0100 |
commit | e5d5ab397384001566d573a13a142ed1bc2bc2aa (patch) | |
tree | d9b268f51a5cb33d8876a35d12b6c5c8ac9e17a5 /internal/openfiletable/inummap.go | |
parent | 31ff557f85cca54b935231668d382cfc0e61751a (diff) |
openfiletable: add inummap
Generates unique inode numbers for files on different
devices.
https://github.com/rfjakob/gocryptfs/issues/435
Diffstat (limited to 'internal/openfiletable/inummap.go')
-rw-r--r-- | internal/openfiletable/inummap.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/openfiletable/inummap.go b/internal/openfiletable/inummap.go new file mode 100644 index 0000000..d9f6862 --- /dev/null +++ b/internal/openfiletable/inummap.go @@ -0,0 +1,63 @@ +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) +} |