mirror of
https://github.com/pgsty/minio.git
synced 2026-07-20 20:50:22 +03:00
fs: Re-implement object layer to remember the fd (#3509)
This patch re-writes FS backend to support shared backend sharing locks for safe concurrent access across multiple servers.
This commit is contained in:
+15
-15
@@ -28,6 +28,14 @@ import (
|
||||
// Global name space lock.
|
||||
var globalNSMutex *nsLockMap
|
||||
|
||||
// RWLocker - locker interface extends sync.Locker
|
||||
// to introduce RLock, RUnlock.
|
||||
type RWLocker interface {
|
||||
sync.Locker
|
||||
RLock()
|
||||
RUnlock()
|
||||
}
|
||||
|
||||
// Initialize distributed locking only in case of distributed setup.
|
||||
// Returns if the setup is distributed or not on success.
|
||||
func initDsyncNodes(eps []*url.URL) error {
|
||||
@@ -68,13 +76,6 @@ func initNSLock(isDistXL bool) {
|
||||
globalNSMutex.debugLockMap = make(map[nsParam]*debugLockInfoPerVolumePath)
|
||||
}
|
||||
|
||||
// RWLocker - interface that any read-write locking library should implement.
|
||||
type RWLocker interface {
|
||||
sync.Locker
|
||||
RLock()
|
||||
RUnlock()
|
||||
}
|
||||
|
||||
// nsParam - carries name space resource.
|
||||
type nsParam struct {
|
||||
volume string
|
||||
@@ -94,8 +95,7 @@ type nsLockMap struct {
|
||||
counters *lockStat
|
||||
debugLockMap map[nsParam]*debugLockInfoPerVolumePath // Info for instrumentation on locks.
|
||||
|
||||
// Indicates whether the locking service is part
|
||||
// of a distributed setup or not.
|
||||
// Indicates if namespace is part of a distributed setup.
|
||||
isDistXL bool
|
||||
lockMap map[nsParam]*nsLock
|
||||
lockMapMutex sync.Mutex
|
||||
@@ -256,14 +256,14 @@ func (n *nsLockMap) ForceUnlock(volume, path string) {
|
||||
|
||||
// lockInstance - frontend/top-level interface for namespace locks.
|
||||
type lockInstance struct {
|
||||
n *nsLockMap
|
||||
ns *nsLockMap
|
||||
volume, path, opsID string
|
||||
}
|
||||
|
||||
// NewNSLock - returns a lock instance for a given volume and
|
||||
// path. The returned lockInstance object encapsulates the nsLockMap,
|
||||
// volume, path and operation ID.
|
||||
func (n *nsLockMap) NewNSLock(volume, path string) *lockInstance {
|
||||
func (n *nsLockMap) NewNSLock(volume, path string) RWLocker {
|
||||
return &lockInstance{n, volume, path, getOpsID()}
|
||||
}
|
||||
|
||||
@@ -271,24 +271,24 @@ func (n *nsLockMap) NewNSLock(volume, path string) *lockInstance {
|
||||
func (li *lockInstance) Lock() {
|
||||
lockSource := callerSource()
|
||||
readLock := false
|
||||
li.n.lock(li.volume, li.path, lockSource, li.opsID, readLock)
|
||||
li.ns.lock(li.volume, li.path, lockSource, li.opsID, readLock)
|
||||
}
|
||||
|
||||
// Unlock - block until write lock is released.
|
||||
func (li *lockInstance) Unlock() {
|
||||
readLock := false
|
||||
li.n.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.
|
||||
func (li *lockInstance) RLock() {
|
||||
lockSource := callerSource()
|
||||
readLock := true
|
||||
li.n.lock(li.volume, li.path, lockSource, li.opsID, readLock)
|
||||
li.ns.lock(li.volume, li.path, lockSource, li.opsID, readLock)
|
||||
}
|
||||
|
||||
// RUnlock - block until read lock is released.
|
||||
func (li *lockInstance) RUnlock() {
|
||||
readLock := true
|
||||
li.n.unlock(li.volume, li.path, li.opsID, readLock)
|
||||
li.ns.unlock(li.volume, li.path, li.opsID, readLock)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user