Skip to content

Commit fb93f17

Browse files
trondnowend74
authored andcommitted
MB-34949: BP. StateLock is not held in all cases
This is a back-port of a399135. See: http://review.couchbase.org/c/kv_engine/+/111623 Change-Id: Ic1587b9aa2401f24a0123309f3c3a58245b8b87c Reviewed-on: http://review.couchbase.org/c/kv_engine/+/140978 Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]> Well-Formed: Build Bot <[email protected]>
1 parent 3b03448 commit fb93f17

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

engines/ep/src/kv_bucket.cc

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,12 @@ protocol_binary_response_status KVBucket::evictKey(const DocKey& key,
508508
VBucket::id_type vbucket,
509509
const char** msg) {
510510
VBucketPtr vb = getVBucket(vbucket);
511-
if (!vb || (vb->getState() != vbucket_state_active)) {
511+
if (!vb) {
512+
return PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET;
513+
}
514+
515+
ReaderLockHolder rlh(vb->getStateLock());
516+
if (vb->getState() != vbucket_state_active) {
512517
return PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET;
513518
}
514519

@@ -1411,34 +1416,26 @@ GetValue KVBucket::getInternal(const DocKey& key,
14111416
GetValue KVBucket::getRandomKey() {
14121417
VBucketMap::id_type max = vbMap.getSize();
14131418

1414-
const long start = getRandom() % max;
1419+
const long start = labs(getRandom() % max);
14151420
long curr = start;
14161421
std::unique_ptr<Item> itm;
14171422

1418-
while (itm == NULL) {
1423+
while (true) {
14191424
VBucketPtr vb = getVBucket(curr++);
1420-
while (!vb || vb->getState() != vbucket_state_active) {
1421-
if (curr == max) {
1422-
curr = 0;
1423-
}
1424-
if (curr == start) {
1425-
return GetValue(NULL, ENGINE_KEY_ENOENT);
1425+
if (vb) {
1426+
ReaderLockHolder rlh(vb->getStateLock());
1427+
if (vb->getState() == vbucket_state_active &&
1428+
(itm = vb->ht.getRandomKey(getRandom()))) {
1429+
GetValue rv(std::move(itm), ENGINE_SUCCESS);
1430+
return rv;
14261431
}
1427-
1428-
vb = getVBucket(curr++);
1429-
}
1430-
1431-
if ((itm = vb->ht.getRandomKey(getRandom()))) {
1432-
GetValue rv(std::move(itm), ENGINE_SUCCESS);
1433-
return rv;
14341432
}
14351433

14361434
if (curr == max) {
14371435
curr = 0;
14381436
}
1439-
14401437
if (curr == start) {
1441-
return GetValue(NULL, ENGINE_KEY_ENOENT);
1438+
break;
14421439
}
14431440
// Search next vbucket
14441441
}
@@ -1585,7 +1582,13 @@ GetValue KVBucket::getLocked(const DocKey& key, uint16_t vbucket,
15851582
rel_time_t currentTime, uint32_t lockTimeout,
15861583
const void *cookie) {
15871584
VBucketPtr vb = getVBucket(vbucket);
1588-
if (!vb || vb->getState() != vbucket_state_active) {
1585+
if (!vb) {
1586+
++stats.numNotMyVBuckets;
1587+
return GetValue(NULL, ENGINE_NOT_MY_VBUCKET);
1588+
}
1589+
1590+
ReaderLockHolder rlh(vb->getStateLock());
1591+
if (vb->getState() != vbucket_state_active) {
15891592
++stats.numNotMyVBuckets;
15901593
return GetValue(NULL, ENGINE_NOT_MY_VBUCKET);
15911594
}
@@ -1612,7 +1615,13 @@ ENGINE_ERROR_CODE KVBucket::unlockKey(const DocKey& key,
16121615
{
16131616

16141617
VBucketPtr vb = getVBucket(vbucket);
1615-
if (!vb || vb->getState() != vbucket_state_active) {
1618+
if (!vb) {
1619+
++stats.numNotMyVBuckets;
1620+
return ENGINE_NOT_MY_VBUCKET;
1621+
}
1622+
1623+
ReaderLockHolder rlh(vb->getStateLock());
1624+
if (vb->getState() != vbucket_state_active) {
16161625
++stats.numNotMyVBuckets;
16171626
return ENGINE_NOT_MY_VBUCKET;
16181627
}
@@ -1667,6 +1676,7 @@ ENGINE_ERROR_CODE KVBucket::getKeyStats(const DocKey& key,
16671676
return ENGINE_NOT_MY_VBUCKET;
16681677
}
16691678

1679+
ReaderLockHolder rlh(vb->getStateLock());
16701680
{ // collections read scope
16711681
auto collectionsRHandle = vb->lockCollections(key);
16721682
if (!collectionsRHandle.valid()) {
@@ -1679,7 +1689,7 @@ ENGINE_ERROR_CODE KVBucket::getKeyStats(const DocKey& key,
16791689
kstats,
16801690
wantsDeleted,
16811691
collectionsRHandle);
1682-
}
1692+
}
16831693
}
16841694

16851695
std::string KVBucket::validateKey(const DocKey& key, uint16_t vbucket,
@@ -1723,7 +1733,13 @@ ENGINE_ERROR_CODE KVBucket::deleteItem(const DocKey& key,
17231733
ItemMetaData* itemMeta,
17241734
mutation_descr_t& mutInfo) {
17251735
VBucketPtr vb = getVBucket(vbucket);
1726-
if (!vb || vb->getState() == vbucket_state_dead) {
1736+
if (!vb) {
1737+
++stats.numNotMyVBuckets;
1738+
return ENGINE_NOT_MY_VBUCKET;
1739+
}
1740+
1741+
ReaderLockHolder rlh(vb->getStateLock());
1742+
if (vb->getState() == vbucket_state_dead) {
17271743
++stats.numNotMyVBuckets;
17281744
return ENGINE_NOT_MY_VBUCKET;
17291745
} else if (vb->getState() == vbucket_state_replica) {

0 commit comments

Comments
 (0)