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

Side by Side Diff: webkit/fileapi/obfuscated_file_system_file_util.cc

Issue 7608018: Handle inconsistency between DB and Files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed regression Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webkit/fileapi/file_system_usage_cache.cc ('k') | webkit/fileapi/obfuscated_file_system_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698