OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/storage_partition_impl_map.h" | 5 #include "content/browser/storage_partition_impl_map.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 // |valid_paths_to_keep|. | 259 // |valid_paths_to_keep|. |
260 std::vector<base::FilePath> paths_to_consider; | 260 std::vector<base::FilePath> paths_to_consider; |
261 paths_to_consider.push_back(root); | 261 paths_to_consider.push_back(root); |
262 while(!paths_to_consider.empty()) { | 262 while(!paths_to_consider.empty()) { |
263 base::FilePath path = paths_to_consider.back(); | 263 base::FilePath path = paths_to_consider.back(); |
264 paths_to_consider.pop_back(); | 264 paths_to_consider.pop_back(); |
265 ObliterateOneDirectory(path, valid_paths_to_keep, &paths_to_consider); | 265 ObliterateOneDirectory(path, valid_paths_to_keep, &paths_to_consider); |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
| 269 // Ensures each path in |active_paths| is a direct child of storage_root. |
| 270 void NormalizeActivePaths(const base::FilePath& storage_root, |
| 271 base::hash_set<base::FilePath>* active_paths) { |
| 272 base::hash_set<base::FilePath> normalized_active_paths; |
| 273 |
| 274 for (base::hash_set<base::FilePath>::iterator iter = active_paths->begin(); |
| 275 iter != active_paths->end(); ++iter) { |
| 276 base::FilePath relative_path; |
| 277 if (!storage_root.AppendRelativePath(*iter, &relative_path)) |
| 278 continue; |
| 279 |
| 280 std::vector<base::FilePath::StringType> components; |
| 281 relative_path.GetComponents(&components); |
| 282 |
| 283 DCHECK(!relative_path.empty()); |
| 284 normalized_active_paths.insert(storage_root.Append(components.front())); |
| 285 } |
| 286 |
| 287 active_paths->swap(normalized_active_paths); |
| 288 } |
| 289 |
269 // Deletes all entries inside the |storage_root| that are not in the | 290 // Deletes all entries inside the |storage_root| that are not in the |
270 // |active_paths|. Deletion is done in 2 steps: | 291 // |active_paths|. Deletion is done in 2 steps: |
271 // | 292 // |
272 // (1) Moving all garbage collected paths into a trash directory. | 293 // (1) Moving all garbage collected paths into a trash directory. |
273 // (2) Asynchronously deleting the trash directory. | 294 // (2) Asynchronously deleting the trash directory. |
274 // | 295 // |
275 // The deletion is asynchronous because after (1) completes, calling code can | 296 // The deletion is asynchronous because after (1) completes, calling code can |
276 // safely continue to use the paths that had just been garbage collected | 297 // safely continue to use the paths that had just been garbage collected |
277 // without fear of race conditions. | 298 // without fear of race conditions. |
278 // | 299 // |
279 // This code also ignores failed moves rather than attempting a smarter retry. | 300 // This code also ignores failed moves rather than attempting a smarter retry. |
280 // Moves shouldn't fail here unless there is some out-of-band error (eg., | 301 // Moves shouldn't fail here unless there is some out-of-band error (eg., |
281 // FS corruption). Retry logic is dangerous in the general case because | 302 // FS corruption). Retry logic is dangerous in the general case because |
282 // there is not necessarily a guaranteed case where the logic may succeed. | 303 // there is not necessarily a guaranteed case where the logic may succeed. |
283 // | 304 // |
284 // This function is still named BlockingGarbageCollect() because it does | 305 // This function is still named BlockingGarbageCollect() because it does |
285 // execute a few filesystem operations synchronously. | 306 // execute a few filesystem operations synchronously. |
286 void BlockingGarbageCollect( | 307 void BlockingGarbageCollect( |
287 const base::FilePath& storage_root, | 308 const base::FilePath& storage_root, |
288 const scoped_refptr<base::TaskRunner>& file_access_runner, | 309 const scoped_refptr<base::TaskRunner>& file_access_runner, |
289 scoped_ptr<base::hash_set<base::FilePath> > active_paths) { | 310 scoped_ptr<base::hash_set<base::FilePath> > active_paths) { |
290 CHECK(storage_root.IsAbsolute()); | 311 CHECK(storage_root.IsAbsolute()); |
291 | 312 |
| 313 NormalizeActivePaths(storage_root, active_paths.get()); |
| 314 |
292 base::FileEnumerator enumerator(storage_root, false, kAllFileTypes); | 315 base::FileEnumerator enumerator(storage_root, false, kAllFileTypes); |
293 base::FilePath trash_directory; | 316 base::FilePath trash_directory; |
294 if (!base::CreateTemporaryDirInDir(storage_root, kTrashDirname, | 317 if (!base::CreateTemporaryDirInDir(storage_root, kTrashDirname, |
295 &trash_directory)) { | 318 &trash_directory)) { |
296 // Unable to continue without creating the trash directory so give up. | 319 // Unable to continue without creating the trash directory so give up. |
297 return; | 320 return; |
298 } | 321 } |
299 for (base::FilePath path = enumerator.Next(); !path.empty(); | 322 for (base::FilePath path = enumerator.Next(); !path.empty(); |
300 path = enumerator.Next()) { | 323 path = enumerator.Next()) { |
301 if (active_paths->find(path) == active_paths->end() && | 324 if (active_paths->find(path) == active_paths->end() && |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 | 584 |
562 // We do not call InitializeURLRequestContext() for media contexts because, | 585 // We do not call InitializeURLRequestContext() for media contexts because, |
563 // other than the HTTP cache, the media contexts share the same backing | 586 // other than the HTTP cache, the media contexts share the same backing |
564 // objects as their associated "normal" request context. Thus, the previous | 587 // objects as their associated "normal" request context. Thus, the previous |
565 // call serves to initialize the media request context for this storage | 588 // call serves to initialize the media request context for this storage |
566 // partition as well. | 589 // partition as well. |
567 } | 590 } |
568 } | 591 } |
569 | 592 |
570 } // namespace content | 593 } // namespace content |
OLD | NEW |