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
3 // found in the LICENSE file.
5 #include "net/disk_cache/simple/simple_synchronous_entry.h"
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/file_util.h"
15 #include "base/hash.h"
16 #include "base/location.h"
17 #include "base/metrics/histogram.h"
18 #include "base/sha1.h"
19 #include "base/strings/stringprintf.h"
20 #include "net/base/io_buffer.h"
21 #include "net/base/net_errors.h"
22 #include "net/disk_cache/simple/simple_util.h"
23 #include "third_party/zlib/zlib.h"
25 using base::kInvalidPlatformFileValue
;
26 using base::ClosePlatformFile
;
28 using base::GetPlatformFileInfo
;
29 using base::PlatformFileError
;
30 using base::PlatformFileInfo
;
31 using base::PLATFORM_FILE_CREATE
;
32 using base::PLATFORM_FILE_ERROR_EXISTS
;
33 using base::PLATFORM_FILE_OK
;
34 using base::PLATFORM_FILE_OPEN
;
35 using base::PLATFORM_FILE_READ
;
36 using base::PLATFORM_FILE_WRITE
;
37 using base::ReadPlatformFile
;
39 using base::TruncatePlatformFile
;
40 using base::WritePlatformFile
;
44 // Used in histograms, please only add entries at the end.
45 enum OpenEntryResult
{
46 OPEN_ENTRY_SUCCESS
= 0,
47 OPEN_ENTRY_PLATFORM_FILE_ERROR
= 1,
48 OPEN_ENTRY_CANT_READ_HEADER
= 2,
49 OPEN_ENTRY_BAD_MAGIC_NUMBER
= 3,
50 OPEN_ENTRY_BAD_VERSION
= 4,
51 OPEN_ENTRY_CANT_READ_KEY
= 5,
52 // OPEN_ENTRY_KEY_MISMATCH = 6, Deprecated.
53 OPEN_ENTRY_KEY_HASH_MISMATCH
= 7,
57 // Used in histograms, please only add entries at the end.
58 enum CreateEntryResult
{
59 CREATE_ENTRY_SUCCESS
= 0,
60 CREATE_ENTRY_PLATFORM_FILE_ERROR
= 1,
61 CREATE_ENTRY_CANT_WRITE_HEADER
= 2,
62 CREATE_ENTRY_CANT_WRITE_KEY
= 3,
66 // Used in histograms, please only add entries at the end.
68 WRITE_RESULT_SUCCESS
= 0,
69 WRITE_RESULT_PRETRUNCATE_FAILURE
,
70 WRITE_RESULT_WRITE_FAILURE
,
71 WRITE_RESULT_TRUNCATE_FAILURE
,
75 // Used in histograms, please only add entries at the end.
77 CHECK_EOF_RESULT_SUCCESS
,
78 CHECK_EOF_RESULT_READ_FAILURE
,
79 CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH
,
80 CHECK_EOF_RESULT_CRC_MISMATCH
,
84 // Used in histograms, please only add entries at the end.
87 CLOSE_RESULT_WRITE_FAILURE
,
90 void RecordSyncOpenResult(OpenEntryResult result
, bool had_index
) {
91 DCHECK_GT(OPEN_ENTRY_MAX
, result
);
92 UMA_HISTOGRAM_ENUMERATION(
93 "SimpleCache.SyncOpenResult", result
, OPEN_ENTRY_MAX
);
95 UMA_HISTOGRAM_ENUMERATION(
96 "SimpleCache.SyncOpenResult_WithIndex", result
, OPEN_ENTRY_MAX
);
98 UMA_HISTOGRAM_ENUMERATION(
99 "SimpleCache.SyncOpenResult_WithoutIndex", result
, OPEN_ENTRY_MAX
);
103 void RecordSyncCreateResult(CreateEntryResult result
, bool had_index
) {
104 DCHECK_GT(CREATE_ENTRY_MAX
, result
);
105 UMA_HISTOGRAM_ENUMERATION(
106 "SimpleCache.SyncCreateResult", result
, CREATE_ENTRY_MAX
);
108 UMA_HISTOGRAM_ENUMERATION(
109 "SimpleCache.SyncCreateResult_WithIndex", result
, CREATE_ENTRY_MAX
);
111 UMA_HISTOGRAM_ENUMERATION(
112 "SimpleCache.SyncCreateResult_WithoutIndex", result
, CREATE_ENTRY_MAX
);
116 void RecordWriteResult(WriteResult result
) {
117 UMA_HISTOGRAM_ENUMERATION(
118 "SimpleCache.SyncWriteResult", result
, WRITE_RESULT_MAX
);
121 void RecordCheckEOFResult(CheckEOFResult result
) {
122 UMA_HISTOGRAM_ENUMERATION(
123 "SimpleCache.SyncCheckEOFResult", result
, CHECK_EOF_RESULT_MAX
);
126 void RecordCloseResult(CloseResult result
) {
127 UMA_HISTOGRAM_ENUMERATION(
128 "SimpleCache.SyncCloseResult", result
, WRITE_RESULT_MAX
);
133 namespace disk_cache
{
135 using simple_util::ConvertEntryHashKeyToHexString
;
136 using simple_util::GetEntryHashKey
;
137 using simple_util::GetFilenameFromEntryHashAndIndex
;
138 using simple_util::GetDataSizeFromKeyAndFileSize
;
139 using simple_util::GetFileSizeFromKeyAndDataSize
;
140 using simple_util::GetFileOffsetFromKeyAndDataOffset
;
142 SimpleEntryStat::SimpleEntryStat() {}
144 SimpleEntryStat::SimpleEntryStat(base::Time last_used_p
,
145 base::Time last_modified_p
,
146 const int32 data_size_p
[])
147 : last_used(last_used_p
),
148 last_modified(last_modified_p
) {
149 memcpy(data_size
, data_size_p
, sizeof(data_size
));
152 SimpleEntryCreationResults::SimpleEntryCreationResults(
153 SimpleEntryStat entry_stat
)
155 entry_stat(entry_stat
),
159 SimpleEntryCreationResults::~SimpleEntryCreationResults() {
162 SimpleSynchronousEntry::CRCRecord::CRCRecord() : index(-1),
167 SimpleSynchronousEntry::CRCRecord::CRCRecord(int index_p
,
171 has_crc32(has_crc32_p
),
172 data_crc32(data_crc32_p
) {}
174 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p
,
179 buf_len(buf_len_p
) {}
181 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p
,
188 truncate(truncate_p
) {}
191 void SimpleSynchronousEntry::OpenEntry(
192 const FilePath
& path
,
193 const uint64 entry_hash
,
195 SimpleEntryCreationResults
*out_results
) {
196 SimpleSynchronousEntry
* sync_entry
= new SimpleSynchronousEntry(path
, "",
198 out_results
->result
= sync_entry
->InitializeForOpen(
199 had_index
, &out_results
->entry_stat
);
200 if (out_results
->result
!= net::OK
) {
203 out_results
->sync_entry
= NULL
;
206 out_results
->sync_entry
= sync_entry
;
210 void SimpleSynchronousEntry::CreateEntry(
211 const FilePath
& path
,
212 const std::string
& key
,
213 const uint64 entry_hash
,
215 SimpleEntryCreationResults
*out_results
) {
216 DCHECK_EQ(entry_hash
, GetEntryHashKey(key
));
217 SimpleSynchronousEntry
* sync_entry
= new SimpleSynchronousEntry(path
, key
,
219 out_results
->result
= sync_entry
->InitializeForCreate(
220 had_index
, &out_results
->entry_stat
);
221 if (out_results
->result
!= net::OK
) {
222 if (out_results
->result
!= net::ERR_FILE_EXISTS
)
225 out_results
->sync_entry
= NULL
;
228 out_results
->sync_entry
= sync_entry
;
231 // TODO(gavinp): Move this function to its correct location in this .cc file.
233 bool SimpleSynchronousEntry::DeleteFilesForEntryHash(
234 const FilePath
& path
,
235 const uint64 entry_hash
) {
237 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
238 FilePath to_delete
= path
.AppendASCII(
239 GetFilenameFromEntryHashAndIndex(entry_hash
, i
));
240 if (!base::DeleteFile(to_delete
, false)) {
242 DLOG(ERROR
) << "Could not delete " << to_delete
.MaybeAsASCII();
249 void SimpleSynchronousEntry::DoomEntry(
250 const FilePath
& path
,
251 const std::string
& key
,
254 DCHECK_EQ(entry_hash
, GetEntryHashKey(key
));
255 bool deleted_well
= DeleteFilesForEntryHash(path
, entry_hash
);
256 *out_result
= deleted_well
? net::OK
: net::ERR_FAILED
;
260 int SimpleSynchronousEntry::DoomEntrySet(
261 scoped_ptr
<std::vector
<uint64
> > key_hashes
,
262 const FilePath
& path
) {
263 const size_t did_delete_count
= std::count_if(
264 key_hashes
->begin(), key_hashes
->end(), std::bind1st(
265 std::ptr_fun(SimpleSynchronousEntry::DeleteFilesForEntryHash
), path
));
266 return (did_delete_count
== key_hashes
->size()) ? net::OK
: net::ERR_FAILED
;
269 void SimpleSynchronousEntry::ReadData(const EntryOperationData
& in_entry_op
,
270 net::IOBuffer
* out_buf
,
272 base::Time
* out_last_used
,
273 int* out_result
) const {
274 DCHECK(initialized_
);
276 GetFileOffsetFromKeyAndDataOffset(key_
, in_entry_op
.offset
);
277 int bytes_read
= ReadPlatformFile(files_
[in_entry_op
.index
],
280 in_entry_op
.buf_len
);
281 if (bytes_read
> 0) {
282 *out_last_used
= Time::Now();
283 *out_crc32
= crc32(crc32(0L, Z_NULL
, 0),
284 reinterpret_cast<const Bytef
*>(out_buf
->data()),
287 if (bytes_read
>= 0) {
288 *out_result
= bytes_read
;
290 *out_result
= net::ERR_CACHE_READ_FAILURE
;
295 void SimpleSynchronousEntry::WriteData(const EntryOperationData
& in_entry_op
,
296 net::IOBuffer
* in_buf
,
297 SimpleEntryStat
* out_entry_stat
,
298 int* out_result
) const {
299 DCHECK(initialized_
);
300 int index
= in_entry_op
.index
;
301 int offset
= in_entry_op
.offset
;
302 int buf_len
= in_entry_op
.buf_len
;
303 int truncate
= in_entry_op
.truncate
;
305 bool extending_by_write
= offset
+ buf_len
> out_entry_stat
->data_size
[index
];
306 if (extending_by_write
) {
307 // We are extending the file, and need to insure the EOF record is zeroed.
308 const int64 file_eof_offset
= GetFileOffsetFromKeyAndDataOffset(
309 key_
, out_entry_stat
->data_size
[index
]);
310 if (!TruncatePlatformFile(files_
[index
], file_eof_offset
)) {
311 RecordWriteResult(WRITE_RESULT_PRETRUNCATE_FAILURE
);
313 *out_result
= net::ERR_CACHE_WRITE_FAILURE
;
317 const int64 file_offset
= GetFileOffsetFromKeyAndDataOffset(key_
, offset
);
319 if (WritePlatformFile(
320 files_
[index
], file_offset
, in_buf
->data(), buf_len
) != buf_len
) {
321 RecordWriteResult(WRITE_RESULT_WRITE_FAILURE
);
323 *out_result
= net::ERR_CACHE_WRITE_FAILURE
;
327 if (!truncate
&& (buf_len
> 0 || !extending_by_write
)) {
328 out_entry_stat
->data_size
[index
] =
329 std::max(out_entry_stat
->data_size
[index
], offset
+ buf_len
);
331 if (!TruncatePlatformFile(files_
[index
], file_offset
+ buf_len
)) {
332 RecordWriteResult(WRITE_RESULT_TRUNCATE_FAILURE
);
334 *out_result
= net::ERR_CACHE_WRITE_FAILURE
;
337 out_entry_stat
->data_size
[index
] = offset
+ buf_len
;
340 RecordWriteResult(WRITE_RESULT_SUCCESS
);
341 out_entry_stat
->last_used
= out_entry_stat
->last_modified
= Time::Now();
342 *out_result
= buf_len
;
345 void SimpleSynchronousEntry::CheckEOFRecord(int index
,
347 uint32 expected_crc32
,
348 int* out_result
) const {
349 DCHECK(initialized_
);
351 SimpleFileEOF eof_record
;
352 int64 file_offset
= GetFileOffsetFromKeyAndDataOffset(key_
, data_size
);
353 if (ReadPlatformFile(files_
[index
],
355 reinterpret_cast<char*>(&eof_record
),
356 sizeof(eof_record
)) != sizeof(eof_record
)) {
357 RecordCheckEOFResult(CHECK_EOF_RESULT_READ_FAILURE
);
359 *out_result
= net::ERR_CACHE_CHECKSUM_READ_FAILURE
;
363 if (eof_record
.final_magic_number
!= kSimpleFinalMagicNumber
) {
364 RecordCheckEOFResult(CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH
);
365 DLOG(INFO
) << "eof record had bad magic number.";
367 *out_result
= net::ERR_CACHE_CHECKSUM_READ_FAILURE
;
371 const bool has_crc
= (eof_record
.flags
& SimpleFileEOF::FLAG_HAS_CRC32
) ==
372 SimpleFileEOF::FLAG_HAS_CRC32
;
373 UMA_HISTOGRAM_BOOLEAN("SimpleCache.SyncCheckEOFHasCrc", has_crc
);
374 if (has_crc
&& eof_record
.data_crc32
!= expected_crc32
) {
375 RecordCheckEOFResult(CHECK_EOF_RESULT_CRC_MISMATCH
);
376 DLOG(INFO
) << "eof record had bad crc.";
378 *out_result
= net::ERR_CACHE_CHECKSUM_MISMATCH
;
382 RecordCheckEOFResult(CHECK_EOF_RESULT_SUCCESS
);
383 *out_result
= net::OK
;
386 void SimpleSynchronousEntry::Close(
387 const SimpleEntryStat
& entry_stat
,
388 scoped_ptr
<std::vector
<CRCRecord
> > crc32s_to_write
) {
389 for (std::vector
<CRCRecord
>::const_iterator it
= crc32s_to_write
->begin();
390 it
!= crc32s_to_write
->end(); ++it
) {
391 SimpleFileEOF eof_record
;
392 eof_record
.final_magic_number
= kSimpleFinalMagicNumber
;
393 eof_record
.flags
= 0;
395 eof_record
.flags
|= SimpleFileEOF::FLAG_HAS_CRC32
;
396 eof_record
.data_crc32
= it
->data_crc32
;
397 int64 file_offset
= GetFileOffsetFromKeyAndDataOffset(
398 key_
, entry_stat
.data_size
[it
->index
]);
399 if (WritePlatformFile(files_
[it
->index
],
401 reinterpret_cast<const char*>(&eof_record
),
402 sizeof(eof_record
)) != sizeof(eof_record
)) {
403 RecordCloseResult(CLOSE_RESULT_WRITE_FAILURE
);
404 DLOG(INFO
) << "Could not write eof record.";
408 const int64 file_size
= file_offset
+ sizeof(eof_record
);
409 UMA_HISTOGRAM_CUSTOM_COUNTS("SimpleCache.LastClusterSize",
410 file_size
% 4096, 0, 4097, 50);
411 const int64 cluster_loss
= file_size
% 4096 ? 4096 - file_size
% 4096 : 0;
412 UMA_HISTOGRAM_PERCENTAGE("SimpleCache.LastClusterLossPercent",
413 cluster_loss
* 100 / (cluster_loss
+ file_size
));
416 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
417 bool did_close_file
= ClosePlatformFile(files_
[i
]);
418 CHECK(did_close_file
);
420 RecordCloseResult(CLOSE_RESULT_SUCCESS
);
421 have_open_files_
= false;
425 SimpleSynchronousEntry::SimpleSynchronousEntry(const FilePath
& path
,
426 const std::string
& key
,
427 const uint64 entry_hash
)
429 entry_hash_(entry_hash
),
431 have_open_files_(false),
432 initialized_(false) {
433 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
434 files_
[i
] = kInvalidPlatformFileValue
;
438 SimpleSynchronousEntry::~SimpleSynchronousEntry() {
439 DCHECK(!(have_open_files_
&& initialized_
));
440 if (have_open_files_
)
444 bool SimpleSynchronousEntry::OpenOrCreateFiles(
447 SimpleEntryStat
* out_entry_stat
) {
448 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
449 FilePath filename
= path_
.AppendASCII(
450 GetFilenameFromEntryHashAndIndex(entry_hash_
, i
));
451 int flags
= PLATFORM_FILE_READ
| PLATFORM_FILE_WRITE
;
453 flags
|= PLATFORM_FILE_CREATE
;
455 flags
|= PLATFORM_FILE_OPEN
;
456 PlatformFileError error
;
457 files_
[i
] = CreatePlatformFile(filename
, flags
, NULL
, &error
);
458 if (error
!= PLATFORM_FILE_OK
) {
459 // TODO(ttuttle,gavinp): Remove one each of these triplets of histograms.
460 // We can calculate the third as the sum or difference of the other two.
462 RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR
, had_index
);
463 UMA_HISTOGRAM_ENUMERATION("SimpleCache.SyncCreatePlatformFileError",
464 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
466 UMA_HISTOGRAM_ENUMERATION(
467 "SimpleCache.SyncCreatePlatformFileError_WithIndex",
468 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
470 UMA_HISTOGRAM_ENUMERATION(
471 "SimpleCache.SyncCreatePlatformFileError_WithoutIndex",
472 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
475 RecordSyncOpenResult(OPEN_ENTRY_PLATFORM_FILE_ERROR
, had_index
);
476 UMA_HISTOGRAM_ENUMERATION("SimpleCache.SyncOpenPlatformFileError",
477 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
479 UMA_HISTOGRAM_ENUMERATION(
480 "SimpleCache.SyncOpenPlatformFileError_WithIndex",
481 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
483 UMA_HISTOGRAM_ENUMERATION(
484 "SimpleCache.SyncOpenPlatformFileError_WithoutIndex",
485 -error
, -base::PLATFORM_FILE_ERROR_MAX
);
489 bool ALLOW_UNUSED did_close
= ClosePlatformFile(files_
[i
]);
490 DLOG_IF(INFO
, !did_close
) << "Could not close file "
491 << filename
.MaybeAsASCII();
497 have_open_files_
= true;
499 out_entry_stat
->last_modified
= out_entry_stat
->last_used
= Time::Now();
500 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
)
501 out_entry_stat
->data_size
[i
] = 0;
503 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
504 PlatformFileInfo file_info
;
505 bool success
= GetPlatformFileInfo(files_
[i
], &file_info
);
506 base::Time file_last_modified
;
508 DLOG(WARNING
) << "Could not get platform file info.";
511 out_entry_stat
->last_used
= file_info
.last_accessed
;
512 if (simple_util::GetMTime(path_
, &file_last_modified
))
513 out_entry_stat
->last_modified
= file_last_modified
;
515 out_entry_stat
->last_modified
= file_info
.last_modified
;
517 // Keep the file size in |data size_| briefly until the key is initialized
519 out_entry_stat
->data_size
[i
] = file_info
.size
;
526 void SimpleSynchronousEntry::CloseFiles() {
527 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
528 DCHECK_NE(kInvalidPlatformFileValue
, files_
[i
]);
529 bool did_close
= ClosePlatformFile(files_
[i
]);
534 int SimpleSynchronousEntry::InitializeForOpen(bool had_index
,
535 SimpleEntryStat
* out_entry_stat
) {
536 DCHECK(!initialized_
);
537 if (!OpenOrCreateFiles(false, had_index
, out_entry_stat
))
538 return net::ERR_FAILED
;
540 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
541 SimpleFileHeader header
;
542 int header_read_result
=
543 ReadPlatformFile(files_
[i
], 0, reinterpret_cast<char*>(&header
),
545 if (header_read_result
!= sizeof(header
)) {
546 DLOG(WARNING
) << "Cannot read header from entry.";
547 RecordSyncOpenResult(OPEN_ENTRY_CANT_READ_HEADER
, had_index
);
548 return net::ERR_FAILED
;
551 if (header
.initial_magic_number
!= kSimpleInitialMagicNumber
) {
552 // TODO(gavinp): This seems very bad; for now we log at WARNING, but we
553 // should give consideration to not saturating the log with these if that
554 // becomes a problem.
555 DLOG(WARNING
) << "Magic number did not match.";
556 RecordSyncOpenResult(OPEN_ENTRY_BAD_MAGIC_NUMBER
, had_index
);
557 return net::ERR_FAILED
;
560 if (header
.version
!= kSimpleVersion
) {
561 DLOG(WARNING
) << "Unreadable version.";
562 RecordSyncOpenResult(OPEN_ENTRY_BAD_VERSION
, had_index
);
563 return net::ERR_FAILED
;
566 scoped_ptr
<char[]> key(new char[header
.key_length
]);
567 int key_read_result
= ReadPlatformFile(files_
[i
], sizeof(header
),
568 key
.get(), header
.key_length
);
569 if (key_read_result
!= implicit_cast
<int>(header
.key_length
)) {
570 DLOG(WARNING
) << "Cannot read key from entry.";
571 RecordSyncOpenResult(OPEN_ENTRY_CANT_READ_KEY
, had_index
);
572 return net::ERR_FAILED
;
575 key_
= std::string(key
.get(), header
.key_length
);
576 out_entry_stat
->data_size
[i
] =
577 GetDataSizeFromKeyAndFileSize(key_
, out_entry_stat
->data_size
[i
]);
578 if (out_entry_stat
->data_size
[i
] < 0) {
579 // This entry can't possibly be valid, as it does not have enough space to
580 // store a valid SimpleFileEOF record.
581 return net::ERR_FAILED
;
584 if (base::Hash(key
.get(), header
.key_length
) != header
.key_hash
) {
585 DLOG(WARNING
) << "Hash mismatch on key.";
586 RecordSyncOpenResult(OPEN_ENTRY_KEY_HASH_MISMATCH
, had_index
);
587 return net::ERR_FAILED
;
590 RecordSyncOpenResult(OPEN_ENTRY_SUCCESS
, had_index
);
595 int SimpleSynchronousEntry::InitializeForCreate(
597 SimpleEntryStat
* out_entry_stat
) {
598 DCHECK(!initialized_
);
599 if (!OpenOrCreateFiles(true, had_index
, out_entry_stat
)) {
600 DLOG(WARNING
) << "Could not create platform files.";
601 return net::ERR_FILE_EXISTS
;
603 for (int i
= 0; i
< kSimpleEntryFileCount
; ++i
) {
604 SimpleFileHeader header
;
605 header
.initial_magic_number
= kSimpleInitialMagicNumber
;
606 header
.version
= kSimpleVersion
;
608 header
.key_length
= key_
.size();
609 header
.key_hash
= base::Hash(key_
);
611 if (WritePlatformFile(files_
[i
], 0, reinterpret_cast<char*>(&header
),
612 sizeof(header
)) != sizeof(header
)) {
613 DLOG(WARNING
) << "Could not write headers to new cache entry.";
614 RecordSyncCreateResult(CREATE_ENTRY_CANT_WRITE_HEADER
, had_index
);
615 return net::ERR_FAILED
;
618 if (WritePlatformFile(files_
[i
], sizeof(header
), key_
.data(),
619 key_
.size()) != implicit_cast
<int>(key_
.size())) {
620 DLOG(WARNING
) << "Could not write keys to new cache entry.";
621 RecordSyncCreateResult(CREATE_ENTRY_CANT_WRITE_KEY
, had_index
);
622 return net::ERR_FAILED
;
625 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS
, had_index
);
630 void SimpleSynchronousEntry::Doom() const {
631 // TODO(gavinp): Consider if we should guard against redundant Doom() calls.
632 DeleteFilesForEntryHash(path_
, entry_hash_
);
635 } // namespace disk_cache