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

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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 kFeedField[] = "feed"; 58 const char kFeedField[] = "feed";
59 const char kWildCard[] = "*"; 59 const char kWildCard[] = "*";
60 const char kLocallyModifiedFileExtension[] = "local"; 60 const char kLocallyModifiedFileExtension[] = "local";
61 const char kMountedArchiveFileExtension[] = "mounted";
61 62
62 const FilePath::CharType kGDataCacheVersionDir[] = FILE_PATH_LITERAL("v1"); 63 const FilePath::CharType kGDataCacheVersionDir[] = FILE_PATH_LITERAL("v1");
63 const FilePath::CharType kGDataCacheMetaDir[] = FILE_PATH_LITERAL("meta"); 64 const FilePath::CharType kGDataCacheMetaDir[] = FILE_PATH_LITERAL("meta");
64 const FilePath::CharType kGDataCachePinnedDir[] = FILE_PATH_LITERAL("pinned"); 65 const FilePath::CharType kGDataCachePinnedDir[] = FILE_PATH_LITERAL("pinned");
65 const FilePath::CharType kGDataCacheOutgoingDir[] = 66 const FilePath::CharType kGDataCacheOutgoingDir[] =
66 FILE_PATH_LITERAL("outgoing"); 67 FILE_PATH_LITERAL("outgoing");
67 const FilePath::CharType kGDataCachePersistentDir[] = 68 const FilePath::CharType kGDataCachePersistentDir[] =
68 FILE_PATH_LITERAL("persistent"); 69 FILE_PATH_LITERAL("persistent");
69 const FilePath::CharType kGDataCacheTmpDir[] = FILE_PATH_LITERAL("tmp"); 70 const FilePath::CharType kGDataCacheTmpDir[] = FILE_PATH_LITERAL("tmp");
70 const FilePath::CharType kGDataCacheTmpDownloadsDir[] = 71 const FilePath::CharType kGDataCacheTmpDownloadsDir[] =
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 const std::string& md5, 503 const std::string& md5,
503 const FilePath& gdata_file_path, 504 const FilePath& gdata_file_path,
504 FilePath* cache_file_path) { 505 FilePath* cache_file_path) {
505 DCHECK(error); 506 DCHECK(error);
506 DCHECK(cache_file_path); 507 DCHECK(cache_file_path);
507 508
508 if (!callback.is_null()) 509 if (!callback.is_null())
509 callback.Run(*error, resource_id, md5, gdata_file_path, *cache_file_path); 510 callback.Run(*error, resource_id, md5, gdata_file_path, *cache_file_path);
510 } 511 }
511 512
513 // Ditto for SetMountedStateCallback
514 void RunSetMountedStateCallbackHelper(
515 const SetMountedStateCallback& callback,
516 base::PlatformFileError* error,
517 FilePath* cache_file_path) {
518 DCHECK(error);
519 DCHECK(cache_file_path);
520
521 if (!callback.is_null())
522 callback.Run(*error, *cache_file_path);
523 }
524
512 void RunGetCacheStateCallbackHelper( 525 void RunGetCacheStateCallbackHelper(
513 const GetCacheStateCallback& callback, 526 const GetCacheStateCallback& callback,
514 base::PlatformFileError* error, 527 base::PlatformFileError* error,
515 int* cache_state) { 528 int* cache_state) {
516 DCHECK(error); 529 DCHECK(error);
517 DCHECK(cache_state); 530 DCHECK(cache_state);
518 531
519 if (!callback.is_null()) 532 if (!callback.is_null())
520 callback.Run(*error, *cache_state); 533 callback.Run(*error, *cache_state);
521 } 534 }
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 if (regular_file) { 1945 if (regular_file) {
1933 properties->file_md5 = regular_file->file_md5(); 1946 properties->file_md5 = regular_file->file_md5();
1934 properties->mime_type = regular_file->content_mime_type(); 1947 properties->mime_type = regular_file->content_mime_type();
1935 properties->content_url = regular_file->content_url(); 1948 properties->content_url = regular_file->content_url();
1936 properties->alternate_url = regular_file->alternate_url(); 1949 properties->alternate_url = regular_file->alternate_url();
1937 properties->is_hosted_document = regular_file->is_hosted_document(); 1950 properties->is_hosted_document = regular_file->is_hosted_document();
1938 } 1951 }
1939 return true; 1952 return true;
1940 } 1953 }
1941 1954
1955 bool GDataFileSystem::IsUnderGDataCacheDirectory(const FilePath& path) const {
1956 return gdata_cache_path_ == path || gdata_cache_path_.IsParent(path);
1957 }
1958
1942 FilePath GDataFileSystem::GetGDataCacheTmpDirectory() const { 1959 FilePath GDataFileSystem::GetGDataCacheTmpDirectory() const {
1943 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP]; 1960 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP];
1944 } 1961 }
1945 1962
1946 FilePath GDataFileSystem::GetGDataTempDownloadFolderPath() const { 1963 FilePath GDataFileSystem::GetGDataTempDownloadFolderPath() const {
1947 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS]; 1964 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS];
1948 } 1965 }
1949 1966
1950 FilePath GDataFileSystem::GetGDataTempDocumentFolderPath() const { 1967 FilePath GDataFileSystem::GetGDataTempDocumentFolderPath() const {
1951 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS]; 1968 return cache_paths_[GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS];
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 GetWeakPtrForCurrentThread(), 2097 GetWeakPtrForCurrentThread(),
2081 callback); 2098 callback);
2082 } 2099 }
2083 2100
2084 if (to_pin) 2101 if (to_pin)
2085 Pin(resource_id, md5, cache_callback); 2102 Pin(resource_id, md5, cache_callback);
2086 else 2103 else
2087 Unpin(resource_id, md5, cache_callback); 2104 Unpin(resource_id, md5, cache_callback);
2088 } 2105 }
2089 2106
2107 void GDataFileSystem::SetMountedState(const FilePath& file_path, bool to_mount,
2108 const SetMountedStateCallback& callback) {
2109 InitializeCacheIfNecessary();
2110
2111 base::PlatformFileError* error =
2112 new base::PlatformFileError(base::PLATFORM_FILE_OK);
2113 FilePath* cache_file_path = new FilePath;
2114 PostBlockingPoolSequencedTaskAndReply(
2115 kGDataFileSystemToken,
2116 FROM_HERE,
2117 base::Bind(&GDataFileSystem::SetMountedStateOnIOThreadPool,
2118 base::Unretained(this),
2119 file_path,
2120 to_mount,
2121 error,
2122 cache_file_path),
2123 base::Bind(&RunSetMountedStateCallbackHelper,
2124 callback,
2125 base::Owned(error),
2126 base::Owned(cache_file_path)));
2127 }
2128
2129 void GDataFileSystem::SetMountedStateOnIOThreadPool(
2130 const FilePath& file_path,
2131 bool to_mount,
2132 base::PlatformFileError *error,
2133 FilePath* cache_file_path) {
2134 DCHECK(error);
2135 DCHECK(cache_file_path);
2136
2137 // Lock to access cache map.
2138 base::AutoLock lock(lock_);
2139
2140 FilePath base_name = file_path.BaseName();
2141 FilePath::StringType resource_id = base_name.RemoveExtension().value();
2142 FilePath::StringType extension = base_name.Extension();
2143 FilePath::StringType md5 = FilePath::StringType();
satorux1 2012/04/20 20:11:25 nit: the following is sufficient FilePath::String
2144 if (!extension.empty()) {
2145 // FilePath::Extension returns ".", so strip it.
2146 md5 = GDataEntry::UnescapeUtf8FileName(extension.substr(1));
2147 if (md5 == kMountedArchiveFileExtension) {
2148 DCHECK(!to_mount);
2149 // Files that are already mounted have filenames in format of
2150 // resource_id.md5.mounted, i.e. ".mounted" is the extension, so
2151 // strip it and get the actual resource_id and md5.
2152 base_name = base_name.RemoveExtension();
2153 resource_id = GDataEntry::UnescapeUtf8FileName(
2154 base_name.RemoveExtension().value());
2155 extension = base_name.Extension();
2156 md5 = !extension.empty() ?
2157 GDataEntry::UnescapeUtf8FileName(extension.substr(1)) :
2158 FilePath::StringType();
2159 }
2160 }
satorux1 2012/04/20 20:11:25 This function is already large. can you factor out
2161 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id,
2162 md5);
2163 if (!entry) {
2164 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
2165 return;
2166 }
2167 if (to_mount == entry->IsMounted()) {
2168 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
2169 return;
2170 }
2171
2172 md5 = entry->md5;
2173 // Get subdir types for the unmounted and mounted state.
2174 GDataRootDirectory::CacheSubDirectoryType unmounted_subdir =
2175 entry->IsPinned() ? GDataRootDirectory::CACHE_TYPE_PERSISTENT :
2176 GDataRootDirectory::CACHE_TYPE_TMP;
2177 GDataRootDirectory::CacheSubDirectoryType mounted_subdir =
2178 GDataRootDirectory::CACHE_TYPE_PERSISTENT;
2179 // Gets path of the file if it were to be unmounted.
2180 FilePath unmounted_path = GetCacheFilePath(resource_id, md5, unmounted_subdir,
2181 CACHED_FILE_FROM_SERVER);
2182 // Gets path of the file if it were to be mounted.
2183 FilePath mounted_path = GetCacheFilePath(resource_id, md5, mounted_subdir,
2184 CACHED_FILE_MOUNTED);
2185
2186 // Determine the source and destination paths for moving the cache blob.
2187 FilePath source_path;
2188 GDataRootDirectory::CacheSubDirectoryType dest_subdir;
2189 int cache_state = entry->cache_state;
2190 if (to_mount) {
2191 source_path = unmounted_path;
2192 *cache_file_path = mounted_path;
2193 dest_subdir = mounted_subdir;
2194 cache_state = GDataFile::SetCacheMounted(cache_state);
2195 } else {
2196 source_path = mounted_path;
2197 *cache_file_path = unmounted_path;
2198 dest_subdir = unmounted_subdir;
2199 cache_state = GDataFile::ClearCacheMounted(cache_state);
2200 }
2201
2202 // Move cache blob from source path to destination path.
2203 *error = ModifyCacheState(source_path, *cache_file_path,
2204 GDataFileSystem::FILE_OPERATION_MOVE,
2205 FilePath(), false);
2206 if (*error == base::PLATFORM_FILE_OK) {
2207 // Now that cache operation is complete, update cache map
2208 root_->UpdateCacheMap(resource_id, md5, dest_subdir, cache_state);
2209 }
2210 }
2211
2090 void GDataFileSystem::OnSetPinStateCompleted( 2212 void GDataFileSystem::OnSetPinStateCompleted(
2091 const FileOperationCallback& callback, 2213 const FileOperationCallback& callback,
2092 base::PlatformFileError error, 2214 base::PlatformFileError error,
2093 const std::string& resource_id, 2215 const std::string& resource_id,
2094 const std::string& md5) { 2216 const std::string& md5) {
2095 callback.Run(error); 2217 callback.Run(error);
2096 } 2218 }
2097 2219
2098 void GDataFileSystem::OnGetAvailableSpace( 2220 void GDataFileSystem::OnGetAvailableSpace(
2099 const GetAvailableSpaceCallback& callback, 2221 const GetAvailableSpaceCallback& callback,
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3261 // name and md5 is the extension. 3383 // name and md5 is the extension.
3262 std::string base_name = GDataEntry::EscapeUtf8FileName(resource_id); 3384 std::string base_name = GDataEntry::EscapeUtf8FileName(resource_id);
3263 if (file_origin == CACHED_FILE_LOCALLY_MODIFIED) { 3385 if (file_origin == CACHED_FILE_LOCALLY_MODIFIED) {
3264 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT); 3386 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
3265 base_name += FilePath::kExtensionSeparator; 3387 base_name += FilePath::kExtensionSeparator;
3266 base_name += kLocallyModifiedFileExtension; 3388 base_name += kLocallyModifiedFileExtension;
3267 } else if (!md5.empty()) { 3389 } else if (!md5.empty()) {
3268 base_name += FilePath::kExtensionSeparator; 3390 base_name += FilePath::kExtensionSeparator;
3269 base_name += GDataEntry::EscapeUtf8FileName(md5); 3391 base_name += GDataEntry::EscapeUtf8FileName(md5);
3270 } 3392 }
3393 // For mounted archives the filename is formatted as resource_id.md5.mounted,
3394 // i.e. resource_id.md5 is the base name and ".mounted" is the extension
3395 if (file_origin == CACHED_FILE_MOUNTED) {
3396 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
3397 base_name += FilePath::kExtensionSeparator;
3398 base_name += kMountedArchiveFileExtension;
3399 }
3271 return cache_paths_[sub_dir_type].Append(base_name); 3400 return cache_paths_[sub_dir_type].Append(base_name);
3272 } 3401 }
3273 3402
3274 void GDataFileSystem::GetFromCache(const std::string& resource_id, 3403 void GDataFileSystem::GetFromCache(const std::string& resource_id,
3275 const std::string& md5, 3404 const std::string& md5,
3276 const GetFromCacheCallback& callback) { 3405 const GetFromCacheCallback& callback) {
3277 GetFromCacheInternal(resource_id, md5, FilePath(), callback); 3406 GetFromCacheInternal(resource_id, md5, FilePath(), callback);
3278 } 3407 }
3279 3408
3280 void GDataFileSystem::StoreToCache(const std::string& resource_id, 3409 void GDataFileSystem::StoreToCache(const std::string& resource_id,
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
3499 FilePath* cache_file_path) { 3628 FilePath* cache_file_path) {
3500 DCHECK(error); 3629 DCHECK(error);
3501 DCHECK(cache_file_path); 3630 DCHECK(cache_file_path);
3502 3631
3503 // Lock to access cache map. 3632 // Lock to access cache map.
3504 base::AutoLock lock(lock_); 3633 base::AutoLock lock(lock_);
3505 3634
3506 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id, 3635 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(resource_id,
3507 md5); 3636 md5);
3508 if (entry && entry->IsPresent()) { 3637 if (entry && entry->IsPresent()) {
3638 CachedFileOrigin file_origin;
3639 if (entry->IsMounted()) {
3640 file_origin = CACHED_FILE_MOUNTED;
3641 } else if (entry->IsDirty()) {
3642 file_origin = CACHED_FILE_LOCALLY_MODIFIED;
3643 } else {
3644 file_origin = CACHED_FILE_FROM_SERVER;
3645 }
3509 *cache_file_path = GetCacheFilePath( 3646 *cache_file_path = GetCacheFilePath(
3510 resource_id, 3647 resource_id,
3511 md5, 3648 md5,
3512 entry->sub_dir_type, 3649 entry->sub_dir_type,
3513 entry->IsDirty() ? CACHED_FILE_LOCALLY_MODIFIED : 3650 file_origin);
3514 CACHED_FILE_FROM_SERVER);
3515 *error = base::PLATFORM_FILE_OK; 3651 *error = base::PLATFORM_FILE_OK;
3516 } else { 3652 } else {
3517 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; 3653 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
3518 } 3654 }
3519 } 3655 }
3520 3656
3521 void GDataFileSystem::GetCacheStateOnIOThreadPool( 3657 void GDataFileSystem::GetCacheStateOnIOThreadPool(
3522 const std::string& resource_id, 3658 const std::string& resource_id,
3523 const std::string& md5, 3659 const std::string& md5,
3524 base::PlatformFileError* error, 3660 base::PlatformFileError* error,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 int cache_state = GDataFile::CACHE_STATE_PRESENT; 3697 int cache_state = GDataFile::CACHE_STATE_PRESENT;
3562 GDataRootDirectory::CacheSubDirectoryType sub_dir_type = 3698 GDataRootDirectory::CacheSubDirectoryType sub_dir_type =
3563 GDataRootDirectory::CACHE_TYPE_TMP; 3699 GDataRootDirectory::CACHE_TYPE_TMP;
3564 3700
3565 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry( 3701 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(
3566 resource_id, md5); 3702 resource_id, md5);
3567 3703
3568 // If file was previously pinned, store it in persistent dir and create 3704 // If file was previously pinned, store it in persistent dir and create
3569 // symlink in pinned dir. 3705 // symlink in pinned dir.
3570 if (entry) { // File exists in cache. 3706 if (entry) { // File exists in cache.
3571 // If file is dirty, return error. 3707 // If file is dirty or mounted, return error.
3572 if (entry->IsDirty()) { 3708 if (entry->IsDirty() || entry->IsMounted()) {
3573 LOG(WARNING) << "Can't store a file to replace a dirty file: res_id=" 3709 LOG(WARNING) << "Can't store a file to replace a "
3574 << resource_id 3710 << (entry->IsDirty() ? "dirty" : "mounted")
3711 << " file: res_id=" << resource_id
3575 << ", md5=" << md5; 3712 << ", md5=" << md5;
3576 *error = base::PLATFORM_FILE_ERROR_IN_USE; 3713 *error = base::PLATFORM_FILE_ERROR_IN_USE;
3577 return; 3714 return;
3578 } 3715 }
3579 3716
3580 cache_state |= entry->cache_state; 3717 cache_state |= entry->cache_state;
3581 3718
3582 // If file is pinned, determines destination path. 3719 // If file is pinned, determines destination path.
3583 if (entry->IsPinned()) { 3720 if (entry->IsPinned()) {
3584 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT; 3721 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 3800
3664 // Set sub_dir_type to PINNED to indicate that the file doesn't exist. 3801 // Set sub_dir_type to PINNED to indicate that the file doesn't exist.
3665 // When the file is finally downloaded and StoreToCache called, it will be 3802 // When the file is finally downloaded and StoreToCache called, it will be
3666 // moved to persistent directory. 3803 // moved to persistent directory.
3667 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PINNED; 3804 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PINNED;
3668 } else { // File exists in cache, determines destination path. 3805 } else { // File exists in cache, determines destination path.
3669 cache_state |= entry->cache_state; 3806 cache_state |= entry->cache_state;
3670 3807
3671 // Determine source and destination paths. 3808 // Determine source and destination paths.
3672 3809
3673 // If file is dirty, don't move it, so determine |dest_path| and set 3810 // If file is dirty or mounted, don't move it, so determine |dest_path| and
3674 // |source_path| the same, because ModifyCacheState only moves files if 3811 // set |source_path| the same, because ModifyCacheState only moves files if
3675 // source and destination are different. 3812 // source and destination are different.
3676 if (entry->IsDirty()) { 3813 if (entry->IsDirty() || entry->IsMounted()) {
3677 DCHECK_EQ(GDataRootDirectory::CACHE_TYPE_PERSISTENT, entry->sub_dir_type); 3814 DCHECK_EQ(GDataRootDirectory::CACHE_TYPE_PERSISTENT, entry->sub_dir_type);
3678 dest_path = GetCacheFilePath(resource_id, 3815 dest_path = GetCacheFilePath(resource_id,
3679 md5, 3816 md5,
3680 entry->sub_dir_type, 3817 entry->sub_dir_type,
3681 CACHED_FILE_LOCALLY_MODIFIED); 3818 CACHED_FILE_LOCALLY_MODIFIED);
3682 source_path = dest_path; 3819 source_path = dest_path;
3683 } else { 3820 } else {
3684 // Gets the current path of the file in cache. 3821 // Gets the current path of the file in cache.
3685 source_path = GetCacheFilePath(resource_id, 3822 source_path = GetCacheFilePath(resource_id,
3686 md5, 3823 md5,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3746 return; 3883 return;
3747 } 3884 }
3748 3885
3749 // Entry exists in cache, determines source and destination paths. 3886 // Entry exists in cache, determines source and destination paths.
3750 3887
3751 FilePath source_path; 3888 FilePath source_path;
3752 FilePath dest_path; 3889 FilePath dest_path;
3753 GDataRootDirectory::CacheSubDirectoryType sub_dir_type = 3890 GDataRootDirectory::CacheSubDirectoryType sub_dir_type =
3754 GDataRootDirectory::CACHE_TYPE_TMP; 3891 GDataRootDirectory::CACHE_TYPE_TMP;
3755 3892
3756 // If file is dirty, don't move it, so determine |dest_path| and set 3893 // If file is dirty or mounted, don't move it, so determine |dest_path| and
3757 // |source_path| the same, because ModifyCacheState moves files if source 3894 // set |source_path| the same, because ModifyCacheState moves files if source
3758 // and destination are different. 3895 // and destination are different.
3759 if (entry->IsDirty()) { 3896 if (entry->IsDirty() || entry->IsMounted()) {
3760 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT; 3897 sub_dir_type = GDataRootDirectory::CACHE_TYPE_PERSISTENT;
3761 DCHECK_EQ(sub_dir_type, entry->sub_dir_type); 3898 DCHECK_EQ(sub_dir_type, entry->sub_dir_type);
3762 dest_path = GetCacheFilePath(resource_id, 3899 dest_path = GetCacheFilePath(resource_id,
3763 md5, 3900 md5,
3764 entry->sub_dir_type, 3901 entry->sub_dir_type,
3765 CACHED_FILE_LOCALLY_MODIFIED); 3902 CACHED_FILE_LOCALLY_MODIFIED);
3766 source_path = dest_path; 3903 source_path = dest_path;
3767 } else { 3904 } else {
3768 // Gets the current path of the file in cache. 3905 // Gets the current path of the file in cache.
3769 source_path = GetCacheFilePath(resource_id, 3906 source_path = GetCacheFilePath(resource_id,
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 // Lock to access cache map. 4218 // Lock to access cache map.
4082 base::AutoLock lock(lock_); 4219 base::AutoLock lock(lock_);
4083 4220
4084 // MD5 is not passed into RemoveFromCache and hence 4221 // MD5 is not passed into RemoveFromCache and hence
4085 // RemoveFromCacheOnIOThreadPool, because we would delete all cache files 4222 // RemoveFromCacheOnIOThreadPool, because we would delete all cache files
4086 // corresponding to <resource_id> regardless of the md5. 4223 // corresponding to <resource_id> regardless of the md5.
4087 // So, search for entry in cache without taking md5 into account. 4224 // So, search for entry in cache without taking md5 into account.
4088 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry( 4225 GDataRootDirectory::CacheEntry* entry = root_->GetCacheEntry(
4089 resource_id, std::string()); 4226 resource_id, std::string());
4090 4227
4091 // If entry doesn't exist or is dirty in cache, nothing to do. 4228 // If entry doesn't exist or is dirty or mounted in cache, nothing to do.
4092 if (!entry || entry->IsDirty()) { 4229 if (!entry || entry->IsDirty() || entry->IsMounted()) {
4093 DVLOG(1) << "Entry " << (entry ? "is dirty" : "doesn't exist") 4230 DVLOG(1) << "Entry is "
4231 << (entry ? (entry->IsDirty() ? "dirty" : "mounted") :
4232 "non-existent")
4094 << " in cache, not removing"; 4233 << " in cache, not removing";
4095 *error = base::PLATFORM_FILE_OK; 4234 *error = base::PLATFORM_FILE_OK;
4096 return; 4235 return;
4097 } 4236 }
4098 4237
4099 // Determine paths to delete all cache versions of |resource_id| in 4238 // Determine paths to delete all cache versions of |resource_id| in
4100 // persistent, tmp and pinned directories. 4239 // persistent, tmp and pinned directories.
4101 std::vector<FilePath> paths_to_delete; 4240 std::vector<FilePath> paths_to_delete;
4102 4241
4103 // For files in persistent and tmp dirs, delete files that match 4242 // For files in persistent and tmp dirs, delete files that match
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4233 // Determine cache state. 4372 // Determine cache state.
4234 int cache_state = GDataFile::CACHE_STATE_NONE; 4373 int cache_state = GDataFile::CACHE_STATE_NONE;
4235 // If we're scanning pinned directory and if entry already exists, just 4374 // If we're scanning pinned directory and if entry already exists, just
4236 // update its pinned state. 4375 // update its pinned state.
4237 if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_PINNED) { 4376 if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_PINNED) {
4238 GDataRootDirectory::CacheMap::iterator iter = 4377 GDataRootDirectory::CacheMap::iterator iter =
4239 cache_map->find(resource_id); 4378 cache_map->find(resource_id);
4240 if (iter != cache_map->end()) { // Entry exists, update pinned state. 4379 if (iter != cache_map->end()) { // Entry exists, update pinned state.
4241 GDataRootDirectory::CacheEntry* entry = iter->second; 4380 GDataRootDirectory::CacheEntry* entry = iter->second;
4242 entry->cache_state = GDataFile::SetCachePinned(entry->cache_state); 4381 entry->cache_state = GDataFile::SetCachePinned(entry->cache_state);
4382 // Check that the file exists in the persistent directory
4383 FilePath expected_path = GetCacheFilePath(
4384 resource_id, entry->md5,
4385 GDataRootDirectory::CACHE_TYPE_PERSISTENT,
4386 CACHED_FILE_FROM_SERVER);
4387 if (!file_util::PathExists(expected_path))
4388 {
satorux1 2012/04/20 20:11:25 nit: move { to the previous line.
4389 // If the pinned file is a mounted archive, it may be stripped of the
4390 // suffix ".mounted" and moved to tmp. Move it again to persistent.
satorux1 2012/04/20 20:11:25 I'm confused. when can it happen?
hshi 2012/04/20 20:20:30 This happens when a zip file is pinned and also mo
satorux1 2012/04/20 21:46:10 Oh I see. This is fairly tricky and hard to test..
4391 FilePath tmp_path = GetCacheFilePath(
4392 resource_id, entry->md5,
4393 GDataRootDirectory::CACHE_TYPE_TMP,
4394 CACHED_FILE_FROM_SERVER);
4395 DCHECK(file_util::PathExists(tmp_path));
4396 file_util::Move(tmp_path, expected_path);
4397 }
4243 continue; 4398 continue;
4244 } 4399 }
4245 // Entry doesn't exist, this is a special symlink that refers to 4400 // Entry doesn't exist, this is a special symlink that refers to
4246 // /dev/null; follow through to create an entry with the PINNED but not 4401 // /dev/null; follow through to create an entry with the PINNED but not
4247 // PRESENT state. 4402 // PRESENT state.
4248 cache_state = GDataFile::SetCachePinned(cache_state); 4403 cache_state = GDataFile::SetCachePinned(cache_state);
4249 } else if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_OUTGOING) { 4404 } else if (sub_dir_type == GDataRootDirectory::CACHE_TYPE_OUTGOING) {
4250 // If we're scanning outgoing directory, entry must exist, update its 4405 // If we're scanning outgoing directory, entry must exist, update its
4251 // dirty state. 4406 // dirty state.
4252 // If entry doesn't exist, it's a logic error from previous execution, 4407 // If entry doesn't exist, it's a logic error from previous execution,
4253 // ignore this outgoing symlink and move on. 4408 // ignore this outgoing symlink and move on.
4254 GDataRootDirectory::CacheMap::iterator iter = 4409 GDataRootDirectory::CacheMap::iterator iter =
4255 cache_map->find(resource_id); 4410 cache_map->find(resource_id);
4256 if (iter != cache_map->end()) { // Entry exists, update dirty state. 4411 if (iter != cache_map->end()) { // Entry exists, update dirty state.
4257 GDataRootDirectory::CacheEntry* entry = iter->second; 4412 GDataRootDirectory::CacheEntry* entry = iter->second;
4258 entry->cache_state = GDataFile::SetCacheDirty(entry->cache_state); 4413 entry->cache_state = GDataFile::SetCacheDirty(entry->cache_state);
4259 } else { 4414 } else {
4260 NOTREACHED() << "Dirty cache file MUST have actual file blob"; 4415 NOTREACHED() << "Dirty cache file MUST have actual file blob";
4261 } 4416 }
4262 continue; 4417 continue;
4263 } else { 4418 } else {
4264 // Scanning other directories means that cache file is actually present. 4419 // Scanning other directories means that cache file is actually present.
4265 cache_state = GDataFile::SetCachePresent(cache_state); 4420 cache_state = GDataFile::SetCachePresent(cache_state);
4266 } 4421 }
4267 4422
4423 // Mounted archives in cache should be unmounted upon logout/shutdown.
4424 // But if we encounter a mounted file at start, move it back to tmp.
4425 if (md5 == kMountedArchiveFileExtension) {
4426 DCHECK(sub_dir_type == GDataRootDirectory::CACHE_TYPE_PERSISTENT);
4427 sub_dir_type = GDataRootDirectory::CACHE_TYPE_TMP;
4428 // Files that are already mounted have filenames in format of
4429 // resource_id.md5.mounted, i.e. ".mounted" is the extension, so strip
4430 // it and get the actual resource_id and md5
4431 base_name = base_name.RemoveExtension();
4432 resource_id = GDataEntry::UnescapeUtf8FileName(
4433 base_name.RemoveExtension().value());
4434 FilePath::StringType extension = base_name.Extension();
4435 md5 = !extension.empty() ?
4436 GDataEntry::UnescapeUtf8FileName(extension.substr(1)) :
4437 std::string();
4438 file_util::Move(current, GetCacheFilePath(resource_id, md5, sub_dir_type,
4439 CACHED_FILE_FROM_SERVER));
4440 }
4441
4268 // Create and insert new entry into cache map. 4442 // Create and insert new entry into cache map.
4269 GDataRootDirectory::CacheEntry* entry = new GDataRootDirectory::CacheEntry( 4443 GDataRootDirectory::CacheEntry* entry = new GDataRootDirectory::CacheEntry(
4270 md5, sub_dir_type, cache_state); 4444 md5, sub_dir_type, cache_state);
4271 cache_map->insert(std::make_pair(resource_id, entry)); 4445 cache_map->insert(std::make_pair(resource_id, entry));
4272 } 4446 }
4273 } 4447 }
4274 4448
4275 void GDataFileSystem::GetFromCacheInternal( 4449 void GDataFileSystem::GetFromCacheInternal(
4276 const std::string& resource_id, 4450 const std::string& resource_id,
4277 const std::string& md5, 4451 const std::string& md5,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
4362 pref_registrar_->Init(profile_->GetPrefs()); 4536 pref_registrar_->Init(profile_->GetPrefs());
4363 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); 4537 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this);
4364 } 4538 }
4365 4539
4366 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { 4540 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) {
4367 delete global_free_disk_getter_for_testing; // Safe to delete NULL; 4541 delete global_free_disk_getter_for_testing; // Safe to delete NULL;
4368 global_free_disk_getter_for_testing = getter; 4542 global_free_disk_getter_for_testing = getter;
4369 } 4543 }
4370 4544
4371 } // namespace gdata 4545 } // 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