diff options
Diffstat (limited to 'internal')
| -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 -} | 
