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

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

Issue 7042029: Code to migrate a single directory from the old sandbox to the new. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added TODO about directory mtime updates. Created 9 years, 7 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 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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698