Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Unified Diff: net/disk_cache/rankings.cc

Issue 10148001: Disk Cache: Add more corruption tracking histograms. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« net/disk_cache/rankings.h ('K') | « net/disk_cache/rankings.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/disk_cache/rankings.cc
===================================================================
--- net/disk_cache/rankings.cc (revision 133063)
+++ net/disk_cache/rankings.cc (working copy)
@@ -724,14 +724,6 @@
control_data_->operation = 0;
}
-bool Rankings::CheckEntry(CacheRankingsBlock* rankings) {
- if (rankings->VerifyHash())
- return true;
-
- // If this entry is not dirty, it is a serious problem.
- return backend_->GetCurrentEntryId() != rankings->Data()->dirty;
-}
-
bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev,
CacheRankingsBlock* next, List* list) {
CacheAddr node_addr = node->address().value();
@@ -787,44 +779,119 @@
}
int Rankings::CheckList(List list) {
- Addr& my_head = heads_[list];
- Addr& my_tail = tails_[list];
- if (!my_head.is_initialized()) {
- if (!my_tail.is_initialized())
- return 0;
- // If there is no head, having a tail is an error.
- return ERR_INVALID_TAIL;
+ Addr last1, last2;
+ int num_items;
+ int rv = CheckListSection(list, last1, last2, FORWARD,
+ &last1, &last2, &num_items);
+ if (rv == 0)
+ return num_items;
+
+ Addr last3, last4;
gavinp 2012/04/26 15:46:54 Don't we mean "first" and "second" here?
rvargas (doing something else) 2012/04/27 00:18:10 I'm sorry I don't follow you here. What is first a
gavinp 2012/04/30 18:57:15 If I'm moving backwards, then when I reach the end
rvargas (doing something else) 2012/04/30 22:03:00 sort of... but that would confuse me. The returned
+ int num_items2;
gavinp 2012/04/26 15:46:54 num_items_backwards ?
+ int rv2 = CheckListSection(list, last1, last2, BACKWARD,
+ &last3, &last4, &num_items2);
+
+ if (!num_items && rv != ERR_INVALID_NEXT)
+ rv = ERR_INVALID_HEAD;
+
+ if (!num_items2 && rv2 != ERR_INVALID_NEXT)
+ rv2 = ERR_INVALID_HEAD;
+
+ int expected = control_data_->sizes[list];
+ int total_items = num_items + num_items2;
+
+ if (!count_lists_) {
+ // There's no expected value, so we'll use something else.
gavinp 2012/04/26 15:46:54 So, if the second element is the last element or t
rvargas (doing something else) 2012/04/27 00:18:10 Not an exact science, but if the two searches over
+ if (last3 == last1 || last3 == last2 || last4 == last1 || last4 == last2)
+ expected = total_items + 1;
}
- // If there is no tail, having a head is an error.
- if (!my_tail.is_initialized())
- return ERR_INVALID_HEAD;
- if (my_tail.is_separate_file())
- return ERR_INVALID_TAIL;
+ if (expected) {
+ // This histogram has an offset so that we can see small negative values. In
+ // practice, it is linear from -9 to +8.
+ UMA_HISTOGRAM_CUSTOM_COUNTS("DiskCache.LostItems",
gavinp 2012/04/26 15:46:54 So if I understand the comment, the range is -9 t
rvargas (doing something else) 2012/04/27 00:18:10 Nope. IMO, the histogram ranges (log ones) are kin
gavinp 2012/04/30 18:57:15 Aha! This is right on the cusp (so it's probably
rvargas (doing something else) 2012/04/30 22:03:00 Note that I'm actually happy with the usual 50 buc
+ expected - total_items + 10, 0, 2000, 75);
+ }
- if (my_head.is_separate_file())
+ const int kInvalidHead = 1;
+ const int kInvalidTail = 2;
+ const int kInvalidHeadAndTail = 3;
+ const int kOneInvalidEntry = 4;
+ const int kTwoInvalidEntries = 5;
+ const int kOneInvalidLink = 6;
+ const int kTwoInvalidLinks = 7;
+ const int kOneInvalidEntryOneInvalidLink = 8;
+
+ int error = list * 10;
gavinp 2012/04/26 15:46:54 10? And not 9?
rvargas (doing something else) 2012/04/27 00:18:10 I'm going for something that is easier to read (wh
gavinp 2012/04/30 18:57:15 Yeah, I thought as much. It's a shame we can't pu
rvargas (doing something else) 2012/04/30 22:03:00 I was thinking over lunch.. sure, ...ErrorWithList
+ if (rv == ERR_INVALID_HEAD && rv2 != ERR_INVALID_HEAD) {
+ error += kInvalidHead;
+ } else if (rv == ERR_INVALID_HEAD && rv2 == ERR_INVALID_HEAD) {
+ error += kInvalidHeadAndTail;
+ } else if (rv != ERR_INVALID_HEAD && rv2 == ERR_INVALID_HEAD) {
+ error += kInvalidTail;
+ } else if (rv == ERR_INVALID_ENTRY && rv2 == ERR_INVALID_ENTRY) {
+ error += kTwoInvalidEntries;
+ } else if (rv == ERR_INVALID_ENTRY && rv2 == 0) {
+ error += kOneInvalidEntry;
+ } else if (rv == ERR_INVALID_ENTRY || rv2 == ERR_INVALID_ENTRY) {
+ error += kOneInvalidEntryOneInvalidLink;
+ } else if (rv2 != 0) {
+ error += kTwoInvalidLinks;
+ } else {
+ error += kOneInvalidLink;
+ }
+ CACHE_UMA(CACHE_ERROR, "ListError", 0, error);
gavinp 2012/04/26 15:46:54 "ListTypeAndError" ??
rvargas (doing something else) 2012/04/27 00:18:10 ListType sounds unrelated to ListError, so ListTyp
+
+ return rv;
+}
+
+// Note that the returned error codes assume a forward walk (from head to tail)
+// so they have to be adjusted accordingly by the caller. We use two stop values
+// to be able to detect a corrupt node at the end that is not linked going back.
+int Rankings::CheckListSection(List list, Addr stop1, Addr stop2,
+ ListDirection dir,
+ Addr* last1, Addr* last2, int* num_items) {
+ Addr current = (dir == FORWARD) ? heads_[list] : tails_[list];
+ *last1 = *last2 = current;
+ *num_items = 0;
+ if (!current.is_initialized())
+ return 0;
+
+ if (!current.SanityCheckForRankings())
return ERR_INVALID_HEAD;
- int num_items = 0;
- Addr address(my_head.value());
- Addr prev(my_head.value());
scoped_ptr<CacheRankingsBlock> node;
+ Addr prev_addr(current);
do {
- node.reset(new CacheRankingsBlock(backend_->File(address), address));
+ node.reset(new CacheRankingsBlock(backend_->File(current), current));
node->Load();
- if (node->Data()->prev != prev.value())
- return ERR_INVALID_PREV;
- if (!CheckEntry(node.get()))
+ if (!SanityCheck(node.get(), true))
return ERR_INVALID_ENTRY;
- prev.set_value(address.value());
- address.set_value(node->Data()->next);
- if (!address.is_initialized() || address.is_separate_file())
+ CacheAddr next = (dir == FORWARD) ? node->Data()->next : node->Data()->prev;
gavinp 2012/04/26 15:46:54 This is really pessimal, including dir == FORWARD
rvargas (doing something else) 2012/04/27 00:18:10 This is getting ridiculous. The natural value is b
gavinp 2012/04/30 18:57:15 OK, so what motivates me on this is that I want ca
rvargas (doing something else) 2012/04/30 22:03:00 as you wish. On 2012/04/30 18:57:15, gavinp wrote
+ CacheAddr prev = (dir == FORWARD) ? node->Data()->prev : node->Data()->next;
+
+ if (prev != prev_addr.value())
+ return ERR_INVALID_PREV;
+
+ Addr next_addr(next);
+ if (!next_addr.SanityCheckForRankings())
return ERR_INVALID_NEXT;
- num_items++;
- } while (node->address().value() != address.value());
- return num_items;
+ prev_addr = current;
+ current = next_addr;
+ *last2 = *last1;
+ *last1 = current;
+ (*num_items)++;
+
+ if (next_addr == prev_addr) {
+ Addr last = (dir == FORWARD) ? tails_[list] : heads_[list];
+ if (next_addr == last)
+ return 0;
+ return ERR_INVALID_TAIL;
+ }
+ } while (current != stop1 && current != stop2);
+ return 0;
gavinp 2012/04/26 15:46:54 return OK;
}
bool Rankings::IsHead(CacheAddr addr, List* list) const {
« net/disk_cache/rankings.h ('K') | « net/disk_cache/rankings.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698