mirror of
https://github.com/minio/minio.git
synced 2025-04-19 10:07:30 -04:00
Do no access nsLockMap.lockMap when using dsync (#7464)
There is no need to access nsLockMap.lockMap when using dsync
This commit is contained in:
parent
53011606a5
commit
ef791764e0
@ -51,14 +51,6 @@ type RWLocker interface {
|
|||||||
RUnlock()
|
RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RWLockerSync - internal locker interface.
|
|
||||||
type RWLockerSync interface {
|
|
||||||
GetLock(id, source string, timeout time.Duration) bool
|
|
||||||
Unlock()
|
|
||||||
GetRLock(id, source string, timeout time.Duration) bool
|
|
||||||
RUnlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize distributed locking only in case of distributed setup.
|
// Initialize distributed locking only in case of distributed setup.
|
||||||
// Returns lock clients and the node index for the current server.
|
// Returns lock clients and the node index for the current server.
|
||||||
func newDsyncNodes(endpoints EndpointList) (clnts []dsync.NetLocker, myNode int) {
|
func newDsyncNodes(endpoints EndpointList) (clnts []dsync.NetLocker, myNode int) {
|
||||||
@ -101,8 +93,11 @@ func newDsyncNodes(endpoints EndpointList) (clnts []dsync.NetLocker, myNode int)
|
|||||||
func newNSLock(isDistXL bool) *nsLockMap {
|
func newNSLock(isDistXL bool) *nsLockMap {
|
||||||
nsMutex := nsLockMap{
|
nsMutex := nsLockMap{
|
||||||
isDistXL: isDistXL,
|
isDistXL: isDistXL,
|
||||||
lockMap: make(map[nsParam]*nsLock),
|
|
||||||
}
|
}
|
||||||
|
if isDistXL {
|
||||||
|
return &nsMutex
|
||||||
|
}
|
||||||
|
nsMutex.lockMap = make(map[nsParam]*nsLock)
|
||||||
return &nsMutex
|
return &nsMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +114,7 @@ type nsParam struct {
|
|||||||
|
|
||||||
// nsLock - provides primitives for locking critical namespace regions.
|
// nsLock - provides primitives for locking critical namespace regions.
|
||||||
type nsLock struct {
|
type nsLock struct {
|
||||||
RWLockerSync
|
*lsync.LRWMutex
|
||||||
ref uint
|
ref uint
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,12 +136,7 @@ func (n *nsLockMap) lock(volume, path string, lockSource, opsID string, readLock
|
|||||||
nsLk, found := n.lockMap[param]
|
nsLk, found := n.lockMap[param]
|
||||||
if !found {
|
if !found {
|
||||||
n.lockMap[param] = &nsLock{
|
n.lockMap[param] = &nsLock{
|
||||||
RWLockerSync: func() RWLockerSync {
|
LRWMutex: &lsync.LRWMutex{},
|
||||||
if n.isDistXL {
|
|
||||||
return dsync.NewDRWMutex(pathJoin(volume, path), globalDsync)
|
|
||||||
}
|
|
||||||
return &lsync.LRWMutex{}
|
|
||||||
}(),
|
|
||||||
ref: 1,
|
ref: 1,
|
||||||
}
|
}
|
||||||
nsLk = n.lockMap[param]
|
nsLk = n.lockMap[param]
|
||||||
@ -259,8 +249,49 @@ func (n *nsLockMap) ForceUnlock(volume, path string) {
|
|||||||
delete(n.lockMap, nsParam{volume, path})
|
delete(n.lockMap, nsParam{volume, path})
|
||||||
}
|
}
|
||||||
|
|
||||||
// lockInstance - frontend/top-level interface for namespace locks.
|
// dsync's distributed lock instance.
|
||||||
type lockInstance struct {
|
type distLockInstance struct {
|
||||||
|
rwMutex *dsync.DRWMutex
|
||||||
|
volume, path, opsID string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock - block until write lock is taken or timeout has occurred.
|
||||||
|
func (di *distLockInstance) GetLock(timeout *dynamicTimeout) (timedOutErr error) {
|
||||||
|
lockSource := getSource()
|
||||||
|
start := UTCNow()
|
||||||
|
|
||||||
|
if !di.rwMutex.GetLock(di.opsID, lockSource, timeout.Timeout()) {
|
||||||
|
timeout.LogFailure()
|
||||||
|
return OperationTimedOut{Path: di.path}
|
||||||
|
}
|
||||||
|
timeout.LogSuccess(UTCNow().Sub(start))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock - block until write lock is released.
|
||||||
|
func (di *distLockInstance) Unlock() {
|
||||||
|
di.rwMutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RLock - block until read lock is taken or timeout has occurred.
|
||||||
|
func (di *distLockInstance) GetRLock(timeout *dynamicTimeout) (timedOutErr error) {
|
||||||
|
lockSource := getSource()
|
||||||
|
start := UTCNow()
|
||||||
|
if !di.rwMutex.GetRLock(di.opsID, lockSource, timeout.Timeout()) {
|
||||||
|
timeout.LogFailure()
|
||||||
|
return OperationTimedOut{Path: di.path}
|
||||||
|
}
|
||||||
|
timeout.LogSuccess(UTCNow().Sub(start))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RUnlock - block until read lock is released.
|
||||||
|
func (di *distLockInstance) RUnlock() {
|
||||||
|
di.rwMutex.RUnlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// localLockInstance - frontend/top-level interface for namespace locks.
|
||||||
|
type localLockInstance struct {
|
||||||
ns *nsLockMap
|
ns *nsLockMap
|
||||||
volume, path, opsID string
|
volume, path, opsID string
|
||||||
}
|
}
|
||||||
@ -270,11 +301,14 @@ type lockInstance struct {
|
|||||||
// volume, path and operation ID.
|
// volume, path and operation ID.
|
||||||
func (n *nsLockMap) NewNSLock(volume, path string) RWLocker {
|
func (n *nsLockMap) NewNSLock(volume, path string) RWLocker {
|
||||||
opsID := mustGetUUID()
|
opsID := mustGetUUID()
|
||||||
return &lockInstance{n, volume, path, opsID}
|
if n.isDistXL {
|
||||||
|
return &distLockInstance{dsync.NewDRWMutex(pathJoin(volume, path), globalDsync), volume, path, opsID}
|
||||||
|
}
|
||||||
|
return &localLockInstance{n, volume, path, opsID}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock - block until write lock is taken or timeout has occurred.
|
// Lock - block until write lock is taken or timeout has occurred.
|
||||||
func (li *lockInstance) GetLock(timeout *dynamicTimeout) (timedOutErr error) {
|
func (li *localLockInstance) GetLock(timeout *dynamicTimeout) (timedOutErr error) {
|
||||||
lockSource := getSource()
|
lockSource := getSource()
|
||||||
start := UTCNow()
|
start := UTCNow()
|
||||||
readLock := false
|
readLock := false
|
||||||
@ -287,13 +321,13 @@ func (li *lockInstance) GetLock(timeout *dynamicTimeout) (timedOutErr error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unlock - block until write lock is released.
|
// Unlock - block until write lock is released.
|
||||||
func (li *lockInstance) Unlock() {
|
func (li *localLockInstance) Unlock() {
|
||||||
readLock := false
|
readLock := false
|
||||||
li.ns.unlock(li.volume, li.path, li.opsID, readLock)
|
li.ns.unlock(li.volume, li.path, li.opsID, readLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RLock - block until read lock is taken or timeout has occurred.
|
// RLock - block until read lock is taken or timeout has occurred.
|
||||||
func (li *lockInstance) GetRLock(timeout *dynamicTimeout) (timedOutErr error) {
|
func (li *localLockInstance) GetRLock(timeout *dynamicTimeout) (timedOutErr error) {
|
||||||
lockSource := getSource()
|
lockSource := getSource()
|
||||||
start := UTCNow()
|
start := UTCNow()
|
||||||
readLock := true
|
readLock := true
|
||||||
@ -306,7 +340,7 @@ func (li *lockInstance) GetRLock(timeout *dynamicTimeout) (timedOutErr error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RUnlock - block until read lock is released.
|
// RUnlock - block until read lock is released.
|
||||||
func (li *lockInstance) RUnlock() {
|
func (li *localLockInstance) RUnlock() {
|
||||||
readLock := true
|
readLock := true
|
||||||
li.ns.unlock(li.volume, li.path, li.opsID, readLock)
|
li.ns.unlock(li.volume, li.path, li.opsID, readLock)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user