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: |
| 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 |