Pollute buffer before calling Read() (#8955)
Summary: Add a paranoid check where in case FileSystem layer doesn't fill the buffer but returns succeed, checksum is unlikely to match even if buffer contains a previous block. The byte modified is not useful anyway, so it isn't expect to change any behavior. Pull Request resolved: https://github.com/facebook/rocksdb/pull/8955 Test Plan: See existing CI to pass. Reviewed By: pdillinger Differential Revision: D31183966 fbshipit-source-id: dcc4de429e18131873f783b90d3be55d7eb44a1f
This commit is contained in:
parent
345f4c9462
commit
b88109db19
@ -48,6 +48,9 @@
|
|||||||
* Extended parameter `output_file_names` of `CompactFiles` API to also include paths of the blob files generated by the compaction in Integrated BlobDB.
|
* Extended parameter `output_file_names` of `CompactFiles` API to also include paths of the blob files generated by the compaction in Integrated BlobDB.
|
||||||
* Most `BackupEngine` functions now return `IOStatus` instead of `Status`. Most existing code should be compatible with this change but some calls might need to be updated.
|
* Most `BackupEngine` functions now return `IOStatus` instead of `Status`. Most existing code should be compatible with this change but some calls might need to be updated.
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* Add a paranoid check where in case FileSystem layer doesn't fill the buffer but returns succeed, checksum is unlikely to match even if buffer contains a previous block. The byte modified is not useful anyway, so it isn't expected to change any behavior when FileSystem is satisfying its contract.
|
||||||
|
|
||||||
## 6.24.0 (2021-08-20)
|
## 6.24.0 (2021-08-20)
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* If the primary's CURRENT file is missing or inaccessible, the secondary instance should not hang repeatedly trying to switch to a new MANIFEST. It should instead return the error code encountered while accessing the file.
|
* If the primary's CURRENT file is missing or inaccessible, the secondary instance should not hang repeatedly trying to switch to a new MANIFEST. It should instead return the error code encountered while accessing the file.
|
||||||
|
@ -41,6 +41,15 @@ IOStatus RandomAccessFileReader::Read(const IOOptions& opts, uint64_t offset,
|
|||||||
(void)aligned_buf;
|
(void)aligned_buf;
|
||||||
|
|
||||||
TEST_SYNC_POINT_CALLBACK("RandomAccessFileReader::Read", nullptr);
|
TEST_SYNC_POINT_CALLBACK("RandomAccessFileReader::Read", nullptr);
|
||||||
|
|
||||||
|
// To be paranoid: modify scratch a little bit, so in case underlying
|
||||||
|
// FileSystem doesn't fill the buffer but return success and `scratch` returns
|
||||||
|
// contains a previous block, returned value will not pass checksum.
|
||||||
|
if (n > 0 && scratch != nullptr) {
|
||||||
|
// This byte might not change anything for direct I/O case, but it's OK.
|
||||||
|
scratch[0]++;
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus io_s;
|
IOStatus io_s;
|
||||||
uint64_t elapsed = 0;
|
uint64_t elapsed = 0;
|
||||||
{
|
{
|
||||||
@ -214,6 +223,18 @@ IOStatus RandomAccessFileReader::MultiRead(const IOOptions& opts,
|
|||||||
AlignedBuf* aligned_buf) const {
|
AlignedBuf* aligned_buf) const {
|
||||||
(void)aligned_buf; // suppress warning of unused variable in LITE mode
|
(void)aligned_buf; // suppress warning of unused variable in LITE mode
|
||||||
assert(num_reqs > 0);
|
assert(num_reqs > 0);
|
||||||
|
|
||||||
|
// To be paranoid modify scratch a little bit, so in case underlying
|
||||||
|
// FileSystem doesn't fill the buffer but return succee and `scratch` returns
|
||||||
|
// contains a previous block, returned value will not pass checksum.
|
||||||
|
// This byte might not change anything for direct I/O case, but it's OK.
|
||||||
|
for (size_t i = 0; i < num_reqs; i++) {
|
||||||
|
FSReadRequest& r = read_reqs[i];
|
||||||
|
if (r.len > 0 && r.scratch != nullptr) {
|
||||||
|
r.scratch[0]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus io_s;
|
IOStatus io_s;
|
||||||
uint64_t elapsed = 0;
|
uint64_t elapsed = 0;
|
||||||
{
|
{
|
||||||
|
@ -58,6 +58,14 @@ IOStatus SequentialFileReader::Read(size_t n, Slice* result, char* scratch) {
|
|||||||
*result = Slice(scratch, r);
|
*result = Slice(scratch, r);
|
||||||
#endif // !ROCKSDB_LITE
|
#endif // !ROCKSDB_LITE
|
||||||
} else {
|
} else {
|
||||||
|
// To be paranoid, modify scratch a little bit, so in case underlying
|
||||||
|
// FileSystem doesn't fill the buffer but return succee and `scratch`
|
||||||
|
// returns contains a previous block, returned value will not pass
|
||||||
|
// checksum.
|
||||||
|
// It's hard to find useful byte for direct I/O case, so we skip it.
|
||||||
|
if (n > 0 && scratch != nullptr) {
|
||||||
|
scratch[0]++;
|
||||||
|
}
|
||||||
io_s = file_->Read(n, IOOptions(), result, scratch, nullptr);
|
io_s = file_->Read(n, IOOptions(), result, scratch, nullptr);
|
||||||
}
|
}
|
||||||
IOSTATS_ADD(bytes_read, result->size());
|
IOSTATS_ADD(bytes_read, result->size());
|
||||||
|
Loading…
Reference in New Issue
Block a user