diff --git a/vendor/github.com/minio/dsync/drwmutex.go b/vendor/github.com/minio/dsync/drwmutex.go index cf29a68ee..3fcac6546 100644 --- a/vendor/github.com/minio/dsync/drwmutex.go +++ b/vendor/github.com/minio/dsync/drwmutex.go @@ -211,7 +211,8 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool { (*locks)[grant.index] = grant.lockUid } else { locksFailed++ - if locksFailed > dnodeCount-dquorum { + if !isReadLock && locksFailed > dnodeCount-dquorum || + isReadLock && locksFailed > dnodeCount-dquorumReads { // We know that we are not going to get the lock anymore, so exit out // and release any locks that did get acquired done = true @@ -223,7 +224,7 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool { done = true // timeout happened, maybe one of the nodes is slow, count // number of locks to check whether we have quorum or not - if !quorumMet(locks) { + if !quorumMet(locks, isReadLock) { releaseAll(clnts, locks, lockName, isReadLock) } } @@ -234,7 +235,7 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool { } // Count locks in order to determine whterh we have quorum or not - quorum = quorumMet(locks) + quorum = quorumMet(locks, isReadLock) // Signal that we have the quorum wg.Done() @@ -263,8 +264,8 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool { return quorum } -// quorumMet determines whether we have acquired n/2+1 underlying locks or not -func quorumMet(locks *[]string) bool { +// quorumMet determines whether we have acquired the required quorum of underlying locks or not +func quorumMet(locks *[]string, isReadLock bool) bool { count := 0 for _, uid := range *locks { @@ -273,7 +274,11 @@ func quorumMet(locks *[]string) bool { } } - return count >= dquorum + if isReadLock { + return count >= dquorumReads + } else { + return count >= dquorum + } } // releaseAll releases all locks that are marked as locked diff --git a/vendor/github.com/minio/dsync/dsync.go b/vendor/github.com/minio/dsync/dsync.go index 5e77b4efa..d302e924d 100644 --- a/vendor/github.com/minio/dsync/dsync.go +++ b/vendor/github.com/minio/dsync/dsync.go @@ -34,6 +34,8 @@ var ownNode int // Simple majority based quorum, set to dNodeCount/2+1 var dquorum int +// Simple quorum for read operations, set to dNodeCount/2 +var dquorumReads int // SetNodesWithPath - initializes package-level global state variables such as clnts. // N B - This function should be called only once inside any program that uses @@ -47,15 +49,17 @@ func SetNodesWithClients(rpcClnts []RPC, rpcOwnNode int) (err error) { return errors.New("Dsync not designed for less than 4 nodes") } else if len(rpcClnts) > 16 { return errors.New("Dsync not designed for more than 16 nodes") + } else if len(rpcClnts)&1 == 1 { + return errors.New("Dsync not designed for an uneven number of nodes") } if rpcOwnNode > len(rpcClnts) { return errors.New("Index for own node is too large") } - dnodeCount = len(rpcClnts) dquorum = dnodeCount/2 + 1 + dquorumReads = dnodeCount/2 // Initialize node name and rpc path for each RPCClient object. clnts = make([]RPC, dnodeCount) copy(clnts, rpcClnts) diff --git a/vendor/vendor.json b/vendor/vendor.json index ec3e7ced1..3fdc0ee68 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -111,10 +111,10 @@ "revisionTime": "2015-11-18T20:00:48-08:00" }, { - "checksumSHA1": "0wc4gxRamjyjVSiZF73KIaCRC6k=", + "checksumSHA1": "5DKBTLXf5GY5RkVC9DGP2XFMabc=", "path": "github.com/minio/dsync", - "revision": "531818cd6458e24e30eec2c67136a8bcb24520af", - "revisionTime": "2016-09-15T18:37:01Z" + "revision": "66c2a42bf14fcaad0322e9f06d9ab85dd6dba9b7", + "revisionTime": "2016-10-07T07:30:36Z" }, { "path": "github.com/minio/go-homedir",