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 |