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/rankings.h" | 5 #include "net/disk_cache/rankings.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "net/disk_cache/backend_impl.h" | 8 #include "net/disk_cache/backend_impl.h" |
9 #include "net/disk_cache/entry_impl.h" | 9 #include "net/disk_cache/entry_impl.h" |
10 #include "net/disk_cache/errors.h" | 10 #include "net/disk_cache/errors.h" |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 for (int i = 0; i < LAST_ELEMENT; i++) { | 487 for (int i = 0; i < LAST_ELEMENT; i++) { |
488 int partial = CheckList(static_cast<List>(i)); | 488 int partial = CheckList(static_cast<List>(i)); |
489 if (partial < 0) | 489 if (partial < 0) |
490 return partial; | 490 return partial; |
491 total += partial; | 491 total += partial; |
492 } | 492 } |
493 return total; | 493 return total; |
494 } | 494 } |
495 | 495 |
496 bool Rankings::SanityCheck(CacheRankingsBlock* node, bool from_list) const { | 496 bool Rankings::SanityCheck(CacheRankingsBlock* node, bool from_list) const { |
| 497 if (!node->VerifyHash()) |
| 498 return false; |
| 499 |
497 const RankingsNode* data = node->Data(); | 500 const RankingsNode* data = node->Data(); |
498 | 501 |
499 if ((!data->next && data->prev) || (data->next && !data->prev)) | 502 if ((!data->next && data->prev) || (data->next && !data->prev)) |
500 return false; | 503 return false; |
501 | 504 |
502 // Both pointers on zero is a node out of the list. | 505 // Both pointers on zero is a node out of the list. |
503 if (!data->next && !data->prev && from_list) | 506 if (!data->next && !data->prev && from_list) |
504 return false; | 507 return false; |
505 | 508 |
506 List list = NO_USE; // Initialize it to something. | 509 List list = NO_USE; // Initialize it to something. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 if (!rankings->Load()) | 568 if (!rankings->Load()) |
566 return false; | 569 return false; |
567 | 570 |
568 if (!SanityCheck(rankings, true)) { | 571 if (!SanityCheck(rankings, true)) { |
569 backend_->CriticalError(ERR_INVALID_LINKS); | 572 backend_->CriticalError(ERR_INVALID_LINKS); |
570 return false; | 573 return false; |
571 } | 574 } |
572 | 575 |
573 backend_->OnEvent(Stats::OPEN_RANKINGS); | 576 backend_->OnEvent(Stats::OPEN_RANKINGS); |
574 | 577 |
575 // "dummy" is the old "pointer" value, so it has to be 0. | 578 if (!rankings->Data()->dirty) |
576 if (!rankings->Data()->dirty && !rankings->Data()->dummy) | |
577 return true; | 579 return true; |
578 | 580 |
579 EntryImpl* entry = backend_->GetOpenEntry(rankings); | 581 EntryImpl* entry = backend_->GetOpenEntry(rankings); |
580 if (!entry) { | 582 if (!entry) { |
581 // We cannot trust this entry, but we cannot initiate a cleanup from this | 583 // We cannot trust this entry, but we cannot initiate a cleanup from this |
582 // point (we may be in the middle of a cleanup already). Just get rid of | 584 // point (we may be in the middle of a cleanup already). The entry will be |
583 // the invalid pointer and continue; the entry will be deleted when detected | 585 // deleted when detected from a regular open/create path. |
584 // from a regular open/create path. | |
585 rankings->Data()->dummy = 0; | |
586 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1; | 586 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1; |
587 if (!rankings->Data()->dirty) | 587 if (!rankings->Data()->dirty) |
588 rankings->Data()->dirty--; | 588 rankings->Data()->dirty--; |
589 return true; | 589 return true; |
590 } | 590 } |
591 | 591 |
592 // Note that we should not leave this module without deleting rankings first. | 592 // Note that we should not leave this module without deleting rankings first. |
593 rankings->SetData(entry->rankings()->Data()); | 593 rankings->SetData(entry->rankings()->Data()); |
594 | 594 |
595 CACHE_UMA(AGE_MS, "GetRankings", 0, start); | 595 CACHE_UMA(AGE_MS, "GetRankings", 0, start); |
(...skipping 20 matching lines...) Expand all Loading... |
616 LOG(ERROR) << "Invalid rankings info."; | 616 LOG(ERROR) << "Invalid rankings info."; |
617 return; | 617 return; |
618 } | 618 } |
619 | 619 |
620 Trace("CompleteTransaction 0x%x", node_addr.value()); | 620 Trace("CompleteTransaction 0x%x", node_addr.value()); |
621 | 621 |
622 CacheRankingsBlock node(backend_->File(node_addr), node_addr); | 622 CacheRankingsBlock node(backend_->File(node_addr), node_addr); |
623 if (!node.Load()) | 623 if (!node.Load()) |
624 return; | 624 return; |
625 | 625 |
626 node.Data()->dummy = 0; | |
627 node.Store(); | 626 node.Store(); |
628 | 627 |
629 Addr& my_head = heads_[control_data_->operation_list]; | 628 Addr& my_head = heads_[control_data_->operation_list]; |
630 Addr& my_tail = tails_[control_data_->operation_list]; | 629 Addr& my_tail = tails_[control_data_->operation_list]; |
631 | 630 |
632 // We want to leave the node inside the list. The entry must me marked as | 631 // We want to leave the node inside the list. The entry must me marked as |
633 // dirty, and will be removed later. Otherwise, we'll get assertions when | 632 // dirty, and will be removed later. Otherwise, we'll get assertions when |
634 // attempting to remove the dirty entry. | 633 // attempting to remove the dirty entry. |
635 if (INSERT == control_data_->operation) { | 634 if (INSERT == control_data_->operation) { |
636 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value()); | 635 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 WriteTail(my_list); | 712 WriteTail(my_list); |
714 } | 713 } |
715 | 714 |
716 next.Store(); | 715 next.Store(); |
717 prev.Store(); | 716 prev.Store(); |
718 control_data_->transaction = 0; | 717 control_data_->transaction = 0; |
719 control_data_->operation = 0; | 718 control_data_->operation = 0; |
720 } | 719 } |
721 | 720 |
722 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) { | 721 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) { |
723 if (!rankings->Data()->dummy) | 722 if (rankings->VerifyHash()) |
724 return true; | 723 return true; |
725 | 724 |
726 // If this entry is not dirty, it is a serious problem. | 725 // If this entry is not dirty, it is a serious problem. |
727 return backend_->GetCurrentEntryId() != rankings->Data()->dirty; | 726 return backend_->GetCurrentEntryId() != rankings->Data()->dirty; |
728 } | 727 } |
729 | 728 |
730 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, | 729 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, |
731 CacheRankingsBlock* next, List* list) { | 730 CacheRankingsBlock* next, List* list) { |
732 CacheAddr node_addr = node->address().value(); | 731 CacheAddr node_addr = node->address().value(); |
733 if (prev->Data()->next == node_addr && | 732 if (prev->Data()->next == node_addr && |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 void Rankings::DecrementCounter(List list) { | 882 void Rankings::DecrementCounter(List list) { |
884 if (!count_lists_) | 883 if (!count_lists_) |
885 return; | 884 return; |
886 | 885 |
887 DCHECK(control_data_->sizes[list] > 0); | 886 DCHECK(control_data_->sizes[list] > 0); |
888 if (control_data_->sizes[list] > 0) | 887 if (control_data_->sizes[list] > 0) |
889 control_data_->sizes[list]--; | 888 control_data_->sizes[list]--; |
890 } | 889 } |
891 | 890 |
892 } // namespace disk_cache | 891 } // namespace disk_cache |
OLD | NEW |