diff --git a/file/file_prefetch_buffer.cc b/file/file_prefetch_buffer.cc index ce98177be..218983254 100644 --- a/file/file_prefetch_buffer.cc +++ b/file/file_prefetch_buffer.cc @@ -109,7 +109,8 @@ Status FilePrefetchBuffer::Prefetch(const IOOptions& opts, bool FilePrefetchBuffer::TryReadFromCache(const IOOptions& opts, uint64_t offset, size_t n, - Slice* result, bool for_compaction) { + Slice* result, Status* status, + bool for_compaction) { if (track_min_offset_ && offset < min_offset_read_) { min_offset_read_ = static_cast(offset); } @@ -134,6 +135,9 @@ bool FilePrefetchBuffer::TryReadFromCache(const IOOptions& opts, for_compaction); } if (!s.ok()) { + if (status) { + *status = s; + } #ifndef NDEBUG IGNORE_STATUS_IF_ERROR(s); #endif diff --git a/file/file_prefetch_buffer.h b/file/file_prefetch_buffer.h index d8e9c0ff6..5532e79df 100644 --- a/file/file_prefetch_buffer.h +++ b/file/file_prefetch_buffer.h @@ -75,7 +75,7 @@ class FilePrefetchBuffer { // result : output buffer to put the data into. // for_compaction : if cache read is done for compaction read. bool TryReadFromCache(const IOOptions& opts, uint64_t offset, size_t n, - Slice* result, bool for_compaction = false); + Slice* result, Status* s, bool for_compaction = false); // The minimum `offset` ever passed to TryReadFromCache(). This will nly be // tracked if track_min_offset = true. diff --git a/file/file_util.cc b/file/file_util.cc index 451ef7728..4e92673d6 100644 --- a/file/file_util.cc +++ b/file/file_util.cc @@ -195,7 +195,7 @@ IOStatus GenerateOneFileChecksum( size_t bytes_to_read = static_cast(std::min(uint64_t{readahead_size}, size)); if (!prefetch_buffer.TryReadFromCache(opts, offset, bytes_to_read, &slice, - false)) { + nullptr, false)) { return IOStatus::Corruption("file read failed"); } if (slice.size() == 0) { diff --git a/table/block_fetcher.cc b/table/block_fetcher.cc index b0880d516..e9df0f7af 100644 --- a/table/block_fetcher.cc +++ b/table/block_fetcher.cc @@ -63,13 +63,16 @@ inline bool BlockFetcher::TryGetFromPrefetchBuffer() { Status s = PrepareIOFromReadOptions(read_options_, file_->env(), opts); if (s.ok() && prefetch_buffer_->TryReadFromCache( opts, handle_.offset(), block_size_with_trailer_, &slice_, - for_compaction_)) { + &s, for_compaction_)) { CheckBlockChecksum(); if (!status_.ok()) { return true; } got_from_prefetch_buffer_ = true; used_buf_ = const_cast(slice_.data()); + } else if (!s.ok()) { + status_ = s; + return true; } } return got_from_prefetch_buffer_; diff --git a/table/format.cc b/table/format.cc index 8fb66f8a1..b87274700 100644 --- a/table/format.cc +++ b/table/format.cc @@ -307,8 +307,9 @@ Status ReadFooterFromFile(const IOOptions& opts, RandomAccessFileReader* file, // for iterator, TryReadFromCache might do a readahead. Revisit to see if we // need to pass a timeout at that point if (prefetch_buffer == nullptr || - !prefetch_buffer->TryReadFromCache( - IOOptions(), read_offset, Footer::kMaxEncodedLength, &footer_input)) { + !prefetch_buffer->TryReadFromCache(IOOptions(), read_offset, + Footer::kMaxEncodedLength, + &footer_input, nullptr)) { if (file->use_direct_io()) { s = file->Read(opts, read_offset, Footer::kMaxEncodedLength, &footer_input, nullptr, &internal_buf); diff --git a/table/table_test.cc b/table/table_test.cc index bfec7b79b..db765d483 100644 --- a/table/table_test.cc +++ b/table/table_test.cc @@ -4559,9 +4559,9 @@ TEST_F(BBTTailPrefetchTest, FilePrefetchBufferMinOffset) { TailPrefetchStats tpstats; FilePrefetchBuffer buffer(nullptr, 0, 0, false, true); IOOptions opts; - buffer.TryReadFromCache(opts, 500, 10, nullptr); - buffer.TryReadFromCache(opts, 480, 10, nullptr); - buffer.TryReadFromCache(opts, 490, 10, nullptr); + buffer.TryReadFromCache(opts, 500, 10, nullptr, nullptr); + buffer.TryReadFromCache(opts, 480, 10, nullptr, nullptr); + buffer.TryReadFromCache(opts, 490, 10, nullptr, nullptr); ASSERT_EQ(480, buffer.min_offset_read()); }