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

Side by Side Diff: content/browser/cache_storage/cache_storage.cc

Issue 2186433004: [CacheStorage] Deleting a cache could delete the wrong directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix1
Patch Set: Nit Created 4 years, 4 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 unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/cache_storage/cache_storage_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/cache_storage/cache_storage.h" 5 #include "content/browser/cache_storage/cache_storage.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // load the backend, that happens lazily when the cache is used. 106 // load the backend, that happens lazily when the cache is used.
107 virtual std::unique_ptr<CacheStorageCache> CreateCache( 107 virtual std::unique_ptr<CacheStorageCache> CreateCache(
108 const std::string& cache_name) = 0; 108 const std::string& cache_name) = 0;
109 109
110 // Deletes any pre-existing cache of the same name and then loads it. 110 // Deletes any pre-existing cache of the same name and then loads it.
111 virtual void PrepareNewCacheDestination(const std::string& cache_name, 111 virtual void PrepareNewCacheDestination(const std::string& cache_name,
112 const CacheCallback& callback) = 0; 112 const CacheCallback& callback) = 0;
113 113
114 // After the backend has been deleted, do any extra house keeping such as 114 // After the backend has been deleted, do any extra house keeping such as
115 // removing the cache's directory. 115 // removing the cache's directory.
116 virtual void CleanUpDeletedCache(const std::string& key) = 0; 116 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0;
117 117
118 // Writes the cache names (and sizes) to disk if applicable. 118 // Writes the cache names (and sizes) to disk if applicable.
119 virtual void WriteIndex(const StringVector& cache_names, 119 virtual void WriteIndex(const StringVector& cache_names,
120 const BoolCallback& callback) = 0; 120 const BoolCallback& callback) = 0;
121 121
122 // Loads the cache names from disk if applicable. 122 // Loads the cache names from disk if applicable.
123 virtual void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, 123 virtual void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names,
124 const StringVectorCallback& callback) = 0; 124 const StringVectorCallback& callback) = 0;
125 125
126 // Called when CacheStorage has created a cache. Used to hold onto a handle to 126 // Called when CacheStorage has created a cache. Used to hold onto a handle to
127 // the cache if necessary. 127 // the cache if necessary.
128 virtual void NotifyCacheCreated( 128 virtual void NotifyCacheCreated(
129 const std::string& cache_name, 129 const std::string& cache_name,
130 std::unique_ptr<CacheStorageCacheHandle> cache_handle){}; 130 std::unique_ptr<CacheStorageCacheHandle> cache_handle){};
jsbell 2016/07/26 17:43:01 nit: space between () and {}
jkarlin 2016/07/26 17:50:21 Looks like a clang-format bug. Filed https://crbug
131 131
132 // Notification that a cache has been doomed and will be deleted once the last 132 // Notification that the cache for |cache_handle| has been doomed. If the
133 // cache handle has been dropped. If the loader is holding a handle to the 133 // loader is holding a handle to the cache, it should drop it now.
134 // cache, it should drop it now. 134 virtual void NotifyCacheDoomed(
135 virtual void NotifyCacheDoomed(const std::string& cache_name){}; 135 std::unique_ptr<CacheStorageCacheHandle> cache_handle){};
jsbell 2016/07/26 17:43:01 ditto
jkarlin 2016/07/26 17:50:21 Done.
136 136
137 protected: 137 protected:
138 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; 138 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
139 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 139 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
140 140
141 // Owned by CacheStorage which owns this. 141 // Owned by CacheStorage which owns this.
142 storage::QuotaManagerProxy* quota_manager_proxy_; 142 storage::QuotaManagerProxy* quota_manager_proxy_;
143 143
144 base::WeakPtr<storage::BlobStorageContext> blob_context_; 144 base::WeakPtr<storage::BlobStorageContext> blob_context_;
145 145
(...skipping 28 matching lines...) Expand all
174 origin_, cache_name, cache_storage_, request_context_getter_, 174 origin_, cache_name, cache_storage_, request_context_getter_,
175 quota_manager_proxy_, blob_context_); 175 quota_manager_proxy_, blob_context_);
176 } 176 }
177 177
178 void PrepareNewCacheDestination(const std::string& cache_name, 178 void PrepareNewCacheDestination(const std::string& cache_name,
179 const CacheCallback& callback) override { 179 const CacheCallback& callback) override {
180 std::unique_ptr<CacheStorageCache> cache = CreateCache(cache_name); 180 std::unique_ptr<CacheStorageCache> cache = CreateCache(cache_name);
181 callback.Run(std::move(cache)); 181 callback.Run(std::move(cache));
182 } 182 }
183 183
184 void CleanUpDeletedCache(const std::string& cache_name) override { 184 void CleanUpDeletedCache(CacheStorageCache* cache) override {}
185 }
186 185
187 void WriteIndex(const StringVector& cache_names, 186 void WriteIndex(const StringVector& cache_names,
188 const BoolCallback& callback) override { 187 const BoolCallback& callback) override {
189 callback.Run(true); 188 callback.Run(true);
190 } 189 }
191 190
192 void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, 191 void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names,
193 const StringVectorCallback& callback) override { 192 const StringVectorCallback& callback) override {
194 callback.Run(std::move(cache_names)); 193 callback.Run(std::move(cache_names));
195 } 194 }
196 195
197 void NotifyCacheCreated( 196 void NotifyCacheCreated(
198 const std::string& cache_name, 197 const std::string& cache_name,
199 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { 198 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
200 DCHECK(!ContainsKey(cache_handles_, cache_name)); 199 DCHECK(!ContainsKey(cache_handles_, cache_name));
201 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); 200 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle)));
202 }; 201 };
203 202
204 void NotifyCacheDoomed(const std::string& cache_name) override { 203 void NotifyCacheDoomed(
205 DCHECK(ContainsKey(cache_handles_, cache_name)); 204 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
206 cache_handles_.erase(cache_name); 205 DCHECK(ContainsKey(cache_handles_, cache_handle->value()->cache_name()));
206 cache_handles_.erase(cache_handle->value()->cache_name());
207 }; 207 };
208 208
209 private: 209 private:
210 typedef std::map<std::string, std::unique_ptr<CacheStorageCacheHandle>> 210 typedef std::map<std::string, std::unique_ptr<CacheStorageCacheHandle>>
211 CacheHandles; 211 CacheHandles;
212 ~MemoryLoader() override {} 212 ~MemoryLoader() override {}
213 213
214 // Keep a reference to each cache to ensure that it's not freed before the 214 // Keep a reference to each cache to ensure that it's not freed before the
215 // client calls CacheStorage::Delete or the CacheStorage is 215 // client calls CacheStorage::Delete or the CacheStorage is
216 // freed. 216 // freed.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 const std::string& cache_dir) { 277 const std::string& cache_dir) {
278 if (cache_dir.empty()) { 278 if (cache_dir.empty()) {
279 callback.Run(std::unique_ptr<CacheStorageCache>()); 279 callback.Run(std::unique_ptr<CacheStorageCache>());
280 return; 280 return;
281 } 281 }
282 282
283 cache_name_to_cache_dir_[cache_name] = cache_dir; 283 cache_name_to_cache_dir_[cache_name] = cache_dir;
284 callback.Run(CreateCache(cache_name)); 284 callback.Run(CreateCache(cache_name));
285 } 285 }
286 286
287 void CleanUpDeletedCache(const std::string& cache_name) override { 287 void CleanUpDeletedCache(CacheStorageCache* cache) override {
288 DCHECK_CURRENTLY_ON(BrowserThread::IO); 288 DCHECK_CURRENTLY_ON(BrowserThread::IO);
289 DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_name)); 289 DCHECK(ContainsKey(doomed_cache_to_path_, cache));
290 290
291 base::FilePath cache_path = 291 base::FilePath cache_path =
292 origin_path_.AppendASCII(cache_name_to_cache_dir_[cache_name]); 292 origin_path_.AppendASCII(doomed_cache_to_path_[cache]);
293 cache_name_to_cache_dir_.erase(cache_name); 293 doomed_cache_to_path_.erase(cache);
294 294
295 cache_task_runner_->PostTask( 295 cache_task_runner_->PostTask(
296 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, 296 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool,
297 cache_path)); 297 cache_path));
298 } 298 }
299 299
300 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { 300 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) {
301 base::DeleteFile(cache_path, true /* recursive */); 301 base::DeleteFile(cache_path, true /* recursive */);
302 } 302 }
303 303
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 cache_dirs->insert(cache.cache_dir()); 383 cache_dirs->insert(cache.cache_dir());
384 } 384 }
385 } 385 }
386 386
387 cache_task_runner_->PostTask( 387 cache_task_runner_->PostTask(
388 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, 388 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_,
389 base::Passed(&cache_dirs))); 389 base::Passed(&cache_dirs)));
390 callback.Run(std::move(names)); 390 callback.Run(std::move(names));
391 } 391 }
392 392
393 void NotifyCacheDoomed(
394 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
395 DCHECK(ContainsKey(cache_name_to_cache_dir_,
396 cache_handle->value()->cache_name()));
397 auto iter =
398 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name());
399 doomed_cache_to_path_[cache_handle->value()] = iter->second;
400 cache_name_to_cache_dir_.erase(iter);
401 };
402
393 private: 403 private:
394 friend class MigratedLegacyCacheDirectoryNameTest; 404 friend class MigratedLegacyCacheDirectoryNameTest;
395 ~SimpleCacheLoader() override {} 405 ~SimpleCacheLoader() override {}
396 406
397 // Iterates over the caches and deletes any directory not found in 407 // Iterates over the caches and deletes any directory not found in
398 // |cache_dirs|. Runs on cache_task_runner_ 408 // |cache_dirs|. Runs on cache_task_runner_
399 static void DeleteUnreferencedCachesInPool( 409 static void DeleteUnreferencedCachesInPool(
400 const base::FilePath& cache_base_dir, 410 const base::FilePath& cache_base_dir,
401 std::unique_ptr<std::set<std::string>> cache_dirs) { 411 std::unique_ptr<std::set<std::string>> cache_dirs) {
402 base::FileEnumerator file_enum(cache_base_dir, false /* recursive */, 412 base::FileEnumerator file_enum(cache_base_dir, false /* recursive */,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 static std::string ReadAndMigrateIndexInPool( 478 static std::string ReadAndMigrateIndexInPool(
469 const base::FilePath& index_path) { 479 const base::FilePath& index_path) {
470 std::string body; 480 std::string body;
471 base::ReadFileToString(index_path, &body); 481 base::ReadFileToString(index_path, &body);
472 482
473 return MigrateCachesIfNecessaryInPool(body, index_path); 483 return MigrateCachesIfNecessaryInPool(body, index_path);
474 } 484 }
475 485
476 const base::FilePath origin_path_; 486 const base::FilePath origin_path_;
477 std::map<std::string, std::string> cache_name_to_cache_dir_; 487 std::map<std::string, std::string> cache_name_to_cache_dir_;
488 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_;
478 489
479 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; 490 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_;
480 }; 491 };
481 492
482 CacheStorage::CacheStorage( 493 CacheStorage::CacheStorage(
483 const base::FilePath& path, 494 const base::FilePath& path,
484 bool memory_only, 495 bool memory_only,
485 base::SequencedTaskRunner* cache_task_runner, 496 base::SequencedTaskRunner* cache_task_runner,
486 scoped_refptr<net::URLRequestContextGetter> request_context, 497 scoped_refptr<net::URLRequestContextGetter> request_context,
487 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 498 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 bool success) { 788 bool success) {
778 DCHECK_CURRENTLY_ON(BrowserThread::IO); 789 DCHECK_CURRENTLY_ON(BrowserThread::IO);
779 790
780 if (!success) { 791 if (!success) {
781 // Undo any changes if the change couldn't be written to disk. 792 // Undo any changes if the change couldn't be written to disk.
782 ordered_cache_names_ = original_ordered_cache_names; 793 ordered_cache_names_ = original_ordered_cache_names;
783 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); 794 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE);
784 return; 795 return;
785 } 796 }
786 797
798 // Make sure that a cache handle exists for the doomed cache to ensure that
799 // DeleteCacheFinalize is called.
800 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
801 GetLoadedCache(cache_name);
802
787 CacheMap::iterator map_iter = cache_map_.find(cache_name); 803 CacheMap::iterator map_iter = cache_map_.find(cache_name);
788 doomed_caches_.insert( 804 doomed_caches_.insert(
789 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); 805 std::make_pair(map_iter->second.get(), std::move(map_iter->second)));
790 cache_map_.erase(map_iter); 806 cache_map_.erase(map_iter);
791 807
792 cache_loader_->NotifyCacheDoomed(cache_name); 808 cache_loader_->NotifyCacheDoomed(std::move(cache_handle));
793 809
794 callback.Run(true, CACHE_STORAGE_OK); 810 callback.Run(true, CACHE_STORAGE_OK);
795 } 811 }
796 812
797 // Call this once the last handle to a doomed cache is gone. It's okay if this 813 // Call this once the last handle to a doomed cache is gone. It's okay if this
798 // doesn't get to complete before shutdown, the cache will be removed from disk 814 // doesn't get to complete before shutdown, the cache will be removed from disk
799 // on next startup in that case. 815 // on next startup in that case.
800 void CacheStorage::DeleteCacheFinalize( 816 void CacheStorage::DeleteCacheFinalize(
801 std::unique_ptr<CacheStorageCache> doomed_cache) { 817 std::unique_ptr<CacheStorageCache> doomed_cache) {
802 CacheStorageCache* cache = doomed_cache.get(); 818 CacheStorageCache* cache = doomed_cache.get();
803 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, 819 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize,
804 weak_factory_.GetWeakPtr(), 820 weak_factory_.GetWeakPtr(),
805 base::Passed(std::move(doomed_cache)))); 821 base::Passed(std::move(doomed_cache))));
806 } 822 }
807 823
808 void CacheStorage::DeleteCacheDidGetSize( 824 void CacheStorage::DeleteCacheDidGetSize(
809 std::unique_ptr<CacheStorageCache> cache, 825 std::unique_ptr<CacheStorageCache> cache,
810 int64_t cache_size) { 826 int64_t cache_size) {
811 quota_manager_proxy_->NotifyStorageModified( 827 quota_manager_proxy_->NotifyStorageModified(
812 storage::QuotaClient::kServiceWorkerCache, origin_, 828 storage::QuotaClient::kServiceWorkerCache, origin_,
813 storage::kStorageTypeTemporary, -1 * cache_size); 829 storage::kStorageTypeTemporary, -1 * cache_size);
814 830
815 cache_loader_->CleanUpDeletedCache(cache->cache_name()); 831 cache_loader_->CleanUpDeletedCache(cache.get());
816 } 832 }
817 833
818 void CacheStorage::EnumerateCachesImpl( 834 void CacheStorage::EnumerateCachesImpl(
819 const StringsAndErrorCallback& callback) { 835 const StringsAndErrorCallback& callback) {
820 callback.Run(ordered_cache_names_, CACHE_STORAGE_OK); 836 callback.Run(ordered_cache_names_, CACHE_STORAGE_OK);
821 } 837 }
822 838
823 void CacheStorage::MatchCacheImpl( 839 void CacheStorage::MatchCacheImpl(
824 const std::string& cache_name, 840 const std::string& cache_name,
825 std::unique_ptr<ServiceWorkerFetchRequest> request, 841 std::unique_ptr<ServiceWorkerFetchRequest> request,
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 1027 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
1012 GetLoadedCache(cache_name); 1028 GetLoadedCache(cache_name);
1013 CacheStorageCache* cache = cache_handle->value(); 1029 CacheStorageCache* cache = cache_handle->value();
1014 cache->Size(base::Bind(&SizeRetrievedFromCache, 1030 cache->Size(base::Bind(&SizeRetrievedFromCache,
1015 base::Passed(std::move(cache_handle)), 1031 base::Passed(std::move(cache_handle)),
1016 barrier_closure, accumulator_ptr)); 1032 barrier_closure, accumulator_ptr));
1017 } 1033 }
1018 } 1034 }
1019 1035
1020 } // namespace content 1036 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/cache_storage/cache_storage_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698