Index: net/disk_cache/entry_impl.cc |
=================================================================== |
--- net/disk_cache/entry_impl.cc (revision 102424) |
+++ net/disk_cache/entry_impl.cc (working copy) |
@@ -496,17 +496,17 @@ |
// Remove all traces of this entry. |
backend_->RemoveEntry(this); |
+ // Note that at this point node_ and entry_ are just two blocks of data, and |
+ // even if they reference each other, nobody should be referencing them. |
+ |
Addr address(entry_.Data()->long_key); |
DeleteData(address, kKeyFileIndex); |
backend_->ModifyStorageSize(entry_.Data()->key_len, 0); |
- memset(node_.buffer(), 0, node_.size()); |
- memset(entry_.buffer(), 0, entry_.size()); |
- node_.Store(); |
- entry_.Store(); |
+ backend_->DeleteBlock(entry_.address(), true); |
- backend_->DeleteBlock(node_.address(), false); |
- backend_->DeleteBlock(entry_.address(), false); |
+ if (!LeaveRankingsBehind()) |
+ backend_->DeleteBlock(node_.address(), true); |
} |
CacheAddr EntryImpl::GetNextAddress() { |
@@ -551,6 +551,9 @@ |
if (node_.Data()->dirty && current_id != node_.Data()->dirty) |
dirty_ = true; |
+ |
+ if (!current_id) |
+ dirty_ = true; |
} |
void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { |
@@ -559,6 +562,14 @@ |
node_.Store(); |
} |
+bool EntryImpl::LeaveRankingsBehind() { |
+ return !node_.Data()->contents; |
+} |
+ |
+// This only includes checks that relate to the first block of the entry (the |
+// first 256 bytes), and values that should be set from the entry creation. |
+// Basically, even if there is something wrong with this entry, we want to see |
+// if it is possible to load the rankings node and delete them together. |
bool EntryImpl::SanityCheck() { |
EntryStore* stored = entry_.Data(); |
if (!stored->rankings_node || stored->key_len <= 0) |
@@ -569,7 +580,7 @@ |
Addr rankings_addr(stored->rankings_node); |
if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || |
- rankings_addr.file_type() != RANKINGS) |
+ rankings_addr.file_type() != RANKINGS || rankings_addr.num_blocks() != 1) |
return false; |
Addr next_addr(stored->next); |
@@ -600,6 +611,13 @@ |
if (entry_.address().num_blocks() != num_blocks) |
return false; |
+ return true; |
+} |
+ |
+bool EntryImpl::DataSanityCheck() { |
+ EntryStore* stored = entry_.Data(); |
+ Addr key_addr(stored->long_key); |
+ |
// The key must be NULL terminated. |
if (!key_addr.is_initialized() && stored->key[stored->key_len]) |
return false; |
@@ -623,10 +641,35 @@ |
if (data_size > kMaxBlockSize && data_addr.is_block_file()) |
return false; |
} |
- |
return true; |
} |
+void EntryImpl::FixForDelete() { |
+ EntryStore* stored = entry_.Data(); |
+ Addr key_addr(stored->long_key); |
+ |
+ if (!key_addr.is_initialized()) |
+ stored->key[stored->key_len] = '\0'; |
+ |
+ for (int i = 0; i < kNumStreams; i++) { |
+ Addr data_addr(stored->data_addr[i]); |
+ int data_size = stored->data_size[i]; |
+ if (data_addr.is_initialized()) { |
+ if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) || |
+ (data_size > kMaxBlockSize && data_addr.is_block_file()) || |
+ !data_addr.SanityCheck()) { |
+ // The address is weird so don't attempt to delete it. |
+ stored->data_addr[i] = 0; |
+ // In general, trust the stored size as it should be in sync with the |
+ // total size tracked by the backend. |
+ } |
+ } |
+ if (data_size < 0) |
+ stored->data_size[i] = 0; |
+ } |
+ entry_.Store(); |
+} |
+ |
void EntryImpl::IncrementIoCount() { |
backend_->IncrementIoCount(); |
} |