diff options
Diffstat (limited to 'internal/fusefrontend')
-rw-r--r-- | internal/fusefrontend/write_lock.go | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/internal/fusefrontend/write_lock.go b/internal/fusefrontend/write_lock.go index a8ec6b6..2f8ea4e 100644 --- a/internal/fusefrontend/write_lock.go +++ b/internal/fusefrontend/write_lock.go @@ -5,7 +5,7 @@ import ( ) func init() { - wlock.m = make(map[uint64]*refCntMutex) + wlock.inodeLocks = make(map[uint64]*refCntMutex) } // wlock - serializes write accesses to each file (identified by inode number) @@ -20,47 +20,59 @@ var wlock wlockMap // 2) lock ... unlock ... // 3) unregister type wlockMap struct { - mapMutex sync.RWMutex - m map[uint64]*refCntMutex + // Protects map access + sync.Mutex + inodeLocks map[uint64]*refCntMutex +} + +// refCntMutex - mutex with reference count +type refCntMutex struct { + // Write lock for this inode + sync.Mutex + // Reference count + refCnt int } +// register creates an entry for "ino", or incrementes the reference count +// if the entry already exists. func (w *wlockMap) register(ino uint64) { - w.mapMutex.Lock() - r := w.m[ino] + w.Lock() + defer w.Unlock() + + r := w.inodeLocks[ino] if r == nil { r = &refCntMutex{} - w.m[ino] = r + w.inodeLocks[ino] = r } - r.refCnt++ // this must happen inside the mapMutex lock - w.mapMutex.Unlock() + r.refCnt++ } +// unregister decrements the reference count for "ino" and deletes the entry if +// the reference count has reached 0. func (w *wlockMap) unregister(ino uint64) { - w.mapMutex.Lock() - r := w.m[ino] + w.Lock() + defer w.Unlock() + + r := w.inodeLocks[ino] r.refCnt-- if r.refCnt == 0 { - delete(w.m, ino) + delete(w.inodeLocks, ino) } - w.mapMutex.Unlock() } +// lock retrieves the entry for "ino" and locks it. func (w *wlockMap) lock(ino uint64) { - w.mapMutex.RLock() - r := w.m[ino] - w.mapMutex.RUnlock() - r.Lock() // this can take a long time - execute outside the mapMutex lock + w.Lock() + r := w.inodeLocks[ino] + w.Unlock() + // this can take a long time - execute outside the wlockMap lock + r.Lock() } +// unlock retrieves the entry for "ino" and unlocks it. func (w *wlockMap) unlock(ino uint64) { - w.mapMutex.RLock() - r := w.m[ino] - w.mapMutex.RUnlock() + w.Lock() + r := w.inodeLocks[ino] + w.Unlock() r.Unlock() } - -// refCntMutex - mutex with reference count -type refCntMutex struct { - sync.Mutex - refCnt int -} |