Chromium Code Reviews| 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 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/format_macros.h" | |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 12 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
| 14 #include "base/stringprintf.h" | |
| 13 #include "base/sys_string_conversions.h" | 15 #include "base/sys_string_conversions.h" |
| 14 #include "base/stl_util-inl.h" | 16 #include "base/stl_util-inl.h" |
| 15 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
| 16 #include "webkit/fileapi/file_system_context.h" | 18 #include "webkit/fileapi/file_system_context.h" |
| 17 #include "webkit/fileapi/file_system_operation_context.h" | 19 #include "webkit/fileapi/file_system_operation_context.h" |
| 18 #include "webkit/fileapi/file_system_path_manager.h" | 20 #include "webkit/fileapi/file_system_path_manager.h" |
| 19 #include "webkit/fileapi/quota_file_util.h" | 21 #include "webkit/fileapi/quota_file_util.h" |
| 20 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 22 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
| 21 | 23 |
| 22 // TODO(ericu): Every instance of FileSystemFileUtil in this file should switch | 24 // TODO(ericu): Every instance of FileSystemFileUtil in this file should switch |
| 23 // to QuotaFileUtil as soon as I sort out FileSystemPathManager's and | 25 // to QuotaFileUtil as soon as I sort out FileSystemPathManager's and |
| 24 // SandboxMountPointProvider's lookups of the root path for a filesystem. | 26 // SandboxMountPointProvider's lookups of the root path for a filesystem. |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 const int64 kFlushDelaySeconds = 10 * 60; // 10 minutes | 29 const int64 kFlushDelaySeconds = 10 * 60; // 10 minutes |
| 28 | 30 |
| 29 const char kOriginDatabaseName[] = "Origins"; | 31 const char kOriginDatabaseName[] = "Origins"; |
| 30 const char kDirectoryDatabaseName[] = "Paths"; | 32 const char kDirectoryDatabaseName[] = "Paths"; |
| 31 | 33 |
| 32 void InitFileInfo( | 34 void InitFileInfo( |
| 33 fileapi::FileSystemDirectoryDatabase::FileInfo* file_info, | 35 fileapi::FileSystemDirectoryDatabase::FileInfo* file_info, |
| 34 fileapi::FileSystemDirectoryDatabase::FileId parent_id, | 36 fileapi::FileSystemDirectoryDatabase::FileId parent_id, |
| 35 const FilePath::StringType& file_name, | 37 const FilePath::StringType& file_name) { |
| 36 const FilePath& data_path) { | |
| 37 DCHECK(file_info); | 38 DCHECK(file_info); |
| 38 file_info->parent_id = parent_id; | 39 file_info->parent_id = parent_id; |
| 39 file_info->data_path = data_path; | |
| 40 file_info->name = file_name; | 40 file_info->name = file_name; |
| 41 } | 41 } |
| 42 | 42 |
| 43 const FilePath::CharType kLegacyDataDirectory[] = FILE_PATH_LITERAL("Legacy"); | |
| 44 | |
| 45 const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t"); | |
| 46 const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p"); | |
| 47 | |
| 43 } // namespace | 48 } // namespace |
| 44 | 49 |
| 45 namespace fileapi { | 50 namespace fileapi { |
| 46 | 51 |
| 47 using base::PlatformFile; | 52 using base::PlatformFile; |
| 48 using base::PlatformFileError; | 53 using base::PlatformFileError; |
| 49 | 54 |
| 50 ObfuscatedFileSystemFileUtil::ObfuscatedFileSystemFileUtil( | 55 ObfuscatedFileSystemFileUtil::ObfuscatedFileSystemFileUtil( |
| 51 const FilePath& file_system_directory) | 56 const FilePath& file_system_directory) |
| 52 : file_system_directory_(file_system_directory) { | 57 : file_system_directory_(file_system_directory) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 70 FileId file_id; | 75 FileId file_id; |
| 71 if (!db->GetFileWithPath(virtual_path, &file_id)) { | 76 if (!db->GetFileWithPath(virtual_path, &file_id)) { |
| 72 // The file doesn't exist. | 77 // The file doesn't exist. |
| 73 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | 78 if (!(file_flags & (base::PLATFORM_FILE_CREATE | |
| 74 base::PLATFORM_FILE_CREATE_ALWAYS))) | 79 base::PLATFORM_FILE_CREATE_ALWAYS))) |
| 75 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 80 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 76 FileId parent_id; | 81 FileId parent_id; |
| 77 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 82 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
| 78 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 83 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 79 FileInfo file_info; | 84 FileInfo file_info; |
| 80 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(), | 85 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
| 81 FilePath()); | |
| 82 PlatformFileError error = CreateFile( | 86 PlatformFileError error = CreateFile( |
| 83 context, context->src_origin_url(), context->src_type(), &file_info, | 87 context, context->src_origin_url(), context->src_type(), FilePath(), |
| 84 file_flags, file_handle); | 88 &file_info, file_flags, file_handle); |
| 85 if (created && base::PLATFORM_FILE_OK == error) | 89 if (created && base::PLATFORM_FILE_OK == error) |
| 86 *created = true; | 90 *created = true; |
| 87 return error; | 91 return error; |
| 88 } | 92 } |
| 89 if (file_flags & base::PLATFORM_FILE_CREATE) | 93 if (file_flags & base::PLATFORM_FILE_CREATE) |
| 90 return base::PLATFORM_FILE_ERROR_EXISTS; | 94 return base::PLATFORM_FILE_ERROR_EXISTS; |
| 91 | 95 |
| 92 FileInfo file_info; | 96 FileInfo file_info; |
| 93 if (!db->GetFileInfo(file_id, &file_info)) { | 97 if (!db->GetFileInfo(file_id, &file_info)) { |
| 94 NOTREACHED(); | 98 NOTREACHED(); |
| 95 return base::PLATFORM_FILE_ERROR_FAILED; | 99 return base::PLATFORM_FILE_ERROR_FAILED; |
| 96 } | 100 } |
| 97 if (file_info.is_directory()) | 101 if (file_info.is_directory()) |
| 98 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 102 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 103 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 104 context->src_type(), file_info.data_path); | |
| 99 return FileSystemFileUtil::GetInstance()->CreateOrOpen( | 105 return FileSystemFileUtil::GetInstance()->CreateOrOpen( |
| 100 context, file_info.data_path, file_flags, file_handle, created); | 106 context, data_path, file_flags, file_handle, created); |
| 101 } | 107 } |
| 102 | 108 |
| 103 PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( | 109 PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists( |
| 104 FileSystemOperationContext* context, | 110 FileSystemOperationContext* context, |
| 105 const FilePath& virtual_path, | 111 const FilePath& virtual_path, |
| 106 bool* created) { | 112 bool* created) { |
| 107 FileSystemDirectoryDatabase* db = | 113 FileSystemDirectoryDatabase* db = |
| 108 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); | 114 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); |
| 109 if (!db) | 115 if (!db) |
| 110 return base::PLATFORM_FILE_ERROR_FAILED; | 116 return base::PLATFORM_FILE_ERROR_FAILED; |
| 111 FileId file_id; | 117 FileId file_id; |
| 112 if (db->GetFileWithPath(virtual_path, &file_id)) { | 118 if (db->GetFileWithPath(virtual_path, &file_id)) { |
| 113 FileInfo file_info; | 119 FileInfo file_info; |
| 114 if (!db->GetFileInfo(file_id, &file_info)) { | 120 if (!db->GetFileInfo(file_id, &file_info)) { |
| 115 NOTREACHED(); | 121 NOTREACHED(); |
| 116 return base::PLATFORM_FILE_ERROR_FAILED; | 122 return base::PLATFORM_FILE_ERROR_FAILED; |
| 117 } | 123 } |
| 118 if (file_info.is_directory()) | 124 if (file_info.is_directory()) |
| 119 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 125 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 120 if (created) | 126 if (created) |
| 121 *created = false; | 127 *created = false; |
| 122 return base::PLATFORM_FILE_OK; | 128 return base::PLATFORM_FILE_OK; |
| 123 } | 129 } |
| 124 FileId parent_id; | 130 FileId parent_id; |
| 125 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 131 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
| 126 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 132 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 127 | 133 |
| 128 FileInfo file_info; | 134 FileInfo file_info; |
| 129 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(), | 135 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
| 130 FilePath()); | 136 PlatformFileError error = CreateFile(context, context->src_origin_url(), |
| 131 PlatformFileError error = CreateFile(context, | 137 context->src_type(), FilePath(), &file_info, 0, NULL); |
| 132 context->src_origin_url(), context->src_type(), &file_info, 0, NULL); | |
| 133 if (created && base::PLATFORM_FILE_OK == error) | 138 if (created && base::PLATFORM_FILE_OK == error) |
| 134 *created = true; | 139 *created = true; |
| 135 return error; | 140 return error; |
| 136 } | 141 } |
| 137 | 142 |
| 138 PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( | 143 PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( |
| 139 FileSystemOperationContext* context, | 144 FileSystemOperationContext* context, |
| 140 const FilePath& virtual_path, | 145 const FilePath& virtual_path, |
| 141 FilePath* local_path) { | 146 FilePath* local_path) { |
| 142 FilePath path = | 147 FilePath path = |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 169 if (local_info.is_directory()) { | 174 if (local_info.is_directory()) { |
| 170 file_info->is_directory = true; | 175 file_info->is_directory = true; |
| 171 file_info->is_symbolic_link = false; | 176 file_info->is_symbolic_link = false; |
| 172 file_info->last_modified = local_info.modification_time; | 177 file_info->last_modified = local_info.modification_time; |
| 173 *platform_file_path = FilePath(); | 178 *platform_file_path = FilePath(); |
| 174 // We don't fill in ctime or atime. | 179 // We don't fill in ctime or atime. |
| 175 return base::PLATFORM_FILE_OK; | 180 return base::PLATFORM_FILE_OK; |
| 176 } | 181 } |
| 177 if (local_info.data_path.empty()) | 182 if (local_info.data_path.empty()) |
| 178 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 183 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 184 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 185 context->src_type(), local_info.data_path); | |
| 179 return FileSystemFileUtil::GetInstance()->GetFileInfo( | 186 return FileSystemFileUtil::GetInstance()->GetFileInfo( |
| 180 context, local_info.data_path, file_info, platform_file_path); | 187 context, data_path, file_info, platform_file_path); |
| 181 } | 188 } |
| 182 | 189 |
| 183 PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory( | 190 PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory( |
| 184 FileSystemOperationContext* context, | 191 FileSystemOperationContext* context, |
| 185 const FilePath& virtual_path, | 192 const FilePath& virtual_path, |
| 186 std::vector<base::FileUtilProxy::Entry>* entries) { | 193 std::vector<base::FileUtilProxy::Entry>* entries) { |
| 187 // TODO(kkanetkar): Implement directory read in multiple chunks. | 194 // TODO(kkanetkar): Implement directory read in multiple chunks. |
| 188 FileSystemDirectoryDatabase* db = | 195 FileSystemDirectoryDatabase* db = |
| 189 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); | 196 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); |
| 190 if (!db) | 197 if (!db) |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 * Create new metadata pointing to new backing file. | 318 * Create new metadata pointing to new backing file. |
| 312 * Move-with-overwrite | 319 * Move-with-overwrite |
| 313 * transaction: | 320 * transaction: |
| 314 * Remove source entry. | 321 * Remove source entry. |
| 315 * Point target entry to source entry's backing file. | 322 * Point target entry to source entry's backing file. |
| 316 * Delete target entry's old backing file | 323 * Delete target entry's old backing file |
| 317 * Move-without-overwrite | 324 * Move-without-overwrite |
| 318 * Just update metadata | 325 * Just update metadata |
| 319 */ | 326 */ |
| 320 if (copy) { | 327 if (copy) { |
| 328 FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 329 context->src_type(), src_file_info.data_path); | |
| 321 if (overwrite) { | 330 if (overwrite) { |
| 331 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 332 context->src_type(), dest_file_info.data_path); | |
| 322 return FileSystemFileUtil::GetInstance()->CopyOrMoveFile(context, | 333 return FileSystemFileUtil::GetInstance()->CopyOrMoveFile(context, |
| 323 src_file_info.data_path, dest_file_info.data_path, copy); | 334 src_data_path, dest_data_path, copy); |
| 324 } else { | 335 } else { |
| 325 FileId dest_parent_id; | 336 FileId dest_parent_id; |
| 326 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 337 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
| 327 NOTREACHED(); // We shouldn't be called in this case. | 338 NOTREACHED(); // We shouldn't be called in this case. |
| 328 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 339 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 329 } | 340 } |
| 330 InitFileInfo(&dest_file_info, dest_parent_id, | 341 InitFileInfo(&dest_file_info, dest_parent_id, |
| 331 dest_file_path.BaseName().value(), src_file_info.data_path); | 342 dest_file_path.BaseName().value()); |
| 332 return CreateFile(context, context->dest_origin_url(), | 343 return CreateFile(context, context->dest_origin_url(), |
| 333 context->dest_type(), &dest_file_info, 0, NULL); | 344 context->dest_type(), src_data_path, &dest_file_info, 0, |
| 345 NULL); | |
| 334 } | 346 } |
| 335 } else { // It's a move. | 347 } else { // It's a move. |
| 336 if (overwrite) { | 348 if (overwrite) { |
| 337 if (!db->OverwritingMoveFile(src_file_id, dest_file_id)) | 349 if (!db->OverwritingMoveFile(src_file_id, dest_file_id)) |
| 338 return base::PLATFORM_FILE_ERROR_FAILED; | 350 return base::PLATFORM_FILE_ERROR_FAILED; |
| 351 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 352 context->src_type(), dest_file_info.data_path); | |
| 339 if (base::PLATFORM_FILE_OK != | 353 if (base::PLATFORM_FILE_OK != |
| 340 FileSystemFileUtil::GetInstance()->DeleteFile( | 354 FileSystemFileUtil::GetInstance()->DeleteFile( |
| 341 context, dest_file_info.data_path)) | 355 context, dest_data_path)) |
| 342 LOG(WARNING) << "Leaked a backing file."; | 356 LOG(WARNING) << "Leaked a backing file."; |
| 343 return base::PLATFORM_FILE_OK; | 357 return base::PLATFORM_FILE_OK; |
| 344 } else { | 358 } else { |
| 345 FileId dest_parent_id; | 359 FileId dest_parent_id; |
| 346 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 360 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
| 347 NOTREACHED(); | 361 NOTREACHED(); |
| 348 return base::PLATFORM_FILE_ERROR_FAILED; | 362 return base::PLATFORM_FILE_ERROR_FAILED; |
| 349 } | 363 } |
| 350 src_file_info.parent_id = dest_parent_id; | 364 src_file_info.parent_id = dest_parent_id; |
| 351 src_file_info.name = dest_file_path.BaseName().value(); | 365 src_file_info.name = dest_file_path.BaseName().value(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 370 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 384 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 371 FileInfo file_info; | 385 FileInfo file_info; |
| 372 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { | 386 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
| 373 NOTREACHED(); | 387 NOTREACHED(); |
| 374 return base::PLATFORM_FILE_ERROR_FAILED; | 388 return base::PLATFORM_FILE_ERROR_FAILED; |
| 375 } | 389 } |
| 376 if (!db->RemoveFileInfo(file_id)) { | 390 if (!db->RemoveFileInfo(file_id)) { |
| 377 NOTREACHED(); | 391 NOTREACHED(); |
| 378 return base::PLATFORM_FILE_ERROR_FAILED; | 392 return base::PLATFORM_FILE_ERROR_FAILED; |
| 379 } | 393 } |
| 394 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 395 context->src_type(), file_info.data_path); | |
| 380 if (base::PLATFORM_FILE_OK != | 396 if (base::PLATFORM_FILE_OK != |
| 381 FileSystemFileUtil::GetInstance()->DeleteFile( | 397 FileSystemFileUtil::GetInstance()->DeleteFile(context, data_path)) |
| 382 context, file_info.data_path)) | |
| 383 LOG(WARNING) << "Leaked a backing file."; | 398 LOG(WARNING) << "Leaked a backing file."; |
| 384 return base::PLATFORM_FILE_OK; | 399 return base::PLATFORM_FILE_OK; |
| 385 } | 400 } |
| 386 | 401 |
| 387 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( | 402 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( |
| 388 FileSystemOperationContext* context, | 403 FileSystemOperationContext* context, |
| 389 const FilePath& virtual_path) { | 404 const FilePath& virtual_path) { |
| 390 FileSystemDirectoryDatabase* db = | 405 FileSystemDirectoryDatabase* db = |
| 391 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); | 406 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); |
| 392 if (!db) | 407 if (!db) |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 419 if (!db->GetFileInfo(file_id, &file_info)) { | 434 if (!db->GetFileInfo(file_id, &file_info)) { |
| 420 NOTREACHED(); | 435 NOTREACHED(); |
| 421 return base::PLATFORM_FILE_ERROR_FAILED; | 436 return base::PLATFORM_FILE_ERROR_FAILED; |
| 422 } | 437 } |
| 423 if (file_info.is_directory()) { | 438 if (file_info.is_directory()) { |
| 424 file_info.modification_time = last_modified_time; | 439 file_info.modification_time = last_modified_time; |
| 425 if (!db->UpdateFileInfo(file_id, file_info)) | 440 if (!db->UpdateFileInfo(file_id, file_info)) |
| 426 return base::PLATFORM_FILE_ERROR_FAILED; | 441 return base::PLATFORM_FILE_ERROR_FAILED; |
| 427 return base::PLATFORM_FILE_OK; | 442 return base::PLATFORM_FILE_OK; |
| 428 } | 443 } |
| 444 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | |
| 445 context->src_type(), file_info.data_path); | |
| 429 return FileSystemFileUtil::GetInstance()->Touch( | 446 return FileSystemFileUtil::GetInstance()->Touch( |
| 430 context, file_info.data_path, last_access_time, last_modified_time); | 447 context, data_path, last_access_time, last_modified_time); |
| 431 } | 448 } |
| 432 FileId parent_id; | 449 FileId parent_id; |
| 433 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 450 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
| 434 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 451 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 435 | 452 |
| 436 FileInfo file_info; | 453 FileInfo file_info; |
| 437 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(), | 454 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
| 438 FilePath()); | |
| 439 // In the event of a sporadic underlying failure, we might create a new file, | 455 // In the event of a sporadic underlying failure, we might create a new file, |
| 440 // but fail to update its mtime + atime. | 456 // but fail to update its mtime + atime. |
| 441 PlatformFileError error = CreateFile(context, | 457 PlatformFileError error = CreateFile(context, context->src_origin_url(), |
| 442 context->src_origin_url(), context->src_type(), &file_info, 0, NULL); | 458 context->src_type(), FilePath(), &file_info, 0, NULL); |
| 443 if (base::PLATFORM_FILE_OK != error) | 459 if (base::PLATFORM_FILE_OK != error) |
| 444 return error; | 460 return error; |
| 445 | 461 |
| 446 return FileSystemFileUtil::GetInstance()->Touch(context, file_info.data_path, | 462 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
| 463 context->src_type(), file_info.data_path); | |
| 464 return FileSystemFileUtil::GetInstance()->Touch(context, data_path, | |
| 447 last_access_time, last_modified_time); | 465 last_access_time, last_modified_time); |
| 448 } | 466 } |
| 449 | 467 |
| 450 PlatformFileError ObfuscatedFileSystemFileUtil::Truncate( | 468 PlatformFileError ObfuscatedFileSystemFileUtil::Truncate( |
| 451 FileSystemOperationContext* context, | 469 FileSystemOperationContext* context, |
| 452 const FilePath& virtual_path, | 470 const FilePath& virtual_path, |
| 453 int64 length) { | 471 int64 length) { |
| 454 FilePath local_path = | 472 FilePath local_path = |
| 455 GetLocalPath(context->src_origin_url(), context->src_type(), | 473 GetLocalPath(context->src_origin_url(), context->src_type(), |
| 456 virtual_path); | 474 virtual_path); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 const FilePath& root_path) { | 609 const FilePath& root_path) { |
| 592 FileSystemDirectoryDatabase* db = | 610 FileSystemDirectoryDatabase* db = |
| 593 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); | 611 GetDirectoryDatabase(context->src_origin_url(), context->src_type()); |
| 594 if (!db) | 612 if (!db) |
| 595 return new FileSystemFileUtil::EmptyFileEnumerator(); | 613 return new FileSystemFileUtil::EmptyFileEnumerator(); |
| 596 return new ObfuscatedFileSystemFileEnumerator(db, root_path); | 614 return new ObfuscatedFileSystemFileEnumerator(db, root_path); |
| 597 } | 615 } |
| 598 | 616 |
| 599 PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile( | 617 PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile( |
| 600 FileSystemOperationContext* context, | 618 FileSystemOperationContext* context, |
| 601 const GURL& origin_url, FileSystemType type, | 619 const GURL& origin_url, FileSystemType type, const FilePath& source_path, |
| 602 FileInfo* file_info, int file_flags, PlatformFile* handle) { | 620 FileInfo* file_info, int file_flags, PlatformFile* handle) { |
| 603 if (handle) | 621 if (handle) |
| 604 *handle = base::kInvalidPlatformFileValue; | 622 *handle = base::kInvalidPlatformFileValue; |
| 605 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type); | 623 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type); |
| 606 int64 number; | 624 int64 number; |
| 607 if (!db || !db->GetNextInteger(&number)) | 625 if (!db || !db->GetNextInteger(&number)) |
| 608 return base::PLATFORM_FILE_ERROR_FAILED; | 626 return base::PLATFORM_FILE_ERROR_FAILED; |
| 609 // We use the third- and fourth-to-last digits as the directory. | 627 // We use the third- and fourth-to-last digits as the directory. |
| 610 int64 directory_number = number % 10000 / 100; | 628 int64 directory_number = number % 10000 / 100; |
| 611 FilePath path = | 629 FilePath path = |
| 612 GetDirectoryForOriginAndType(origin_url, type, false); | 630 GetDirectoryForOriginAndType(origin_url, type, false); |
| 613 if (path.empty()) | 631 if (path.empty()) |
| 614 return base::PLATFORM_FILE_ERROR_FAILED; | 632 return base::PLATFORM_FILE_ERROR_FAILED; |
| 615 path = path.AppendASCII(base::Int64ToString(directory_number)); | 633 |
| 634 path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); | |
| 616 PlatformFileError error; | 635 PlatformFileError error; |
| 617 error = FileSystemFileUtil::GetInstance()->CreateDirectory( | 636 error = FileSystemFileUtil::GetInstance()->CreateDirectory( |
| 618 context, path, false /* exclusive */, false /* recursive */); | 637 context, path, false /* exclusive */, false /* recursive */); |
| 619 if (base::PLATFORM_FILE_OK != error) | 638 if (base::PLATFORM_FILE_OK != error) |
| 620 return error; | 639 return error; |
| 621 path = path.AppendASCII(base::Int64ToString(number)); | 640 path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); |
| 641 FilePath data_path = LocalPathToDataPath(origin_url, type, path); | |
| 642 if (data_path.empty()) | |
| 643 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 622 bool created = false; | 644 bool created = false; |
| 623 if (!file_info->data_path.empty()) { | 645 if (!source_path.empty()) { |
| 624 DCHECK(!file_flags); | 646 DCHECK(!file_flags); |
| 625 DCHECK(!handle); | 647 DCHECK(!handle); |
| 626 error = FileSystemFileUtil::GetInstance()->CopyOrMoveFile( | 648 error = FileSystemFileUtil::GetInstance()->CopyOrMoveFile( |
| 627 context, file_info->data_path, path, true /* copy */); | 649 context, source_path, path, true /* copy */); |
| 628 created = true; | 650 created = true; |
| 629 } else { | 651 } else { |
| 630 if (handle) { | 652 if (handle) { |
| 631 error = FileSystemFileUtil::GetInstance()->CreateOrOpen( | 653 error = FileSystemFileUtil::GetInstance()->CreateOrOpen( |
| 632 context, path, file_flags, handle, &created); | 654 context, path, file_flags, handle, &created); |
| 633 // If this succeeds, we must close handle on any subsequent error. | 655 // If this succeeds, we must close handle on any subsequent error. |
| 634 } else { | 656 } else { |
| 635 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. | 657 DCHECK(!file_flags); // file_flags is only used by CreateOrOpen. |
| 636 error = FileSystemFileUtil::GetInstance()->EnsureFileExists( | 658 error = FileSystemFileUtil::GetInstance()->EnsureFileExists( |
| 637 context, path, &created); | 659 context, path, &created); |
| 638 } | 660 } |
| 639 } | 661 } |
| 640 if (error != base::PLATFORM_FILE_OK) | 662 if (error != base::PLATFORM_FILE_OK) |
| 641 return error; | 663 return error; |
| 642 | 664 |
| 643 if (!created) { | 665 if (!created) { |
| 644 NOTREACHED(); | 666 NOTREACHED(); |
| 645 if (handle) { | 667 if (handle) { |
| 646 base::ClosePlatformFile(*handle); | 668 base::ClosePlatformFile(*handle); |
| 647 FileSystemFileUtil::GetInstance()->DeleteFile(context, path); | 669 FileSystemFileUtil::GetInstance()->DeleteFile(context, path); |
| 648 } | 670 } |
| 649 return base::PLATFORM_FILE_ERROR_FAILED; | 671 return base::PLATFORM_FILE_ERROR_FAILED; |
| 650 } | 672 } |
| 651 file_info->data_path = path; | 673 file_info->data_path = data_path; |
| 652 FileId file_id; | 674 FileId file_id; |
| 653 if (!db->AddFileInfo(*file_info, &file_id)) { | 675 if (!db->AddFileInfo(*file_info, &file_id)) { |
| 654 if (handle) | 676 if (handle) |
| 655 base::ClosePlatformFile(*handle); | 677 base::ClosePlatformFile(*handle); |
| 656 FileSystemFileUtil::GetInstance()->DeleteFile(context, path); | 678 FileSystemFileUtil::GetInstance()->DeleteFile(context, path); |
| 657 return base::PLATFORM_FILE_ERROR_FAILED; | 679 return base::PLATFORM_FILE_ERROR_FAILED; |
| 658 } | 680 } |
| 659 | 681 |
| 660 return base::PLATFORM_FILE_OK; | 682 return base::PLATFORM_FILE_OK; |
| 661 } | 683 } |
| 662 | 684 |
| 663 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( | 685 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( |
| 664 const GURL& origin_url, | 686 const GURL& origin_url, |
| 665 FileSystemType type, | 687 FileSystemType type, |
| 666 const FilePath& virtual_path) { | 688 const FilePath& virtual_path) { |
| 667 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type); | 689 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type); |
| 668 if (!db) | 690 if (!db) |
| 669 return FilePath(); | 691 return FilePath(); |
| 670 FileId file_id; | 692 FileId file_id; |
| 671 if (!db->GetFileWithPath(virtual_path, &file_id)) | 693 if (!db->GetFileWithPath(virtual_path, &file_id)) |
| 672 return FilePath(); | 694 return FilePath(); |
| 673 FileInfo file_info; | 695 FileInfo file_info; |
| 674 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { | 696 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
| 675 NOTREACHED(); | 697 NOTREACHED(); |
| 676 return FilePath(); // Directories have no local path. | 698 return FilePath(); // Directories have no local path. |
| 677 } | 699 } |
| 678 return file_info.data_path; | 700 return DataPathToLocalPath(origin_url, type, file_info.data_path); |
| 679 } | 701 } |
| 680 | 702 |
| 681 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType( | 703 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType( |
| 682 const GURL& origin, FileSystemType type, bool create) { | 704 const GURL& origin, FileSystemType type, bool create) { |
| 683 FilePath origin_dir = GetDirectoryForOrigin(origin, create); | 705 FilePath origin_dir = GetDirectoryForOrigin(origin, create); |
| 684 if (origin_dir.empty()) | 706 if (origin_dir.empty()) |
| 685 return FilePath(); | 707 return FilePath(); |
| 686 std::string type_string = | 708 FilePath::StringType type_string = GetDirectoryNameForType(type); |
| 687 FileSystemPathManager::GetFileSystemTypeString(type); | |
| 688 if (type_string.empty()) { | 709 if (type_string.empty()) { |
| 689 LOG(WARNING) << "Unknown filesystem type requested:" << type; | 710 LOG(WARNING) << "Unknown filesystem type requested:" << type; |
| 690 return FilePath(); | 711 return FilePath(); |
| 691 } | 712 } |
| 692 return origin_dir.AppendASCII(type_string); | 713 return origin_dir.Append(type_string); |
| 693 } | 714 } |
| 694 | 715 |
| 695 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( | 716 FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin( |
| 696 const GURL& origin, bool create) { | 717 const GURL& origin, bool create) { |
| 697 if (!origin_database_.get()) { | 718 if (!origin_database_.get()) { |
| 698 if (!create && !file_util::DirectoryExists(file_system_directory_)) { | 719 if (!create && !file_util::DirectoryExists(file_system_directory_)) { |
| 699 return FilePath(); | 720 return FilePath(); |
| 700 } | 721 } |
| 701 if (!file_util::CreateDirectory(file_system_directory_)) { | 722 if (!file_util::CreateDirectory(file_system_directory_)) { |
| 702 LOG(WARNING) << "Failed to create FileSystem directory: " << | 723 LOG(WARNING) << "Failed to create FileSystem directory: " << |
| 703 file_system_directory_.value(); | 724 file_system_directory_.value(); |
| 704 return FilePath(); | 725 return FilePath(); |
| 705 } | 726 } |
| 706 origin_database_.reset( | 727 origin_database_.reset( |
| 707 new FileSystemOriginDatabase( | 728 new FileSystemOriginDatabase( |
| 708 file_system_directory_.AppendASCII(kOriginDatabaseName))); | 729 file_system_directory_.AppendASCII(kOriginDatabaseName))); |
| 709 } | 730 } |
| 710 FilePath directory_name; | 731 FilePath directory_name; |
| 711 // TODO(ericu): This should probably be using GetOriginIdentifierFromURL from | 732 // TODO(ericu): This should probably be using GetOriginIdentifierFromURL from |
| 712 // sandbox_mount_point_provider.cc, instead of just using origin.spec(). | 733 // sandbox_mount_point_provider.cc, instead of just using origin.spec(). |
| 713 if (!create && !origin_database_->HasOriginPath(origin.spec())) | 734 if (!create && !origin_database_->HasOriginPath(origin.spec())) |
| 714 return FilePath(); | 735 return FilePath(); |
| 715 if (!origin_database_->GetPathForOrigin(origin.spec(), &directory_name)) | 736 if (!origin_database_->GetPathForOrigin(origin.spec(), &directory_name)) |
| 716 return FilePath(); | 737 return FilePath(); |
| 717 return file_system_directory_.Append(directory_name); | 738 return file_system_directory_.Append(directory_name); |
| 718 } | 739 } |
| 719 | 740 |
| 741 bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox( | |
| 742 const GURL& origin_url, FileSystemType type, const FilePath& src_root) { | |
| 743 if (!DestroyDirectoryDatabase(origin_url, type)) | |
| 744 return false; | |
| 745 FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true); | |
| 746 if (dest_root.empty()) | |
| 747 return false; | |
| 748 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type); | |
| 749 if (!db) | |
| 750 return false; | |
| 751 | |
| 752 file_util::FileEnumerator file_enum(src_root, true, | |
| 753 static_cast<file_util::FileEnumerator::FILE_TYPE>( | |
| 754 file_util::FileEnumerator::FILES | | |
| 755 file_util::FileEnumerator::DIRECTORIES)); | |
| 756 FilePath src_full_path; | |
| 757 size_t root_path_length = src_root.value().length() + 1; // +1 for the slash | |
| 758 while (!(src_full_path = file_enum.Next()).empty()) { | |
| 759 file_util::FileEnumerator::FindInfo info; | |
| 760 file_enum.GetFindInfo(&info); | |
| 761 FilePath relative_virtual_path = | |
| 762 FilePath(src_full_path.value().substr(root_path_length)); | |
| 763 if (relative_virtual_path.empty()) { | |
| 764 LOG(WARNING) << "Failed to convert path to relative: " << | |
| 765 src_full_path.value(); | |
| 766 return false; | |
| 767 } | |
| 768 FileId file_id; | |
| 769 if (db->GetFileWithPath(relative_virtual_path, &file_id)) { | |
| 770 NOTREACHED(); // File already exists. | |
| 771 return false; | |
| 772 } | |
| 773 if (!db->GetFileWithPath(relative_virtual_path.DirName(), &file_id)) { | |
| 774 NOTREACHED(); // Parent doesn't exist. | |
| 775 return false; | |
| 776 } | |
| 777 | |
| 778 FileInfo file_info; | |
| 779 file_info.name = src_full_path.BaseName().value(); | |
| 780 if (file_util::FileEnumerator::IsDirectory(info)) { | |
| 781 #if defined(OS_WIN) | |
| 782 file_info.modification_time = | |
| 783 base::Time::FromFileTime(info.ftLastWriteTime); | |
| 784 #elif defined(OS_POSIX) | |
| 785 file_info.modification_time = base::Time::FromTimeT(info.stat.st_mtime); | |
| 786 #endif | |
| 787 } else { | |
| 788 file_info.data_path = | |
| 789 FilePath(kLegacyDataDirectory).Append(relative_virtual_path); | |
| 790 } | |
| 791 file_info.parent_id = file_id; | |
| 792 if (!db->AddFileInfo(file_info, &file_id)) { | |
| 793 NOTREACHED(); | |
| 794 return false; | |
| 795 } | |
| 796 } | |
| 797 // TODO(ericu): Should we adjust the mtime of the root directory to match as | |
| 798 // well? | |
| 799 FilePath legacy_dest_dir = dest_root.Append(kLegacyDataDirectory); | |
| 800 return file_util::Move(src_root, legacy_dest_dir); | |
| 801 } | |
| 802 | |
| 803 FilePath::StringType ObfuscatedFileSystemFileUtil::GetDirectoryNameForType( | |
| 804 FileSystemType type) const { | |
| 805 switch (type) { | |
| 806 case kFileSystemTypeTemporary: | |
|
michaeln
2011/05/20 02:15:16
nit: i think our style-guide wants the case to be
ericu
2011/05/20 02:23:25
Done.
| |
| 807 return kTemporaryDirectoryName; | |
| 808 case kFileSystemTypePersistent: | |
| 809 return kPersistentDirectoryName; | |
| 810 case kFileSystemTypeUnknown: | |
| 811 default: | |
| 812 return FilePath::StringType(); | |
| 813 } | |
| 814 } | |
| 815 | |
| 816 FilePath ObfuscatedFileSystemFileUtil::DataPathToLocalPath( | |
| 817 const GURL& origin, FileSystemType type, const FilePath& data_path) { | |
| 818 FilePath root = GetDirectoryForOriginAndType(origin, type, false); | |
| 819 if (root.empty()) | |
| 820 return root; | |
| 821 return root.Append(data_path); | |
| 822 } | |
| 823 | |
| 824 FilePath ObfuscatedFileSystemFileUtil::LocalPathToDataPath( | |
| 825 const GURL& origin, FileSystemType type, const FilePath& local_path) { | |
| 826 FilePath root = GetDirectoryForOriginAndType(origin, type, false); | |
| 827 if (root.empty()) | |
| 828 return root; | |
| 829 // This removes the root, including the trailing slash, leaving a relative | |
| 830 // path. | |
| 831 return FilePath(local_path.value().substr(root.value().length() + 1)); | |
| 832 } | |
| 833 | |
| 720 // TODO: How to do the whole validation-without-creation thing? We may not have | 834 // TODO: How to do the whole validation-without-creation thing? We may not have |
| 721 // quota even to create the database. Ah, in that case don't even get here? | 835 // quota even to create the database. Ah, in that case don't even get here? |
| 722 // Still doesn't answer the quota issue, though. | 836 // Still doesn't answer the quota issue, though. |
| 723 FileSystemDirectoryDatabase* ObfuscatedFileSystemFileUtil::GetDirectoryDatabase( | 837 FileSystemDirectoryDatabase* ObfuscatedFileSystemFileUtil::GetDirectoryDatabase( |
| 724 const GURL& origin, FileSystemType type) { | 838 const GURL& origin, FileSystemType type) { |
| 725 | 839 |
| 726 MarkUsed(); | 840 MarkUsed(); |
| 727 std::string type_string = | 841 std::string type_string = |
| 728 FileSystemPathManager::GetFileSystemTypeString(type); | 842 FileSystemPathManager::GetFileSystemTypeString(type); |
| 729 if (type_string.empty()) { | 843 if (type_string.empty()) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 760 &ObfuscatedFileSystemFileUtil::DropDatabases); | 874 &ObfuscatedFileSystemFileUtil::DropDatabases); |
| 761 } | 875 } |
| 762 | 876 |
| 763 void ObfuscatedFileSystemFileUtil::DropDatabases() { | 877 void ObfuscatedFileSystemFileUtil::DropDatabases() { |
| 764 origin_database_.reset(); | 878 origin_database_.reset(); |
| 765 STLDeleteContainerPairSecondPointers( | 879 STLDeleteContainerPairSecondPointers( |
| 766 directories_.begin(), directories_.end()); | 880 directories_.begin(), directories_.end()); |
| 767 directories_.clear(); | 881 directories_.clear(); |
| 768 } | 882 } |
| 769 | 883 |
| 884 bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase( | |
| 885 const GURL& origin, FileSystemType type) { | |
| 886 std::string type_string = | |
| 887 FileSystemPathManager::GetFileSystemTypeString(type); | |
| 888 if (type_string.empty()) { | |
| 889 LOG(WARNING) << "Unknown filesystem type requested:" << type; | |
| 890 return true; | |
| 891 } | |
| 892 // TODO(ericu): This should probably be using GetOriginIdentifierFromURL from | |
| 893 // sandbox_mount_point_provider.cc, instead of just using origin.spec(). | |
| 894 std::string key = origin.spec() + type_string; | |
| 895 DirectoryMap::iterator iter = directories_.find(key); | |
| 896 if (iter != directories_.end()) | |
| 897 directories_.erase(iter); | |
| 898 | |
| 899 FilePath path = GetDirectoryForOriginAndType(origin, type, false); | |
| 900 if (path.empty()) | |
| 901 return true; | |
| 902 if (!file_util::DirectoryExists(path)) | |
| 903 return true; | |
| 904 path = path.AppendASCII(kDirectoryDatabaseName); | |
| 905 return FileSystemDirectoryDatabase::DestroyDatabase(path); | |
| 906 } | |
| 907 | |
| 770 } // namespace fileapi | 908 } // namespace fileapi |
| OLD | NEW |