| 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 "chrome/browser/chromeos/gdata/gdata_cache.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_cache.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/chromeos/chromeos_version.h" | 9 #include "base/chromeos/chromeos_version.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 704 } |
| 705 | 705 |
| 706 void GDataCache::RequestInitializeOnUIThread() { | 706 void GDataCache::RequestInitializeOnUIThread() { |
| 707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 708 | 708 |
| 709 pool_->GetSequencedTaskRunner(sequence_token_)->PostTask( | 709 pool_->GetSequencedTaskRunner(sequence_token_)->PostTask( |
| 710 FROM_HERE, | 710 FROM_HERE, |
| 711 base::Bind(&GDataCache::Initialize, base::Unretained(this))); | 711 base::Bind(&GDataCache::Initialize, base::Unretained(this))); |
| 712 } | 712 } |
| 713 | 713 |
| 714 scoped_ptr<GDataCacheEntry> GDataCache::GetCacheEntry( | 714 bool GDataCache::GetCacheEntry(const std::string& resource_id, |
| 715 const std::string& resource_id, | 715 const std::string& md5, |
| 716 const std::string& md5) { | 716 GDataCacheEntry* entry) { |
| 717 DCHECK(entry); |
| 717 AssertOnSequencedWorkerPool(); | 718 AssertOnSequencedWorkerPool(); |
| 718 return metadata_->GetCacheEntry(resource_id, md5); | 719 return metadata_->GetCacheEntry(resource_id, md5, entry); |
| 719 } | 720 } |
| 720 | 721 |
| 721 // static | 722 // static |
| 722 GDataCache* GDataCache::CreateGDataCacheOnUIThread( | 723 GDataCache* GDataCache::CreateGDataCacheOnUIThread( |
| 723 const FilePath& cache_root_path, | 724 const FilePath& cache_root_path, |
| 724 base::SequencedWorkerPool* pool, | 725 base::SequencedWorkerPool* pool, |
| 725 const base::SequencedWorkerPool::SequenceToken& sequence_token) { | 726 const base::SequencedWorkerPool::SequenceToken& sequence_token) { |
| 726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 727 return new GDataCache(cache_root_path, pool, sequence_token); | 728 return new GDataCache(cache_root_path, pool, sequence_token); |
| 728 } | 729 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 } | 774 } |
| 774 | 775 |
| 775 void GDataCache::GetFile(const std::string& resource_id, | 776 void GDataCache::GetFile(const std::string& resource_id, |
| 776 const std::string& md5, | 777 const std::string& md5, |
| 777 base::PlatformFileError* error, | 778 base::PlatformFileError* error, |
| 778 FilePath* cache_file_path) { | 779 FilePath* cache_file_path) { |
| 779 AssertOnSequencedWorkerPool(); | 780 AssertOnSequencedWorkerPool(); |
| 780 DCHECK(error); | 781 DCHECK(error); |
| 781 DCHECK(cache_file_path); | 782 DCHECK(cache_file_path); |
| 782 | 783 |
| 783 scoped_ptr<GDataCacheEntry> cache_entry = GetCacheEntry( | 784 GDataCacheEntry cache_entry; |
| 784 resource_id, md5); | 785 if (GetCacheEntry(resource_id, md5, &cache_entry) && |
| 785 if (cache_entry.get() && cache_entry->IsPresent()) { | 786 cache_entry.IsPresent()) { |
| 786 CachedFileOrigin file_origin; | 787 CachedFileOrigin file_origin; |
| 787 if (cache_entry->IsMounted()) { | 788 if (cache_entry.IsMounted()) { |
| 788 file_origin = CACHED_FILE_MOUNTED; | 789 file_origin = CACHED_FILE_MOUNTED; |
| 789 } else if (cache_entry->IsDirty()) { | 790 } else if (cache_entry.IsDirty()) { |
| 790 file_origin = CACHED_FILE_LOCALLY_MODIFIED; | 791 file_origin = CACHED_FILE_LOCALLY_MODIFIED; |
| 791 } else { | 792 } else { |
| 792 file_origin = CACHED_FILE_FROM_SERVER; | 793 file_origin = CACHED_FILE_FROM_SERVER; |
| 793 } | 794 } |
| 794 *cache_file_path = GetCacheFilePath( | 795 *cache_file_path = GetCacheFilePath( |
| 795 resource_id, | 796 resource_id, |
| 796 md5, | 797 md5, |
| 797 GetSubDirectoryType(*cache_entry), | 798 GetSubDirectoryType(cache_entry), |
| 798 file_origin); | 799 file_origin); |
| 799 *error = base::PLATFORM_FILE_OK; | 800 *error = base::PLATFORM_FILE_OK; |
| 800 } else { | 801 } else { |
| 801 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 802 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 802 } | 803 } |
| 803 } | 804 } |
| 804 | 805 |
| 805 void GDataCache::Store(const std::string& resource_id, | 806 void GDataCache::Store(const std::string& resource_id, |
| 806 const std::string& md5, | 807 const std::string& md5, |
| 807 const FilePath& source_path, | 808 const FilePath& source_path, |
| 808 FileOperationType file_operation_type, | 809 FileOperationType file_operation_type, |
| 809 base::PlatformFileError* error) { | 810 base::PlatformFileError* error) { |
| 810 AssertOnSequencedWorkerPool(); | 811 AssertOnSequencedWorkerPool(); |
| 811 DCHECK(error); | 812 DCHECK(error); |
| 812 | 813 |
| 813 FilePath dest_path; | 814 FilePath dest_path; |
| 814 FilePath symlink_path; | 815 FilePath symlink_path; |
| 815 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_TMP; | 816 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_TMP; |
| 816 | 817 |
| 817 scoped_ptr<GDataCacheEntry> cache_entry = GetCacheEntry(resource_id, md5); | |
| 818 | |
| 819 // If file was previously pinned, store it in persistent dir and create | 818 // If file was previously pinned, store it in persistent dir and create |
| 820 // symlink in pinned dir. | 819 // symlink in pinned dir. |
| 821 if (cache_entry.get()) { // File exists in cache. | 820 GDataCacheEntry cache_entry; |
| 821 if (GetCacheEntry(resource_id, md5, &cache_entry)) { // File exists in cache. |
| 822 // If file is dirty or mounted, return error. | 822 // If file is dirty or mounted, return error. |
| 823 if (cache_entry->IsDirty() || cache_entry->IsMounted()) { | 823 if (cache_entry.IsDirty() || cache_entry.IsMounted()) { |
| 824 LOG(WARNING) << "Can't store a file to replace a " | 824 LOG(WARNING) << "Can't store a file to replace a " |
| 825 << (cache_entry->IsDirty() ? "dirty" : "mounted") | 825 << (cache_entry.IsDirty() ? "dirty" : "mounted") |
| 826 << " file: res_id=" << resource_id | 826 << " file: res_id=" << resource_id |
| 827 << ", md5=" << md5; | 827 << ", md5=" << md5; |
| 828 *error = base::PLATFORM_FILE_ERROR_IN_USE; | 828 *error = base::PLATFORM_FILE_ERROR_IN_USE; |
| 829 return; | 829 return; |
| 830 } | 830 } |
| 831 | 831 |
| 832 // If file is pinned, determines destination path. | 832 // If file is pinned, determines destination path. |
| 833 if (cache_entry->IsPinned()) { | 833 if (cache_entry.IsPinned()) { |
| 834 sub_dir_type = CACHE_TYPE_PERSISTENT; | 834 sub_dir_type = CACHE_TYPE_PERSISTENT; |
| 835 dest_path = GetCacheFilePath(resource_id, md5, sub_dir_type, | 835 dest_path = GetCacheFilePath(resource_id, md5, sub_dir_type, |
| 836 CACHED_FILE_FROM_SERVER); | 836 CACHED_FILE_FROM_SERVER); |
| 837 symlink_path = GetCacheFilePath( | 837 symlink_path = GetCacheFilePath( |
| 838 resource_id, std::string(), CACHE_TYPE_PINNED, | 838 resource_id, std::string(), CACHE_TYPE_PINNED, |
| 839 CACHED_FILE_FROM_SERVER); | 839 CACHED_FILE_FROM_SERVER); |
| 840 } | 840 } |
| 841 } else { | |
| 842 // The file does not exist in the cache. Create a new entry. | |
| 843 cache_entry.reset(new GDataCacheEntry); | |
| 844 } | 841 } |
| 845 | 842 |
| 846 // File wasn't pinned or doesn't exist in cache, store in tmp dir. | 843 // File wasn't pinned or doesn't exist in cache, store in tmp dir. |
| 847 if (dest_path.empty()) { | 844 if (dest_path.empty()) { |
| 848 DCHECK_EQ(CACHE_TYPE_TMP, sub_dir_type); | 845 DCHECK_EQ(CACHE_TYPE_TMP, sub_dir_type); |
| 849 dest_path = GetCacheFilePath(resource_id, md5, sub_dir_type, | 846 dest_path = GetCacheFilePath(resource_id, md5, sub_dir_type, |
| 850 CACHED_FILE_FROM_SERVER); | 847 CACHED_FILE_FROM_SERVER); |
| 851 } | 848 } |
| 852 | 849 |
| 853 *error = ModifyCacheState( | 850 *error = ModifyCacheState( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 873 // Note that ReplaceExtension automatically prefixes the extension with the | 870 // Note that ReplaceExtension automatically prefixes the extension with the |
| 874 // extension separator '.'. | 871 // extension separator '.'. |
| 875 stale_filenames_pattern = dest_path.ReplaceExtension(util::kWildCard); | 872 stale_filenames_pattern = dest_path.ReplaceExtension(util::kWildCard); |
| 876 } | 873 } |
| 877 | 874 |
| 878 // Delete files that match |stale_filenames_pattern| except for |dest_path|. | 875 // Delete files that match |stale_filenames_pattern| except for |dest_path|. |
| 879 DeleteFilesSelectively(stale_filenames_pattern, dest_path); | 876 DeleteFilesSelectively(stale_filenames_pattern, dest_path); |
| 880 | 877 |
| 881 if (*error == base::PLATFORM_FILE_OK) { | 878 if (*error == base::PLATFORM_FILE_OK) { |
| 882 // Now that file operations have completed, update cache map. | 879 // Now that file operations have completed, update cache map. |
| 883 cache_entry->set_md5(md5); | 880 cache_entry.set_md5(md5); |
| 884 cache_entry->SetPresent(true); | 881 cache_entry.SetPresent(true); |
| 885 cache_entry->SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); | 882 cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); |
| 886 metadata_->AddOrUpdateCacheEntry(resource_id, *cache_entry); | 883 metadata_->AddOrUpdateCacheEntry(resource_id, cache_entry); |
| 887 } | 884 } |
| 888 } | 885 } |
| 889 | 886 |
| 890 void GDataCache::Pin(const std::string& resource_id, | 887 void GDataCache::Pin(const std::string& resource_id, |
| 891 const std::string& md5, | 888 const std::string& md5, |
| 892 FileOperationType file_operation_type, | 889 FileOperationType file_operation_type, |
| 893 base::PlatformFileError* error) { | 890 base::PlatformFileError* error) { |
| 894 AssertOnSequencedWorkerPool(); | 891 AssertOnSequencedWorkerPool(); |
| 895 DCHECK(error); | 892 DCHECK(error); |
| 896 | 893 |
| 897 FilePath source_path; | 894 FilePath source_path; |
| 898 FilePath dest_path; | 895 FilePath dest_path; |
| 899 FilePath symlink_path; | 896 FilePath symlink_path; |
| 900 bool create_symlink = true; | 897 bool create_symlink = true; |
| 901 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_PERSISTENT; | 898 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_PERSISTENT; |
| 902 | 899 |
| 903 scoped_ptr<GDataCacheEntry> cache_entry = GetCacheEntry(resource_id, md5); | 900 GDataCacheEntry cache_entry; |
| 904 | 901 if (!GetCacheEntry(resource_id, md5, &cache_entry)) { |
| 905 if (!cache_entry.get()) { // Entry does not exist in cache. | 902 // Entry does not exist in cache. |
| 906 // Set both |dest_path| and |source_path| to /dev/null, so that: | 903 // Set both |dest_path| and |source_path| to /dev/null, so that: |
| 907 // 1) ModifyCacheState won't move files when |source_path| and |dest_path| | 904 // 1) ModifyCacheState won't move files when |source_path| and |dest_path| |
| 908 // are the same. | 905 // are the same. |
| 909 // 2) symlinks to /dev/null will be picked up by GDataSyncClient to download | 906 // 2) symlinks to /dev/null will be picked up by GDataSyncClient to download |
| 910 // pinned files that don't exist in cache. | 907 // pinned files that don't exist in cache. |
| 911 dest_path = FilePath::FromUTF8Unsafe(util::kSymLinkToDevNull); | 908 dest_path = FilePath::FromUTF8Unsafe(util::kSymLinkToDevNull); |
| 912 source_path = dest_path; | 909 source_path = dest_path; |
| 913 | 910 |
| 914 // Set sub_dir_type to TMP. The file will be first downloaded in 'tmp', | 911 // Set sub_dir_type to TMP. The file will be first downloaded in 'tmp', |
| 915 // then moved to 'persistent'. | 912 // then moved to 'persistent'. |
| 916 sub_dir_type = CACHE_TYPE_TMP; | 913 sub_dir_type = CACHE_TYPE_TMP; |
| 917 | |
| 918 // We'll add a new cache entry. | |
| 919 cache_entry.reset(new GDataCacheEntry); | |
| 920 } else { // File exists in cache, determines destination path. | 914 } else { // File exists in cache, determines destination path. |
| 921 // Determine source and destination paths. | 915 // Determine source and destination paths. |
| 922 | 916 |
| 923 // If file is dirty or mounted, don't move it, so determine |dest_path| and | 917 // If file is dirty or mounted, don't move it, so determine |dest_path| and |
| 924 // set |source_path| the same, because ModifyCacheState only moves files if | 918 // set |source_path| the same, because ModifyCacheState only moves files if |
| 925 // source and destination are different. | 919 // source and destination are different. |
| 926 if (cache_entry->IsDirty() || cache_entry->IsMounted()) { | 920 if (cache_entry.IsDirty() || cache_entry.IsMounted()) { |
| 927 DCHECK(cache_entry->IsPersistent()); | 921 DCHECK(cache_entry.IsPersistent()); |
| 928 dest_path = GetCacheFilePath(resource_id, | 922 dest_path = GetCacheFilePath(resource_id, |
| 929 md5, | 923 md5, |
| 930 GetSubDirectoryType(*cache_entry), | 924 GetSubDirectoryType(cache_entry), |
| 931 CACHED_FILE_LOCALLY_MODIFIED); | 925 CACHED_FILE_LOCALLY_MODIFIED); |
| 932 source_path = dest_path; | 926 source_path = dest_path; |
| 933 } else { | 927 } else { |
| 934 // Gets the current path of the file in cache. | 928 // Gets the current path of the file in cache. |
| 935 source_path = GetCacheFilePath(resource_id, | 929 source_path = GetCacheFilePath(resource_id, |
| 936 md5, | 930 md5, |
| 937 GetSubDirectoryType(*cache_entry), | 931 GetSubDirectoryType(cache_entry), |
| 938 CACHED_FILE_FROM_SERVER); | 932 CACHED_FILE_FROM_SERVER); |
| 939 | 933 |
| 940 // If file was pinned before but actual file blob doesn't exist in cache: | 934 // If file was pinned before but actual file blob doesn't exist in cache: |
| 941 // - don't need to move the file, so set |dest_path| to |source_path|, | 935 // - don't need to move the file, so set |dest_path| to |source_path|, |
| 942 // because ModifyCacheState only moves files if source and destination | 936 // because ModifyCacheState only moves files if source and destination |
| 943 // are different | 937 // are different |
| 944 // - don't create symlink since it already exists. | 938 // - don't create symlink since it already exists. |
| 945 if (!cache_entry->IsPresent()) { | 939 if (!cache_entry.IsPresent()) { |
| 946 dest_path = source_path; | 940 dest_path = source_path; |
| 947 create_symlink = false; | 941 create_symlink = false; |
| 948 } else { // File exists, move it to persistent dir. | 942 } else { // File exists, move it to persistent dir. |
| 949 dest_path = GetCacheFilePath(resource_id, | 943 dest_path = GetCacheFilePath(resource_id, |
| 950 md5, | 944 md5, |
| 951 CACHE_TYPE_PERSISTENT, | 945 CACHE_TYPE_PERSISTENT, |
| 952 CACHED_FILE_FROM_SERVER); | 946 CACHED_FILE_FROM_SERVER); |
| 953 } | 947 } |
| 954 } | 948 } |
| 955 } | 949 } |
| 956 | 950 |
| 957 // Create symlink in pinned dir. | 951 // Create symlink in pinned dir. |
| 958 if (create_symlink) { | 952 if (create_symlink) { |
| 959 symlink_path = GetCacheFilePath(resource_id, | 953 symlink_path = GetCacheFilePath(resource_id, |
| 960 std::string(), | 954 std::string(), |
| 961 CACHE_TYPE_PINNED, | 955 CACHE_TYPE_PINNED, |
| 962 CACHED_FILE_FROM_SERVER); | 956 CACHED_FILE_FROM_SERVER); |
| 963 } | 957 } |
| 964 | 958 |
| 965 *error = ModifyCacheState(source_path, | 959 *error = ModifyCacheState(source_path, |
| 966 dest_path, | 960 dest_path, |
| 967 file_operation_type, | 961 file_operation_type, |
| 968 symlink_path, | 962 symlink_path, |
| 969 create_symlink); | 963 create_symlink); |
| 970 | 964 |
| 971 if (*error == base::PLATFORM_FILE_OK) { | 965 if (*error == base::PLATFORM_FILE_OK) { |
| 972 // Now that file operations have completed, update cache map. | 966 // Now that file operations have completed, update cache map. |
| 973 cache_entry->set_md5(md5); | 967 cache_entry.set_md5(md5); |
| 974 cache_entry->SetPinned(true); | 968 cache_entry.SetPinned(true); |
| 975 cache_entry->SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); | 969 cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); |
| 976 metadata_->AddOrUpdateCacheEntry(resource_id, *cache_entry); | 970 metadata_->AddOrUpdateCacheEntry(resource_id, cache_entry); |
| 977 } | 971 } |
| 978 } | 972 } |
| 979 | 973 |
| 980 void GDataCache::Unpin(const std::string& resource_id, | 974 void GDataCache::Unpin(const std::string& resource_id, |
| 981 const std::string& md5, | 975 const std::string& md5, |
| 982 FileOperationType file_operation_type, | 976 FileOperationType file_operation_type, |
| 983 base::PlatformFileError* error) { | 977 base::PlatformFileError* error) { |
| 984 AssertOnSequencedWorkerPool(); | 978 AssertOnSequencedWorkerPool(); |
| 985 DCHECK(error); | 979 DCHECK(error); |
| 986 | 980 |
| 987 scoped_ptr<GDataCacheEntry> cache_entry = GetCacheEntry(resource_id, md5); | |
| 988 | |
| 989 // Unpinning a file means its entry must exist in cache. | 981 // Unpinning a file means its entry must exist in cache. |
| 990 if (!cache_entry.get()) { | 982 GDataCacheEntry cache_entry; |
| 983 if (!GetCacheEntry(resource_id, md5, &cache_entry)) { |
| 991 LOG(WARNING) << "Can't unpin a file that wasn't pinned or cached: res_id=" | 984 LOG(WARNING) << "Can't unpin a file that wasn't pinned or cached: res_id=" |
| 992 << resource_id | 985 << resource_id |
| 993 << ", md5=" << md5; | 986 << ", md5=" << md5; |
| 994 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 987 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 995 return; | 988 return; |
| 996 } | 989 } |
| 997 | 990 |
| 998 // Entry exists in cache, determines source and destination paths. | 991 // Entry exists in cache, determines source and destination paths. |
| 999 | 992 |
| 1000 FilePath source_path; | 993 FilePath source_path; |
| 1001 FilePath dest_path; | 994 FilePath dest_path; |
| 1002 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_TMP; | 995 CacheSubDirectoryType sub_dir_type = CACHE_TYPE_TMP; |
| 1003 | 996 |
| 1004 // If file is dirty or mounted, don't move it, so determine |dest_path| and | 997 // If file is dirty or mounted, don't move it, so determine |dest_path| and |
| 1005 // set |source_path| the same, because ModifyCacheState moves files if source | 998 // set |source_path| the same, because ModifyCacheState moves files if source |
| 1006 // and destination are different. | 999 // and destination are different. |
| 1007 if (cache_entry->IsDirty() || cache_entry->IsMounted()) { | 1000 if (cache_entry.IsDirty() || cache_entry.IsMounted()) { |
| 1008 sub_dir_type = CACHE_TYPE_PERSISTENT; | 1001 sub_dir_type = CACHE_TYPE_PERSISTENT; |
| 1009 DCHECK(cache_entry->IsPersistent()); | 1002 DCHECK(cache_entry.IsPersistent()); |
| 1010 dest_path = GetCacheFilePath(resource_id, | 1003 dest_path = GetCacheFilePath(resource_id, |
| 1011 md5, | 1004 md5, |
| 1012 GetSubDirectoryType(*cache_entry), | 1005 GetSubDirectoryType(cache_entry), |
| 1013 CACHED_FILE_LOCALLY_MODIFIED); | 1006 CACHED_FILE_LOCALLY_MODIFIED); |
| 1014 source_path = dest_path; | 1007 source_path = dest_path; |
| 1015 } else { | 1008 } else { |
| 1016 // Gets the current path of the file in cache. | 1009 // Gets the current path of the file in cache. |
| 1017 source_path = GetCacheFilePath(resource_id, | 1010 source_path = GetCacheFilePath(resource_id, |
| 1018 md5, | 1011 md5, |
| 1019 GetSubDirectoryType(*cache_entry), | 1012 GetSubDirectoryType(cache_entry), |
| 1020 CACHED_FILE_FROM_SERVER); | 1013 CACHED_FILE_FROM_SERVER); |
| 1021 | 1014 |
| 1022 // If file was pinned but actual file blob still doesn't exist in cache, | 1015 // If file was pinned but actual file blob still doesn't exist in cache, |
| 1023 // don't need to move the file, so set |dest_path| to |source_path|, because | 1016 // don't need to move the file, so set |dest_path| to |source_path|, because |
| 1024 // ModifyCacheState only moves files if source and destination are | 1017 // ModifyCacheState only moves files if source and destination are |
| 1025 // different. | 1018 // different. |
| 1026 if (!cache_entry->IsPresent()) { | 1019 if (!cache_entry.IsPresent()) { |
| 1027 dest_path = source_path; | 1020 dest_path = source_path; |
| 1028 } else { // File exists, move it to tmp dir. | 1021 } else { // File exists, move it to tmp dir. |
| 1029 dest_path = GetCacheFilePath(resource_id, md5, | 1022 dest_path = GetCacheFilePath(resource_id, md5, |
| 1030 CACHE_TYPE_TMP, | 1023 CACHE_TYPE_TMP, |
| 1031 CACHED_FILE_FROM_SERVER); | 1024 CACHED_FILE_FROM_SERVER); |
| 1032 } | 1025 } |
| 1033 } | 1026 } |
| 1034 | 1027 |
| 1035 // If file was pinned, get absolute path of symlink in pinned dir so as to | 1028 // If file was pinned, get absolute path of symlink in pinned dir so as to |
| 1036 // remove it. | 1029 // remove it. |
| 1037 FilePath symlink_path; | 1030 FilePath symlink_path; |
| 1038 if (cache_entry->IsPinned()) { | 1031 if (cache_entry.IsPinned()) { |
| 1039 symlink_path = GetCacheFilePath(resource_id, | 1032 symlink_path = GetCacheFilePath(resource_id, |
| 1040 std::string(), | 1033 std::string(), |
| 1041 CACHE_TYPE_PINNED, | 1034 CACHE_TYPE_PINNED, |
| 1042 CACHED_FILE_FROM_SERVER); | 1035 CACHED_FILE_FROM_SERVER); |
| 1043 } | 1036 } |
| 1044 | 1037 |
| 1045 *error = ModifyCacheState( | 1038 *error = ModifyCacheState( |
| 1046 source_path, | 1039 source_path, |
| 1047 dest_path, | 1040 dest_path, |
| 1048 file_operation_type, | 1041 file_operation_type, |
| 1049 symlink_path, // This will be deleted if it exists. | 1042 symlink_path, // This will be deleted if it exists. |
| 1050 false /* don't create symlink*/); | 1043 false /* don't create symlink*/); |
| 1051 | 1044 |
| 1052 if (*error == base::PLATFORM_FILE_OK) { | 1045 if (*error == base::PLATFORM_FILE_OK) { |
| 1053 // Now that file operations have completed, update cache map. | 1046 // Now that file operations have completed, update cache map. |
| 1054 if (cache_entry->IsPresent()) { | 1047 if (cache_entry.IsPresent()) { |
| 1055 GDataCacheEntry new_cache_entry(md5, cache_entry->cache_state()); | 1048 GDataCacheEntry new_cache_entry(md5, cache_entry.cache_state()); |
| 1056 new_cache_entry.SetPinned(false); | 1049 new_cache_entry.SetPinned(false); |
| 1057 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); | 1050 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); |
| 1058 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); | 1051 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); |
| 1059 } else { | 1052 } else { |
| 1060 // Remove the existing entry if we are unpinning a non-present file. | 1053 // Remove the existing entry if we are unpinning a non-present file. |
| 1061 metadata_->RemoveCacheEntry(resource_id); | 1054 metadata_->RemoveCacheEntry(resource_id); |
| 1062 } | 1055 } |
| 1063 } | 1056 } |
| 1064 } | 1057 } |
| 1065 | 1058 |
| 1066 void GDataCache::SetMountedState(const FilePath& file_path, | 1059 void GDataCache::SetMountedState(const FilePath& file_path, |
| 1067 bool to_mount, | 1060 bool to_mount, |
| 1068 base::PlatformFileError *error, | 1061 base::PlatformFileError *error, |
| 1069 FilePath* cache_file_path) { | 1062 FilePath* cache_file_path) { |
| 1070 AssertOnSequencedWorkerPool(); | 1063 AssertOnSequencedWorkerPool(); |
| 1071 DCHECK(error); | 1064 DCHECK(error); |
| 1072 DCHECK(cache_file_path); | 1065 DCHECK(cache_file_path); |
| 1073 | 1066 |
| 1074 // Parse file path to obtain resource_id, md5 and extra_extension. | 1067 // Parse file path to obtain resource_id, md5 and extra_extension. |
| 1075 std::string resource_id; | 1068 std::string resource_id; |
| 1076 std::string md5; | 1069 std::string md5; |
| 1077 std::string extra_extension; | 1070 std::string extra_extension; |
| 1078 util::ParseCacheFilePath(file_path, &resource_id, &md5, &extra_extension); | 1071 util::ParseCacheFilePath(file_path, &resource_id, &md5, &extra_extension); |
| 1079 // The extra_extension shall be ".mounted" iff we're unmounting. | 1072 // The extra_extension shall be ".mounted" iff we're unmounting. |
| 1080 DCHECK(!to_mount == (extra_extension == util::kMountedArchiveFileExtension)); | 1073 DCHECK(!to_mount == (extra_extension == util::kMountedArchiveFileExtension)); |
| 1081 | 1074 |
| 1082 // Get cache entry associated with the resource_id and md5 | 1075 // Get cache entry associated with the resource_id and md5 |
| 1083 scoped_ptr<GDataCacheEntry> cache_entry = GetCacheEntry( | 1076 GDataCacheEntry cache_entry; |
| 1084 resource_id, md5); | 1077 if (!GetCacheEntry(resource_id, md5, &cache_entry)) { |
| 1085 if (!cache_entry.get()) { | |
| 1086 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1078 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1087 return; | 1079 return; |
| 1088 } | 1080 } |
| 1089 if (to_mount == cache_entry->IsMounted()) { | 1081 if (to_mount == cache_entry.IsMounted()) { |
| 1090 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 1082 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 1091 return; | 1083 return; |
| 1092 } | 1084 } |
| 1093 | 1085 |
| 1094 // Get the subdir type and path for the unmounted state. | 1086 // Get the subdir type and path for the unmounted state. |
| 1095 CacheSubDirectoryType unmounted_subdir = | 1087 CacheSubDirectoryType unmounted_subdir = |
| 1096 cache_entry->IsPinned() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; | 1088 cache_entry.IsPinned() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; |
| 1097 FilePath unmounted_path = GetCacheFilePath( | 1089 FilePath unmounted_path = GetCacheFilePath( |
| 1098 resource_id, md5, unmounted_subdir, CACHED_FILE_FROM_SERVER); | 1090 resource_id, md5, unmounted_subdir, CACHED_FILE_FROM_SERVER); |
| 1099 | 1091 |
| 1100 // Get the subdir type and path for the mounted state. | 1092 // Get the subdir type and path for the mounted state. |
| 1101 CacheSubDirectoryType mounted_subdir = CACHE_TYPE_PERSISTENT; | 1093 CacheSubDirectoryType mounted_subdir = CACHE_TYPE_PERSISTENT; |
| 1102 FilePath mounted_path = GetCacheFilePath( | 1094 FilePath mounted_path = GetCacheFilePath( |
| 1103 resource_id, md5, mounted_subdir, CACHED_FILE_MOUNTED); | 1095 resource_id, md5, mounted_subdir, CACHED_FILE_MOUNTED); |
| 1104 | 1096 |
| 1105 // Determine the source and destination paths for moving the cache blob. | 1097 // Determine the source and destination paths for moving the cache blob. |
| 1106 FilePath source_path; | 1098 FilePath source_path; |
| 1107 CacheSubDirectoryType dest_subdir; | 1099 CacheSubDirectoryType dest_subdir; |
| 1108 GDataCacheEntry new_cache_entry(md5, cache_entry->cache_state()); | 1100 GDataCacheEntry new_cache_entry(md5, cache_entry.cache_state()); |
| 1109 if (to_mount) { | 1101 if (to_mount) { |
| 1110 source_path = unmounted_path; | 1102 source_path = unmounted_path; |
| 1111 *cache_file_path = mounted_path; | 1103 *cache_file_path = mounted_path; |
| 1112 dest_subdir = mounted_subdir; | 1104 dest_subdir = mounted_subdir; |
| 1113 new_cache_entry.SetMounted(true); | 1105 new_cache_entry.SetMounted(true); |
| 1114 } else { | 1106 } else { |
| 1115 source_path = mounted_path; | 1107 source_path = mounted_path; |
| 1116 *cache_file_path = unmounted_path; | 1108 *cache_file_path = unmounted_path; |
| 1117 dest_subdir = unmounted_subdir; | 1109 dest_subdir = unmounted_subdir; |
| 1118 new_cache_entry.SetMounted(false); | 1110 new_cache_entry.SetMounted(false); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1134 base::PlatformFileError* error, | 1126 base::PlatformFileError* error, |
| 1135 FilePath* cache_file_path) { | 1127 FilePath* cache_file_path) { |
| 1136 AssertOnSequencedWorkerPool(); | 1128 AssertOnSequencedWorkerPool(); |
| 1137 DCHECK(error); | 1129 DCHECK(error); |
| 1138 DCHECK(cache_file_path); | 1130 DCHECK(cache_file_path); |
| 1139 | 1131 |
| 1140 // If file has already been marked dirty in previous instance of chrome, we | 1132 // If file has already been marked dirty in previous instance of chrome, we |
| 1141 // would have lost the md5 info during cache initialization, because the file | 1133 // would have lost the md5 info during cache initialization, because the file |
| 1142 // would have been renamed to .local extension. | 1134 // would have been renamed to .local extension. |
| 1143 // So, search for entry in cache without comparing md5. | 1135 // So, search for entry in cache without comparing md5. |
| 1144 scoped_ptr<GDataCacheEntry> cache_entry = | |
| 1145 GetCacheEntry(resource_id, std::string()); | |
| 1146 | 1136 |
| 1147 // Marking a file dirty means its entry and actual file blob must exist in | 1137 // Marking a file dirty means its entry and actual file blob must exist in |
| 1148 // cache. | 1138 // cache. |
| 1149 if (!cache_entry.get() || !cache_entry->IsPresent()) { | 1139 GDataCacheEntry cache_entry; |
| 1140 if (!GetCacheEntry(resource_id, std::string(), &cache_entry) || |
| 1141 !cache_entry.IsPresent()) { |
| 1150 LOG(WARNING) << "Can't mark dirty a file that wasn't cached: res_id=" | 1142 LOG(WARNING) << "Can't mark dirty a file that wasn't cached: res_id=" |
| 1151 << resource_id | 1143 << resource_id |
| 1152 << ", md5=" << md5; | 1144 << ", md5=" << md5; |
| 1153 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1145 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1154 return; | 1146 return; |
| 1155 } | 1147 } |
| 1156 | 1148 |
| 1157 // If a file is already dirty (i.e. MarkDirtyInCache was called before), | 1149 // If a file is already dirty (i.e. MarkDirtyInCache was called before), |
| 1158 // delete outgoing symlink if it exists. | 1150 // delete outgoing symlink if it exists. |
| 1159 // TODO(benchan): We should only delete outgoing symlink if file is currently | 1151 // TODO(benchan): We should only delete outgoing symlink if file is currently |
| 1160 // not being uploaded. However, for now, cache doesn't know if uploading of a | 1152 // not being uploaded. However, for now, cache doesn't know if uploading of a |
| 1161 // file is in progress. Per zel, the upload process should be canceled before | 1153 // file is in progress. Per zel, the upload process should be canceled before |
| 1162 // MarkDirtyInCache is called again. | 1154 // MarkDirtyInCache is called again. |
| 1163 if (cache_entry->IsDirty()) { | 1155 if (cache_entry.IsDirty()) { |
| 1164 // The file must be in persistent dir. | 1156 // The file must be in persistent dir. |
| 1165 DCHECK(cache_entry->IsPersistent()); | 1157 DCHECK(cache_entry.IsPersistent()); |
| 1166 | 1158 |
| 1167 // Determine symlink path in outgoing dir, so as to remove it. | 1159 // Determine symlink path in outgoing dir, so as to remove it. |
| 1168 FilePath symlink_path = GetCacheFilePath( | 1160 FilePath symlink_path = GetCacheFilePath( |
| 1169 resource_id, | 1161 resource_id, |
| 1170 std::string(), | 1162 std::string(), |
| 1171 CACHE_TYPE_OUTGOING, | 1163 CACHE_TYPE_OUTGOING, |
| 1172 CACHED_FILE_FROM_SERVER); | 1164 CACHED_FILE_FROM_SERVER); |
| 1173 | 1165 |
| 1174 // We're not moving files here, so simply use empty FilePath for both | 1166 // We're not moving files here, so simply use empty FilePath for both |
| 1175 // |source_path| and |dest_path| because ModifyCacheState only move files | 1167 // |source_path| and |dest_path| because ModifyCacheState only move files |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1191 } | 1183 } |
| 1192 return; | 1184 return; |
| 1193 } | 1185 } |
| 1194 | 1186 |
| 1195 // Move file to persistent dir with new .local extension. | 1187 // Move file to persistent dir with new .local extension. |
| 1196 | 1188 |
| 1197 // Get the current path of the file in cache. | 1189 // Get the current path of the file in cache. |
| 1198 FilePath source_path = GetCacheFilePath( | 1190 FilePath source_path = GetCacheFilePath( |
| 1199 resource_id, | 1191 resource_id, |
| 1200 md5, | 1192 md5, |
| 1201 GetSubDirectoryType(*cache_entry), | 1193 GetSubDirectoryType(cache_entry), |
| 1202 CACHED_FILE_FROM_SERVER); | 1194 CACHED_FILE_FROM_SERVER); |
| 1203 | 1195 |
| 1204 // Determine destination path. | 1196 // Determine destination path. |
| 1205 const CacheSubDirectoryType sub_dir_type = CACHE_TYPE_PERSISTENT; | 1197 const CacheSubDirectoryType sub_dir_type = CACHE_TYPE_PERSISTENT; |
| 1206 *cache_file_path = GetCacheFilePath(resource_id, | 1198 *cache_file_path = GetCacheFilePath(resource_id, |
| 1207 md5, | 1199 md5, |
| 1208 sub_dir_type, | 1200 sub_dir_type, |
| 1209 CACHED_FILE_LOCALLY_MODIFIED); | 1201 CACHED_FILE_LOCALLY_MODIFIED); |
| 1210 | 1202 |
| 1211 // If file is pinned, update symlink in pinned dir. | 1203 // If file is pinned, update symlink in pinned dir. |
| 1212 FilePath symlink_path; | 1204 FilePath symlink_path; |
| 1213 if (cache_entry->IsPinned()) { | 1205 if (cache_entry.IsPinned()) { |
| 1214 symlink_path = GetCacheFilePath(resource_id, | 1206 symlink_path = GetCacheFilePath(resource_id, |
| 1215 std::string(), | 1207 std::string(), |
| 1216 CACHE_TYPE_PINNED, | 1208 CACHE_TYPE_PINNED, |
| 1217 CACHED_FILE_FROM_SERVER); | 1209 CACHED_FILE_FROM_SERVER); |
| 1218 } | 1210 } |
| 1219 | 1211 |
| 1220 *error = ModifyCacheState( | 1212 *error = ModifyCacheState( |
| 1221 source_path, | 1213 source_path, |
| 1222 *cache_file_path, | 1214 *cache_file_path, |
| 1223 file_operation_type, | 1215 file_operation_type, |
| 1224 symlink_path, | 1216 symlink_path, |
| 1225 !symlink_path.empty() /* create symlink */); | 1217 !symlink_path.empty() /* create symlink */); |
| 1226 | 1218 |
| 1227 if (*error == base::PLATFORM_FILE_OK) { | 1219 if (*error == base::PLATFORM_FILE_OK) { |
| 1228 // Now that file operations have completed, update cache map. | 1220 // Now that file operations have completed, update cache map. |
| 1229 GDataCacheEntry new_cache_entry(md5, cache_entry->cache_state()); | 1221 GDataCacheEntry new_cache_entry(md5, cache_entry.cache_state()); |
| 1230 new_cache_entry.SetDirty(true); | 1222 new_cache_entry.SetDirty(true); |
| 1231 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); | 1223 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); |
| 1232 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); | 1224 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); |
| 1233 } | 1225 } |
| 1234 } | 1226 } |
| 1235 | 1227 |
| 1236 void GDataCache::CommitDirty(const std::string& resource_id, | 1228 void GDataCache::CommitDirty(const std::string& resource_id, |
| 1237 const std::string& md5, | 1229 const std::string& md5, |
| 1238 FileOperationType file_operation_type, | 1230 FileOperationType file_operation_type, |
| 1239 base::PlatformFileError* error) { | 1231 base::PlatformFileError* error) { |
| 1240 AssertOnSequencedWorkerPool(); | 1232 AssertOnSequencedWorkerPool(); |
| 1241 DCHECK(error); | 1233 DCHECK(error); |
| 1242 | 1234 |
| 1243 // If file has already been marked dirty in previous instance of chrome, we | 1235 // If file has already been marked dirty in previous instance of chrome, we |
| 1244 // would have lost the md5 info during cache initialization, because the file | 1236 // would have lost the md5 info during cache initialization, because the file |
| 1245 // would have been renamed to .local extension. | 1237 // would have been renamed to .local extension. |
| 1246 // So, search for entry in cache without comparing md5. | 1238 // So, search for entry in cache without comparing md5. |
| 1247 scoped_ptr<GDataCacheEntry> cache_entry = | |
| 1248 GetCacheEntry(resource_id, std::string()); | |
| 1249 | 1239 |
| 1250 // Committing a file dirty means its entry and actual file blob must exist in | 1240 // Committing a file dirty means its entry and actual file blob must exist in |
| 1251 // cache. | 1241 // cache. |
| 1252 if (!cache_entry.get() || !cache_entry->IsPresent()) { | 1242 GDataCacheEntry cache_entry; |
| 1243 if (!GetCacheEntry(resource_id, std::string(), &cache_entry) || |
| 1244 !cache_entry.IsPresent()) { |
| 1253 LOG(WARNING) << "Can't commit dirty a file that wasn't cached: res_id=" | 1245 LOG(WARNING) << "Can't commit dirty a file that wasn't cached: res_id=" |
| 1254 << resource_id | 1246 << resource_id |
| 1255 << ", md5=" << md5; | 1247 << ", md5=" << md5; |
| 1256 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1248 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1257 return; | 1249 return; |
| 1258 } | 1250 } |
| 1259 | 1251 |
| 1260 // If a file is not dirty (it should have been marked dirty via | 1252 // If a file is not dirty (it should have been marked dirty via |
| 1261 // MarkDirtyInCache), committing it dirty is an invalid operation. | 1253 // MarkDirtyInCache), committing it dirty is an invalid operation. |
| 1262 if (!cache_entry->IsDirty()) { | 1254 if (!cache_entry.IsDirty()) { |
| 1263 LOG(WARNING) << "Can't commit a non-dirty file: res_id=" | 1255 LOG(WARNING) << "Can't commit a non-dirty file: res_id=" |
| 1264 << resource_id | 1256 << resource_id |
| 1265 << ", md5=" << md5; | 1257 << ", md5=" << md5; |
| 1266 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 1258 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 1267 return; | 1259 return; |
| 1268 } | 1260 } |
| 1269 | 1261 |
| 1270 // Dirty files must be in persistent dir. | 1262 // Dirty files must be in persistent dir. |
| 1271 DCHECK(cache_entry->IsPersistent()); | 1263 DCHECK(cache_entry.IsPersistent()); |
| 1272 | 1264 |
| 1273 // Create symlink in outgoing dir. | 1265 // Create symlink in outgoing dir. |
| 1274 FilePath symlink_path = GetCacheFilePath(resource_id, | 1266 FilePath symlink_path = GetCacheFilePath(resource_id, |
| 1275 std::string(), | 1267 std::string(), |
| 1276 CACHE_TYPE_OUTGOING, | 1268 CACHE_TYPE_OUTGOING, |
| 1277 CACHED_FILE_FROM_SERVER); | 1269 CACHED_FILE_FROM_SERVER); |
| 1278 | 1270 |
| 1279 // Get target path of symlink i.e. current path of the file in cache. | 1271 // Get target path of symlink i.e. current path of the file in cache. |
| 1280 FilePath target_path = GetCacheFilePath(resource_id, | 1272 FilePath target_path = GetCacheFilePath(resource_id, |
| 1281 md5, | 1273 md5, |
| 1282 GetSubDirectoryType(*cache_entry), | 1274 GetSubDirectoryType(cache_entry), |
| 1283 CACHED_FILE_LOCALLY_MODIFIED); | 1275 CACHED_FILE_LOCALLY_MODIFIED); |
| 1284 | 1276 |
| 1285 // Since there's no need to move files, use |target_path| for both | 1277 // Since there's no need to move files, use |target_path| for both |
| 1286 // |source_path| and |dest_path|, because ModifyCacheState only moves files | 1278 // |source_path| and |dest_path|, because ModifyCacheState only moves files |
| 1287 // if source and destination are different. | 1279 // if source and destination are different. |
| 1288 *error = ModifyCacheState(target_path, // source | 1280 *error = ModifyCacheState(target_path, // source |
| 1289 target_path, // destination | 1281 target_path, // destination |
| 1290 file_operation_type, | 1282 file_operation_type, |
| 1291 symlink_path, | 1283 symlink_path, |
| 1292 true /* create symlink */); | 1284 true /* create symlink */); |
| 1293 } | 1285 } |
| 1294 | 1286 |
| 1295 void GDataCache::ClearDirty(const std::string& resource_id, | 1287 void GDataCache::ClearDirty(const std::string& resource_id, |
| 1296 const std::string& md5, | 1288 const std::string& md5, |
| 1297 FileOperationType file_operation_type, | 1289 FileOperationType file_operation_type, |
| 1298 base::PlatformFileError* error) { | 1290 base::PlatformFileError* error) { |
| 1299 AssertOnSequencedWorkerPool(); | 1291 AssertOnSequencedWorkerPool(); |
| 1300 DCHECK(error); | 1292 DCHECK(error); |
| 1301 | 1293 |
| 1302 // |md5| is the new .<md5> extension to rename the file to. | 1294 // |md5| is the new .<md5> extension to rename the file to. |
| 1303 // So, search for entry in cache without comparing md5. | 1295 // So, search for entry in cache without comparing md5. |
| 1304 scoped_ptr<GDataCacheEntry> cache_entry = | 1296 GDataCacheEntry cache_entry; |
| 1305 GetCacheEntry(resource_id, std::string()); | |
| 1306 | 1297 |
| 1307 // Clearing a dirty file means its entry and actual file blob must exist in | 1298 // Clearing a dirty file means its entry and actual file blob must exist in |
| 1308 // cache. | 1299 // cache. |
| 1309 if (!cache_entry.get() || !cache_entry->IsPresent()) { | 1300 if (!GetCacheEntry(resource_id, std::string(), &cache_entry) || |
| 1301 !cache_entry.IsPresent()) { |
| 1310 LOG(WARNING) << "Can't clear dirty state of a file that wasn't cached: " | 1302 LOG(WARNING) << "Can't clear dirty state of a file that wasn't cached: " |
| 1311 << "res_id=" << resource_id | 1303 << "res_id=" << resource_id |
| 1312 << ", md5=" << md5; | 1304 << ", md5=" << md5; |
| 1313 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1305 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1314 return; | 1306 return; |
| 1315 } | 1307 } |
| 1316 | 1308 |
| 1317 // If a file is not dirty (it should have been marked dirty via | 1309 // If a file is not dirty (it should have been marked dirty via |
| 1318 // MarkDirtyInCache), clearing its dirty state is an invalid operation. | 1310 // MarkDirtyInCache), clearing its dirty state is an invalid operation. |
| 1319 if (!cache_entry->IsDirty()) { | 1311 if (!cache_entry.IsDirty()) { |
| 1320 LOG(WARNING) << "Can't clear dirty state of a non-dirty file: res_id=" | 1312 LOG(WARNING) << "Can't clear dirty state of a non-dirty file: res_id=" |
| 1321 << resource_id | 1313 << resource_id |
| 1322 << ", md5=" << md5; | 1314 << ", md5=" << md5; |
| 1323 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 1315 *error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 1324 return; | 1316 return; |
| 1325 } | 1317 } |
| 1326 | 1318 |
| 1327 // File must be dirty and hence in persistent dir. | 1319 // File must be dirty and hence in persistent dir. |
| 1328 DCHECK(cache_entry->IsPersistent()); | 1320 DCHECK(cache_entry.IsPersistent()); |
| 1329 | 1321 |
| 1330 // Get the current path of the file in cache. | 1322 // Get the current path of the file in cache. |
| 1331 FilePath source_path = GetCacheFilePath(resource_id, | 1323 FilePath source_path = GetCacheFilePath(resource_id, |
| 1332 md5, | 1324 md5, |
| 1333 GetSubDirectoryType(*cache_entry), | 1325 GetSubDirectoryType(cache_entry), |
| 1334 CACHED_FILE_LOCALLY_MODIFIED); | 1326 CACHED_FILE_LOCALLY_MODIFIED); |
| 1335 | 1327 |
| 1336 // Determine destination path. | 1328 // Determine destination path. |
| 1337 // If file is pinned, move it to persistent dir with .md5 extension; | 1329 // If file is pinned, move it to persistent dir with .md5 extension; |
| 1338 // otherwise, move it to tmp dir with .md5 extension. | 1330 // otherwise, move it to tmp dir with .md5 extension. |
| 1339 const CacheSubDirectoryType sub_dir_type = | 1331 const CacheSubDirectoryType sub_dir_type = |
| 1340 cache_entry->IsPinned() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; | 1332 cache_entry.IsPinned() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; |
| 1341 FilePath dest_path = GetCacheFilePath(resource_id, | 1333 FilePath dest_path = GetCacheFilePath(resource_id, |
| 1342 md5, | 1334 md5, |
| 1343 sub_dir_type, | 1335 sub_dir_type, |
| 1344 CACHED_FILE_FROM_SERVER); | 1336 CACHED_FILE_FROM_SERVER); |
| 1345 | 1337 |
| 1346 // Delete symlink in outgoing dir. | 1338 // Delete symlink in outgoing dir. |
| 1347 FilePath symlink_path = GetCacheFilePath(resource_id, | 1339 FilePath symlink_path = GetCacheFilePath(resource_id, |
| 1348 std::string(), | 1340 std::string(), |
| 1349 CACHE_TYPE_OUTGOING, | 1341 CACHE_TYPE_OUTGOING, |
| 1350 CACHED_FILE_FROM_SERVER); | 1342 CACHED_FILE_FROM_SERVER); |
| 1351 | 1343 |
| 1352 *error = ModifyCacheState(source_path, | 1344 *error = ModifyCacheState(source_path, |
| 1353 dest_path, | 1345 dest_path, |
| 1354 file_operation_type, | 1346 file_operation_type, |
| 1355 symlink_path, | 1347 symlink_path, |
| 1356 false /* don't create symlink */); | 1348 false /* don't create symlink */); |
| 1357 | 1349 |
| 1358 // If file is pinned, update symlink in pinned dir. | 1350 // If file is pinned, update symlink in pinned dir. |
| 1359 if (*error == base::PLATFORM_FILE_OK && cache_entry->IsPinned()) { | 1351 if (*error == base::PLATFORM_FILE_OK && cache_entry.IsPinned()) { |
| 1360 symlink_path = GetCacheFilePath(resource_id, | 1352 symlink_path = GetCacheFilePath(resource_id, |
| 1361 std::string(), | 1353 std::string(), |
| 1362 CACHE_TYPE_PINNED, | 1354 CACHE_TYPE_PINNED, |
| 1363 CACHED_FILE_FROM_SERVER); | 1355 CACHED_FILE_FROM_SERVER); |
| 1364 | 1356 |
| 1365 // Since there's no moving of files here, use |dest_path| for both | 1357 // Since there's no moving of files here, use |dest_path| for both |
| 1366 // |source_path| and |dest_path|, because ModifyCacheState only moves files | 1358 // |source_path| and |dest_path|, because ModifyCacheState only moves files |
| 1367 // if source and destination are different. | 1359 // if source and destination are different. |
| 1368 *error = ModifyCacheState(dest_path, // source path | 1360 *error = ModifyCacheState(dest_path, // source path |
| 1369 dest_path, // destination path | 1361 dest_path, // destination path |
| 1370 file_operation_type, | 1362 file_operation_type, |
| 1371 symlink_path, | 1363 symlink_path, |
| 1372 true /* create symlink */); | 1364 true /* create symlink */); |
| 1373 } | 1365 } |
| 1374 | 1366 |
| 1375 if (*error == base::PLATFORM_FILE_OK) { | 1367 if (*error == base::PLATFORM_FILE_OK) { |
| 1376 // Now that file operations have completed, update cache map. | 1368 // Now that file operations have completed, update cache map. |
| 1377 GDataCacheEntry new_cache_entry(md5, cache_entry->cache_state()); | 1369 GDataCacheEntry new_cache_entry(md5, cache_entry.cache_state()); |
| 1378 new_cache_entry.SetDirty(false); | 1370 new_cache_entry.SetDirty(false); |
| 1379 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); | 1371 new_cache_entry.SetPersistent(sub_dir_type == CACHE_TYPE_PERSISTENT); |
| 1380 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); | 1372 metadata_->AddOrUpdateCacheEntry(resource_id, new_cache_entry); |
| 1381 } | 1373 } |
| 1382 } | 1374 } |
| 1383 | 1375 |
| 1384 void GDataCache::Remove(const std::string& resource_id, | 1376 void GDataCache::Remove(const std::string& resource_id, |
| 1385 base::PlatformFileError* error) { | 1377 base::PlatformFileError* error) { |
| 1386 AssertOnSequencedWorkerPool(); | 1378 AssertOnSequencedWorkerPool(); |
| 1387 DCHECK(error); | 1379 DCHECK(error); |
| 1388 | 1380 |
| 1389 // MD5 is not passed into RemoveCacheEntry because we would delete all | 1381 // MD5 is not passed into RemoveCacheEntry because we would delete all |
| 1390 // cache files corresponding to <resource_id> regardless of the md5. | 1382 // cache files corresponding to <resource_id> regardless of the md5. |
| 1391 // So, search for entry in cache without taking md5 into account. | 1383 // So, search for entry in cache without taking md5 into account. |
| 1392 scoped_ptr<GDataCacheEntry> cache_entry = | 1384 GDataCacheEntry cache_entry; |
| 1393 GetCacheEntry(resource_id, std::string()); | |
| 1394 | 1385 |
| 1395 // If entry doesn't exist or is dirty or mounted in cache, nothing to do. | 1386 // If entry doesn't exist or is dirty or mounted in cache, nothing to do. |
| 1396 if (!cache_entry.get() || | 1387 const bool entry_found = |
| 1397 cache_entry->IsDirty() || | 1388 GetCacheEntry(resource_id, std::string(), &cache_entry); |
| 1398 cache_entry->IsMounted()) { | 1389 if (!entry_found || cache_entry.IsDirty() || cache_entry.IsMounted()) { |
| 1399 DVLOG(1) << "Entry is " | 1390 DVLOG(1) << "Entry is " |
| 1400 << (cache_entry.get() ? | 1391 << (entry_found ? |
| 1401 (cache_entry->IsDirty() ? "dirty" : "mounted") : | 1392 (cache_entry.IsDirty() ? "dirty" : "mounted") : |
| 1402 "non-existent") | 1393 "non-existent") |
| 1403 << " in cache, not removing"; | 1394 << " in cache, not removing"; |
| 1404 *error = base::PLATFORM_FILE_OK; | 1395 *error = base::PLATFORM_FILE_OK; |
| 1405 return; | 1396 return; |
| 1406 } | 1397 } |
| 1407 | 1398 |
| 1408 // Determine paths to delete all cache versions of |resource_id| in | 1399 // Determine paths to delete all cache versions of |resource_id| in |
| 1409 // persistent, tmp and pinned directories. | 1400 // persistent, tmp and pinned directories. |
| 1410 std::vector<FilePath> paths_to_delete; | 1401 std::vector<FilePath> paths_to_delete; |
| 1411 | 1402 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 } | 1489 } |
| 1499 | 1490 |
| 1500 void GDataCache::GetCacheEntryHelper(const std::string& resource_id, | 1491 void GDataCache::GetCacheEntryHelper(const std::string& resource_id, |
| 1501 const std::string& md5, | 1492 const std::string& md5, |
| 1502 bool* success, | 1493 bool* success, |
| 1503 GDataCacheEntry* cache_entry) { | 1494 GDataCacheEntry* cache_entry) { |
| 1504 AssertOnSequencedWorkerPool(); | 1495 AssertOnSequencedWorkerPool(); |
| 1505 DCHECK(success); | 1496 DCHECK(success); |
| 1506 DCHECK(cache_entry); | 1497 DCHECK(cache_entry); |
| 1507 | 1498 |
| 1508 scoped_ptr<GDataCacheEntry> value(GetCacheEntry(resource_id, md5)); | 1499 *success = GetCacheEntry(resource_id, md5, cache_entry); |
| 1509 *success = value.get(); | |
| 1510 if (*success) | |
| 1511 *cache_entry = *value; | |
| 1512 } | 1500 } |
| 1513 | 1501 |
| 1514 // static | 1502 // static |
| 1515 FilePath GDataCache::GetCacheRootPath(Profile* profile) { | 1503 FilePath GDataCache::GetCacheRootPath(Profile* profile) { |
| 1516 FilePath cache_base_path; | 1504 FilePath cache_base_path; |
| 1517 chrome::GetUserCacheDirectory(profile->GetPath(), &cache_base_path); | 1505 chrome::GetUserCacheDirectory(profile->GetPath(), &cache_base_path); |
| 1518 FilePath cache_root_path = | 1506 FilePath cache_root_path = |
| 1519 cache_base_path.Append(chrome::kGDataCacheDirname); | 1507 cache_base_path.Append(chrome::kGDataCacheDirname); |
| 1520 return cache_root_path.Append(kGDataCacheVersionDir); | 1508 return cache_root_path.Append(kGDataCacheVersionDir); |
| 1521 } | 1509 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 const GDataCacheEntry& cache_entry) { | 1548 const GDataCacheEntry& cache_entry) { |
| 1561 return cache_entry.IsPersistent() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; | 1549 return cache_entry.IsPersistent() ? CACHE_TYPE_PERSISTENT : CACHE_TYPE_TMP; |
| 1562 } | 1550 } |
| 1563 | 1551 |
| 1564 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { | 1552 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { |
| 1565 delete global_free_disk_getter_for_testing; // Safe to delete NULL; | 1553 delete global_free_disk_getter_for_testing; // Safe to delete NULL; |
| 1566 global_free_disk_getter_for_testing = getter; | 1554 global_free_disk_getter_for_testing = getter; |
| 1567 } | 1555 } |
| 1568 | 1556 |
| 1569 } // namespace gdata | 1557 } // namespace gdata |
| OLD | NEW |