#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "net/disk_cache/simple/simple_synchronous_entry.h"
#include <cstring>
#include <functional>
#include <limits>
#include <optional>
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/files/file_util.h"
#include "base/hash/hash.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/histogram_macros_local.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/task/sequenced_task_runner.h"
#include "base/timer/elapsed_timer.h"
#include "crypto/secure_hash.h"
#include "net/base/hash_value.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/cache_util.h"
#include "net/disk_cache/simple/simple_backend_version.h"
#include "net/disk_cache/simple/simple_histogram_enums.h"
#include "net/disk_cache/simple/simple_histogram_macros.h"
#include "net/disk_cache/simple/simple_util.h"
#include "third_party/abseil-cpp/absl/container/inlined_vector.h"
#include "third_party/zlib/zlib.h"
FilePath;
Time;
namespace disk_cache {
namespace {
void RecordSyncOpenResult(net::CacheType cache_type, OpenEntryResult result) { … }
void RecordWriteResult(net::CacheType cache_type, SyncWriteResult result) { … }
void RecordCheckEOFResult(net::CacheType cache_type, CheckEOFResult result) { … }
void RecordCloseResult(net::CacheType cache_type, CloseResult result) { … }
void RecordOpenPrefetchMode(net::CacheType cache_type, OpenPrefetchMode mode) { … }
void RecordDiskCreateLatency(net::CacheType cache_type, base::TimeDelta delay) { … }
bool CanOmitEmptyFile(int file_index) { … }
bool TruncatePath(const FilePath& filename_to_truncate,
BackendFileOperations* file_operations) { … }
void CalculateSHA256OfKey(const std::string& key,
net::SHA256HashValue* out_hash_value) { … }
SimpleFileTracker::SubFile SubFileForFileIndex(int file_index) { … }
int FileIndexForSubFile(SimpleFileTracker::SubFile sub_file) { … }
}
class SimpleSynchronousEntry::PrefetchData final { … };
class SimpleSynchronousEntry::ScopedFileOperationsBinding final { … };
GetEntryHashKey;
GetFilenameFromEntryFileKeyAndFileIndex;
GetSparseFilenameFromEntryFileKey;
GetHeaderSize;
GetDataSizeFromFileSize;
GetFileSizeFromDataSize;
GetFileIndexFromStreamIndex;
BASE_FEATURE(…);
const char kSimpleCacheFullPrefetchBytesParam[] = …;
constexpr base::FeatureParam<int> kSimpleCacheFullPrefetchSize{ … };
const char kSimpleCacheTrailerPrefetchSpeculativeBytesParam[] = …;
constexpr base::FeatureParam<int> kSimpleCacheTrailerPrefetchSpeculativeBytes{ … };
int GetSimpleCacheFullPrefetchSize() { … }
int GetSimpleCacheTrailerPrefetchSize(int hint_size) { … }
SimpleEntryStat::SimpleEntryStat(base::Time last_used,
base::Time last_modified,
const int32_t data_size[],
const int32_t sparse_data_size)
: … { … }
int SimpleEntryStat::GetOffsetInFile(size_t key_length,
int offset,
int stream_index) const { … }
int SimpleEntryStat::GetEOFOffsetInFile(size_t key_length,
int stream_index) const { … }
int SimpleEntryStat::GetLastEOFOffsetInFile(size_t key_length,
int stream_index) const { … }
int64_t SimpleEntryStat::GetFileSize(size_t key_length, int file_index) const { … }
SimpleStreamPrefetchData::SimpleStreamPrefetchData()
: … { … }
SimpleStreamPrefetchData::~SimpleStreamPrefetchData() = default;
SimpleEntryCreationResults::SimpleEntryCreationResults(
SimpleEntryStat entry_stat)
: … { … }
SimpleEntryCreationResults::~SimpleEntryCreationResults() = default;
SimpleSynchronousEntry::CRCRecord::CRCRecord() : … { … }
SimpleSynchronousEntry::CRCRecord::CRCRecord(int index_p,
bool has_crc32_p,
uint32_t data_crc32_p)
: … { … }
SimpleSynchronousEntry::ReadRequest::ReadRequest(int index_p,
int offset_p,
int buf_len_p)
: … { … }
SimpleSynchronousEntry::WriteRequest::WriteRequest(int index_p,
int offset_p,
int buf_len_p,
uint32_t previous_crc32_p,
bool truncate_p,
bool doomed_p,
bool request_update_crc_p)
: … { … }
SimpleSynchronousEntry::SparseRequest::SparseRequest(int64_t sparse_offset_p,
int buf_len_p)
: … { … }
void SimpleSynchronousEntry::OpenEntry(
net::CacheType cache_type,
const FilePath& path,
const std::optional<std::string>& key,
const uint64_t entry_hash,
SimpleFileTracker* file_tracker,
std::unique_ptr<UnboundBackendFileOperations> file_operations,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results) { … }
void SimpleSynchronousEntry::CreateEntry(
net::CacheType cache_type,
const FilePath& path,
const std::string& key,
const uint64_t entry_hash,
SimpleFileTracker* file_tracker,
std::unique_ptr<UnboundBackendFileOperations> file_operations,
SimpleEntryCreationResults* out_results) { … }
void SimpleSynchronousEntry::OpenOrCreateEntry(
net::CacheType cache_type,
const FilePath& path,
const std::string& key,
const uint64_t entry_hash,
OpenEntryIndexEnum index_state,
bool optimistic_create,
SimpleFileTracker* file_tracker,
std::unique_ptr<UnboundBackendFileOperations> file_operations,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results) { … }
int SimpleSynchronousEntry::DeleteEntryFiles(
const FilePath& path,
net::CacheType cache_type,
uint64_t entry_hash,
std::unique_ptr<UnboundBackendFileOperations> unbound_file_operations) { … }
int SimpleSynchronousEntry::DeleteEntryFilesInternal(
const FilePath& path,
net::CacheType cache_type,
uint64_t entry_hash,
BackendFileOperations* file_operations) { … }
int SimpleSynchronousEntry::Doom() { … }
int SimpleSynchronousEntry::DoomInternal(
BackendFileOperations* file_operations) { … }
int SimpleSynchronousEntry::TruncateEntryFiles(
const base::FilePath& path,
uint64_t entry_hash,
std::unique_ptr<UnboundBackendFileOperations> unbound_file_operations) { … }
int SimpleSynchronousEntry::DeleteEntrySetFiles(
const std::vector<uint64_t>* key_hashes,
const FilePath& path,
std::unique_ptr<UnboundBackendFileOperations> unbound_file_operations) { … }
void SimpleSynchronousEntry::ReadData(const ReadRequest& in_entry_op,
SimpleEntryStat* entry_stat,
net::IOBuffer* out_buf,
ReadResult* out_result) { … }
void SimpleSynchronousEntry::WriteData(const WriteRequest& in_entry_op,
net::IOBuffer* in_buf,
SimpleEntryStat* out_entry_stat,
WriteResult* out_write_result) { … }
void SimpleSynchronousEntry::ReadSparseData(const SparseRequest& in_entry_op,
net::IOBuffer* out_buf,
base::Time* out_last_used,
int* out_result) { … }
void SimpleSynchronousEntry::WriteSparseData(const SparseRequest& in_entry_op,
net::IOBuffer* in_buf,
uint64_t max_sparse_data_size,
SimpleEntryStat* out_entry_stat,
int* out_result) { … }
void SimpleSynchronousEntry::GetAvailableRange(const SparseRequest& in_entry_op,
RangeResult* out_result) { … }
int SimpleSynchronousEntry::CheckEOFRecord(
BackendFileOperations* file_operations,
base::File* file,
int stream_index,
const SimpleEntryStat& entry_stat,
uint32_t expected_crc32) { … }
int SimpleSynchronousEntry::PreReadStreamPayload(
base::File* file,
PrefetchData* prefetch_data,
int stream_index,
int extra_size,
const SimpleEntryStat& entry_stat,
const SimpleFileEOF& eof_record,
SimpleStreamPrefetchData* out) { … }
void SimpleSynchronousEntry::Close(
const SimpleEntryStat& entry_stat,
std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write,
net::GrowableIOBuffer* stream_0_data,
SimpleEntryCloseResults* out_results) { … }
SimpleSynchronousEntry::SimpleSynchronousEntry(
net::CacheType cache_type,
const FilePath& path,
const std::optional<std::string>& key,
const uint64_t entry_hash,
SimpleFileTracker* file_tracker,
std::unique_ptr<UnboundBackendFileOperations> unbound_file_operations,
int32_t trailer_prefetch_size)
: … { … }
SimpleSynchronousEntry::~SimpleSynchronousEntry() { … }
bool SimpleSynchronousEntry::MaybeOpenFile(
BackendFileOperations* file_operations,
int file_index,
base::File::Error* out_error) { … }
bool SimpleSynchronousEntry::MaybeCreateFile(
BackendFileOperations* file_operations,
int file_index,
FileRequired file_required,
base::File::Error* out_error) { … }
bool SimpleSynchronousEntry::OpenFiles(BackendFileOperations* file_operations,
SimpleEntryStat* out_entry_stat) { … }
bool SimpleSynchronousEntry::CreateFiles(BackendFileOperations* file_operations,
SimpleEntryStat* out_entry_stat) { … }
void SimpleSynchronousEntry::CloseFile(BackendFileOperations* file_operations,
int index) { … }
void SimpleSynchronousEntry::CloseFiles() { … }
bool SimpleSynchronousEntry::CheckHeaderAndKey(base::File* file,
int file_index) { … }
int SimpleSynchronousEntry::InitializeForOpen(
BackendFileOperations* file_operations,
SimpleEntryStat* out_entry_stat,
SimpleStreamPrefetchData stream_prefetch_data[2]) { … }
bool SimpleSynchronousEntry::InitializeCreatedFile(
BackendFileOperations* file_operations,
int file_index) { … }
int SimpleSynchronousEntry::InitializeForCreate(
BackendFileOperations* file_operations,
SimpleEntryStat* out_entry_stat) { … }
int SimpleSynchronousEntry::ReadAndValidateStream0AndMaybe1(
BackendFileOperations* file_operations,
int file_size,
SimpleEntryStat* out_entry_stat,
SimpleStreamPrefetchData stream_prefetch_data[2]) { … }
bool SimpleSynchronousEntry::ReadFromFileOrPrefetched(
base::File* file,
PrefetchData* prefetch_data,
int file_index,
int offset,
int size,
char* dest) { … }
int SimpleSynchronousEntry::GetEOFRecordData(base::File* file,
PrefetchData* prefetch_data,
int file_index,
int file_offset,
SimpleFileEOF* eof_record) { … }
bool SimpleSynchronousEntry::DeleteFileForEntryHash(
const FilePath& path,
const uint64_t entry_hash,
const int file_index,
BackendFileOperations* file_operations) { … }
bool SimpleSynchronousEntry::DeleteFilesForEntryHash(
const FilePath& path,
const uint64_t entry_hash,
BackendFileOperations* file_operations) { … }
bool SimpleSynchronousEntry::TruncateFilesForEntryHash(
const FilePath& path,
const uint64_t entry_hash,
BackendFileOperations* file_operations) { … }
FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(
int file_index) const { … }
base::FilePath SimpleSynchronousEntry::GetFilenameForSubfile(
SimpleFileTracker::SubFile sub_file) const { … }
bool SimpleSynchronousEntry::OpenSparseFileIfExists(
BackendFileOperations* file_operations,
int32_t* out_sparse_data_size) { … }
bool SimpleSynchronousEntry::CreateSparseFile(
BackendFileOperations* file_operations) { … }
void SimpleSynchronousEntry::CloseSparseFile(
BackendFileOperations* file_operations) { … }
bool SimpleSynchronousEntry::TruncateSparseFile(base::File* sparse_file) { … }
bool SimpleSynchronousEntry::InitializeSparseFile(base::File* sparse_file) { … }
bool SimpleSynchronousEntry::ScanSparseFile(base::File* sparse_file,
int32_t* out_sparse_data_size) { … }
bool SimpleSynchronousEntry::ReadSparseRange(base::File* sparse_file,
const SparseRange* range,
int offset,
int len,
char* buf) { … }
bool SimpleSynchronousEntry::WriteSparseRange(base::File* sparse_file,
SparseRange* range,
int offset,
int len,
const char* buf) { … }
bool SimpleSynchronousEntry::AppendSparseRange(base::File* sparse_file,
int64_t offset,
int len,
const char* buf) { … }
}