| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/fileapi/obfuscated_file_system_file_util.h" | 5 #include "webkit/fileapi/obfuscated_file_system_file_util.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 if (file_flags & base::PLATFORM_FILE_CREATE) | 148 if (file_flags & base::PLATFORM_FILE_CREATE) |
| 149 return base::PLATFORM_FILE_ERROR_EXISTS; | 149 return base::PLATFORM_FILE_ERROR_EXISTS; |
| 150 | 150 |
| 151 FileInfo file_info; | 151 FileInfo file_info; |
| 152 if (!db->GetFileInfo(file_id, &file_info)) { | 152 if (!db->GetFileInfo(file_id, &file_info)) { |
| 153 NOTREACHED(); | 153 NOTREACHED(); |
| 154 return base::PLATFORM_FILE_ERROR_FAILED; | 154 return base::PLATFORM_FILE_ERROR_FAILED; |
| 155 } | 155 } |
| 156 if (file_info.is_directory()) | 156 if (file_info.is_directory()) |
| 157 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 157 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 158 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | 158 FilePath local_path = DataPathToLocalPath(context->src_origin_url(), |
| 159 context->src_type(), file_info.data_path); | 159 context->src_type(), file_info.data_path); |
| 160 return underlying_file_util_->CreateOrOpen( | 160 base::PlatformFileError error = underlying_file_util_->CreateOrOpen( |
| 161 context, data_path, file_flags, file_handle, created); | 161 context, local_path, file_flags, file_handle, created); |
| 162 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { |
| 163 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. |
| 164 // TODO(tzik): Delete database entry after ensuring the file lost. |
| 165 context->file_system_context()->GetQuotaUtil(context->src_type())-> |
| 166 InvalidateUsageCache(context->src_origin_url(), |
| 167 context->src_type()); |
| 168 LOG(WARNING) << "Lost a backing file."; |
| 169 error = base::PLATFORM_FILE_ERROR_FAILED; |
| 170 } |
| 171 return error; |
| 162 } | 172 } |
| 163 | 173 |
| 164 PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( | 174 PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( |
| 165 FileSystemOperationContext* context, | 175 FileSystemOperationContext* context, |
| 166 const FilePath& virtual_path, | 176 const FilePath& virtual_path, |
| 167 bool* created) { | 177 bool* created) { |
| 168 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 178 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 169 context->src_origin_url(), context->src_type(), true); | 179 context->src_origin_url(), context->src_type(), true); |
| 170 if (!db) | 180 if (!db) |
| 171 return base::PLATFORM_FILE_ERROR_FAILED; | 181 return base::PLATFORM_FILE_ERROR_FAILED; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 * transaction: | 388 * transaction: |
| 379 * Remove source entry. | 389 * Remove source entry. |
| 380 * Point target entry to source entry's backing file. | 390 * Point target entry to source entry's backing file. |
| 381 * Delete target entry's old backing file | 391 * Delete target entry's old backing file |
| 382 * Move-without-overwrite | 392 * Move-without-overwrite |
| 383 * Just update metadata | 393 * Just update metadata |
| 384 */ | 394 */ |
| 385 if (copy) { | 395 if (copy) { |
| 386 FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(), | 396 FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(), |
| 387 context->src_type(), src_file_info.data_path); | 397 context->src_type(), src_file_info.data_path); |
| 398 if (!underlying_file_util_->PathExists(context, src_data_path)) { |
| 399 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. |
| 400 context->file_system_context()->GetQuotaUtil(context->src_type())-> |
| 401 InvalidateUsageCache(context->src_origin_url(), |
| 402 context->src_type()); |
| 403 LOG(WARNING) << "Lost a backing file."; |
| 404 return base::PLATFORM_FILE_ERROR_FAILED; |
| 405 } |
| 406 |
| 388 if (overwrite) { | 407 if (overwrite) { |
| 389 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), | 408 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), |
| 390 context->src_type(), dest_file_info.data_path); | 409 context->src_type(), dest_file_info.data_path); |
| 391 return underlying_file_util_->CopyOrMoveFile(context, | 410 return underlying_file_util_->CopyOrMoveFile(context, |
| 392 src_data_path, dest_data_path, copy); | 411 src_data_path, dest_data_path, copy); |
| 393 } else { | 412 } else { |
| 394 FileId dest_parent_id; | 413 FileId dest_parent_id; |
| 395 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 414 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
| 396 NOTREACHED(); // We shouldn't be called in this case. | 415 NOTREACHED(); // We shouldn't be called in this case. |
| 397 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 416 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 FileInfo* file_info, int file_flags, PlatformFile* handle) { | 836 FileInfo* file_info, int file_flags, PlatformFile* handle) { |
| 818 if (handle) | 837 if (handle) |
| 819 *handle = base::kInvalidPlatformFileValue; | 838 *handle = base::kInvalidPlatformFileValue; |
| 820 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 839 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 821 origin_url, type, true); | 840 origin_url, type, true); |
| 822 int64 number; | 841 int64 number; |
| 823 if (!db || !db->GetNextInteger(&number)) | 842 if (!db || !db->GetNextInteger(&number)) |
| 824 return base::PLATFORM_FILE_ERROR_FAILED; | 843 return base::PLATFORM_FILE_ERROR_FAILED; |
| 825 // We use the third- and fourth-to-last digits as the directory. | 844 // We use the third- and fourth-to-last digits as the directory. |
| 826 int64 directory_number = number % 10000 / 100; | 845 int64 directory_number = number % 10000 / 100; |
| 827 FilePath path = | 846 // TODO(ericu): local_path is an OS path; underlying_file_util_ isn't |
| 847 // guaranteed to understand OS paths. |
| 848 FilePath local_path = |
| 828 GetDirectoryForOriginAndType(origin_url, type, false); | 849 GetDirectoryForOriginAndType(origin_url, type, false); |
| 829 if (path.empty()) | 850 if (local_path.empty()) |
| 830 return base::PLATFORM_FILE_ERROR_FAILED; | 851 return base::PLATFORM_FILE_ERROR_FAILED; |
| 831 | 852 |
| 832 path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); | 853 local_path = local_path.AppendASCII(StringPrintf("%02" PRIu64, |
| 854 directory_number)); |
| 833 PlatformFileError error; | 855 PlatformFileError error; |
| 834 error = underlying_file_util_->CreateDirectory( | 856 error = underlying_file_util_->CreateDirectory( |
| 835 context, path, false /* exclusive */, false /* recursive */); | 857 context, local_path, false /* exclusive */, false /* recursive */); |
| 836 if (base::PLATFORM_FILE_OK != error) | 858 if (base::PLATFORM_FILE_OK != error) |
| 837 return error; | 859 return error; |
| 838 path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); | 860 local_path = local_path.AppendASCII(StringPrintf("%08" PRIu64, number)); |
| 839 FilePath data_path = LocalPathToDataPath(origin_url, type, path); | 861 FilePath data_path = LocalPathToDataPath(origin_url, type, local_path); |
| 840 if (data_path.empty()) | 862 if (data_path.empty()) |
| 841 return base::PLATFORM_FILE_ERROR_FAILED; | 863 return base::PLATFORM_FILE_ERROR_FAILED; |
| 842 bool created = false; | 864 bool created = false; |
| 843 if (!source_path.empty()) { | 865 if (!source_path.empty()) { |
| 844 DCHECK(!file_flags); | 866 DCHECK(!file_flags); |
| 845 DCHECK(!handle); | 867 DCHECK(!handle); |
| 846 error = underlying_file_util_->CopyOrMoveFile( | 868 error = underlying_file_util_->CopyOrMoveFile( |
| 847 context, source_path, path, true /* copy */); | 869 context, source_path, local_path, true /* copy */); |
| 848 created = true; | 870 created = true; |
| 849 } else { | 871 } else { |
| 872 FilePath path; |
| 873 underlying_file_util_->GetLocalFilePath(context, local_path, &path); |
| 874 if (file_util::PathExists(path)) { |
| 875 if (!file_util::Delete(path, true)) { |
| 876 NOTREACHED(); |
| 877 return base::PLATFORM_FILE_ERROR_FAILED; |
| 878 } |
| 879 LOG(WARNING) << "A stray file detected"; |
| 880 context->file_system_context()->GetQuotaUtil(context->src_type())-> |
| 881 InvalidateUsageCache(context->src_origin_url(), context->src_type()); |
| 882 } |
| 883 |
| 850 if (handle) { | 884 if (handle) { |
| 851 error = underlying_file_util_->CreateOrOpen( | 885 error = underlying_file_util_->CreateOrOpen( |
| 852 context, path, file_flags, handle, &created); | 886 context, local_path, file_flags, handle, &created); |
| 853 // If this succeeds, we must close handle on any subsequent error. | 887 // If this succeeds, we must close handle on any subsequent error. |
| 854 } else { | 888 } else { |
| 855 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. | 889 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. |
| 856 error = underlying_file_util_->EnsureFileExists( | 890 error = underlying_file_util_->EnsureFileExists( |
| 857 context, path, &created); | 891 context, local_path, &created); |
| 858 } | 892 } |
| 859 } | 893 } |
| 860 if (error != base::PLATFORM_FILE_OK) | 894 if (error != base::PLATFORM_FILE_OK) |
| 861 return error; | 895 return error; |
| 862 | 896 |
| 863 if (!created) { | 897 if (!created) { |
| 864 NOTREACHED(); | 898 NOTREACHED(); |
| 865 if (handle) { | 899 if (handle) { |
| 866 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); | 900 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
| 867 base::ClosePlatformFile(*handle); | 901 base::ClosePlatformFile(*handle); |
| 868 underlying_file_util_->DeleteFile(context, path); | 902 underlying_file_util_->DeleteFile(context, local_path); |
| 869 } | 903 } |
| 870 return base::PLATFORM_FILE_ERROR_FAILED; | 904 return base::PLATFORM_FILE_ERROR_FAILED; |
| 871 } | 905 } |
| 872 file_info->data_path = data_path; | 906 file_info->data_path = data_path; |
| 873 FileId file_id; | 907 FileId file_id; |
| 874 if (!db->AddFileInfo(*file_info, &file_id)) { | 908 if (!db->AddFileInfo(*file_info, &file_id)) { |
| 875 if (handle) { | 909 if (handle) { |
| 876 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); | 910 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
| 877 base::ClosePlatformFile(*handle); | 911 base::ClosePlatformFile(*handle); |
| 878 } | 912 } |
| 879 underlying_file_util_->DeleteFile(context, path); | 913 underlying_file_util_->DeleteFile(context, local_path); |
| 880 return base::PLATFORM_FILE_ERROR_FAILED; | 914 return base::PLATFORM_FILE_ERROR_FAILED; |
| 881 } | 915 } |
| 882 UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size()); | 916 UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size()); |
| 883 | 917 |
| 884 return base::PLATFORM_FILE_OK; | 918 return base::PLATFORM_FILE_OK; |
| 885 } | 919 } |
| 886 | 920 |
| 887 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( | 921 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( |
| 888 const GURL& origin_url, | 922 const GURL& origin_url, |
| 889 FileSystemType type, | 923 FileSystemType type, |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 directories_[key] = database; | 1120 directories_[key] = database; |
| 1087 return database; | 1121 return database; |
| 1088 } | 1122 } |
| 1089 | 1123 |
| 1090 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( | 1124 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( |
| 1091 const GURL& origin, bool create) { | 1125 const GURL& origin, bool create) { |
| 1092 if (!InitOriginDatabase(create)) | 1126 if (!InitOriginDatabase(create)) |
| 1093 return FilePath(); | 1127 return FilePath(); |
| 1094 FilePath directory_name; | 1128 FilePath directory_name; |
| 1095 std::string id = GetOriginIdentifierFromURL(origin); | 1129 std::string id = GetOriginIdentifierFromURL(origin); |
| 1096 if (!create && !origin_database_->HasOriginPath(id)) | 1130 |
| 1131 bool exists_in_db = origin_database_->HasOriginPath(id); |
| 1132 if (!exists_in_db && !create) |
| 1097 return FilePath(); | 1133 return FilePath(); |
| 1098 if (!origin_database_->GetPathForOrigin(id, &directory_name)) | 1134 if (!origin_database_->GetPathForOrigin(id, &directory_name)) |
| 1099 return FilePath(); | 1135 return FilePath(); |
| 1136 |
| 1100 FilePath path = file_system_directory_.Append(directory_name); | 1137 FilePath path = file_system_directory_.Append(directory_name); |
| 1101 if (!file_util::DirectoryExists(path) && | 1138 bool exists_in_fs = file_util::DirectoryExists(path); |
| 1102 (!create || !file_util::CreateDirectory(path))) | 1139 if (!exists_in_db && exists_in_fs) { |
| 1103 return FilePath(); | 1140 if (!file_util::Delete(path, true)) |
| 1141 return FilePath(); |
| 1142 exists_in_fs = false; |
| 1143 } |
| 1144 |
| 1145 if (!exists_in_fs) { |
| 1146 if (!create || !file_util::CreateDirectory(path)) |
| 1147 return FilePath(); |
| 1148 } |
| 1149 |
| 1104 return path; | 1150 return path; |
| 1105 } | 1151 } |
| 1106 | 1152 |
| 1107 void ObfuscatedFileSystemFileUtil::MarkUsed() { | 1153 void ObfuscatedFileSystemFileUtil::MarkUsed() { |
| 1108 if (timer_.IsRunning()) | 1154 if (timer_.IsRunning()) |
| 1109 timer_.Reset(); | 1155 timer_.Reset(); |
| 1110 else | 1156 else |
| 1111 timer_.Start(base::TimeDelta::FromSeconds(kFlushDelaySeconds), this, | 1157 timer_.Start(base::TimeDelta::FromSeconds(kFlushDelaySeconds), this, |
| 1112 &ObfuscatedFileSystemFileUtil::DropDatabases); | 1158 &ObfuscatedFileSystemFileUtil::DropDatabases); |
| 1113 } | 1159 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 return false; | 1205 return false; |
| 1160 } | 1206 } |
| 1161 origin_database_.reset( | 1207 origin_database_.reset( |
| 1162 new FileSystemOriginDatabase( | 1208 new FileSystemOriginDatabase( |
| 1163 file_system_directory_.AppendASCII(kOriginDatabaseName))); | 1209 file_system_directory_.AppendASCII(kOriginDatabaseName))); |
| 1164 } | 1210 } |
| 1165 return true; | 1211 return true; |
| 1166 } | 1212 } |
| 1167 | 1213 |
| 1168 } // namespace fileapi | 1214 } // namespace fileapi |
| OLD | NEW |