Fix stale memory access with FSBuffer and tiered sec cache (#12712) · facebook/rocksdb@6c60c8f (original) (raw)
`@@ -873,6 +873,111 @@ TEST_P(DBTieredAdmPolicyTest, CompressedCacheAdmission) {
`
873
873
`Destroy(options);
`
874
874
`}
`
875
875
``
``
876
`+
TEST_F(DBTieredSecondaryCacheTest, FSBufferTest) {
`
``
877
`+
class WrapFS : public FileSystemWrapper {
`
``
878
`+
public:
`
``
879
`+
explicit WrapFS(const std::shared_ptr& _target)
`
``
880
`+
: FileSystemWrapper(_target) {}
`
``
881
`+
~WrapFS() override {}
`
``
882
`+
const char* Name() const override { return "WrapFS"; }
`
``
883
+
``
884
`+
IOStatus NewRandomAccessFile(const std::string& fname,
`
``
885
`+
const FileOptions& opts,
`
``
886
`+
std::unique_ptr* result,
`
``
887
`+
IODebugContext* dbg) override {
`
``
888
`+
class WrappedRandomAccessFile : public FSRandomAccessFileOwnerWrapper {
`
``
889
`+
public:
`
``
890
`+
explicit WrappedRandomAccessFile(
`
``
891
`+
std::unique_ptr& file)
`
``
892
`+
: FSRandomAccessFileOwnerWrapper(std::move(file)) {}
`
``
893
+
``
894
`+
IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
`
``
895
`+
const IOOptions& options,
`
``
896
`+
IODebugContext* dbg) override {
`
``
897
`+
for (size_t i = 0; i < num_reqs; ++i) {
`
``
898
`+
FSReadRequest& req = reqs[i];
`
``
899
`+
FSAllocationPtr buffer(new char[req.len], [](void* ptr) {
`
``
900
`+
delete[] static_cast<char*>(ptr);
`
``
901
`+
});
`
``
902
`+
req.fs_scratch = std::move(buffer);
`
``
903
`+
req.status = Read(req.offset, req.len, options, &req.result,
`
``
904
`+
static_cast<char*>(req.fs_scratch.get()), dbg);
`
``
905
`+
}
`
``
906
`+
return IOStatus::OK();
`
``
907
`+
}
`
``
908
`+
};
`
``
909
+
``
910
`+
std::unique_ptr file;
`
``
911
`+
IOStatus s = target()->NewRandomAccessFile(fname, opts, &file, dbg);
`
``
912
`+
EXPECT_OK(s);
`
``
913
`+
result->reset(new WrappedRandomAccessFile(file));
`
``
914
+
``
915
`+
return s;
`
``
916
`+
}
`
``
917
+
``
918
`+
void SupportedOps(int64_t& supported_ops) override {
`
``
919
`+
supported_ops = 1 << FSSupportedOps::kAsyncIO;
`
``
920
`+
supported_ops |= 1 << FSSupportedOps::kFSBuffer;
`
``
921
`+
}
`
``
922
`+
};
`
``
923
+
``
924
`+
if (!LZ4_Supported()) {
`
``
925
`+
ROCKSDB_GTEST_SKIP("This test requires LZ4 support.");
`
``
926
`+
return;
`
``
927
`+
}
`
``
928
+
``
929
`+
std::shared_ptr wrap_fs =
`
``
930
`+
std::make_shared(env_->GetFileSystem());
`
``
931
`+
std::unique_ptr wrap_env(new CompositeEnvWrapper(env_, wrap_fs));
`
``
932
`+
BlockBasedTableOptions table_options;
`
``
933
`+
table_options.block_cache = NewCache(250 * 1024, 20 * 1024, 256 * 1024,
`
``
934
`+
TieredAdmissionPolicy::kAdmPolicyAuto,
`
``
935
`+
/ready_before_wait=/true);
`
``
936
`+
table_options.block_size = 4 * 1024;
`
``
937
`+
table_options.cache_index_and_filter_blocks = false;
`
``
938
`+
Options options = GetDefaultOptions();
`
``
939
`+
options.create_if_missing = true;
`
``
940
`+
options.table_factory.reset(NewBlockBasedTableFactory(table_options));
`
``
941
`+
options.statistics = CreateDBStatistics();
`
``
942
`+
options.env = wrap_env.get();
`
``
943
+
``
944
`+
options.paranoid_file_checks = false;
`
``
945
`+
DestroyAndReopen(options);
`
``
946
`+
Random rnd(301);
`
``
947
`+
const int N = 256;
`
``
948
`+
for (int i = 0; i < N; i++) {
`
``
949
`+
std::string p_v;
`
``
950
`+
test::CompressibleString(&rnd, 0.5, 1007, &p_v);
`
``
951
`+
ASSERT_OK(Put(Key(i), p_v));
`
``
952
`+
}
`
``
953
+
``
954
`+
ASSERT_OK(Flush());
`
``
955
+
``
956
`+
std::vectorstd::string keys;
`
``
957
`+
std::vectorstd::string values;
`
``
958
+
``
959
`+
keys.push_back(Key(0));
`
``
960
`+
keys.push_back(Key(4));
`
``
961
`+
keys.push_back(Key(8));
`
``
962
`+
values = MultiGet(keys, /snapshot=/nullptr, /async=/true);
`
``
963
`+
ASSERT_EQ(values.size(), keys.size());
`
``
964
`+
for (const auto& value : values) {
`
``
965
`+
ASSERT_EQ(1007, value.size());
`
``
966
`+
}
`
``
967
`+
ASSERT_EQ(nvm_sec_cache()->num_insert_saved(), 3u);
`
``
968
`+
ASSERT_EQ(nvm_sec_cache()->num_misses(), 3u);
`
``
969
`+
ASSERT_EQ(nvm_sec_cache()->num_hits(), 0u);
`
``
970
+
``
971
`+
std::string v = Get(Key(12));
`
``
972
`+
ASSERT_EQ(1007, v.size());
`
``
973
`+
ASSERT_EQ(nvm_sec_cache()->num_insert_saved(), 4u);
`
``
974
`+
ASSERT_EQ(nvm_sec_cache()->num_misses(), 4u);
`
``
975
`+
ASSERT_EQ(options.statistics->getTickerCount(BLOCK_CACHE_MISS), 4u);
`
``
976
+
``
977
`+
Close();
`
``
978
`+
Destroy(options);
`
``
979
`+
}
`
``
980
+
876
981
`INSTANTIATE_TEST_CASE_P(
`
877
982
` DBTieredAdmPolicyTest, DBTieredAdmPolicyTest,
`
878
983
`::testing::Values(TieredAdmissionPolicy::kAdmPolicyAuto,
`