blob: only allow unblobbification on aligned to ranges
If unblobbify request comes in, reject it if the start and end do not align to a blob granule boundary.
This commit is contained in:
parent
dc27c9bbd7
commit
046141b5be
|
@ -9988,18 +9988,26 @@ ACTOR Future<bool> setBlobRangeActor(Reference<DatabaseContext> cx, KeyRange ran
|
|||
tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
|
||||
tr->setOption(FDBTransactionOptions::PRIORITY_SYSTEM_IMMEDIATE);
|
||||
|
||||
state Standalone<VectorRef<KeyRangeRef>> startBlobRanges = wait(getBlobRanges(tr, range, 10));
|
||||
state Standalone<VectorRef<KeyRangeRef>> endBlobRanges =
|
||||
wait(getBlobRanges(tr, KeyRangeRef(range.end, keyAfter(range.end)), 10));
|
||||
|
||||
if (active) {
|
||||
state RangeResult results = wait(krmGetRanges(tr, blobRangeKeys.begin, range));
|
||||
ASSERT(results.size() >= 2);
|
||||
if (results[0].key == range.begin && results[1].key == range.end &&
|
||||
results[0].value == blobRangeActive) {
|
||||
// Idempotent request.
|
||||
if (!startBlobRanges.empty() && !endBlobRanges.empty()) {
|
||||
return startBlobRanges.front().begin == range.begin && endBlobRanges.front().end == range.end;
|
||||
}
|
||||
} else {
|
||||
// An unblobbify request must be aligned to boundaries.
|
||||
// It is okay to unblobbify multiple regions all at once.
|
||||
if (startBlobRanges.empty() && endBlobRanges.empty()) {
|
||||
return true;
|
||||
} else {
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
if (results[i].value == blobRangeActive) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there is a blob at the beginning of the range and it isn't aligned,
|
||||
// or there is a blob range that begins before the end of the range, then fail.
|
||||
if ((!startBlobRanges.empty() && startBlobRanges.front().begin != range.begin) ||
|
||||
(!endBlobRanges.empty() && endBlobRanges.front().begin < range.end)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ struct BlobGranuleRangesWorkload : TestWorkload {
|
|||
bool fail7 = wait(self->isRangeActive(cx, KeyRangeRef(activeRange.begin, range.end)));
|
||||
ASSERT(!fail7);
|
||||
|
||||
wait(self->tearDownRangeAfterUnit(cx, self, range));
|
||||
wait(self->tearDownRangeAfterUnit(cx, self, activeRange));
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue