content/browser/storage_partition_impl_map.cc
// Deletes all entries inside the |storage_root| that are not in the
// |active_paths|.  Deletion is done in 2 steps:
//
//   (1) Moving all garbage collected paths into a trash directory.
//   (2) Asynchronously deleting the trash directory.
//
// The deletion is asynchronous because after (1) completes, calling code can
// safely continue to use the paths that had just been garbage collected
// without fear of race conditions.
//
// This code also ignores failed moves rather than attempting a smarter retry.
// Moves shouldn't fail here unless there is some out-of-band error (eg.,
// FS corruption). Retry logic is dangerous in the general case because
// there is not necessarily a guaranteed case where the logic may succeed.
//
// This function is still named BlockingGarbageCollect() because it does
// execute a few filesystem operations synchronously.
Deletes all entries inside the |storage_root| that are not in the
|active_paths|.  Deletion is done in 2 steps.

(1) Moving all garbage collected paths into a trash directory.
(2) Asynchronously deleting the trash directory.

The deletion is asynchronous because after (1) completes, calling code can
safely continue to use the paths that had just been garbage collected
without fear of race conditions.

This code also ignores failed moves rather than attempting a smarter retry.
Moves shouldn't fail here unless there is some out-of-band error . Retry logic is dangerous in the general case because
there is not necessarily a guaranteed case where the logic may succeed.

This function is still named BlockingGarbageCollect() because it does
execute a few filesystem operations synchronously.
Deletes all entries inside the |storage_root| that are not in the |active_paths| . Deletion is done in 2 steps . ( 1 ) Moving all garbage collected paths into a trash directory . ( 2 ) Asynchronously deleting the trash directory . The deletion is asynchronous because after ( 1 ) completes calling code can safely continue to use the paths that had just been garbage collected without fear of race conditions . This code also ignores failed moves rather than attempting a smarter retry . Moves shouldn ' t fail here unless there is some out - of - band error . Retry logic is dangerous in the general case because there is not necessarily a guaranteed case where the logic may succeed . This function is still named BlockingGarbageCollect () because it does execute a few filesystem operations synchronously .
void BlockingGarbageCollect(
    const FilePath& storage_root,
    const scoped_refptr<base::TaskRunner>& file_access_runner,
    scoped_ptr<base::hash_set<FilePath> > active_paths) {
  CHECK(storage_root.IsAbsolute());
  file_util::FileEnumerator enumerator(storage_root, false, kAllFileTypes);
  FilePath trash_directory;
  if (!file_util::CreateTemporaryDirInDir(storage_root, kTrashDirname,
                                          &trash_directory)) {
    return;
  }
  for (FilePath path = enumerator.Next(); !path.empty();
       path = enumerator.Next()) {
    if (active_paths->find(path) == active_paths->end() &&
        path != trash_directory) {
      file_util::Move(path, trash_directory.Append(path.BaseName()));
    }
  }
  file_access_runner->PostTask(
      FROM_HERE,
      base::Bind(base::IgnoreResult(&file_util::Delete), trash_directory,
                 true));
}
void BlockingGarbageCollect ( const FilePath & storage_root , const scoped_refptr < base :: TaskRunner > & file_access_runner , scoped_ptr < base :: hash_set < FilePath > > active_paths ) { CHECK ( storage_root . IsAbsolute ( ) ) ; file_util :: FileEnumerator enumerator ( storage_root , false , kAllFileTypes ) ; FilePath trash_directory ; if ( ! file_util :: CreateTemporaryDirInDir ( storage_root , kTrashDirname , & trash_directory ) ) { return ; } for ( FilePath path = enumerator . Next ( ) ; ! path . empty ( ) ; path = enumerator . Next ( ) ) { if ( active_paths -> find ( path ) == active_paths -> end ( ) && path != trash_directory ) { file_util :: Move ( path , trash_directory . Append ( path . BaseName ( ) ) ) ; } } file_access_runner -> PostTask ( FROM_HERE , base :: Bind ( base :: IgnoreResult ( & file_util :: Delete ) , trash_directory , true ) ) ; }
Deletes all entries inside the |storage_root| that are not in the
|active_paths|.
Deletes all entries inside the |storage_root| that are not in the |active_paths| .
// Unable to continue without creating the trash directory so give up. // Since |trash_directory| is unique for each run of this function there // can be no colllisions on the move.