| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/entry_impl.h" | 5 #include "net/disk_cache/entry_impl.h" |
| 6 | 6 |
| 7 #include "base/hash.h" | 7 #include "base/hash.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
| 12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 13 #include "net/disk_cache/backend_impl.h" | 13 #include "net/disk_cache/backend_impl.h" |
| 14 #include "net/disk_cache/bitmap.h" | 14 #include "net/disk_cache/bitmap.h" |
| 15 #include "net/disk_cache/cache_util.h" | 15 #include "net/disk_cache/cache_util.h" |
| 16 #include "net/disk_cache/disk_format.h" |
| 16 #include "net/disk_cache/histogram_macros.h" | 17 #include "net/disk_cache/histogram_macros.h" |
| 17 #include "net/disk_cache/net_log_parameters.h" | 18 #include "net/disk_cache/net_log_parameters.h" |
| 18 #include "net/disk_cache/sparse_control.h" | 19 #include "net/disk_cache/sparse_control.h" |
| 19 | 20 |
| 20 using base::Time; | 21 using base::Time; |
| 21 using base::TimeDelta; | 22 using base::TimeDelta; |
| 22 using base::TimeTicks; | 23 using base::TimeTicks; |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 return false; | 575 return false; |
| 575 | 576 |
| 576 if (stored->reuse_count < 0 || stored->refetch_count < 0) | 577 if (stored->reuse_count < 0 || stored->refetch_count < 0) |
| 577 return false; | 578 return false; |
| 578 | 579 |
| 579 Addr rankings_addr(stored->rankings_node); | 580 Addr rankings_addr(stored->rankings_node); |
| 580 if (!rankings_addr.SanityCheckForRankings()) | 581 if (!rankings_addr.SanityCheckForRankings()) |
| 581 return false; | 582 return false; |
| 582 | 583 |
| 583 Addr next_addr(stored->next); | 584 Addr next_addr(stored->next); |
| 584 if (next_addr.is_initialized() && !next_addr.SanityCheckForEntry()) { | 585 if (next_addr.is_initialized() && !next_addr.SanityCheckForEntryV2()) { |
| 585 STRESS_NOTREACHED(); | 586 STRESS_NOTREACHED(); |
| 586 return false; | 587 return false; |
| 587 } | 588 } |
| 588 STRESS_DCHECK(next_addr.value() != entry_.address().value()); | 589 STRESS_DCHECK(next_addr.value() != entry_.address().value()); |
| 589 | 590 |
| 590 if (stored->state > ENTRY_DOOMED || stored->state < ENTRY_NORMAL) | 591 if (stored->state > ENTRY_DOOMED || stored->state < ENTRY_NORMAL) |
| 591 return false; | 592 return false; |
| 592 | 593 |
| 593 Addr key_addr(stored->long_key); | 594 Addr key_addr(stored->long_key); |
| 594 if ((stored->key_len <= kMaxInternalKeyLength && key_addr.is_initialized()) || | 595 if ((stored->key_len <= kMaxInternalKeyLength && key_addr.is_initialized()) || |
| 595 (stored->key_len > kMaxInternalKeyLength && !key_addr.is_initialized())) | 596 (stored->key_len > kMaxInternalKeyLength && !key_addr.is_initialized())) |
| 596 return false; | 597 return false; |
| 597 | 598 |
| 598 if (!key_addr.SanityCheck()) | 599 if (!key_addr.SanityCheckV2()) |
| 599 return false; | 600 return false; |
| 600 | 601 |
| 601 if (key_addr.is_initialized() && | 602 if (key_addr.is_initialized() && |
| 602 ((stored->key_len < kMaxBlockSize && key_addr.is_separate_file()) || | 603 ((stored->key_len < kMaxBlockSize && key_addr.is_separate_file()) || |
| 603 (stored->key_len >= kMaxBlockSize && key_addr.is_block_file()))) | 604 (stored->key_len >= kMaxBlockSize && key_addr.is_block_file()))) |
| 604 return false; | 605 return false; |
| 605 | 606 |
| 606 int num_blocks = NumBlocksForEntry(stored->key_len); | 607 int num_blocks = NumBlocksForEntry(stored->key_len); |
| 607 if (entry_.address().num_blocks() != num_blocks) | 608 if (entry_.address().num_blocks() != num_blocks) |
| 608 return false; | 609 return false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 621 if (stored->hash != base::Hash(GetKey())) | 622 if (stored->hash != base::Hash(GetKey())) |
| 622 return false; | 623 return false; |
| 623 | 624 |
| 624 for (int i = 0; i < kNumStreams; i++) { | 625 for (int i = 0; i < kNumStreams; i++) { |
| 625 Addr data_addr(stored->data_addr[i]); | 626 Addr data_addr(stored->data_addr[i]); |
| 626 int data_size = stored->data_size[i]; | 627 int data_size = stored->data_size[i]; |
| 627 if (data_size < 0) | 628 if (data_size < 0) |
| 628 return false; | 629 return false; |
| 629 if (!data_size && data_addr.is_initialized()) | 630 if (!data_size && data_addr.is_initialized()) |
| 630 return false; | 631 return false; |
| 631 if (!data_addr.SanityCheck()) | 632 if (!data_addr.SanityCheckV2()) |
| 632 return false; | 633 return false; |
| 633 if (!data_size) | 634 if (!data_size) |
| 634 continue; | 635 continue; |
| 635 if (data_size <= kMaxBlockSize && data_addr.is_separate_file()) | 636 if (data_size <= kMaxBlockSize && data_addr.is_separate_file()) |
| 636 return false; | 637 return false; |
| 637 if (data_size > kMaxBlockSize && data_addr.is_block_file()) | 638 if (data_size > kMaxBlockSize && data_addr.is_block_file()) |
| 638 return false; | 639 return false; |
| 639 } | 640 } |
| 640 return true; | 641 return true; |
| 641 } | 642 } |
| 642 | 643 |
| 643 void EntryImpl::FixForDelete() { | 644 void EntryImpl::FixForDelete() { |
| 644 EntryStore* stored = entry_.Data(); | 645 EntryStore* stored = entry_.Data(); |
| 645 Addr key_addr(stored->long_key); | 646 Addr key_addr(stored->long_key); |
| 646 | 647 |
| 647 if (!key_addr.is_initialized()) | 648 if (!key_addr.is_initialized()) |
| 648 stored->key[stored->key_len] = '\0'; | 649 stored->key[stored->key_len] = '\0'; |
| 649 | 650 |
| 650 for (int i = 0; i < kNumStreams; i++) { | 651 for (int i = 0; i < kNumStreams; i++) { |
| 651 Addr data_addr(stored->data_addr[i]); | 652 Addr data_addr(stored->data_addr[i]); |
| 652 int data_size = stored->data_size[i]; | 653 int data_size = stored->data_size[i]; |
| 653 if (data_addr.is_initialized()) { | 654 if (data_addr.is_initialized()) { |
| 654 if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) || | 655 if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) || |
| 655 (data_size > kMaxBlockSize && data_addr.is_block_file()) || | 656 (data_size > kMaxBlockSize && data_addr.is_block_file()) || |
| 656 !data_addr.SanityCheck()) { | 657 !data_addr.SanityCheckV2()) { |
| 657 STRESS_NOTREACHED(); | 658 STRESS_NOTREACHED(); |
| 658 // The address is weird so don't attempt to delete it. | 659 // The address is weird so don't attempt to delete it. |
| 659 stored->data_addr[i] = 0; | 660 stored->data_addr[i] = 0; |
| 660 // In general, trust the stored size as it should be in sync with the | 661 // In general, trust the stored size as it should be in sync with the |
| 661 // total size tracked by the backend. | 662 // total size tracked by the backend. |
| 662 } | 663 } |
| 663 } | 664 } |
| 664 if (data_size < 0) | 665 if (data_size < 0) |
| 665 stored->data_size[i] = 0; | 666 stored->data_size[i] = 0; |
| 666 } | 667 } |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 if (!backend_) | 1175 if (!backend_) |
| 1175 return false; | 1176 return false; |
| 1176 | 1177 |
| 1177 FileType file_type = Addr::RequiredFileType(size); | 1178 FileType file_type = Addr::RequiredFileType(size); |
| 1178 if (EXTERNAL == file_type) { | 1179 if (EXTERNAL == file_type) { |
| 1179 if (size > backend_->MaxFileSize()) | 1180 if (size > backend_->MaxFileSize()) |
| 1180 return false; | 1181 return false; |
| 1181 if (!backend_->CreateExternalFile(address)) | 1182 if (!backend_->CreateExternalFile(address)) |
| 1182 return false; | 1183 return false; |
| 1183 } else { | 1184 } else { |
| 1184 int num_blocks = (size + Addr::BlockSizeForFileType(file_type) - 1) / | 1185 int num_blocks = Addr::RequiredBlocks(size, file_type); |
| 1185 Addr::BlockSizeForFileType(file_type); | |
| 1186 | 1186 |
| 1187 if (!backend_->CreateBlock(file_type, num_blocks, address)) | 1187 if (!backend_->CreateBlock(file_type, num_blocks, address)) |
| 1188 return false; | 1188 return false; |
| 1189 } | 1189 } |
| 1190 return true; | 1190 return true; |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 // Note that this method may end up modifying a block file so upon return the | 1193 // Note that this method may end up modifying a block file so upon return the |
| 1194 // involved block will be free, and could be reused for something else. If there | 1194 // involved block will be free, and could be reused for something else. If there |
| 1195 // is a crash after that point (and maybe before returning to the caller), the | 1195 // is a crash after that point (and maybe before returning to the caller), the |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 | 1282 |
| 1283 if (!user_buffers_[index].get() && offset < kMaxBlockSize) { | 1283 if (!user_buffers_[index].get() && offset < kMaxBlockSize) { |
| 1284 // We are about to create a buffer for the first 16KB, make sure that we | 1284 // We are about to create a buffer for the first 16KB, make sure that we |
| 1285 // preserve existing data. | 1285 // preserve existing data. |
| 1286 if (!CopyToLocalBuffer(index)) | 1286 if (!CopyToLocalBuffer(index)) |
| 1287 return false; | 1287 return false; |
| 1288 } | 1288 } |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 if (!user_buffers_[index].get()) | 1291 if (!user_buffers_[index].get()) |
| 1292 user_buffers_[index].reset(new UserBuffer(backend_)); | 1292 user_buffers_[index].reset(new UserBuffer(backend_.get())); |
| 1293 | 1293 |
| 1294 return PrepareBuffer(index, offset, buf_len); | 1294 return PrepareBuffer(index, offset, buf_len); |
| 1295 } | 1295 } |
| 1296 | 1296 |
| 1297 // We get to this function with some data already stored. If there is a | 1297 // We get to this function with some data already stored. If there is a |
| 1298 // truncation that results on data stored internally, we'll explicitly | 1298 // truncation that results on data stored internally, we'll explicitly |
| 1299 // handle the case here. | 1299 // handle the case here. |
| 1300 bool EntryImpl::HandleTruncation(int index, int offset, int buf_len) { | 1300 bool EntryImpl::HandleTruncation(int index, int offset, int buf_len) { |
| 1301 Addr address(entry_.Data()->data_addr[index]); | 1301 Addr address(entry_.Data()->data_addr[index]); |
| 1302 | 1302 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 | 1353 |
| 1354 return ImportSeparateFile(index, offset + buf_len); | 1354 return ImportSeparateFile(index, offset + buf_len); |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 bool EntryImpl::CopyToLocalBuffer(int index) { | 1357 bool EntryImpl::CopyToLocalBuffer(int index) { |
| 1358 Addr address(entry_.Data()->data_addr[index]); | 1358 Addr address(entry_.Data()->data_addr[index]); |
| 1359 DCHECK(!user_buffers_[index].get()); | 1359 DCHECK(!user_buffers_[index].get()); |
| 1360 DCHECK(address.is_initialized()); | 1360 DCHECK(address.is_initialized()); |
| 1361 | 1361 |
| 1362 int len = std::min(entry_.Data()->data_size[index], kMaxBlockSize); | 1362 int len = std::min(entry_.Data()->data_size[index], kMaxBlockSize); |
| 1363 user_buffers_[index].reset(new UserBuffer(backend_)); | 1363 user_buffers_[index].reset(new UserBuffer(backend_.get())); |
| 1364 user_buffers_[index]->Write(len, NULL, 0); | 1364 user_buffers_[index]->Write(len, NULL, 0); |
| 1365 | 1365 |
| 1366 File* file = GetBackingFile(address, index); | 1366 File* file = GetBackingFile(address, index); |
| 1367 int offset = 0; | 1367 int offset = 0; |
| 1368 | 1368 |
| 1369 if (address.is_block_file()) | 1369 if (address.is_block_file()) |
| 1370 offset = address.start_block() * address.BlockSize() + kBlockHeaderSize; | 1370 offset = address.start_block() * address.BlockSize() + kBlockHeaderSize; |
| 1371 | 1371 |
| 1372 if (!file || | 1372 if (!file || |
| 1373 !file->Read(user_buffers_[index]->Data(), len, offset, NULL, NULL)) { | 1373 !file->Read(user_buffers_[index]->Data(), len, offset, NULL, NULL)) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), | 1541 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), |
| 1542 entry_.address().value(), node_.address().value()); | 1542 entry_.address().value(), node_.address().value()); |
| 1543 | 1543 |
| 1544 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 1544 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
| 1545 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 1545 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
| 1546 | 1546 |
| 1547 Trace(" doomed: %d 0x%x", doomed_, dirty); | 1547 Trace(" doomed: %d 0x%x", doomed_, dirty); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 } // namespace disk_cache | 1550 } // namespace disk_cache |
| OLD | NEW |