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

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_file_system.cc

Issue 10116044: gdata: Support mounting archive files in GData cache. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: gdata: Support mounting archive files in GData cache. 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 unified diff | Download patch
OLDNEW
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 "chrome/browser/chromeos/gdata/gdata_file_system.h" 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include <set> 10 #include <set>
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 50
51 namespace gdata { 51 namespace gdata {
52 namespace { 52 namespace {
53 53
54 const char kMimeTypeJson[] = "application/json"; 54 const char kMimeTypeJson[] = "application/json";
55 const char kMimeTypeOctetStream[] = "application/octet-stream"; 55 const char kMimeTypeOctetStream[] = "application/octet-stream";
56 56
57 const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("gdata"); 57 const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("gdata");
58 const char kWildCard[] = "*"; 58 const char kWildCard[] = "*";
59 const char kLocallyModifiedFileExtension[] = "local"; 59 const char kLocallyModifiedFileExtension[] = "local";
60 const char kMountedArchiveFileExtension[] = "mounted";
60 61
61 const FilePath::CharType kGDataCacheVersionDir[] = FILE_PATH_LITERAL("v1"); 62 const FilePath::CharType kGDataCacheVersionDir[] = FILE_PATH_LITERAL("v1");
62 const FilePath::CharType kGDataCacheMetaDir[] = FILE_PATH_LITERAL("meta"); 63 const FilePath::CharType kGDataCacheMetaDir[] = FILE_PATH_LITERAL("meta");
63 const FilePath::CharType kGDataCachePinnedDir[] = FILE_PATH_LITERAL("pinned"); 64 const FilePath::CharType kGDataCachePinnedDir[] = FILE_PATH_LITERAL("pinned");
64 const FilePath::CharType kGDataCacheOutgoingDir[] = 65 const FilePath::CharType kGDataCacheOutgoingDir[] =
65 FILE_PATH_LITERAL("outgoing"); 66 FILE_PATH_LITERAL("outgoing");
66 const FilePath::CharType kGDataCachePersistentDir[] = 67 const FilePath::CharType kGDataCachePersistentDir[] =
67 FILE_PATH_LITERAL("persistent"); 68 FILE_PATH_LITERAL("persistent");
68 const FilePath::CharType kGDataCacheTmpDir[] = FILE_PATH_LITERAL("tmp"); 69 const FilePath::CharType kGDataCacheTmpDir[] = FILE_PATH_LITERAL("tmp");
69 const FilePath::CharType kGDataCacheTmpDownloadsDir[] = 70 const FilePath::CharType kGDataCacheTmpDownloadsDir[] =
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 const std::string& md5, 502 const std::string& md5,
502 const FilePath& gdata_file_path, 503 const FilePath& gdata_file_path,
503 FilePath* cache_file_path) { 504 FilePath* cache_file_path) {
504 DCHECK(error); 505 DCHECK(error);
505 DCHECK(cache_file_path); 506 DCHECK(cache_file_path);
506 507
507 if (!callback.is_null()) 508 if (!callback.is_null())
508 callback.Run(*error, resource_id, md5, gdata_file_path, *cache_file_path); 509 callback.Run(*error, resource_id, md5, gdata_file_path, *cache_file_path);
509 } 510 }
510 511
512 // Ditto for SetMountedStateCallback
513 void RunSetMountedStateCallbackHelper(
514 const SetMountedStateCallback& callback,
515 base::PlatformFileError* error,
516 FilePath* cache_file_path) {
517 DCHECK(error);
518 DCHECK(cache_file_path);
519
520 if (!callback.is_null())
521 callback.Run(*error, *cache_file_path);
522 }
523
511 void RunGetCacheStateCallbackHelper( 524 void RunGetCacheStateCallbackHelper(
512 const GetCacheStateCallback& callback, 525 const GetCacheStateCallback& callback,
513 base::PlatformFileError* error, 526 base::PlatformFileError* error,
514 int* cache_state) { 527 int* cache_state) {
515 DCHECK(error); 528 DCHECK(error);
516 DCHECK(cache_state); 529 DCHECK(cache_state);
517 530
518 if (!callback.is_null()) 531 if (!callback.is_null())
519 callback.Run(*error, *cache_state); 532 callback.Run(*error, *cache_state);
520 } 533 }
(...skipping 1483 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 if (regular_file) { 2017 if (regular_file) {
2005 properties->file_md5 = regular_file->file_md5(); 2018 properties->file_md5 = regular_file->file_md5();
2006 properties->mime_type = regular_file->content_mime_type(); 2019 properties->mime_type = regular_file->content_mime_type();
2007 properties->content_url = regular_file->content_url(); 2020 properties->content_url = regular_file->content_url();
2008 properties->alternate_url = regular_file->alternate_url(); 2021 properties->alternate_url = regular_file->alternate_url();
2009 properties->is_hosted_document = regular_file->is_hosted_document(); 2022 properties->is_hosted_document = regular_file->is_hosted_document();
2010 } 2023 }
2011 return true; 2024 return true;
2012 } 2025 }
2013 2026
2027 bool GDataFileSystem::IsUnderGDataCacheDirectory(const FilePath& path) const {
2028 return gdata_cache_path_ == path || gdata_cache_path_.IsParent(path);
2029 }
2030
2014 FilePath GDataFileSystem::GetGDataCacheTmpDirectory() const { 2031 FilePath GDataFileSystem::GetGDataCacheTmpDirectory() const {
2015 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP]; 2032 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP];
2016 } 2033 }
2017 2034
2018 FilePath GDataFileSystem::GetGDataTempDownloadFolderPath() const { 2035 FilePath GDataFileSystem::GetGDataTempDownloadFolderPath() const {
2019 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS]; 2036 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS];
2020 } 2037 }
2021 2038
2022 FilePath GDataFileSystem::GetGDataTempDocumentFolderPath() const { 2039 FilePath GDataFileSystem::GetGDataTempDocumentFolderPath() const {
2023 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS]; 2040 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS];
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2118 GetWeakPtrForCurrentThread(), 2135 GetWeakPtrForCurrentThread(),
2119 callback); 2136 callback);
2120 } 2137 }
2121 2138
2122 if (to_pin) 2139 if (to_pin)
2123 Pin(resource_id, md5, cache_callback); 2140 Pin(resource_id, md5, cache_callback);
2124 else 2141 else
2125 Unpin(resource_id, md5, cache_callback); 2142 Unpin(resource_id, md5, cache_callback);
2126 } 2143 }
2127 2144
2145 void GDataFileSystem::SetMountedState(const FilePath& file_path, bool to_mount,
2146 const SetMountedStateCallback& callback) {
2147 InitializeCacheIfNecessary();
2148
2149 base::PlatformFileError* error =
2150 new base::PlatformFileError(base::PLATFORM_FILE_OK);
2151 FilePath* cache_file_path = new FilePath;
2152 PostBlockingPoolSequencedTaskAndReply(
2153 kGDataFileSystemToken,
2154 FROM_HERE,
2155 base::Bind(&GDataFileSystem::SetMountedStateOnIOThreadPool,
2156 base::Unretained(this),
2157 file_path,
2158 to_mount,
2159 error,
2160 cache_file_path),
2161 base::Bind(&RunSetMountedStateCallbackHelper,
2162 callback,
2163 base::Owned(error),
2164 base::Owned(cache_file_path)));
2165 }
2166
2167 void GDataFileSystem::SetMountedStateOnIOThreadPool(
2168 const FilePath& file_path,
2169 bool to_mount,
2170 base::PlatformFileError *error,
2171 FilePath* cache_file_path) {
2172 DCHECK(error);
2173 DCHECK(cache_file_path);
2174
2175 // Lock to access cache map.
2176 base::AutoLock lock(lock_);
2177
2178 // Parse file path to obtain resource_id, md5 and extra_extension.
2179 std::string resource_id;
2180 std::string md5;
2181 std::string extra_extension;
2182 util::ParseCacheFilePath(file_path, &resource_id, &md5, &extra_extension);
2183 // The extra_extension shall be ".mounted" iff we're unmounting.
2184 DCHECK(!to_mount == (extra_extension == kMountedArchiveFileExtension));
2185
2186 // Get cache entry associated with the resource_id and md5
2187 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id,
2188 md5);
2189 if (!entry) {
2190 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
2191 return;
2192 }
2193 if (to_mount == entry->IsMounted()) {
2194 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
2195 return;
2196 }
2197
2198 // Get the subdir type and path for the unmounted state.
2199 GDataRootDirectory::CacheSubDirectoryType unmounted_subdir =
2200 entry->IsPinned() ? GDataRootDirectory::CACHE_TYPE_PERSISTENT :
2201 GDataRootDirectory::CACHE_TYPE_TMP;
2202 FilePath unmounted_path = GetCacheFilePath(resource_id, md5, unmounted_subdir,
2203 CACHED_FILE_FROM_SERVER);
2204
2205 // Get the subdir type and path for the mounted state.
2206 GDataRootDirectory::CacheSubDirectoryType mounted_subdir =
2207 GDataRootDirectory::CACHE_TYPE_PERSISTENT;
2208 FilePath mounted_path = GetCacheFilePath(resource_id, md5, mounted_subdir,
2209 CACHED_FILE_MOUNTED);
2210
2211 // Determine the source and destination paths for moving the cache blob.
2212 FilePath source_path;
2213 GDataRootDirectory::CacheSubDirectoryType dest_subdir;
2214 int cache_state = entry->cache_state;
2215 if (to_mount) {
2216 source_path = unmounted_path;
2217 *cache_file_path = mounted_path;
2218 dest_subdir = mounted_subdir;
2219 cache_state = GDataFile::SetCacheMounted(cache_state);
2220 } else {
2221 source_path = mounted_path;
2222 *cache_file_path = unmounted_path;
2223 dest_subdir = unmounted_subdir;
2224 cache_state = GDataFile::ClearCacheMounted(cache_state);
2225 }
2226
2227 // Move cache blob from source path to destination path.
2228 *error = ModifyCacheState(source_path, *cache_file_path,
2229 GDataFileSystem::FILE_OPERATION_MOVE,
2230 FilePath(), false);
2231 if (*error == base::PLATFORM_FILE_OK) {
2232 // Now that cache operation is complete, update cache map
2233 root_->UpdateCacheMap(resource_id, md5, dest_subdir, cache_state);
2234 }
2235 }
2236
2128 void GDataFileSystem::OnSetPinStateCompleted( 2237 void GDataFileSystem::OnSetPinStateCompleted(
2129 const FileOperationCallback& callback, 2238 const FileOperationCallback& callback,
2130 base::PlatformFileError error, 2239 base::PlatformFileError error,
2131 const std::string& resource_id, 2240 const std::string& resource_id,
2132 const std::string& md5) { 2241 const std::string& md5) {
2133 callback.Run(error); 2242 callback.Run(error);
2134 } 2243 }
2135 2244
2136 void GDataFileSystem::OnGetAvailableSpace( 2245 void GDataFileSystem::OnGetAvailableSpace(
2137 const GetAvailableSpaceCallback& callback, 2246 const GetAvailableSpaceCallback& callback,
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
3208 FilePath GDataFileSystem::GetCacheFilePath( 3317 FilePath GDataFileSystem::GetCacheFilePath(
3209 const std::string& resource_id, 3318 const std::string& resource_id,
3210 const std::string& md5, 3319 const std::string& md5,
3211 GDataRootDirectory::CacheSubDirectoryType sub_dir_type, 3320 GDataRootDirectory::CacheSubDirectoryType sub_dir_type,
3212 CachedFileOrigin file_origin) const { 3321 CachedFileOrigin file_origin) const {
3213 DCHECK(sub_dir_type != GDataRootDirectory::CACHE_TYPE_META); 3322 DCHECK(sub_dir_type != GDataRootDirectory::CACHE_TYPE_META);
3214 3323
3215 // Runs on any thread. 3324 // Runs on any thread.
3216 // Filename is formatted as resource_id.md5, i.e. resource_id is the base 3325 // Filename is formatted as resource_id.md5, i.e. resource_id is the base
3217 // name and md5 is the extension. 3326 // name and md5 is the extension.
3218 std::string base_name = GDataEntry::EscapeUtf8FileName(resource_id); 3327 std::string base_name = util::EscapeCacheFileName(resource_id);
3219 if (file_origin == CACHED_FILE_LOCALLY_MODIFIED) { 3328 if (file_origin == CACHED_FILE_LOCALLY_MODIFIED) {
3220 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT); 3329 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
3221 base_name += FilePath::kExtensionSeparator; 3330 base_name += FilePath::kExtensionSeparator;
3222 base_name += kLocallyModifiedFileExtension; 3331 base_name += kLocallyModifiedFileExtension;
3223 } else if (!md5.empty()) { 3332 } else if (!md5.empty()) {
3224 base_name += FilePath::kExtensionSeparator; 3333 base_name += FilePath::kExtensionSeparator;
3225 base_name += GDataEntry::EscapeUtf8FileName(md5); 3334 base_name += util::EscapeCacheFileName(md5);
3335 }
3336 // For mounted archives the filename is formatted as resource_id.md5.mounted,
3337 // i.e. resource_id.md5 is the base name and ".mounted" is the extension
3338 if (file_origin == CACHED_FILE_MOUNTED) {
3339 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
3340 base_name += FilePath::kExtensionSeparator;
3341 base_name += kMountedArchiveFileExtension;
3226 } 3342 }
3227 return cache_paths_[sub_dir_type].Append(base_name); 3343 return cache_paths_[sub_dir_type].Append(base_name);
3228 } 3344 }
3229 3345
3230 void GDataFileSystem::GetFileFromCacheByResourceIdAndMd5( 3346 void GDataFileSystem::GetFileFromCacheByResourceIdAndMd5(
3231 const std::string& resource_id, 3347 const std::string& resource_id,
3232 const std::string& md5, 3348 const std::string& md5,
3233 const GetFileFromCacheCallback& callback) { 3349 const GetFileFromCacheCallback& callback) {
3234 GetFileFromCacheByResourceIdAndMd5Internal( 3350 GetFileFromCacheByResourceIdAndMd5Internal(
3235 resource_id, md5, FilePath(), callback); 3351 resource_id, md5, FilePath(), callback);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 FilePath* cache_file_path) { 3574 FilePath* cache_file_path) {
3459 DCHECK(error); 3575 DCHECK(error);
3460 DCHECK(cache_file_path); 3576 DCHECK(cache_file_path);
3461 3577
3462 // Lock to access cache map. 3578 // Lock to access cache map.
3463 base::AutoLock lock(lock_); 3579 base::AutoLock lock(lock_);
3464 3580
3465 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id, 3581 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id,
3466 md5); 3582 md5);
3467 if (entry && entry->IsPresent()) { 3583 if (entry && entry->IsPresent()) {
3584 CachedFileOrigin file_origin;
3585 if (entry->IsMounted()) {
3586 file_origin = CACHED_FILE_MOUNTED;
3587 } else if (entry->IsDirty()) {
3588 file_origin = CACHED_FILE_LOCALLY_MODIFIED;
3589 } else {
3590 file_origin = CACHED_FILE_FROM_SERVER;
3591 }
3468 *cache_file_path = GetCacheFilePath( 3592 *cache_file_path = GetCacheFilePath(
3469 resource_id, 3593 resource_id,
3470 md5, 3594 md5,
3471 entry->sub_dir_type, 3595 entry->sub_dir_type,
3472 entry->IsDirty() ? CACHED_FILE_LOCALLY_MODIFIED : 3596 file_origin);
3473 CACHED_FILE_FROM_SERVER);
3474 *error = base::PLATFORM_FILE_OK; 3597 *error = base::PLATFORM_FILE_OK;
3475 } else { 3598 } else {
3476 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; 3599 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
3477 } 3600 }
3478 } 3601 }
3479 3602
3480 void GDataFileSystem::GetCacheStateOnIOThreadPool( 3603 void GDataFileSystem::GetCacheStateOnIOThreadPool(
3481 const std::string& resource_id, 3604 const std::string& resource_id,
3482 const std::string& md5, 3605 const std::string& md5,
3483 base::PlatformFileError* error, 3606 base::PlatformFileError* error,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3520 int cache_state = GDataFile::CACHE_STATE_PRESENT; 3643 int cache_state = GDataFile::CACHE_STATE_PRESENT;
3521 GDataRootDirectory::CacheSubDirectoryType sub_dir_type = 3644 GDataRootDirectory::CacheSubDirectoryType sub_dir_type =
3522 GDataRootDirectory::CACHE_TYPE_TMP; 3645 GDataRootDirectory::CACHE_TYPE_TMP;
3523 3646
3524 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry( 3647 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(
3525 resource_id, md5); 3648 resource_id, md5);
3526 3649
3527 // If file was previously pinned, store it in persistent dir and create 3650 // If file was previously pinned, store it in persistent dir and create
3528 // symlink in pinned dir. 3651 // symlink in pinned dir.
3529 if (entry) { // File exists in cache. 3652 if (entry) { // File exists in cache.
3530 // If file is dirty, return error. 3653 // If file is dirty or mounted, return error.
3531 if (entry->IsDirty()) { 3654 if (entry->IsDirty() || entry->IsMounted()) {
3532 LOG(WARNING) << "Can't store a file to replace a dirty file: res_id=" 3655 LOG(WARNING) << "Can't store a file to replace a "
3533 << resource_id 3656 << (entry->IsDirty() ? "dirty" : "mounted")
3657 << " file: res_id=" << resource_id
3534 << ", md5=" << md5; 3658 << ", md5=" << md5;
3535 *error = base::PLATFORM_FILE_ERROR_IN_USE; 3659 *error = base::PLATFORM_FILE_ERROR_IN_USE;
3536 return; 3660 return;
3537 } 3661 }
3538 3662
3539 cache_state |= entry->cache_state; 3663 cache_state |= entry->cache_state;
3540 3664
3541 // If file is pinned, determines destination path. 3665 // If file is pinned, determines destination path.
3542 if (entry->IsPinned()) { 3666 if (entry->IsPinned()) {
3543 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT; 3667 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3622 3746
3623 // Set sub_dir_type to PINNED to indicate that the file doesn't exist. 3747 // Set sub_dir_type to PINNED to indicate that the file doesn't exist.
3624 // When the file is finally downloaded and StoreToCache called, it will be 3748 // When the file is finally downloaded and StoreToCache called, it will be
3625 // moved to persistent directory. 3749 // moved to persistent directory.
3626 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PINNED; 3750 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PINNED;
3627 } else { // File exists in cache, determines destination path. 3751 } else { // File exists in cache, determines destination path.
3628 cache_state |= entry->cache_state; 3752 cache_state |= entry->cache_state;
3629 3753
3630 // Determine source and destination paths. 3754 // Determine source and destination paths.
3631 3755
3632 // If file is dirty, don't move it, so determine |dest_path| and set 3756 // If file is dirty or mounted, don't move it, so determine |dest_path| and
3633 // |source_path| the same, because ModifyCacheState only moves files if 3757 // set |source_path| the same, because ModifyCacheState only moves files if
3634 // source and destination are different. 3758 // source and destination are different.
3635 if (entry->IsDirty()) { 3759 if (entry->IsDirty() || entry->IsMounted()) {
3636 DCHECK_EQ(GDataRootDirectory::CACHE_TYPE_PERSISTENT, entry->sub_dir_type); 3760 DCHECK_EQ(GDataRootDirectory::CACHE_TYPE_PERSISTENT, entry->sub_dir_type);
3637 dest_path = GetCacheFilePath(resource_id, 3761 dest_path = GetCacheFilePath(resource_id,
3638 md5, 3762 md5,
3639 entry->sub_dir_type, 3763 entry->sub_dir_type,
3640 CACHED_FILE_LOCALLY_MODIFIED); 3764 CACHED_FILE_LOCALLY_MODIFIED);
3641 source_path = dest_path; 3765 source_path = dest_path;
3642 } else { 3766 } else {
3643 // Gets the current path of the file in cache. 3767 // Gets the current path of the file in cache.
3644 source_path = GetCacheFilePath(resource_id, 3768 source_path = GetCacheFilePath(resource_id,
3645 md5, 3769 md5,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3705 return; 3829 return;
3706 } 3830 }
3707 3831
3708 // Entry exists in cache, determines source and destination paths. 3832 // Entry exists in cache, determines source and destination paths.
3709 3833
3710 FilePath source_path; 3834 FilePath source_path;
3711 FilePath dest_path; 3835 FilePath dest_path;
3712 GDataRootDirectory::CacheSubDirectoryType sub_dir_type = 3836 GDataRootDirectory::CacheSubDirectoryType sub_dir_type =
3713 GDataRootDirectory::CACHE_TYPE_TMP; 3837 GDataRootDirectory::CACHE_TYPE_TMP;
3714 3838
3715 // If file is dirty, don't move it, so determine |dest_path| and set 3839 // If file is dirty or mounted, don't move it, so determine |dest_path| and
3716 // |source_path| the same, because ModifyCacheState moves files if source 3840 // set |source_path| the same, because ModifyCacheState moves files if source
3717 // and destination are different. 3841 // and destination are different.
3718 if (entry->IsDirty()) { 3842 if (entry->IsDirty() || entry->IsMounted()) {
3719 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT; 3843 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT;
3720 DCHECK_EQ(sub_dir_type, entry->sub_dir_type); 3844 DCHECK_EQ(sub_dir_type, entry->sub_dir_type);
3721 dest_path = GetCacheFilePath(resource_id, 3845 dest_path = GetCacheFilePath(resource_id,
3722 md5, 3846 md5,
3723 entry->sub_dir_type, 3847 entry->sub_dir_type,
3724 CACHED_FILE_LOCALLY_MODIFIED); 3848 CACHED_FILE_LOCALLY_MODIFIED);
3725 source_path = dest_path; 3849 source_path = dest_path;
3726 } else { 3850 } else {
3727 // Gets the current path of the file in cache. 3851 // Gets the current path of the file in cache.
3728 source_path = GetCacheFilePath(resource_id, 3852 source_path = GetCacheFilePath(resource_id,
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 // Lock to access cache map. 4164 // Lock to access cache map.
4041 base::AutoLock lock(lock_); 4165 base::AutoLock lock(lock_);
4042 4166
4043 // MD5 is not passed into RemoveFromCache and hence 4167 // MD5 is not passed into RemoveFromCache and hence
4044 // RemoveFromCacheOnIOThreadPool, because we would delete all cache files 4168 // RemoveFromCacheOnIOThreadPool, because we would delete all cache files
4045 // corresponding to <resource_id> regardless of the md5. 4169 // corresponding to <resource_id> regardless of the md5.
4046 // So, search for entry in cache without taking md5 into account. 4170 // So, search for entry in cache without taking md5 into account.
4047 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry( 4171 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(
4048 resource_id, std::string()); 4172 resource_id, std::string());
4049 4173
4050 // If entry doesn't exist or is dirty in cache, nothing to do. 4174 // If entry doesn't exist or is dirty or mounted in cache, nothing to do.
4051 if (!entry || entry->IsDirty()) { 4175 if (!entry || entry->IsDirty() || entry->IsMounted()) {
4052 DVLOG(1) << "Entry " << (entry ? "is dirty" : "doesn't exist") 4176 DVLOG(1) << "Entry is "
4177 << (entry ? (entry->IsDirty() ? "dirty" : "mounted") :
4178 "non-existent")
4053 << " in cache, not removing"; 4179 << " in cache, not removing";
4054 *error = base::PLATFORM_FILE_OK; 4180 *error = base::PLATFORM_FILE_OK;
4055 return; 4181 return;
4056 } 4182 }
4057 4183
4058 // Determine paths to delete all cache versions of |resource_id| in 4184 // Determine paths to delete all cache versions of |resource_id| in
4059 // persistent, tmp and pinned directories. 4185 // persistent, tmp and pinned directories.
4060 std::vector<FilePath> paths_to_delete; 4186 std::vector<FilePath> paths_to_delete;
4061 4187
4062 // For files in persistent and tmp dirs, delete files that match 4188 // For files in persistent and tmp dirs, delete files that match
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4164 file_util::FileEnumerator enumerator( 4290 file_util::FileEnumerator enumerator(
4165 cache_paths_[sub_dir_type], 4291 cache_paths_[sub_dir_type],
4166 false, // not recursive 4292 false, // not recursive
4167 static_cast<file_util::FileEnumerator::FileType>( 4293 static_cast<file_util::FileEnumerator::FileType>(
4168 file_util::FileEnumerator::FILES | 4294 file_util::FileEnumerator::FILES |
4169 file_util::FileEnumerator::SHOW_SYM_LINKS), 4295 file_util::FileEnumerator::SHOW_SYM_LINKS),
4170 kWildCard); 4296 kWildCard);
4171 for (FilePath current = enumerator.Next(); !current.empty(); 4297 for (FilePath current = enumerator.Next(); !current.empty();
4172 current = enumerator.Next()) { 4298 current = enumerator.Next()) {
4173 // Extract resource_id and md5 from filename. 4299 // Extract resource_id and md5 from filename.
4174 FilePath base_name = current.BaseName();
4175 std::string resource_id; 4300 std::string resource_id;
4176 std::string md5; 4301 std::string md5;
4177 4302 std::string extra_extension;
4178 // Pinned and outgoing symlinks have no extension. 4303 util::ParseCacheFilePath(current, &resource_id, &md5, &extra_extension);
4179 if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_PINNED ||
4180 sub_dir_type == GDataRootDirectory::CACHE_TYPE_OUTGOING) {
4181 resource_id = GDataEntry::UnescapeUtf8FileName(base_name.value());
4182 } else {
4183 FilePath::StringType extension = base_name.Extension();
4184 if (!extension.empty()) {
4185 // FilePath::Extension returns ".", so strip it.
4186 md5 = GDataEntry::UnescapeUtf8FileName(extension.substr(1));
4187 }
4188 resource_id = GDataEntry::UnescapeUtf8FileName(
4189 base_name.RemoveExtension().value());
4190 }
4191 4304
4192 // Determine cache state. 4305 // Determine cache state.
4193 int cache_state = GDataFile::CACHE_STATE_NONE; 4306 int cache_state = GDataFile::CACHE_STATE_NONE;
4194 // If we're scanning pinned directory and if entry already exists, just 4307 // If we're scanning pinned directory and if entry already exists, just
4195 // update its pinned state. 4308 // update its pinned state.
4196 if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_PINNED) { 4309 if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_PINNED) {
4197 GDataRootDirectory::CacheMap::iterator iter = 4310 GDataRootDirectory::CacheMap::iterator iter =
4198 cache_map->find(resource_id); 4311 cache_map->find(resource_id);
4199 if (iter != cache_map->end()) { // Entry exists, update pinned state. 4312 if (iter != cache_map->end()) { // Entry exists, update pinned state.
4200 GDataRootDirectory::CacheEntry* entry = iter->second; 4313 GDataRootDirectory::CacheEntry* entry = iter->second;
(...skipping 11 matching lines...) Expand all
4212 // ignore this outgoing symlink and move on. 4325 // ignore this outgoing symlink and move on.
4213 GDataRootDirectory::CacheMap::iterator iter = 4326 GDataRootDirectory::CacheMap::iterator iter =
4214 cache_map->find(resource_id); 4327 cache_map->find(resource_id);
4215 if (iter != cache_map->end()) { // Entry exists, update dirty state. 4328 if (iter != cache_map->end()) { // Entry exists, update dirty state.
4216 GDataRootDirectory::CacheEntry* entry = iter->second; 4329 GDataRootDirectory::CacheEntry* entry = iter->second;
4217 entry->cache_state = GDataFile::SetCacheDirty(entry->cache_state); 4330 entry->cache_state = GDataFile::SetCacheDirty(entry->cache_state);
4218 } else { 4331 } else {
4219 NOTREACHED() << "Dirty cache file MUST have actual file blob"; 4332 NOTREACHED() << "Dirty cache file MUST have actual file blob";
4220 } 4333 }
4221 continue; 4334 continue;
4335 } else if (extra_extension == kMountedArchiveFileExtension) {
4336 // Mounted archives in cache should be unmounted upon logout/shutdown.
4337 // But if we encounter a mounted file at start, delete it and create an
4338 // entry with not PRESENT state.
4339 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
4340 file_util::Delete(current, false);
4222 } else { 4341 } else {
4223 // Scanning other directories means that cache file is actually present. 4342 // Scanning other directories means that cache file is actually present.
4224 cache_state = GDataFile::SetCachePresent(cache_state); 4343 cache_state = GDataFile::SetCachePresent(cache_state);
4225 } 4344 }
4226 4345
4227 // Create and insert new entry into cache map. 4346 // Create and insert new entry into cache map.
4228 GDataRootDirectory::CacheEntry* entry = new GDataRootDirectory::CacheEntry( 4347 GDataRootDirectory::CacheEntry* entry = new GDataRootDirectory::CacheEntry(
4229 md5, sub_dir_type, cache_state); 4348 md5, sub_dir_type, cache_state);
4230 cache_map->insert(std::make_pair(resource_id, entry)); 4349 cache_map->insert(std::make_pair(resource_id, entry));
4231 } 4350 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 pref_registrar_->Init(profile_->GetPrefs()); 4440 pref_registrar_->Init(profile_->GetPrefs());
4322 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); 4441 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this);
4323 } 4442 }
4324 4443
4325 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { 4444 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) {
4326 delete global_free_disk_getter_for_testing; // Safe to delete NULL; 4445 delete global_free_disk_getter_for_testing; // Safe to delete NULL;
4327 global_free_disk_getter_for_testing = getter; 4446 global_free_disk_getter_for_testing = getter;
4328 } 4447 }
4329 4448
4330 } // namespace gdata 4449 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system.h ('k') | chrome/browser/chromeos/gdata/gdata_file_system_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698