Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/disk_cache/simple/simple_synchronous_entry.h" | 5 #include "net/disk_cache/simple/simple_synchronous_entry.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <functional> | 9 #include <functional> |
| 10 #include <limits> | 10 #include <limits> |
| 11 | 11 |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 14 #include "base/hash.h" | 14 #include "base/hash.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/numerics/safe_conversions.h" | 17 #include "base/numerics/safe_conversions.h" |
| 18 #include "base/sha1.h" | 18 #include "base/sha1.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/timer/elapsed_timer.h" | 20 #include "base/timer/elapsed_timer.h" |
| 21 #include "crypto/secure_hash.h" | |
| 22 #include "net/base/hash_value.h" | |
| 21 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
| 22 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
| 23 #include "net/disk_cache/simple/simple_backend_version.h" | 25 #include "net/disk_cache/simple/simple_backend_version.h" |
| 24 #include "net/disk_cache/simple/simple_histogram_macros.h" | 26 #include "net/disk_cache/simple/simple_histogram_macros.h" |
| 25 #include "net/disk_cache/simple/simple_util.h" | 27 #include "net/disk_cache/simple/simple_util.h" |
| 26 #include "third_party/zlib/zlib.h" | 28 #include "third_party/zlib/zlib.h" |
| 27 | 29 |
| 28 using base::File; | 30 using base::File; |
| 29 using base::FilePath; | 31 using base::FilePath; |
| 30 using base::Time; | 32 using base::Time; |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 // Used in histograms, please only add entries at the end. | 36 // Used in histograms, please only add entries at the end. |
| 35 enum OpenEntryResult { | 37 enum OpenEntryResult { |
| 36 OPEN_ENTRY_SUCCESS = 0, | 38 OPEN_ENTRY_SUCCESS = 0, |
| 37 OPEN_ENTRY_PLATFORM_FILE_ERROR = 1, | 39 OPEN_ENTRY_PLATFORM_FILE_ERROR = 1, |
| 38 OPEN_ENTRY_CANT_READ_HEADER = 2, | 40 OPEN_ENTRY_CANT_READ_HEADER = 2, |
| 39 OPEN_ENTRY_BAD_MAGIC_NUMBER = 3, | 41 OPEN_ENTRY_BAD_MAGIC_NUMBER = 3, |
| 40 OPEN_ENTRY_BAD_VERSION = 4, | 42 OPEN_ENTRY_BAD_VERSION = 4, |
| 41 OPEN_ENTRY_CANT_READ_KEY = 5, | 43 OPEN_ENTRY_CANT_READ_KEY = 5, |
| 42 // OPEN_ENTRY_KEY_MISMATCH = 6, Deprecated. | 44 OPEN_ENTRY_KEY_MISMATCH = 6, |
| 43 OPEN_ENTRY_KEY_HASH_MISMATCH = 7, | 45 OPEN_ENTRY_KEY_HASH_MISMATCH = 7, |
| 44 OPEN_ENTRY_SPARSE_OPEN_FAILED = 8, | 46 OPEN_ENTRY_SPARSE_OPEN_FAILED = 8, |
| 45 OPEN_ENTRY_MAX = 9, | 47 OPEN_ENTRY_MAX = 9, |
| 46 }; | 48 }; |
| 47 | 49 |
| 48 // Used in histograms, please only add entries at the end. | 50 // Used in histograms, please only add entries at the end. |
| 49 enum WriteResult { | 51 enum WriteResult { |
| 50 WRITE_RESULT_SUCCESS = 0, | 52 WRITE_RESULT_SUCCESS = 0, |
| 51 WRITE_RESULT_PRETRUNCATE_FAILURE, | 53 WRITE_RESULT_PRETRUNCATE_FAILURE, |
| 52 WRITE_RESULT_WRITE_FAILURE, | 54 WRITE_RESULT_WRITE_FAILURE, |
| 53 WRITE_RESULT_TRUNCATE_FAILURE, | 55 WRITE_RESULT_TRUNCATE_FAILURE, |
| 54 WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED, | 56 WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED, |
| 55 WRITE_RESULT_LAZY_CREATE_FAILURE, | 57 WRITE_RESULT_LAZY_CREATE_FAILURE, |
| 56 WRITE_RESULT_LAZY_INITIALIZE_FAILURE, | 58 WRITE_RESULT_LAZY_INITIALIZE_FAILURE, |
| 57 WRITE_RESULT_MAX, | 59 WRITE_RESULT_MAX, |
| 58 }; | 60 }; |
| 59 | 61 |
| 60 // Used in histograms, please only add entries at the end. | 62 // Used in histograms, please only add entries at the end. |
| 61 enum CheckEOFResult { | 63 enum CheckEOFResult { |
| 62 CHECK_EOF_RESULT_SUCCESS, | 64 CHECK_EOF_RESULT_SUCCESS, |
| 63 CHECK_EOF_RESULT_READ_FAILURE, | 65 CHECK_EOF_RESULT_READ_FAILURE, |
| 64 CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH, | 66 CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH, |
| 65 CHECK_EOF_RESULT_CRC_MISMATCH, | 67 CHECK_EOF_RESULT_CRC_MISMATCH, |
| 68 CHECK_EOF_RESULT_KEY_SHA256_MISMATCH, | |
| 66 CHECK_EOF_RESULT_MAX, | 69 CHECK_EOF_RESULT_MAX, |
| 67 }; | 70 }; |
| 68 | 71 |
| 69 // Used in histograms, please only add entries at the end. | 72 // Used in histograms, please only add entries at the end. |
| 70 enum CloseResult { | 73 enum CloseResult { |
| 71 CLOSE_RESULT_SUCCESS, | 74 CLOSE_RESULT_SUCCESS, |
| 72 CLOSE_RESULT_WRITE_FAILURE, | 75 CLOSE_RESULT_WRITE_FAILURE, |
| 73 }; | 76 }; |
| 74 | 77 |
| 75 void RecordSyncOpenResult(net::CacheType cache_type, | 78 void RecordSyncOpenResult(net::CacheType cache_type, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | | 119 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | |
| 117 File::FLAG_SHARE_DELETE; | 120 File::FLAG_SHARE_DELETE; |
| 118 file_to_truncate.Initialize(filename_to_truncate, flags); | 121 file_to_truncate.Initialize(filename_to_truncate, flags); |
| 119 if (!file_to_truncate.IsValid()) | 122 if (!file_to_truncate.IsValid()) |
| 120 return false; | 123 return false; |
| 121 if (!file_to_truncate.SetLength(0)) | 124 if (!file_to_truncate.SetLength(0)) |
| 122 return false; | 125 return false; |
| 123 return true; | 126 return true; |
| 124 } | 127 } |
| 125 | 128 |
| 129 void CalculateSHA256OfKey(const std::string& key, | |
| 130 net::SHA256HashValue* out_hash_value) { | |
| 131 // Write SHA256 of the key immediately after stream 0 data. | |
| 132 std::unique_ptr<crypto::SecureHash> hash( | |
| 133 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | |
| 134 hash->Update(key.data(), key.size()); | |
| 135 hash->Finish(out_hash_value, sizeof(*out_hash_value)); | |
| 136 } | |
| 137 | |
| 126 } // namespace | 138 } // namespace |
| 127 | 139 |
| 128 namespace disk_cache { | 140 namespace disk_cache { |
| 129 | 141 |
| 130 using simple_util::GetEntryHashKey; | 142 using simple_util::GetEntryHashKey; |
| 131 using simple_util::GetFilenameFromEntryHashAndFileIndex; | 143 using simple_util::GetFilenameFromEntryHashAndFileIndex; |
| 132 using simple_util::GetSparseFilenameFromEntryHash; | 144 using simple_util::GetSparseFilenameFromEntryHash; |
| 133 using simple_util::GetDataSizeFromKeyAndFileSize; | 145 using simple_util::GetHeaderSize; |
| 134 using simple_util::GetFileSizeFromKeyAndDataSize; | 146 using simple_util::GetDataSizeFromFileSize; |
| 147 using simple_util::GetFileSizeFromDataSize; | |
| 135 using simple_util::GetFileIndexFromStreamIndex; | 148 using simple_util::GetFileIndexFromStreamIndex; |
| 136 | 149 |
| 137 SimpleEntryStat::SimpleEntryStat(base::Time last_used, | 150 SimpleEntryStat::SimpleEntryStat(base::Time last_used, |
| 138 base::Time last_modified, | 151 base::Time last_modified, |
| 139 const int32_t data_size[], | 152 const int32_t data_size[], |
| 140 const int32_t sparse_data_size) | 153 const int32_t sparse_data_size) |
| 141 : last_used_(last_used), | 154 : last_used_(last_used), |
| 142 last_modified_(last_modified), | 155 last_modified_(last_modified), |
| 143 sparse_data_size_(sparse_data_size) { | 156 sparse_data_size_(sparse_data_size) { |
| 144 memcpy(data_size_, data_size, sizeof(data_size_)); | 157 memcpy(data_size_, data_size, sizeof(data_size_)); |
| 145 } | 158 } |
| 146 | 159 |
| 147 int SimpleEntryStat::GetOffsetInFile(const std::string& key, | 160 int SimpleEntryStat::GetOffsetInFile(size_t key_length, |
| 148 int offset, | 161 int offset, |
| 149 int stream_index) const { | 162 int stream_index) const { |
| 150 const size_t headers_size = sizeof(SimpleFileHeader) + key.size(); | 163 const size_t headers_size = sizeof(SimpleFileHeader) + key_length; |
| 151 const size_t additional_offset = | 164 const size_t additional_offset = |
| 152 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; | 165 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; |
| 153 return headers_size + offset + additional_offset; | 166 return headers_size + offset + additional_offset; |
| 154 } | 167 } |
| 155 | 168 |
| 156 int SimpleEntryStat::GetEOFOffsetInFile(const std::string& key, | 169 int SimpleEntryStat::GetEOFOffsetInFile(size_t key_length, |
| 157 int stream_index) const { | 170 int stream_index) const { |
| 158 return GetOffsetInFile(key, data_size_[stream_index], stream_index); | 171 size_t additional_offset; |
| 172 if (stream_index != 0) | |
| 173 additional_offset = 0; | |
| 174 else | |
| 175 additional_offset = sizeof(net::SHA256HashValue); | |
| 176 return additional_offset + | |
| 177 GetOffsetInFile(key_length, data_size_[stream_index], stream_index); | |
| 159 } | 178 } |
| 160 | 179 |
| 161 int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key, | 180 int SimpleEntryStat::GetLastEOFOffsetInFile(size_t key_length, |
| 162 int stream_index) const { | 181 int stream_index) const { |
| 163 const int file_index = GetFileIndexFromStreamIndex(stream_index); | 182 if (stream_index == 1) |
| 164 const int eof_data_offset = | 183 return GetEOFOffsetInFile(key_length, 0); |
| 165 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) | 184 return GetEOFOffsetInFile(key_length, stream_index); |
| 166 : data_size_[2]; | |
| 167 return GetOffsetInFile(key, eof_data_offset, stream_index); | |
| 168 } | 185 } |
| 169 | 186 |
| 170 int64_t SimpleEntryStat::GetFileSize(const std::string& key, | 187 int64_t SimpleEntryStat::GetFileSize(size_t key_length, int file_index) const { |
|
Randy Smith (Not in Mondays)
2016/05/19 19:38:49
Comment that this assumes the existence of the SHA
gavinp
2016/05/20 01:42:31
I added a longer comment above all of these explai
| |
| 171 int file_index) const { | 188 int32_t total_data_size; |
| 172 const int32_t total_data_size = | 189 if (file_index == 0) { |
| 173 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) | 190 total_data_size = data_size_[0] + data_size_[1] + |
| 174 : data_size_[2]; | 191 sizeof(net::SHA256HashValue) + sizeof(SimpleFileEOF); |
| 175 return GetFileSizeFromKeyAndDataSize(key, total_data_size); | 192 } else { |
| 193 total_data_size = data_size_[2]; | |
| 194 } | |
| 195 return GetFileSizeFromDataSize(key_length, total_data_size); | |
| 176 } | 196 } |
| 177 | 197 |
| 178 SimpleEntryCreationResults::SimpleEntryCreationResults( | 198 SimpleEntryCreationResults::SimpleEntryCreationResults( |
| 179 SimpleEntryStat entry_stat) | 199 SimpleEntryStat entry_stat) |
| 180 : sync_entry(NULL), | 200 : sync_entry(NULL), |
| 181 entry_stat(entry_stat), | 201 entry_stat(entry_stat), |
| 182 stream_0_crc32(crc32(0, Z_NULL, 0)), | 202 stream_0_crc32(crc32(0, Z_NULL, 0)), |
| 183 result(net::OK) { | 203 result(net::OK) { |
| 184 } | 204 } |
| 185 | 205 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 216 | 236 |
| 217 SimpleSynchronousEntry::EntryOperationData::EntryOperationData( | 237 SimpleSynchronousEntry::EntryOperationData::EntryOperationData( |
| 218 int64_t sparse_offset_p, | 238 int64_t sparse_offset_p, |
| 219 int buf_len_p) | 239 int buf_len_p) |
| 220 : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {} | 240 : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {} |
| 221 | 241 |
| 222 // static | 242 // static |
| 223 void SimpleSynchronousEntry::OpenEntry( | 243 void SimpleSynchronousEntry::OpenEntry( |
| 224 net::CacheType cache_type, | 244 net::CacheType cache_type, |
| 225 const FilePath& path, | 245 const FilePath& path, |
| 246 const std::string& key, | |
| 226 const uint64_t entry_hash, | 247 const uint64_t entry_hash, |
| 227 bool had_index, | 248 const bool had_index, |
| 228 SimpleEntryCreationResults* out_results) { | 249 SimpleEntryCreationResults* out_results) { |
| 229 base::ElapsedTimer open_time; | 250 base::ElapsedTimer open_time; |
| 230 SimpleSynchronousEntry* sync_entry = | 251 SimpleSynchronousEntry* sync_entry = |
| 231 new SimpleSynchronousEntry(cache_type, path, "", entry_hash); | 252 new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index); |
| 232 out_results->result = | 253 out_results->result = sync_entry->InitializeForOpen( |
| 233 sync_entry->InitializeForOpen(had_index, | 254 &out_results->entry_stat, &out_results->stream_0_data, |
| 234 &out_results->entry_stat, | 255 &out_results->stream_0_crc32); |
| 235 &out_results->stream_0_data, | |
| 236 &out_results->stream_0_crc32); | |
| 237 if (out_results->result != net::OK) { | 256 if (out_results->result != net::OK) { |
| 238 sync_entry->Doom(); | 257 sync_entry->Doom(); |
| 239 delete sync_entry; | 258 delete sync_entry; |
| 240 out_results->sync_entry = NULL; | 259 out_results->sync_entry = NULL; |
| 241 out_results->stream_0_data = NULL; | 260 out_results->stream_0_data = NULL; |
| 242 return; | 261 return; |
| 243 } | 262 } |
| 244 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed()); | 263 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed()); |
| 245 out_results->sync_entry = sync_entry; | 264 out_results->sync_entry = sync_entry; |
| 246 } | 265 } |
| 247 | 266 |
| 248 // static | 267 // static |
| 249 void SimpleSynchronousEntry::CreateEntry( | 268 void SimpleSynchronousEntry::CreateEntry( |
| 250 net::CacheType cache_type, | 269 net::CacheType cache_type, |
| 251 const FilePath& path, | 270 const FilePath& path, |
| 252 const std::string& key, | 271 const std::string& key, |
| 253 const uint64_t entry_hash, | 272 const uint64_t entry_hash, |
| 254 bool had_index, | 273 const bool had_index, |
| 255 SimpleEntryCreationResults* out_results) { | 274 SimpleEntryCreationResults* out_results) { |
| 256 DCHECK_EQ(entry_hash, GetEntryHashKey(key)); | 275 DCHECK_EQ(entry_hash, GetEntryHashKey(key)); |
| 257 SimpleSynchronousEntry* sync_entry = | 276 SimpleSynchronousEntry* sync_entry = |
| 258 new SimpleSynchronousEntry(cache_type, path, key, entry_hash); | 277 new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index); |
| 259 out_results->result = sync_entry->InitializeForCreate( | 278 out_results->result = |
| 260 had_index, &out_results->entry_stat); | 279 sync_entry->InitializeForCreate(&out_results->entry_stat); |
| 261 if (out_results->result != net::OK) { | 280 if (out_results->result != net::OK) { |
| 262 if (out_results->result != net::ERR_FILE_EXISTS) | 281 if (out_results->result != net::ERR_FILE_EXISTS) |
| 263 sync_entry->Doom(); | 282 sync_entry->Doom(); |
| 264 delete sync_entry; | 283 delete sync_entry; |
| 265 out_results->sync_entry = NULL; | 284 out_results->sync_entry = NULL; |
| 266 return; | 285 return; |
| 267 } | 286 } |
| 268 out_results->sync_entry = sync_entry; | 287 out_results->sync_entry = sync_entry; |
| 269 } | 288 } |
| 270 | 289 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 291 [&path](const uint64_t& key_hash) { | 310 [&path](const uint64_t& key_hash) { |
| 292 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash); | 311 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash); |
| 293 }); | 312 }); |
| 294 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; | 313 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; |
| 295 } | 314 } |
| 296 | 315 |
| 297 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, | 316 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, |
| 298 net::IOBuffer* out_buf, | 317 net::IOBuffer* out_buf, |
| 299 uint32_t* out_crc32, | 318 uint32_t* out_crc32, |
| 300 SimpleEntryStat* entry_stat, | 319 SimpleEntryStat* entry_stat, |
| 301 int* out_result) const { | 320 int* out_result) { |
| 302 DCHECK(initialized_); | 321 DCHECK(initialized_); |
| 303 DCHECK_NE(0, in_entry_op.index); | 322 DCHECK_NE(0, in_entry_op.index); |
| 304 const int64_t file_offset = | |
| 305 entry_stat->GetOffsetInFile(key_, in_entry_op.offset, in_entry_op.index); | |
| 306 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); | 323 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); |
| 324 if (header_and_key_check_needed_[file_index] && | |
| 325 !CheckHeaderAndKey(file_index)) { | |
| 326 *out_result = net::ERR_FAILED; | |
| 327 Doom(); | |
| 328 return; | |
| 329 } | |
| 330 const int64_t file_offset = entry_stat->GetOffsetInFile( | |
| 331 key_.size(), in_entry_op.offset, in_entry_op.index); | |
| 307 // Zero-length reads and reads to the empty streams of omitted files should | 332 // Zero-length reads and reads to the empty streams of omitted files should |
| 308 // be handled in the SimpleEntryImpl. | 333 // be handled in the SimpleEntryImpl. |
| 309 DCHECK_GT(in_entry_op.buf_len, 0); | 334 DCHECK_GT(in_entry_op.buf_len, 0); |
| 310 DCHECK(!empty_file_omitted_[file_index]); | 335 DCHECK(!empty_file_omitted_[file_index]); |
| 311 File* file = const_cast<File*>(&files_[file_index]); | 336 int bytes_read = files_[file_index].Read(file_offset, out_buf->data(), |
| 312 int bytes_read = | 337 in_entry_op.buf_len); |
| 313 file->Read(file_offset, out_buf->data(), in_entry_op.buf_len); | |
| 314 if (bytes_read > 0) { | 338 if (bytes_read > 0) { |
| 315 entry_stat->set_last_used(Time::Now()); | 339 entry_stat->set_last_used(Time::Now()); |
| 316 *out_crc32 = crc32(crc32(0L, Z_NULL, 0), | 340 *out_crc32 = crc32(crc32(0L, Z_NULL, 0), |
| 317 reinterpret_cast<const Bytef*>(out_buf->data()), | 341 reinterpret_cast<const Bytef*>(out_buf->data()), |
| 318 bytes_read); | 342 bytes_read); |
| 319 } | 343 } |
| 320 if (bytes_read >= 0) { | 344 if (bytes_read >= 0) { |
| 321 *out_result = bytes_read; | 345 *out_result = bytes_read; |
| 322 } else { | 346 } else { |
| 323 *out_result = net::ERR_CACHE_READ_FAILURE; | 347 *out_result = net::ERR_CACHE_READ_FAILURE; |
| 324 Doom(); | 348 Doom(); |
| 325 } | 349 } |
| 326 } | 350 } |
| 327 | 351 |
| 328 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op, | 352 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op, |
| 329 net::IOBuffer* in_buf, | 353 net::IOBuffer* in_buf, |
| 330 SimpleEntryStat* out_entry_stat, | 354 SimpleEntryStat* out_entry_stat, |
| 331 int* out_result) { | 355 int* out_result) { |
| 332 DCHECK(initialized_); | 356 DCHECK(initialized_); |
| 333 DCHECK_NE(0, in_entry_op.index); | 357 DCHECK_NE(0, in_entry_op.index); |
| 334 int index = in_entry_op.index; | 358 int index = in_entry_op.index; |
| 335 int file_index = GetFileIndexFromStreamIndex(index); | 359 int file_index = GetFileIndexFromStreamIndex(index); |
| 360 if (header_and_key_check_needed_[file_index] && | |
| 361 !empty_file_omitted_[file_index] && !CheckHeaderAndKey(file_index)) { | |
| 362 *out_result = net::ERR_FAILED; | |
| 363 Doom(); | |
| 364 return; | |
| 365 } | |
| 336 int offset = in_entry_op.offset; | 366 int offset = in_entry_op.offset; |
| 337 int buf_len = in_entry_op.buf_len; | 367 int buf_len = in_entry_op.buf_len; |
| 338 bool truncate = in_entry_op.truncate; | 368 bool truncate = in_entry_op.truncate; |
| 339 bool doomed = in_entry_op.doomed; | 369 bool doomed = in_entry_op.doomed; |
| 340 const int64_t file_offset = out_entry_stat->GetOffsetInFile( | 370 const int64_t file_offset = out_entry_stat->GetOffsetInFile( |
| 341 key_, in_entry_op.offset, in_entry_op.index); | 371 key_.size(), in_entry_op.offset, in_entry_op.index); |
| 342 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index); | 372 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index); |
| 343 | 373 |
| 344 if (empty_file_omitted_[file_index]) { | 374 if (empty_file_omitted_[file_index]) { |
| 345 // Don't create a new file if the entry has been doomed, to avoid it being | 375 // Don't create a new file if the entry has been doomed, to avoid it being |
| 346 // mixed up with a newly-created entry with the same key. | 376 // mixed up with a newly-created entry with the same key. |
| 347 if (doomed) { | 377 if (doomed) { |
| 348 DLOG(WARNING) << "Rejecting write to lazily omitted stream " | 378 DLOG(WARNING) << "Rejecting write to lazily omitted stream " |
| 349 << in_entry_op.index << " of doomed cache entry."; | 379 << in_entry_op.index << " of doomed cache entry."; |
| 350 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED); | 380 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED); |
| 351 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 381 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 364 Doom(); | 394 Doom(); |
| 365 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 395 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 366 return; | 396 return; |
| 367 } | 397 } |
| 368 } | 398 } |
| 369 DCHECK(!empty_file_omitted_[file_index]); | 399 DCHECK(!empty_file_omitted_[file_index]); |
| 370 | 400 |
| 371 if (extending_by_write) { | 401 if (extending_by_write) { |
| 372 // The EOF record and the eventual stream afterward need to be zeroed out. | 402 // The EOF record and the eventual stream afterward need to be zeroed out. |
| 373 const int64_t file_eof_offset = | 403 const int64_t file_eof_offset = |
| 374 out_entry_stat->GetEOFOffsetInFile(key_, index); | 404 out_entry_stat->GetEOFOffsetInFile(key_.size(), index); |
| 375 if (!files_[file_index].SetLength(file_eof_offset)) { | 405 if (!files_[file_index].SetLength(file_eof_offset)) { |
| 376 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); | 406 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); |
| 377 Doom(); | 407 Doom(); |
| 378 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 408 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 379 return; | 409 return; |
| 380 } | 410 } |
| 381 } | 411 } |
| 382 if (buf_len > 0) { | 412 if (buf_len > 0) { |
| 383 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != | 413 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != |
| 384 buf_len) { | 414 buf_len) { |
| 385 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE); | 415 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE); |
| 386 Doom(); | 416 Doom(); |
| 387 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 417 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 388 return; | 418 return; |
| 389 } | 419 } |
| 390 } | 420 } |
| 391 if (!truncate && (buf_len > 0 || !extending_by_write)) { | 421 if (!truncate && (buf_len > 0 || !extending_by_write)) { |
| 392 out_entry_stat->set_data_size( | 422 out_entry_stat->set_data_size( |
| 393 index, std::max(out_entry_stat->data_size(index), offset + buf_len)); | 423 index, std::max(out_entry_stat->data_size(index), offset + buf_len)); |
| 394 } else { | 424 } else { |
| 395 out_entry_stat->set_data_size(index, offset + buf_len); | 425 out_entry_stat->set_data_size(index, offset + buf_len); |
| 396 int file_eof_offset = out_entry_stat->GetLastEOFOffsetInFile(key_, index); | 426 int file_eof_offset = |
| 427 out_entry_stat->GetLastEOFOffsetInFile(key_.size(), index); | |
| 397 if (!files_[file_index].SetLength(file_eof_offset)) { | 428 if (!files_[file_index].SetLength(file_eof_offset)) { |
| 398 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE); | 429 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE); |
| 399 Doom(); | 430 Doom(); |
| 400 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 431 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 401 return; | 432 return; |
| 402 } | 433 } |
| 403 } | 434 } |
| 404 | 435 |
| 405 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | 436 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); |
| 406 base::Time modification_time = Time::Now(); | 437 base::Time modification_time = Time::Now(); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 *out_result = static_cast<int>(std::min(avail_so_far, len_from_start)); | 645 *out_result = static_cast<int>(std::min(avail_so_far, len_from_start)); |
| 615 } | 646 } |
| 616 | 647 |
| 617 void SimpleSynchronousEntry::CheckEOFRecord(int index, | 648 void SimpleSynchronousEntry::CheckEOFRecord(int index, |
| 618 const SimpleEntryStat& entry_stat, | 649 const SimpleEntryStat& entry_stat, |
| 619 uint32_t expected_crc32, | 650 uint32_t expected_crc32, |
| 620 int* out_result) const { | 651 int* out_result) const { |
| 621 DCHECK(initialized_); | 652 DCHECK(initialized_); |
| 622 uint32_t crc32; | 653 uint32_t crc32; |
| 623 bool has_crc32; | 654 bool has_crc32; |
| 655 bool has_key_sha256; | |
| 624 int stream_size; | 656 int stream_size; |
| 625 *out_result = | 657 *out_result = GetEOFRecordData(index, entry_stat, &has_crc32, &has_key_sha256, |
| 626 GetEOFRecordData(index, entry_stat, &has_crc32, &crc32, &stream_size); | 658 &crc32, &stream_size); |
| 627 if (*out_result != net::OK) { | 659 if (*out_result != net::OK) { |
| 628 Doom(); | 660 Doom(); |
| 629 return; | 661 return; |
| 630 } | 662 } |
| 631 if (has_crc32 && crc32 != expected_crc32) { | 663 if (has_crc32 && crc32 != expected_crc32) { |
| 632 DVLOG(1) << "EOF record had bad crc."; | 664 DVLOG(1) << "EOF record had bad crc."; |
| 633 *out_result = net::ERR_CACHE_CHECKSUM_MISMATCH; | 665 *out_result = net::ERR_CACHE_CHECKSUM_MISMATCH; |
| 634 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); | 666 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); |
| 635 Doom(); | 667 Doom(); |
| 636 return; | 668 return; |
| 637 } | 669 } |
| 638 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); | 670 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); |
| 639 } | 671 } |
| 640 | 672 |
| 641 void SimpleSynchronousEntry::Close( | 673 void SimpleSynchronousEntry::Close( |
| 642 const SimpleEntryStat& entry_stat, | 674 const SimpleEntryStat& entry_stat, |
| 643 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, | 675 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, |
| 644 net::GrowableIOBuffer* stream_0_data) { | 676 net::GrowableIOBuffer* stream_0_data) { |
| 645 DCHECK(stream_0_data); | 677 DCHECK(stream_0_data); |
| 646 // Write stream 0 data. | 678 // Write stream 0 data. |
| 647 int stream_0_offset = entry_stat.GetOffsetInFile(key_, 0, 0); | 679 int stream_0_offset = entry_stat.GetOffsetInFile(key_.size(), 0, 0); |
| 648 if (files_[0].Write(stream_0_offset, stream_0_data->data(), | 680 if (files_[0].Write(stream_0_offset, stream_0_data->data(), |
| 649 entry_stat.data_size(0)) != | 681 entry_stat.data_size(0)) != |
| 650 entry_stat.data_size(0)) { | 682 entry_stat.data_size(0)) { |
| 651 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); | 683 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); |
| 652 DVLOG(1) << "Could not write stream 0 data."; | 684 DVLOG(1) << "Could not write stream 0 data."; |
| 653 Doom(); | 685 Doom(); |
| 654 } | 686 } |
| 687 net::SHA256HashValue hash_value; | |
| 688 CalculateSHA256OfKey(key_, &hash_value); | |
| 689 if (files_[0].Write(stream_0_offset + entry_stat.data_size(0), | |
| 690 reinterpret_cast<char*>(hash_value.data), | |
| 691 sizeof(hash_value)) != sizeof(hash_value)) { | |
| 692 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); | |
| 693 DVLOG(1) << "Could not write stream 0 data."; | |
| 694 Doom(); | |
| 695 } | |
| 655 | 696 |
| 656 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin(); | 697 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin(); |
| 657 it != crc32s_to_write->end(); ++it) { | 698 it != crc32s_to_write->end(); ++it) { |
| 658 const int stream_index = it->index; | 699 const int stream_index = it->index; |
| 659 const int file_index = GetFileIndexFromStreamIndex(stream_index); | 700 const int file_index = GetFileIndexFromStreamIndex(stream_index); |
| 660 if (empty_file_omitted_[file_index]) | 701 if (empty_file_omitted_[file_index]) |
| 661 continue; | 702 continue; |
| 662 | 703 |
| 663 SimpleFileEOF eof_record; | 704 SimpleFileEOF eof_record; |
| 664 eof_record.stream_size = entry_stat.data_size(stream_index); | 705 eof_record.stream_size = entry_stat.data_size(stream_index); |
| 665 eof_record.final_magic_number = kSimpleFinalMagicNumber; | 706 eof_record.final_magic_number = kSimpleFinalMagicNumber; |
| 666 eof_record.flags = 0; | 707 eof_record.flags = 0; |
| 667 if (it->has_crc32) | 708 if (it->has_crc32) |
| 668 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32; | 709 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32; |
| 710 if (stream_index == 0) | |
| 711 eof_record.flags |= SimpleFileEOF::FLAG_HAS_KEY_SHA256; | |
| 669 eof_record.data_crc32 = it->data_crc32; | 712 eof_record.data_crc32 = it->data_crc32; |
| 670 int eof_offset = entry_stat.GetEOFOffsetInFile(key_, stream_index); | 713 int eof_offset = entry_stat.GetEOFOffsetInFile(key_.size(), stream_index); |
| 671 // If stream 0 changed size, the file needs to be resized, otherwise the | 714 // If stream 0 changed size, the file needs to be resized, otherwise the |
| 672 // next open will yield wrong stream sizes. On stream 1 and stream 2 proper | 715 // next open will yield wrong stream sizes. On stream 1 and stream 2 proper |
| 673 // resizing of the file is handled in SimpleSynchronousEntry::WriteData(). | 716 // resizing of the file is handled in SimpleSynchronousEntry::WriteData(). |
| 674 if (stream_index == 0 && | 717 if (stream_index == 0 && |
| 675 !files_[file_index].SetLength(eof_offset)) { | 718 !files_[file_index].SetLength(eof_offset)) { |
| 676 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); | 719 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); |
| 677 DVLOG(1) << "Could not truncate stream 0 file."; | 720 DVLOG(1) << "Could not truncate stream 0 file."; |
| 678 Doom(); | 721 Doom(); |
| 679 break; | 722 break; |
| 680 } | 723 } |
| 681 if (files_[file_index].Write(eof_offset, | 724 if (files_[file_index].Write(eof_offset, |
| 682 reinterpret_cast<const char*>(&eof_record), | 725 reinterpret_cast<const char*>(&eof_record), |
| 683 sizeof(eof_record)) != | 726 sizeof(eof_record)) != |
| 684 sizeof(eof_record)) { | 727 sizeof(eof_record)) { |
| 685 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); | 728 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); |
| 686 DVLOG(1) << "Could not write eof record."; | 729 DVLOG(1) << "Could not write eof record."; |
| 687 Doom(); | 730 Doom(); |
| 688 break; | 731 break; |
| 689 } | 732 } |
| 690 } | 733 } |
| 691 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 734 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 692 if (empty_file_omitted_[i]) | 735 if (empty_file_omitted_[i]) |
| 693 continue; | 736 continue; |
| 694 | 737 |
| 738 if (header_and_key_check_needed_[i] && !CheckHeaderAndKey(i)) { | |
| 739 Doom(); | |
| 740 } | |
| 695 files_[i].Close(); | 741 files_[i].Close(); |
| 696 const int64_t file_size = entry_stat.GetFileSize(key_, i); | 742 const int64_t file_size = entry_stat.GetFileSize(key_.size(), i); |
| 697 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, | 743 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, |
| 698 "LastClusterSize", cache_type_, | 744 "LastClusterSize", cache_type_, |
| 699 file_size % 4096, 0, 4097, 50); | 745 file_size % 4096, 0, 4097, 50); |
| 700 const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; | 746 const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; |
| 701 SIMPLE_CACHE_UMA(PERCENTAGE, | 747 SIMPLE_CACHE_UMA(PERCENTAGE, |
| 702 "LastClusterLossPercent", cache_type_, | 748 "LastClusterLossPercent", cache_type_, |
| 703 static_cast<base::HistogramBase::Sample>( | 749 static_cast<base::HistogramBase::Sample>( |
| 704 cluster_loss * 100 / (cluster_loss + file_size))); | 750 cluster_loss * 100 / (cluster_loss + file_size))); |
| 705 } | 751 } |
| 706 | 752 |
| 707 if (sparse_file_open()) | 753 if (sparse_file_open()) |
| 708 sparse_file_.Close(); | 754 sparse_file_.Close(); |
| 709 | 755 |
| 710 if (files_created_) { | 756 if (files_created_) { |
| 711 const int stream2_file_index = GetFileIndexFromStreamIndex(2); | 757 const int stream2_file_index = GetFileIndexFromStreamIndex(2); |
| 712 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, | 758 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, |
| 713 empty_file_omitted_[stream2_file_index]); | 759 empty_file_omitted_[stream2_file_index]); |
| 714 } | 760 } |
| 715 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); | 761 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); |
| 716 have_open_files_ = false; | 762 have_open_files_ = false; |
| 717 delete this; | 763 delete this; |
| 718 } | 764 } |
| 719 | 765 |
| 720 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, | 766 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, |
| 721 const FilePath& path, | 767 const FilePath& path, |
| 722 const std::string& key, | 768 const std::string& key, |
| 723 const uint64_t entry_hash) | 769 const uint64_t entry_hash, |
| 770 const bool had_index) | |
| 724 : cache_type_(cache_type), | 771 : cache_type_(cache_type), |
| 725 path_(path), | 772 path_(path), |
| 726 entry_hash_(entry_hash), | 773 entry_hash_(entry_hash), |
| 774 had_index_(had_index), | |
| 727 key_(key), | 775 key_(key), |
| 728 have_open_files_(false), | 776 have_open_files_(false), |
| 729 initialized_(false) { | 777 initialized_(false) { |
| 730 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 778 for (int i = 0; i < kSimpleEntryFileCount; ++i) |
| 731 empty_file_omitted_[i] = false; | 779 empty_file_omitted_[i] = false; |
| 732 } | 780 } |
| 733 | 781 |
| 734 SimpleSynchronousEntry::~SimpleSynchronousEntry() { | 782 SimpleSynchronousEntry::~SimpleSynchronousEntry() { |
| 735 DCHECK(!(have_open_files_ && initialized_)); | 783 DCHECK(!(have_open_files_ && initialized_)); |
| 736 if (have_open_files_) | 784 if (have_open_files_) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 772 int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE | | 820 int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE | |
| 773 File::FLAG_SHARE_DELETE; | 821 File::FLAG_SHARE_DELETE; |
| 774 files_[file_index].Initialize(filename, flags); | 822 files_[file_index].Initialize(filename, flags); |
| 775 *out_error = files_[file_index].error_details(); | 823 *out_error = files_[file_index].error_details(); |
| 776 | 824 |
| 777 empty_file_omitted_[file_index] = false; | 825 empty_file_omitted_[file_index] = false; |
| 778 | 826 |
| 779 return files_[file_index].IsValid(); | 827 return files_[file_index].IsValid(); |
| 780 } | 828 } |
| 781 | 829 |
| 782 bool SimpleSynchronousEntry::OpenFiles( | 830 bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) { |
| 783 bool had_index, | |
| 784 SimpleEntryStat* out_entry_stat) { | |
| 785 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 831 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 786 File::Error error; | 832 File::Error error; |
| 787 if (!MaybeOpenFile(i, &error)) { | 833 if (!MaybeOpenFile(i, &error)) { |
| 788 // TODO(juliatuttle,gavinp): Remove one each of these triplets of | 834 // TODO(juliatuttle,gavinp): Remove one each of these triplets of |
| 789 // histograms. We can calculate the third as the sum or difference of the | 835 // histograms. We can calculate the third as the sum or difference of the |
| 790 // other two. | 836 // other two. |
| 791 RecordSyncOpenResult( | 837 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_PLATFORM_FILE_ERROR, |
| 792 cache_type_, OPEN_ENTRY_PLATFORM_FILE_ERROR, had_index); | 838 had_index_); |
| 793 SIMPLE_CACHE_UMA(ENUMERATION, | 839 SIMPLE_CACHE_UMA(ENUMERATION, |
| 794 "SyncOpenPlatformFileError", cache_type_, | 840 "SyncOpenPlatformFileError", cache_type_, |
| 795 -error, -base::File::FILE_ERROR_MAX); | 841 -error, -base::File::FILE_ERROR_MAX); |
| 796 if (had_index) { | 842 if (had_index_) { |
| 797 SIMPLE_CACHE_UMA(ENUMERATION, | 843 SIMPLE_CACHE_UMA(ENUMERATION, |
| 798 "SyncOpenPlatformFileError_WithIndex", cache_type_, | 844 "SyncOpenPlatformFileError_WithIndex", cache_type_, |
| 799 -error, -base::File::FILE_ERROR_MAX); | 845 -error, -base::File::FILE_ERROR_MAX); |
| 800 } else { | 846 } else { |
| 801 SIMPLE_CACHE_UMA(ENUMERATION, | 847 SIMPLE_CACHE_UMA(ENUMERATION, |
| 802 "SyncOpenPlatformFileError_WithoutIndex", | 848 "SyncOpenPlatformFileError_WithoutIndex", |
| 803 cache_type_, | 849 cache_type_, |
| 804 -error, -base::File::FILE_ERROR_MAX); | 850 -error, -base::File::FILE_ERROR_MAX); |
| 805 } | 851 } |
| 806 while (--i >= 0) | 852 while (--i >= 0) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 } | 899 } |
| 854 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, | 900 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, |
| 855 "SyncOpenEntryAge", cache_type_, | 901 "SyncOpenEntryAge", cache_type_, |
| 856 entry_age.InHours(), 1, 1000, 50); | 902 entry_age.InHours(), 1, 1000, 50); |
| 857 | 903 |
| 858 files_created_ = false; | 904 files_created_ = false; |
| 859 | 905 |
| 860 return true; | 906 return true; |
| 861 } | 907 } |
| 862 | 908 |
| 863 bool SimpleSynchronousEntry::CreateFiles( | 909 bool SimpleSynchronousEntry::CreateFiles(SimpleEntryStat* out_entry_stat) { |
| 864 bool had_index, | |
| 865 SimpleEntryStat* out_entry_stat) { | |
| 866 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 910 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 867 File::Error error; | 911 File::Error error; |
| 868 if (!MaybeCreateFile(i, FILE_NOT_REQUIRED, &error)) { | 912 if (!MaybeCreateFile(i, FILE_NOT_REQUIRED, &error)) { |
| 869 // TODO(juliatuttle,gavinp): Remove one each of these triplets of | 913 // TODO(juliatuttle,gavinp): Remove one each of these triplets of |
| 870 // histograms. We can calculate the third as the sum or difference of the | 914 // histograms. We can calculate the third as the sum or difference of the |
| 871 // other two. | 915 // other two. |
| 872 RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR, had_index); | 916 RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR, had_index_); |
| 873 SIMPLE_CACHE_UMA(ENUMERATION, | 917 SIMPLE_CACHE_UMA(ENUMERATION, |
| 874 "SyncCreatePlatformFileError", cache_type_, | 918 "SyncCreatePlatformFileError", cache_type_, |
| 875 -error, -base::File::FILE_ERROR_MAX); | 919 -error, -base::File::FILE_ERROR_MAX); |
| 876 if (had_index) { | 920 if (had_index_) { |
| 877 SIMPLE_CACHE_UMA(ENUMERATION, | 921 SIMPLE_CACHE_UMA(ENUMERATION, |
| 878 "SyncCreatePlatformFileError_WithIndex", cache_type_, | 922 "SyncCreatePlatformFileError_WithIndex", cache_type_, |
| 879 -error, -base::File::FILE_ERROR_MAX); | 923 -error, -base::File::FILE_ERROR_MAX); |
| 880 } else { | 924 } else { |
| 881 SIMPLE_CACHE_UMA(ENUMERATION, | 925 SIMPLE_CACHE_UMA(ENUMERATION, |
| 882 "SyncCreatePlatformFileError_WithoutIndex", | 926 "SyncCreatePlatformFileError_WithoutIndex", |
| 883 cache_type_, | 927 cache_type_, |
| 884 -error, -base::File::FILE_ERROR_MAX); | 928 -error, -base::File::FILE_ERROR_MAX); |
| 885 } | 929 } |
| 886 while (--i >= 0) | 930 while (--i >= 0) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 912 | 956 |
| 913 if (sparse_file_open()) | 957 if (sparse_file_open()) |
| 914 CloseSparseFile(); | 958 CloseSparseFile(); |
| 915 } | 959 } |
| 916 | 960 |
| 917 void SimpleSynchronousEntry::CloseFiles() { | 961 void SimpleSynchronousEntry::CloseFiles() { |
| 918 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 962 for (int i = 0; i < kSimpleEntryFileCount; ++i) |
| 919 CloseFile(i); | 963 CloseFile(i); |
| 920 } | 964 } |
| 921 | 965 |
| 966 bool SimpleSynchronousEntry::CheckHeaderAndKey(int file_index) { | |
| 967 // TODO(gavinp): Frequently we are doing this at the same time as we read from | |
| 968 // the beginning of an entry. It might improve performance to make a single | |
| 969 // read(2) call rather than two separate reads. On the other hand, it would | |
| 970 // mean an extra memory to memory copy. In the case where we are opening an | |
| 971 // entry without a key, the kInitialHeaderRead setting means that we are | |
| 972 // actually already reading stream 1 data here, and tossing it out. | |
| 973 std::vector<char> header_data(key_.empty() ? kInitialHeaderRead | |
| 974 : GetHeaderSize(key_.size())); | |
| 975 int bytes_read = | |
| 976 files_[file_index].Read(0, header_data.data(), header_data.size()); | |
| 977 const SimpleFileHeader* header = | |
| 978 reinterpret_cast<const SimpleFileHeader*>(header_data.data()); | |
| 979 | |
| 980 if (bytes_read == -1 || static_cast<size_t>(bytes_read) < sizeof(*header)) { | |
| 981 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index_); | |
| 982 return false; | |
| 983 } | |
| 984 // This resize will not invalidate iterators since it does not enlarge the | |
| 985 // header_data. | |
| 986 DCHECK_LE(static_cast<size_t>(bytes_read), header_data.size()); | |
| 987 header_data.resize(bytes_read); | |
| 988 | |
| 989 if (header->initial_magic_number != kSimpleInitialMagicNumber) { | |
| 990 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_MAGIC_NUMBER, had_index_); | |
| 991 return false; | |
| 992 } | |
| 993 | |
| 994 if (header->version != kSimpleEntryVersionOnDisk) { | |
| 995 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_VERSION, had_index_); | |
| 996 return false; | |
| 997 } | |
| 998 | |
| 999 size_t expected_header_size = GetHeaderSize(header->key_length); | |
| 1000 if (header_data.size() < expected_header_size) { | |
| 1001 size_t old_size = header_data.size(); | |
| 1002 int bytes_to_read = expected_header_size - old_size; | |
| 1003 // This resize will invalidate iterators, since it is enlarging header_data. | |
| 1004 header_data.resize(expected_header_size); | |
| 1005 int bytes_read = files_[file_index].Read( | |
| 1006 old_size, header_data.data() + old_size, bytes_to_read); | |
| 1007 if (bytes_read != bytes_to_read) { | |
| 1008 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index_); | |
| 1009 return false; | |
| 1010 } | |
| 1011 header = reinterpret_cast<const SimpleFileHeader*>(header_data.data()); | |
| 1012 } | |
| 1013 | |
| 1014 char* key_data = header_data.data() + sizeof(*header); | |
| 1015 if (base::Hash(key_data, header->key_length) != header->key_hash) { | |
| 1016 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index_); | |
| 1017 return false; | |
| 1018 } | |
| 1019 | |
| 1020 std::string key_from_header(key_data, header->key_length); | |
| 1021 if (key_.empty()) { | |
| 1022 key_.swap(key_from_header); | |
| 1023 } else { | |
| 1024 if (key_ != key_from_header) { | |
| 1025 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_KEY_MISMATCH, had_index_); | |
| 1026 return false; | |
| 1027 } | |
| 1028 } | |
| 1029 | |
| 1030 header_and_key_check_needed_[file_index] = false; | |
| 1031 return true; | |
| 1032 } | |
| 1033 | |
| 922 int SimpleSynchronousEntry::InitializeForOpen( | 1034 int SimpleSynchronousEntry::InitializeForOpen( |
| 923 bool had_index, | |
| 924 SimpleEntryStat* out_entry_stat, | 1035 SimpleEntryStat* out_entry_stat, |
| 925 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 1036 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
| 926 uint32_t* out_stream_0_crc32) { | 1037 uint32_t* out_stream_0_crc32) { |
| 927 DCHECK(!initialized_); | 1038 DCHECK(!initialized_); |
| 928 if (!OpenFiles(had_index, out_entry_stat)) { | 1039 if (!OpenFiles(out_entry_stat)) { |
| 929 DLOG(WARNING) << "Could not open platform files for entry."; | 1040 DLOG(WARNING) << "Could not open platform files for entry."; |
| 930 return net::ERR_FAILED; | 1041 return net::ERR_FAILED; |
| 931 } | 1042 } |
| 932 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1043 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 933 if (empty_file_omitted_[i]) | 1044 if (empty_file_omitted_[i]) |
| 934 continue; | 1045 continue; |
| 935 | 1046 |
| 936 SimpleFileHeader header; | 1047 if (!key_.empty()) { |
| 937 int header_read_result = | 1048 header_and_key_check_needed_[i] = true; |
| 938 files_[i].Read(0, reinterpret_cast<char*>(&header), sizeof(header)); | 1049 } else { |
| 939 if (header_read_result != sizeof(header)) { | 1050 if (!CheckHeaderAndKey(i)) |
| 940 DLOG(WARNING) << "Cannot read header from entry."; | 1051 return net::ERR_FAILED; |
| 941 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index); | |
| 942 return net::ERR_FAILED; | |
| 943 } | 1052 } |
| 944 | 1053 |
| 945 if (header.initial_magic_number != kSimpleInitialMagicNumber) { | |
| 946 // TODO(gavinp): This seems very bad; for now we log at WARNING, but we | |
| 947 // should give consideration to not saturating the log with these if that | |
| 948 // becomes a problem. | |
| 949 DLOG(WARNING) << "Magic number did not match."; | |
| 950 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_MAGIC_NUMBER, had_index); | |
| 951 return net::ERR_FAILED; | |
| 952 } | |
| 953 | |
| 954 if (header.version != kSimpleEntryVersionOnDisk) { | |
| 955 DLOG(WARNING) << "Unreadable version."; | |
| 956 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_VERSION, had_index); | |
| 957 return net::ERR_FAILED; | |
| 958 } | |
| 959 | |
| 960 std::unique_ptr<char[]> key(new char[header.key_length]); | |
| 961 int key_read_result = files_[i].Read(sizeof(header), key.get(), | |
| 962 header.key_length); | |
| 963 if (key_read_result != base::checked_cast<int>(header.key_length)) { | |
| 964 DLOG(WARNING) << "Cannot read key from entry."; | |
| 965 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index); | |
| 966 return net::ERR_FAILED; | |
| 967 } | |
| 968 | |
| 969 key_ = std::string(key.get(), header.key_length); | |
| 970 if (i == 0) { | 1054 if (i == 0) { |
| 971 // File size for stream 0 has been stored temporarily in data_size[1]. | 1055 // File size for stream 0 has been stored temporarily in data_size[1]. |
| 972 int total_data_size = | 1056 int ret_value_stream_0 = |
| 973 GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size(1)); | 1057 ReadAndValidateStream0(out_entry_stat->data_size(1), out_entry_stat, |
| 974 int ret_value_stream_0 = ReadAndValidateStream0( | 1058 stream_0_data, out_stream_0_crc32); |
| 975 total_data_size, out_entry_stat, stream_0_data, out_stream_0_crc32); | |
| 976 if (ret_value_stream_0 != net::OK) | 1059 if (ret_value_stream_0 != net::OK) |
| 977 return ret_value_stream_0; | 1060 return ret_value_stream_0; |
| 978 } else { | 1061 } else { |
| 979 out_entry_stat->set_data_size( | 1062 out_entry_stat->set_data_size( |
| 980 2, GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size(2))); | 1063 2, |
| 1064 GetDataSizeFromFileSize(key_.size(), out_entry_stat->data_size(2))); | |
| 981 if (out_entry_stat->data_size(2) < 0) { | 1065 if (out_entry_stat->data_size(2) < 0) { |
| 982 DLOG(WARNING) << "Stream 2 file is too small."; | 1066 DLOG(WARNING) << "Stream 2 file is too small."; |
| 983 return net::ERR_FAILED; | 1067 return net::ERR_FAILED; |
| 984 } | 1068 } |
| 985 } | 1069 } |
| 986 | |
| 987 if (base::Hash(key.get(), header.key_length) != header.key_hash) { | |
| 988 DLOG(WARNING) << "Hash mismatch on key."; | |
| 989 RecordSyncOpenResult( | |
| 990 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index); | |
| 991 return net::ERR_FAILED; | |
| 992 } | |
| 993 } | 1070 } |
| 994 | 1071 |
| 995 int32_t sparse_data_size = 0; | 1072 int32_t sparse_data_size = 0; |
| 996 if (!OpenSparseFileIfExists(&sparse_data_size)) { | 1073 if (!OpenSparseFileIfExists(&sparse_data_size)) { |
| 997 RecordSyncOpenResult( | 1074 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, |
| 998 cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, had_index); | 1075 had_index_); |
| 999 return net::ERR_FAILED; | 1076 return net::ERR_FAILED; |
| 1000 } | 1077 } |
| 1001 out_entry_stat->set_sparse_data_size(sparse_data_size); | 1078 out_entry_stat->set_sparse_data_size(sparse_data_size); |
| 1002 | 1079 |
| 1003 bool removed_stream2 = false; | 1080 bool removed_stream2 = false; |
| 1004 const int stream2_file_index = GetFileIndexFromStreamIndex(2); | 1081 const int stream2_file_index = GetFileIndexFromStreamIndex(2); |
| 1005 DCHECK(CanOmitEmptyFile(stream2_file_index)); | 1082 DCHECK(CanOmitEmptyFile(stream2_file_index)); |
| 1006 if (!empty_file_omitted_[stream2_file_index] && | 1083 if (!empty_file_omitted_[stream2_file_index] && |
| 1007 out_entry_stat->data_size(2) == 0) { | 1084 out_entry_stat->data_size(2) == 0) { |
| 1008 DVLOG(1) << "Removing empty stream 2 file."; | 1085 DVLOG(1) << "Removing empty stream 2 file."; |
| 1009 CloseFile(stream2_file_index); | 1086 CloseFile(stream2_file_index); |
| 1010 DeleteFileForEntryHash(path_, entry_hash_, stream2_file_index); | 1087 DeleteFileForEntryHash(path_, entry_hash_, stream2_file_index); |
| 1011 empty_file_omitted_[stream2_file_index] = true; | 1088 empty_file_omitted_[stream2_file_index] = true; |
| 1012 removed_stream2 = true; | 1089 removed_stream2 = true; |
| 1013 } | 1090 } |
| 1014 | 1091 |
| 1015 SIMPLE_CACHE_UMA(BOOLEAN, "EntryOpenedAndStream2Removed", cache_type_, | 1092 SIMPLE_CACHE_UMA(BOOLEAN, "EntryOpenedAndStream2Removed", cache_type_, |
| 1016 removed_stream2); | 1093 removed_stream2); |
| 1017 | 1094 |
| 1018 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index); | 1095 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index_); |
| 1019 initialized_ = true; | 1096 initialized_ = true; |
| 1020 return net::OK; | 1097 return net::OK; |
| 1021 } | 1098 } |
| 1022 | 1099 |
| 1023 bool SimpleSynchronousEntry::InitializeCreatedFile( | 1100 bool SimpleSynchronousEntry::InitializeCreatedFile( |
| 1024 int file_index, | 1101 int file_index, |
| 1025 CreateEntryResult* out_result) { | 1102 CreateEntryResult* out_result) { |
| 1026 SimpleFileHeader header; | 1103 SimpleFileHeader header; |
| 1027 header.initial_magic_number = kSimpleInitialMagicNumber; | 1104 header.initial_magic_number = kSimpleInitialMagicNumber; |
| 1028 header.version = kSimpleEntryVersionOnDisk; | 1105 header.version = kSimpleEntryVersionOnDisk; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1041 key_.size()); | 1118 key_.size()); |
| 1042 if (bytes_written != base::checked_cast<int>(key_.size())) { | 1119 if (bytes_written != base::checked_cast<int>(key_.size())) { |
| 1043 *out_result = CREATE_ENTRY_CANT_WRITE_KEY; | 1120 *out_result = CREATE_ENTRY_CANT_WRITE_KEY; |
| 1044 return false; | 1121 return false; |
| 1045 } | 1122 } |
| 1046 | 1123 |
| 1047 return true; | 1124 return true; |
| 1048 } | 1125 } |
| 1049 | 1126 |
| 1050 int SimpleSynchronousEntry::InitializeForCreate( | 1127 int SimpleSynchronousEntry::InitializeForCreate( |
| 1051 bool had_index, | |
| 1052 SimpleEntryStat* out_entry_stat) { | 1128 SimpleEntryStat* out_entry_stat) { |
| 1053 DCHECK(!initialized_); | 1129 DCHECK(!initialized_); |
| 1054 if (!CreateFiles(had_index, out_entry_stat)) { | 1130 if (!CreateFiles(out_entry_stat)) { |
| 1055 DLOG(WARNING) << "Could not create platform files."; | 1131 DLOG(WARNING) << "Could not create platform files."; |
| 1056 return net::ERR_FILE_EXISTS; | 1132 return net::ERR_FILE_EXISTS; |
| 1057 } | 1133 } |
| 1058 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1134 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 1059 if (empty_file_omitted_[i]) | 1135 if (empty_file_omitted_[i]) |
| 1060 continue; | 1136 continue; |
| 1061 | 1137 |
| 1062 CreateEntryResult result; | 1138 CreateEntryResult result; |
| 1063 if (!InitializeCreatedFile(i, &result)) { | 1139 if (!InitializeCreatedFile(i, &result)) { |
| 1064 RecordSyncCreateResult(result, had_index); | 1140 RecordSyncCreateResult(result, had_index_); |
| 1065 return net::ERR_FAILED; | 1141 return net::ERR_FAILED; |
| 1066 } | 1142 } |
| 1067 } | 1143 } |
| 1068 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index); | 1144 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index_); |
| 1069 initialized_ = true; | 1145 initialized_ = true; |
| 1070 return net::OK; | 1146 return net::OK; |
| 1071 } | 1147 } |
| 1072 | 1148 |
| 1073 int SimpleSynchronousEntry::ReadAndValidateStream0( | 1149 int SimpleSynchronousEntry::ReadAndValidateStream0( |
| 1074 int total_data_size, | 1150 int file_size, |
| 1075 SimpleEntryStat* out_entry_stat, | 1151 SimpleEntryStat* out_entry_stat, |
| 1076 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 1152 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
| 1077 uint32_t* out_stream_0_crc32) const { | 1153 uint32_t* out_stream_0_crc32) { |
| 1078 // Temporarily assign all the data size to stream 1 in order to read the | 1154 // Temporarily assign all the data size to stream 1 in order to read the |
| 1079 // EOF record for stream 0, which contains the size of stream 0. | 1155 // EOF record for stream 0, which contains the size of stream 0. |
| 1156 int total_data_size = GetDataSizeFromFileSize(key_.size(), file_size); | |
| 1080 out_entry_stat->set_data_size(0, 0); | 1157 out_entry_stat->set_data_size(0, 0); |
| 1081 out_entry_stat->set_data_size(1, total_data_size - sizeof(SimpleFileEOF)); | 1158 out_entry_stat->set_data_size( |
| 1159 1, | |
| 1160 total_data_size - sizeof(net::SHA256HashValue) - sizeof(SimpleFileEOF)); | |
| 1082 | 1161 |
| 1083 bool has_crc32; | 1162 bool has_crc32; |
| 1163 bool has_key_sha256; | |
| 1084 uint32_t read_crc32; | 1164 uint32_t read_crc32; |
| 1085 int stream_0_size; | 1165 int stream_0_size; |
| 1086 int ret_value_crc32 = GetEOFRecordData( | 1166 int ret_value_crc32 = |
| 1087 0, *out_entry_stat, &has_crc32, &read_crc32, &stream_0_size); | 1167 GetEOFRecordData(0, *out_entry_stat, &has_crc32, &has_key_sha256, |
| 1168 &read_crc32, &stream_0_size); | |
| 1088 if (ret_value_crc32 != net::OK) | 1169 if (ret_value_crc32 != net::OK) |
| 1089 return ret_value_crc32; | 1170 return ret_value_crc32; |
| 1090 | 1171 |
| 1091 if (stream_0_size > out_entry_stat->data_size(1)) | 1172 // Calculate and set the real values for data size. |
| 1173 int stream_1_size = out_entry_stat->data_size(1) - stream_0_size; | |
| 1174 if (!has_key_sha256) | |
| 1175 stream_1_size += sizeof(net::SHA256HashValue); | |
| 1176 if (stream_1_size < 0) | |
| 1092 return net::ERR_FAILED; | 1177 return net::ERR_FAILED; |
| 1093 | |
| 1094 // These are the real values of data size. | |
| 1095 out_entry_stat->set_data_size(0, stream_0_size); | 1178 out_entry_stat->set_data_size(0, stream_0_size); |
| 1096 out_entry_stat->set_data_size( | 1179 out_entry_stat->set_data_size(1, stream_1_size); |
| 1097 1, out_entry_stat->data_size(1) - stream_0_size); | |
| 1098 | 1180 |
| 1099 // Put stream 0 data in memory. | 1181 // Put stream 0 data in memory. |
| 1100 *stream_0_data = new net::GrowableIOBuffer(); | 1182 *stream_0_data = new net::GrowableIOBuffer(); |
| 1101 (*stream_0_data)->SetCapacity(stream_0_size); | 1183 (*stream_0_data)->SetCapacity(stream_0_size + sizeof(net::SHA256HashValue)); |
| 1102 int file_offset = out_entry_stat->GetOffsetInFile(key_, 0, 0); | 1184 int file_offset = out_entry_stat->GetOffsetInFile(key_.size(), 0, 0); |
| 1103 File* file = const_cast<File*>(&files_[0]); | 1185 int read_size = stream_0_size; |
| 1104 int bytes_read = | 1186 if (has_key_sha256) |
| 1105 file->Read(file_offset, (*stream_0_data)->data(), stream_0_size); | 1187 read_size += sizeof(net::SHA256HashValue); |
| 1106 if (bytes_read != stream_0_size) | 1188 if (files_[0].Read(file_offset, (*stream_0_data)->data(), read_size) != |
| 1189 read_size) | |
| 1107 return net::ERR_FAILED; | 1190 return net::ERR_FAILED; |
| 1108 | 1191 |
| 1109 // Check the CRC32. | 1192 // Check the CRC32. |
| 1110 uint32_t expected_crc32 = | 1193 uint32_t expected_crc32 = |
| 1111 stream_0_size == 0 | 1194 stream_0_size == 0 |
| 1112 ? crc32(0, Z_NULL, 0) | 1195 ? crc32(0, Z_NULL, 0) |
| 1113 : crc32(crc32(0, Z_NULL, 0), | 1196 : crc32(crc32(0, Z_NULL, 0), |
| 1114 reinterpret_cast<const Bytef*>((*stream_0_data)->data()), | 1197 reinterpret_cast<const Bytef*>((*stream_0_data)->data()), |
| 1115 stream_0_size); | 1198 stream_0_size); |
| 1116 if (has_crc32 && read_crc32 != expected_crc32) { | 1199 if (has_crc32 && read_crc32 != expected_crc32) { |
| 1117 DVLOG(1) << "EOF record had bad crc."; | 1200 DVLOG(1) << "EOF record had bad crc."; |
| 1118 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); | 1201 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); |
| 1119 return net::ERR_FAILED; | 1202 return net::ERR_FAILED; |
| 1120 } | 1203 } |
| 1121 *out_stream_0_crc32 = expected_crc32; | 1204 *out_stream_0_crc32 = expected_crc32; |
| 1205 | |
| 1206 // If present, check the key SHA256. | |
| 1207 if (has_key_sha256) { | |
| 1208 net::SHA256HashValue hash_value; | |
| 1209 CalculateSHA256OfKey(key_, &hash_value); | |
| 1210 if (std::memcmp(&hash_value, (*stream_0_data)->data() + stream_0_size, | |
| 1211 sizeof(hash_value)) != 0) { | |
| 1212 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_KEY_SHA256_MISMATCH); | |
| 1213 return net::ERR_FAILED; | |
| 1214 } | |
| 1215 } | |
| 1216 | |
| 1217 // Ensure the key is validated before completion. | |
| 1218 if (!has_key_sha256 && header_and_key_check_needed_[0]) | |
| 1219 CheckHeaderAndKey(0); | |
| 1220 | |
| 1122 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); | 1221 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); |
| 1123 return net::OK; | 1222 return net::OK; |
| 1124 } | 1223 } |
| 1125 | 1224 |
| 1126 int SimpleSynchronousEntry::GetEOFRecordData(int index, | 1225 int SimpleSynchronousEntry::GetEOFRecordData(int index, |
| 1127 const SimpleEntryStat& entry_stat, | 1226 const SimpleEntryStat& entry_stat, |
| 1128 bool* out_has_crc32, | 1227 bool* out_has_crc32, |
| 1228 bool* out_has_key_sha256, | |
| 1129 uint32_t* out_crc32, | 1229 uint32_t* out_crc32, |
| 1130 int* out_data_size) const { | 1230 int* out_data_size) const { |
| 1131 SimpleFileEOF eof_record; | 1231 SimpleFileEOF eof_record; |
| 1132 int file_offset = entry_stat.GetEOFOffsetInFile(key_, index); | 1232 int file_offset = entry_stat.GetEOFOffsetInFile(key_.size(), index); |
| 1133 int file_index = GetFileIndexFromStreamIndex(index); | 1233 int file_index = GetFileIndexFromStreamIndex(index); |
| 1134 File* file = const_cast<File*>(&files_[file_index]); | 1234 File* file = const_cast<File*>(&files_[file_index]); |
| 1135 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record), | 1235 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record), |
| 1136 sizeof(eof_record)) != | 1236 sizeof(eof_record)) != |
| 1137 sizeof(eof_record)) { | 1237 sizeof(eof_record)) { |
| 1138 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); | 1238 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); |
| 1139 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; | 1239 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; |
| 1140 } | 1240 } |
| 1141 | 1241 |
| 1142 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) { | 1242 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) { |
| 1143 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH); | 1243 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH); |
| 1144 DVLOG(1) << "EOF record had bad magic number."; | 1244 DVLOG(1) << "EOF record had bad magic number."; |
| 1145 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; | 1245 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; |
| 1146 } | 1246 } |
| 1147 | 1247 |
| 1148 *out_has_crc32 = (eof_record.flags & SimpleFileEOF::FLAG_HAS_CRC32) == | 1248 *out_has_crc32 = (eof_record.flags & SimpleFileEOF::FLAG_HAS_CRC32) == |
| 1149 SimpleFileEOF::FLAG_HAS_CRC32; | 1249 SimpleFileEOF::FLAG_HAS_CRC32; |
| 1250 *out_has_key_sha256 = | |
| 1251 (eof_record.flags & SimpleFileEOF::FLAG_HAS_KEY_SHA256) == | |
| 1252 SimpleFileEOF::FLAG_HAS_KEY_SHA256; | |
| 1150 *out_crc32 = eof_record.data_crc32; | 1253 *out_crc32 = eof_record.data_crc32; |
| 1151 *out_data_size = eof_record.stream_size; | 1254 *out_data_size = eof_record.stream_size; |
| 1152 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, *out_has_crc32); | 1255 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, *out_has_crc32); |
| 1256 if (index == 0) { | |
| 1257 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasKeySHA256", cache_type_, | |
| 1258 *out_has_key_sha256); | |
| 1259 } | |
| 1153 return net::OK; | 1260 return net::OK; |
| 1154 } | 1261 } |
| 1155 | 1262 |
| 1156 void SimpleSynchronousEntry::Doom() const { | 1263 void SimpleSynchronousEntry::Doom() const { |
| 1157 DeleteFilesForEntryHash(path_, entry_hash_); | 1264 DeleteFilesForEntryHash(path_, entry_hash_); |
| 1158 } | 1265 } |
| 1159 | 1266 |
| 1160 // static | 1267 // static |
| 1161 bool SimpleSynchronousEntry::DeleteFileForEntryHash(const FilePath& path, | 1268 bool SimpleSynchronousEntry::DeleteFileForEntryHash(const FilePath& path, |
| 1162 const uint64_t entry_hash, | 1269 const uint64_t entry_hash, |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1467 range.offset = offset; | 1574 range.offset = offset; |
| 1468 range.length = len; | 1575 range.length = len; |
| 1469 range.data_crc32 = data_crc32; | 1576 range.data_crc32 = data_crc32; |
| 1470 range.file_offset = data_file_offset; | 1577 range.file_offset = data_file_offset; |
| 1471 sparse_ranges_.insert(std::make_pair(offset, range)); | 1578 sparse_ranges_.insert(std::make_pair(offset, range)); |
| 1472 | 1579 |
| 1473 return true; | 1580 return true; |
| 1474 } | 1581 } |
| 1475 | 1582 |
| 1476 } // namespace disk_cache | 1583 } // namespace disk_cache |
| OLD | NEW |