| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 DeleteData(address, index); | 489 DeleteData(address, index); |
| 490 } | 490 } |
| 491 } | 491 } |
| 492 | 492 |
| 493 if (!everything) | 493 if (!everything) |
| 494 return; | 494 return; |
| 495 | 495 |
| 496 // Remove all traces of this entry. | 496 // Remove all traces of this entry. |
| 497 backend_->RemoveEntry(this); | 497 backend_->RemoveEntry(this); |
| 498 | 498 |
| 499 // Note that at this point node_ and entry_ are just two blocks of data, and |
| 500 // even if they reference each other, nobody should be referencing them. |
| 501 |
| 499 Addr address(entry_.Data()->long_key); | 502 Addr address(entry_.Data()->long_key); |
| 500 DeleteData(address, kKeyFileIndex); | 503 DeleteData(address, kKeyFileIndex); |
| 501 backend_->ModifyStorageSize(entry_.Data()->key_len, 0); | 504 backend_->ModifyStorageSize(entry_.Data()->key_len, 0); |
| 502 | 505 |
| 503 memset(node_.buffer(), 0, node_.size()); | 506 backend_->DeleteBlock(entry_.address(), true); |
| 504 memset(entry_.buffer(), 0, entry_.size()); | |
| 505 node_.Store(); | |
| 506 entry_.Store(); | |
| 507 | 507 |
| 508 backend_->DeleteBlock(node_.address(), false); | 508 if (!LeaveRankingsBehind()) |
| 509 backend_->DeleteBlock(entry_.address(), false); | 509 backend_->DeleteBlock(node_.address(), true); |
| 510 } | 510 } |
| 511 | 511 |
| 512 CacheAddr EntryImpl::GetNextAddress() { | 512 CacheAddr EntryImpl::GetNextAddress() { |
| 513 return entry_.Data()->next; | 513 return entry_.Data()->next; |
| 514 } | 514 } |
| 515 | 515 |
| 516 void EntryImpl::SetNextAddress(Addr address) { | 516 void EntryImpl::SetNextAddress(Addr address) { |
| 517 DCHECK_NE(address.value(), entry_.address().value()); | 517 DCHECK_NE(address.value(), entry_.address().value()); |
| 518 entry_.Data()->next = address.value(); | 518 entry_.Data()->next = address.value(); |
| 519 bool success = entry_.Store(); | 519 bool success = entry_.Store(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 544 | 544 |
| 545 void EntryImpl::SetDirtyFlag(int32 current_id) { | 545 void EntryImpl::SetDirtyFlag(int32 current_id) { |
| 546 DCHECK(node_.HasData()); | 546 DCHECK(node_.HasData()); |
| 547 // We are checking if the entry is valid or not. If there is a pointer here, | 547 // We are checking if the entry is valid or not. If there is a pointer here, |
| 548 // we should not be checking the entry. | 548 // we should not be checking the entry. |
| 549 if (node_.Data()->dummy) | 549 if (node_.Data()->dummy) |
| 550 dirty_ = true; | 550 dirty_ = true; |
| 551 | 551 |
| 552 if (node_.Data()->dirty && current_id != node_.Data()->dirty) | 552 if (node_.Data()->dirty && current_id != node_.Data()->dirty) |
| 553 dirty_ = true; | 553 dirty_ = true; |
| 554 |
| 555 if (!current_id) |
| 556 dirty_ = true; |
| 554 } | 557 } |
| 555 | 558 |
| 556 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { | 559 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { |
| 557 node_.Data()->dirty = new_id; | 560 node_.Data()->dirty = new_id; |
| 558 node_.Data()->dummy = 0; | 561 node_.Data()->dummy = 0; |
| 559 node_.Store(); | 562 node_.Store(); |
| 560 } | 563 } |
| 561 | 564 |
| 565 bool EntryImpl::LeaveRankingsBehind() { |
| 566 return !node_.Data()->contents; |
| 567 } |
| 568 |
| 569 // This only includes checks that relate to the first block of the entry (the |
| 570 // first 256 bytes), and values that should be set from the entry creation. |
| 571 // Basically, even if there is something wrong with this entry, we want to see |
| 572 // if it is possible to load the rankings node and delete them together. |
| 562 bool EntryImpl::SanityCheck() { | 573 bool EntryImpl::SanityCheck() { |
| 563 EntryStore* stored = entry_.Data(); | 574 EntryStore* stored = entry_.Data(); |
| 564 if (!stored->rankings_node || stored->key_len <= 0) | 575 if (!stored->rankings_node || stored->key_len <= 0) |
| 565 return false; | 576 return false; |
| 566 | 577 |
| 567 if (stored->reuse_count < 0 || stored->refetch_count < 0) | 578 if (stored->reuse_count < 0 || stored->refetch_count < 0) |
| 568 return false; | 579 return false; |
| 569 | 580 |
| 570 Addr rankings_addr(stored->rankings_node); | 581 Addr rankings_addr(stored->rankings_node); |
| 571 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || | 582 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || |
| 572 rankings_addr.file_type() != RANKINGS) | 583 rankings_addr.file_type() != RANKINGS || rankings_addr.num_blocks() != 1) |
| 573 return false; | 584 return false; |
| 574 | 585 |
| 575 Addr next_addr(stored->next); | 586 Addr next_addr(stored->next); |
| 576 if (next_addr.is_initialized() && | 587 if (next_addr.is_initialized() && |
| 577 (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256)) | 588 (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256)) |
| 578 return false; | 589 return false; |
| 579 | 590 |
| 580 if (!rankings_addr.SanityCheck() || !next_addr.SanityCheck()) | 591 if (!rankings_addr.SanityCheck() || !next_addr.SanityCheck()) |
| 581 return false; | 592 return false; |
| 582 | 593 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 593 | 604 |
| 594 if (key_addr.is_initialized() && | 605 if (key_addr.is_initialized() && |
| 595 ((stored->key_len <= kMaxBlockSize && key_addr.is_separate_file()) || | 606 ((stored->key_len <= kMaxBlockSize && key_addr.is_separate_file()) || |
| 596 (stored->key_len > kMaxBlockSize && key_addr.is_block_file()))) | 607 (stored->key_len > kMaxBlockSize && key_addr.is_block_file()))) |
| 597 return false; | 608 return false; |
| 598 | 609 |
| 599 int num_blocks = NumBlocksForEntry(stored->key_len); | 610 int num_blocks = NumBlocksForEntry(stored->key_len); |
| 600 if (entry_.address().num_blocks() != num_blocks) | 611 if (entry_.address().num_blocks() != num_blocks) |
| 601 return false; | 612 return false; |
| 602 | 613 |
| 614 return true; |
| 615 } |
| 616 |
| 617 bool EntryImpl::DataSanityCheck() { |
| 618 EntryStore* stored = entry_.Data(); |
| 619 Addr key_addr(stored->long_key); |
| 620 |
| 603 // The key must be NULL terminated. | 621 // The key must be NULL terminated. |
| 604 if (!key_addr.is_initialized() && stored->key[stored->key_len]) | 622 if (!key_addr.is_initialized() && stored->key[stored->key_len]) |
| 605 return false; | 623 return false; |
| 606 | 624 |
| 607 if (stored->hash != Hash(GetKey())) | 625 if (stored->hash != Hash(GetKey())) |
| 608 return false; | 626 return false; |
| 609 | 627 |
| 610 for (int i = 0; i < kNumStreams; i++) { | 628 for (int i = 0; i < kNumStreams; i++) { |
| 611 Addr data_addr(stored->data_addr[i]); | 629 Addr data_addr(stored->data_addr[i]); |
| 612 int data_size = stored->data_size[i]; | 630 int data_size = stored->data_size[i]; |
| 613 if (data_size < 0) | 631 if (data_size < 0) |
| 614 return false; | 632 return false; |
| 615 if (!data_size && data_addr.is_initialized()) | 633 if (!data_size && data_addr.is_initialized()) |
| 616 return false; | 634 return false; |
| 617 if (!data_addr.SanityCheck()) | 635 if (!data_addr.SanityCheck()) |
| 618 return false; | 636 return false; |
| 619 if (!data_size) | 637 if (!data_size) |
| 620 continue; | 638 continue; |
| 621 if (data_size <= kMaxBlockSize && data_addr.is_separate_file()) | 639 if (data_size <= kMaxBlockSize && data_addr.is_separate_file()) |
| 622 return false; | 640 return false; |
| 623 if (data_size > kMaxBlockSize && data_addr.is_block_file()) | 641 if (data_size > kMaxBlockSize && data_addr.is_block_file()) |
| 624 return false; | 642 return false; |
| 625 } | 643 } |
| 644 return true; |
| 645 } |
| 626 | 646 |
| 627 return true; | 647 void EntryImpl::FixForDelete() { |
| 648 EntryStore* stored = entry_.Data(); |
| 649 Addr key_addr(stored->long_key); |
| 650 |
| 651 if (!key_addr.is_initialized()) |
| 652 stored->key[stored->key_len] = '\0'; |
| 653 |
| 654 for (int i = 0; i < kNumStreams; i++) { |
| 655 Addr data_addr(stored->data_addr[i]); |
| 656 int data_size = stored->data_size[i]; |
| 657 if (data_addr.is_initialized()) { |
| 658 if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) || |
| 659 (data_size > kMaxBlockSize && data_addr.is_block_file()) || |
| 660 !data_addr.SanityCheck()) { |
| 661 // The address is weird so don't attempt to delete it. |
| 662 stored->data_addr[i] = 0; |
| 663 // In general, trust the stored size as it should be in sync with the |
| 664 // total size tracked by the backend. |
| 665 } |
| 666 } |
| 667 if (data_size < 0) |
| 668 stored->data_size[i] = 0; |
| 669 } |
| 670 entry_.Store(); |
| 628 } | 671 } |
| 629 | 672 |
| 630 void EntryImpl::IncrementIoCount() { | 673 void EntryImpl::IncrementIoCount() { |
| 631 backend_->IncrementIoCount(); | 674 backend_->IncrementIoCount(); |
| 632 } | 675 } |
| 633 | 676 |
| 634 void EntryImpl::DecrementIoCount() { | 677 void EntryImpl::DecrementIoCount() { |
| 635 backend_->DecrementIoCount(); | 678 backend_->DecrementIoCount(); |
| 636 } | 679 } |
| 637 | 680 |
| (...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), | 1469 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), |
| 1427 entry_.address().value(), node_.address().value()); | 1470 entry_.address().value(), node_.address().value()); |
| 1428 | 1471 |
| 1429 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 1472 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
| 1430 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 1473 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
| 1431 | 1474 |
| 1432 Trace(" doomed: %d 0x%x", doomed_, dirty); | 1475 Trace(" doomed: %d 0x%x", doomed_, dirty); |
| 1433 } | 1476 } |
| 1434 | 1477 |
| 1435 } // namespace disk_cache | 1478 } // namespace disk_cache |
| OLD | NEW |