| 457 | void SsdFile::verifyWrite(AsyncDataCacheEntry& entry, SsdRun ssdRun) { |
| 458 | auto testData = std::make_unique<char[]>(entry.size()); |
| 459 | const auto rc = ::pread(fd_, testData.get(), entry.size(), ssdRun.offset()); |
| 460 | BOLT_CHECK_EQ(rc, entry.size()); |
| 461 | if (entry.tinyData() != 0) { |
| 462 | if (::memcmp(testData.get(), entry.tinyData(), entry.size()) != 0) { |
| 463 | BOLT_FAIL("bad read back"); |
| 464 | } |
| 465 | } else { |
| 466 | const auto& data = entry.data(); |
| 467 | int64_t bytesLeft = entry.size(); |
| 468 | int64_t offset = 0; |
| 469 | for (auto i = 0; i < data.numRuns(); ++i) { |
| 470 | const auto run = data.runAt(i); |
| 471 | const auto compareSize = std::min<int64_t>(bytesLeft, run.numBytes()); |
| 472 | auto badIndex = indexOfFirstMismatch( |
| 473 | run.data<char>(), testData.get() + offset, compareSize); |
| 474 | if (badIndex != -1) { |
| 475 | BOLT_FAIL("Bad read back"); |
| 476 | } |
| 477 | bytesLeft -= run.numBytes(); |
| 478 | offset += run.numBytes(); |
| 479 | if (bytesLeft <= 0) { |
| 480 | break; |
| 481 | }; |
| 482 | } |
| 483 | } |
| 484 | } |
| 485 | |
| 486 | void SsdFile::updateStats(SsdCacheStats& stats) const { |
| 487 | // Lock only in tsan build. Incrementing the counters has no synchronized |
| 488 | // semantics. |
| 489 | std::shared_lock<std::shared_mutex> l(mutex_); |