From 863c3ca36fe756767ad2f86348a0646f2e7a09a5 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 2 Apr 2017 21:32:01 +0200 Subject: fusefrontend: rename write_lock.go -> open_file_table.go The data structure was originally called write lock table, but is now simply called the open file table. Rename the file to reflect that. --- internal/fusefrontend/open_file_table.go | 101 +++++++++++++++++++++++++++++++ internal/fusefrontend/write_lock.go | 101 ------------------------------- 2 files changed, 101 insertions(+), 101 deletions(-) create mode 100644 internal/fusefrontend/open_file_table.go delete mode 100644 internal/fusefrontend/write_lock.go (limited to 'internal') diff --git a/internal/fusefrontend/open_file_table.go b/internal/fusefrontend/open_file_table.go new file mode 100644 index 0000000..053298d --- /dev/null +++ b/internal/fusefrontend/open_file_table.go @@ -0,0 +1,101 @@ +package fusefrontend + +import ( + "sync" + "sync/atomic" + "syscall" +) + +// DevInoStruct uniquely identifies a backing file through device number and +// inode number. +type DevInoStruct struct { + dev uint64 + ino uint64 +} + +// DevInoFromStat fills a new DevInoStruct with the passed Stat_t info +func DevInoFromStat(st *syscall.Stat_t) DevInoStruct { + // Explicit cast to uint64 to prevent build problems on 32-bit platforms + return DevInoStruct{ + dev: uint64(st.Dev), + ino: uint64(st.Ino), + } +} + +func init() { + openFileMap.entries = make(map[DevInoStruct]*openFileEntryT) +} + +// wlock - serializes write accesses to each file (identified by inode number) +// Writing partial blocks means we have to do read-modify-write cycles. We +// really don't want concurrent writes there. +// Concurrent full-block writes could actually be allowed, but are not to +// keep the locking simple. +var openFileMap openFileMapT + +// wlockMap - usage: +// 1) register +// 2) lock ... unlock ... +// 3) unregister +type openFileMapT struct { + // opCount counts writeLock.Lock() calls. As every operation that modifies a file should + // call it, this effectively serves as a write-operation counter. + // The variable is accessed without holding any locks so atomic operations + // must be used. It must be the first element of the struct to guarantee + // 64-bit alignment. + opCount uint64 + // Protects map access + sync.Mutex + entries map[DevInoStruct]*openFileEntryT +} + +type opCountMutex struct { + sync.Mutex + // Points to the opCount variable of the parent openFileMapT + opCount *uint64 +} + +func (o *opCountMutex) Lock() { + o.Mutex.Lock() + atomic.AddUint64(o.opCount, 1) +} + +// refCntMutex - mutex with reference count +type openFileEntryT struct { + // Reference count + refCnt int + // Write lock for this inode + writeLock *opCountMutex + // ID is the file ID in the file header. + ID []byte + IDLock sync.RWMutex +} + +// register creates an entry for "ino", or incrementes the reference count +// if the entry already exists. +func (w *openFileMapT) register(di DevInoStruct) *openFileEntryT { + w.Lock() + defer w.Unlock() + + r := w.entries[di] + if r == nil { + o := opCountMutex{opCount: &w.opCount} + r = &openFileEntryT{writeLock: &o} + w.entries[di] = r + } + r.refCnt++ + return r +} + +// unregister decrements the reference count for "di" and deletes the entry if +// the reference count has reached 0. +func (w *openFileMapT) unregister(di DevInoStruct) { + w.Lock() + defer w.Unlock() + + r := w.entries[di] + r.refCnt-- + if r.refCnt == 0 { + delete(w.entries, di) + } +} diff --git a/internal/fusefrontend/write_lock.go b/internal/fusefrontend/write_lock.go deleted file mode 100644 index 053298d..0000000 --- a/internal/fusefrontend/write_lock.go +++ /dev/null @@ -1,101 +0,0 @@ -package fusefrontend - -import ( - "sync" - "sync/atomic" - "syscall" -) - -// DevInoStruct uniquely identifies a backing file through device number and -// inode number. -type DevInoStruct struct { - dev uint64 - ino uint64 -} - -// DevInoFromStat fills a new DevInoStruct with the passed Stat_t info -func DevInoFromStat(st *syscall.Stat_t) DevInoStruct { - // Explicit cast to uint64 to prevent build problems on 32-bit platforms - return DevInoStruct{ - dev: uint64(st.Dev), - ino: uint64(st.Ino), - } -} - -func init() { - openFileMap.entries = make(map[DevInoStruct]*openFileEntryT) -} - -// wlock - serializes write accesses to each file (identified by inode number) -// Writing partial blocks means we have to do read-modify-write cycles. We -// really don't want concurrent writes there. -// Concurrent full-block writes could actually be allowed, but are not to -// keep the locking simple. -var openFileMap openFileMapT - -// wlockMap - usage: -// 1) register -// 2) lock ... unlock ... -// 3) unregister -type openFileMapT struct { - // opCount counts writeLock.Lock() calls. As every operation that modifies a file should - // call it, this effectively serves as a write-operation counter. - // The variable is accessed without holding any locks so atomic operations - // must be used. It must be the first element of the struct to guarantee - // 64-bit alignment. - opCount uint64 - // Protects map access - sync.Mutex - entries map[DevInoStruct]*openFileEntryT -} - -type opCountMutex struct { - sync.Mutex - // Points to the opCount variable of the parent openFileMapT - opCount *uint64 -} - -func (o *opCountMutex) Lock() { - o.Mutex.Lock() - atomic.AddUint64(o.opCount, 1) -} - -// refCntMutex - mutex with reference count -type openFileEntryT struct { - // Reference count - refCnt int - // Write lock for this inode - writeLock *opCountMutex - // ID is the file ID in the file header. - ID []byte - IDLock sync.RWMutex -} - -// register creates an entry for "ino", or incrementes the reference count -// if the entry already exists. -func (w *openFileMapT) register(di DevInoStruct) *openFileEntryT { - w.Lock() - defer w.Unlock() - - r := w.entries[di] - if r == nil { - o := opCountMutex{opCount: &w.opCount} - r = &openFileEntryT{writeLock: &o} - w.entries[di] = r - } - r.refCnt++ - return r -} - -// unregister decrements the reference count for "di" and deletes the entry if -// the reference count has reached 0. -func (w *openFileMapT) unregister(di DevInoStruct) { - w.Lock() - defer w.Unlock() - - r := w.entries[di] - r.refCnt-- - if r.refCnt == 0 { - delete(w.entries, di) - } -} -- cgit v1.2.3