OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/fileapi/obfuscated_file_system_file_util.h" | 5 #include "webkit/fileapi/obfuscated_file_system_file_util.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
15 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
17 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
18 #include "googleurl/src/gurl.h" | 18 #include "googleurl/src/gurl.h" |
19 #include "webkit/fileapi/file_system_context.h" | 19 #include "webkit/fileapi/file_system_context.h" |
20 #include "webkit/fileapi/file_system_operation_context.h" | 20 #include "webkit/fileapi/file_system_operation_context.h" |
21 #include "webkit/fileapi/file_system_path_manager.h" | 21 #include "webkit/fileapi/file_system_path_manager.h" |
| 22 #include "webkit/fileapi/file_system_quota_util.h" |
22 #include "webkit/fileapi/file_system_util.h" | 23 #include "webkit/fileapi/file_system_util.h" |
23 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 24 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
| 25 #include "webkit/quota/quota_manager.h" |
24 | 26 |
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 DCHECK(file_info); | 38 DCHECK(file_info); |
37 file_info->parent_id = parent_id; | 39 file_info->parent_id = parent_id; |
38 file_info->name = file_name; | 40 file_info->name = file_name; |
39 } | 41 } |
40 | 42 |
41 bool IsRootDirectory(const FilePath& virtual_path) { | 43 bool IsRootDirectory(const FilePath& virtual_path) { |
42 return (virtual_path.empty() || | 44 return (virtual_path.empty() || |
43 virtual_path.value() == FILE_PATH_LITERAL("/")); | 45 virtual_path.value() == FILE_PATH_LITERAL("/")); |
44 } | 46 } |
45 | 47 |
| 48 // Costs computed as per crbug.com/86114, based on the LevelDB implementation of |
| 49 // path storage under Linux. It's not clear if that will differ on Windows, on |
| 50 // which FilePath uses wide chars [since they're converted to UTF-8 for storage |
| 51 // anyway], but as long as the cost is high enough that one can't cheat on quota |
| 52 // by storing data in paths, it doesn't need to be all that accurate. |
| 53 const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically. |
| 54 const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8. |
| 55 |
| 56 int64 GetPathQuotaUsage( |
| 57 int growth_in_number_of_paths, |
| 58 int64 growth_in_bytes_of_path_length) { |
| 59 return growth_in_number_of_paths * kPathCreationQuotaCost + |
| 60 growth_in_bytes_of_path_length * kPathByteQuotaCost; |
| 61 } |
| 62 |
| 63 bool AllocateQuotaForPath( |
| 64 fileapi::FileSystemOperationContext* context, |
| 65 int growth_in_number_of_paths, |
| 66 int64 growth_in_bytes_of_path_length) { |
| 67 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, |
| 68 growth_in_bytes_of_path_length); |
| 69 int64 new_quota = context->allowed_bytes_growth() - growth; |
| 70 |
| 71 if (growth <= 0 || new_quota >= 0) { |
| 72 context->set_allowed_bytes_growth(new_quota); |
| 73 return true; |
| 74 } |
| 75 return false; |
| 76 } |
| 77 |
| 78 void UpdatePathQuotaUsage( |
| 79 fileapi::FileSystemOperationContext* context, |
| 80 const GURL& origin_url, |
| 81 fileapi::FileSystemType type, |
| 82 int growth_in_number_of_paths, // -1, 0, or 1 |
| 83 int64 growth_in_bytes_of_path_length) { |
| 84 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, |
| 85 growth_in_bytes_of_path_length); |
| 86 fileapi::FileSystemQuotaUtil* quota_util = |
| 87 context->file_system_context()->GetQuotaUtil(type); |
| 88 quota::QuotaManagerProxy* quota_manager_proxy = |
| 89 context->file_system_context()->quota_manager_proxy(); |
| 90 quota_util->UpdateOriginUsageOnFileThread(quota_manager_proxy, origin_url, |
| 91 type, growth); |
| 92 } |
| 93 |
46 const FilePath::CharType kLegacyDataDirectory[] = FILE_PATH_LITERAL("Legacy"); | 94 const FilePath::CharType kLegacyDataDirectory[] = FILE_PATH_LITERAL("Legacy"); |
47 | 95 |
48 const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t"); | 96 const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t"); |
49 const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p"); | 97 const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p"); |
50 | 98 |
51 } // namespace | 99 } // namespace |
52 | 100 |
53 namespace fileapi { | 101 namespace fileapi { |
54 | 102 |
55 using base::PlatformFile; | 103 using base::PlatformFile; |
(...skipping 25 matching lines...) Expand all Loading... |
81 if (!db->GetFileWithPath(virtual_path, &file_id)) { | 129 if (!db->GetFileWithPath(virtual_path, &file_id)) { |
82 // The file doesn't exist. | 130 // The file doesn't exist. |
83 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | 131 if (!(file_flags & (base::PLATFORM_FILE_CREATE | |
84 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) | 132 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) |
85 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 133 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
86 FileId parent_id; | 134 FileId parent_id; |
87 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 135 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
88 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 136 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
89 FileInfo file_info; | 137 FileInfo file_info; |
90 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); | 138 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
| 139 if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
| 140 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
91 PlatformFileError error = CreateFile( | 141 PlatformFileError error = CreateFile( |
92 context, context->src_origin_url(), context->src_type(), FilePath(), | 142 context, context->src_origin_url(), context->src_type(), FilePath(), |
93 &file_info, file_flags, file_handle); | 143 &file_info, file_flags, file_handle); |
94 if (created && base::PLATFORM_FILE_OK == error) | 144 if (created && base::PLATFORM_FILE_OK == error) |
95 *created = true; | 145 *created = true; |
96 return error; | 146 return error; |
97 } | 147 } |
98 if (file_flags & base::PLATFORM_FILE_CREATE) | 148 if (file_flags & base::PLATFORM_FILE_CREATE) |
99 return base::PLATFORM_FILE_ERROR_EXISTS; | 149 return base::PLATFORM_FILE_ERROR_EXISTS; |
100 | 150 |
(...skipping 30 matching lines...) Expand all Loading... |
131 if (created) | 181 if (created) |
132 *created = false; | 182 *created = false; |
133 return base::PLATFORM_FILE_OK; | 183 return base::PLATFORM_FILE_OK; |
134 } | 184 } |
135 FileId parent_id; | 185 FileId parent_id; |
136 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 186 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
137 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 187 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
138 | 188 |
139 FileInfo file_info; | 189 FileInfo file_info; |
140 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); | 190 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
| 191 if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
| 192 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
141 PlatformFileError error = CreateFile(context, context->src_origin_url(), | 193 PlatformFileError error = CreateFile(context, context->src_origin_url(), |
142 context->src_type(), FilePath(), &file_info, 0, NULL); | 194 context->src_type(), FilePath(), &file_info, 0, NULL); |
143 if (created && base::PLATFORM_FILE_OK == error) | 195 if (created && base::PLATFORM_FILE_OK == error) |
144 *created = true; | 196 *created = true; |
145 return error; | 197 return error; |
146 } | 198 } |
147 | 199 |
148 PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( | 200 PlatformFileError ObfuscatedFileSystemFileUtil::GetLocalFilePath( |
149 FileSystemOperationContext* context, | 201 FileSystemOperationContext* context, |
150 const FilePath& virtual_path, | 202 const FilePath& virtual_path, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 size_t index; | 310 size_t index; |
259 for (index = 0; index < components.size(); ++index) { | 311 for (index = 0; index < components.size(); ++index) { |
260 FilePath::StringType name = components[index]; | 312 FilePath::StringType name = components[index]; |
261 if (name == FILE_PATH_LITERAL("/")) | 313 if (name == FILE_PATH_LITERAL("/")) |
262 continue; | 314 continue; |
263 if (!db->GetChildWithName(parent_id, name, &parent_id)) | 315 if (!db->GetChildWithName(parent_id, name, &parent_id)) |
264 break; | 316 break; |
265 } | 317 } |
266 if (!recursive && components.size() - index > 1) | 318 if (!recursive && components.size() - index > 1) |
267 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 319 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
268 // TODO(dmikurube): Eliminate do_not_write_actually in future. | |
269 bool do_not_write_actually = context->do_not_write_actually(); | |
270 context->set_do_not_write_actually(true); | |
271 underlying_file_util_->CreateDirectory(context, | |
272 FilePath(), exclusive, recursive); | |
273 context->set_do_not_write_actually(do_not_write_actually); | |
274 for (; index < components.size(); ++index) { | 320 for (; index < components.size(); ++index) { |
275 FileInfo file_info; | 321 FileInfo file_info; |
276 file_info.name = components[index]; | 322 file_info.name = components[index]; |
277 if (file_info.name == FILE_PATH_LITERAL("/")) | 323 if (file_info.name == FILE_PATH_LITERAL("/")) |
278 continue; | 324 continue; |
279 file_info.modification_time = base::Time::Now(); | 325 file_info.modification_time = base::Time::Now(); |
280 file_info.parent_id = parent_id; | 326 file_info.parent_id = parent_id; |
| 327 if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
| 328 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
281 if (!db->AddFileInfo(file_info, &parent_id)) { | 329 if (!db->AddFileInfo(file_info, &parent_id)) { |
282 NOTREACHED(); | 330 NOTREACHED(); |
283 return base::PLATFORM_FILE_ERROR_FAILED; | 331 return base::PLATFORM_FILE_ERROR_FAILED; |
284 } | 332 } |
| 333 UpdatePathQuotaUsage(context, context->src_origin_url(), |
| 334 context->src_type(), 1, file_info.name.size()); |
285 } | 335 } |
286 return base::PLATFORM_FILE_OK; | 336 return base::PLATFORM_FILE_OK; |
287 } | 337 } |
288 | 338 |
289 PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( | 339 PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile( |
290 FileSystemOperationContext* context, | 340 FileSystemOperationContext* context, |
291 const FilePath& src_file_path, | 341 const FilePath& src_file_path, |
292 const FilePath& dest_file_path, | 342 const FilePath& dest_file_path, |
293 bool copy) { | 343 bool copy) { |
| 344 // Cross-filesystem copies and moves should be handled via CopyInForeignFile. |
| 345 DCHECK(context->src_origin_url() == context->dest_origin_url()); |
| 346 DCHECK(context->src_type() == context->dest_type()); |
| 347 |
294 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 348 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
295 context->src_origin_url(), context->src_type(), true); | 349 context->src_origin_url(), context->src_type(), true); |
296 if (!db) | 350 if (!db) |
297 return base::PLATFORM_FILE_ERROR_FAILED; | 351 return base::PLATFORM_FILE_ERROR_FAILED; |
298 FileId src_file_id; | 352 FileId src_file_id; |
299 if (!db->GetFileWithPath(src_file_path, &src_file_id)) | 353 if (!db->GetFileWithPath(src_file_path, &src_file_id)) |
300 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 354 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
301 FileId dest_file_id; | 355 FileId dest_file_id; |
302 bool overwrite = db->GetFileWithPath(dest_file_path, &dest_file_id); | 356 bool overwrite = db->GetFileWithPath(dest_file_path, &dest_file_id); |
303 FileInfo src_file_info; | 357 FileInfo src_file_info; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 return underlying_file_util_->CopyOrMoveFile(context, | 391 return underlying_file_util_->CopyOrMoveFile(context, |
338 src_data_path, dest_data_path, copy); | 392 src_data_path, dest_data_path, copy); |
339 } else { | 393 } else { |
340 FileId dest_parent_id; | 394 FileId dest_parent_id; |
341 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 395 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
342 NOTREACHED(); // We shouldn't be called in this case. | 396 NOTREACHED(); // We shouldn't be called in this case. |
343 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 397 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
344 } | 398 } |
345 InitFileInfo(&dest_file_info, dest_parent_id, | 399 InitFileInfo(&dest_file_info, dest_parent_id, |
346 dest_file_path.BaseName().value()); | 400 dest_file_path.BaseName().value()); |
| 401 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) |
| 402 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
347 return CreateFile(context, context->dest_origin_url(), | 403 return CreateFile(context, context->dest_origin_url(), |
348 context->dest_type(), src_data_path, &dest_file_info, 0, | 404 context->dest_type(), src_data_path, &dest_file_info, 0, |
349 NULL); | 405 NULL); |
350 } | 406 } |
351 } else { // It's a move. | 407 } else { // It's a move. |
352 if (overwrite) { | 408 if (overwrite) { |
| 409 AllocateQuotaForPath(context, -1, |
| 410 -static_cast<int64>(src_file_info.name.size())); |
353 if (!db->OverwritingMoveFile(src_file_id, dest_file_id)) | 411 if (!db->OverwritingMoveFile(src_file_id, dest_file_id)) |
354 return base::PLATFORM_FILE_ERROR_FAILED; | 412 return base::PLATFORM_FILE_ERROR_FAILED; |
355 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), | 413 FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(), |
356 context->src_type(), dest_file_info.data_path); | 414 context->src_type(), dest_file_info.data_path); |
357 if (base::PLATFORM_FILE_OK != | 415 if (base::PLATFORM_FILE_OK != |
358 underlying_file_util_->DeleteFile(context, dest_data_path)) | 416 underlying_file_util_->DeleteFile(context, dest_data_path)) |
359 LOG(WARNING) << "Leaked a backing file."; | 417 LOG(WARNING) << "Leaked a backing file."; |
| 418 UpdatePathQuotaUsage(context, context->src_origin_url(), |
| 419 context->src_type(), -1, |
| 420 -static_cast<int64>(src_file_info.name.size())); |
360 return base::PLATFORM_FILE_OK; | 421 return base::PLATFORM_FILE_OK; |
361 } else { | 422 } else { |
362 FileId dest_parent_id; | 423 FileId dest_parent_id; |
363 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 424 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
364 NOTREACHED(); | 425 NOTREACHED(); |
365 return base::PLATFORM_FILE_ERROR_FAILED; | 426 return base::PLATFORM_FILE_ERROR_FAILED; |
366 } | 427 } |
| 428 if (!AllocateQuotaForPath( |
| 429 context, 0, |
| 430 static_cast<int64>(dest_file_path.BaseName().value().size()) |
| 431 - static_cast<int64>(src_file_info.name.size()))) |
| 432 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
367 src_file_info.parent_id = dest_parent_id; | 433 src_file_info.parent_id = dest_parent_id; |
368 src_file_info.name = dest_file_path.BaseName().value(); | 434 src_file_info.name = dest_file_path.BaseName().value(); |
369 if (!db->UpdateFileInfo(src_file_id, src_file_info)) | 435 if (!db->UpdateFileInfo(src_file_id, src_file_info)) |
370 return base::PLATFORM_FILE_ERROR_FAILED; | 436 return base::PLATFORM_FILE_ERROR_FAILED; |
| 437 UpdatePathQuotaUsage( |
| 438 context, context->src_origin_url(), context->src_type(), 0, |
| 439 static_cast<int64>(dest_file_path.BaseName().value().size()) - |
| 440 static_cast<int64>(src_file_path.BaseName().value().size())); |
371 return base::PLATFORM_FILE_OK; | 441 return base::PLATFORM_FILE_OK; |
372 } | 442 } |
373 } | 443 } |
374 NOTREACHED(); | 444 NOTREACHED(); |
375 return base::PLATFORM_FILE_ERROR_FAILED; | 445 return base::PLATFORM_FILE_ERROR_FAILED; |
376 } | 446 } |
377 | 447 |
378 PlatformFileError ObfuscatedFileSystemFileUtil::CopyInForeignFile( | 448 PlatformFileError ObfuscatedFileSystemFileUtil::CopyInForeignFile( |
379 FileSystemOperationContext* context, | 449 FileSystemOperationContext* context, |
380 const FilePath& src_file_path, | 450 const FilePath& src_file_path, |
(...skipping 16 matching lines...) Expand all Loading... |
397 return underlying_file_util_->CopyOrMoveFile(context, | 467 return underlying_file_util_->CopyOrMoveFile(context, |
398 src_file_path, dest_data_path, true /* copy */); | 468 src_file_path, dest_data_path, true /* copy */); |
399 } else { | 469 } else { |
400 FileId dest_parent_id; | 470 FileId dest_parent_id; |
401 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { | 471 if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) { |
402 NOTREACHED(); // We shouldn't be called in this case. | 472 NOTREACHED(); // We shouldn't be called in this case. |
403 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 473 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
404 } | 474 } |
405 InitFileInfo(&dest_file_info, dest_parent_id, | 475 InitFileInfo(&dest_file_info, dest_parent_id, |
406 dest_file_path.BaseName().value()); | 476 dest_file_path.BaseName().value()); |
| 477 if (!AllocateQuotaForPath(context, 1, dest_file_info.name.size())) |
| 478 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
407 return CreateFile(context, context->dest_origin_url(), | 479 return CreateFile(context, context->dest_origin_url(), |
408 context->dest_type(), src_file_path, &dest_file_info, 0, NULL); | 480 context->dest_type(), src_file_path, &dest_file_info, 0, NULL); |
409 } | 481 } |
410 return base::PLATFORM_FILE_ERROR_FAILED; | 482 return base::PLATFORM_FILE_ERROR_FAILED; |
411 } | 483 } |
412 | 484 |
413 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteFile( | 485 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteFile( |
414 FileSystemOperationContext* context, | 486 FileSystemOperationContext* context, |
415 const FilePath& virtual_path) { | 487 const FilePath& virtual_path) { |
416 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 488 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
417 context->src_origin_url(), context->src_type(), true); | 489 context->src_origin_url(), context->src_type(), true); |
418 if (!db) | 490 if (!db) |
419 return base::PLATFORM_FILE_ERROR_FAILED; | 491 return base::PLATFORM_FILE_ERROR_FAILED; |
420 FileId file_id; | 492 FileId file_id; |
421 if (!db->GetFileWithPath(virtual_path, &file_id)) | 493 if (!db->GetFileWithPath(virtual_path, &file_id)) |
422 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 494 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
423 FileInfo file_info; | 495 FileInfo file_info; |
424 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { | 496 if (!db->GetFileInfo(file_id, &file_info) || file_info.is_directory()) { |
425 NOTREACHED(); | 497 NOTREACHED(); |
426 return base::PLATFORM_FILE_ERROR_FAILED; | 498 return base::PLATFORM_FILE_ERROR_FAILED; |
427 } | 499 } |
428 if (!db->RemoveFileInfo(file_id)) { | 500 if (!db->RemoveFileInfo(file_id)) { |
429 NOTREACHED(); | 501 NOTREACHED(); |
430 return base::PLATFORM_FILE_ERROR_FAILED; | 502 return base::PLATFORM_FILE_ERROR_FAILED; |
431 } | 503 } |
| 504 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
| 505 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
| 506 -1, -static_cast<int64>(file_info.name.size())); |
432 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | 507 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
433 context->src_type(), file_info.data_path); | 508 context->src_type(), file_info.data_path); |
434 if (base::PLATFORM_FILE_OK != | 509 if (base::PLATFORM_FILE_OK != |
435 underlying_file_util_->DeleteFile(context, data_path)) | 510 underlying_file_util_->DeleteFile(context, data_path)) |
436 LOG(WARNING) << "Leaked a backing file."; | 511 LOG(WARNING) << "Leaked a backing file."; |
437 return base::PLATFORM_FILE_OK; | 512 return base::PLATFORM_FILE_OK; |
438 } | 513 } |
439 | 514 |
440 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( | 515 PlatformFileError ObfuscatedFileSystemFileUtil::DeleteSingleDirectory( |
441 FileSystemOperationContext* context, | 516 FileSystemOperationContext* context, |
442 const FilePath& virtual_path) { | 517 const FilePath& virtual_path) { |
443 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 518 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
444 context->src_origin_url(), context->src_type(), true); | 519 context->src_origin_url(), context->src_type(), true); |
445 if (!db) | 520 if (!db) |
446 return base::PLATFORM_FILE_ERROR_FAILED; | 521 return base::PLATFORM_FILE_ERROR_FAILED; |
447 FileId file_id; | 522 FileId file_id; |
448 if (!db->GetFileWithPath(virtual_path, &file_id)) | 523 if (!db->GetFileWithPath(virtual_path, &file_id)) |
449 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 524 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
450 FileInfo file_info; | 525 FileInfo file_info; |
451 if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { | 526 if (!db->GetFileInfo(file_id, &file_info) || !file_info.is_directory()) { |
452 NOTREACHED(); | 527 NOTREACHED(); |
453 return base::PLATFORM_FILE_ERROR_FAILED; | 528 return base::PLATFORM_FILE_ERROR_FAILED; |
454 } | 529 } |
455 if (!db->RemoveFileInfo(file_id)) | 530 if (!db->RemoveFileInfo(file_id)) |
456 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | 531 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; |
| 532 AllocateQuotaForPath(context, -1, -static_cast<int64>(file_info.name.size())); |
| 533 UpdatePathQuotaUsage(context, context->src_origin_url(), context->src_type(), |
| 534 -1, -static_cast<int64>(file_info.name.size())); |
457 return base::PLATFORM_FILE_OK; | 535 return base::PLATFORM_FILE_OK; |
458 } | 536 } |
459 | 537 |
460 PlatformFileError ObfuscatedFileSystemFileUtil::Touch( | 538 PlatformFileError ObfuscatedFileSystemFileUtil::Touch( |
461 FileSystemOperationContext* context, | 539 FileSystemOperationContext* context, |
462 const FilePath& virtual_path, | 540 const FilePath& virtual_path, |
463 const base::Time& last_access_time, | 541 const base::Time& last_access_time, |
464 const base::Time& last_modified_time) { | 542 const base::Time& last_modified_time) { |
465 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 543 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
466 context->src_origin_url(), context->src_type(), true); | 544 context->src_origin_url(), context->src_type(), true); |
(...skipping 18 matching lines...) Expand all Loading... |
485 context, data_path, last_access_time, last_modified_time); | 563 context, data_path, last_access_time, last_modified_time); |
486 } | 564 } |
487 FileId parent_id; | 565 FileId parent_id; |
488 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) | 566 if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id)) |
489 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 567 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
490 | 568 |
491 FileInfo file_info; | 569 FileInfo file_info; |
492 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); | 570 InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value()); |
493 // In the event of a sporadic underlying failure, we might create a new file, | 571 // In the event of a sporadic underlying failure, we might create a new file, |
494 // but fail to update its mtime + atime. | 572 // but fail to update its mtime + atime. |
| 573 if (!AllocateQuotaForPath(context, 1, file_info.name.size())) |
| 574 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
495 PlatformFileError error = CreateFile(context, context->src_origin_url(), | 575 PlatformFileError error = CreateFile(context, context->src_origin_url(), |
496 context->src_type(), FilePath(), &file_info, 0, NULL); | 576 context->src_type(), FilePath(), &file_info, 0, NULL); |
497 if (base::PLATFORM_FILE_OK != error) | 577 if (base::PLATFORM_FILE_OK != error) |
498 return error; | 578 return error; |
499 | 579 |
500 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), | 580 FilePath data_path = DataPathToLocalPath(context->src_origin_url(), |
501 context->src_type(), file_info.data_path); | 581 context->src_type(), file_info.data_path); |
502 return underlying_file_util_->Touch(context, data_path, | 582 return underlying_file_util_->Touch(context, data_path, |
503 last_access_time, last_modified_time); | 583 last_access_time, last_modified_time); |
504 } | 584 } |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 if (!db || !db->GetNextInteger(&number)) | 841 if (!db || !db->GetNextInteger(&number)) |
762 return base::PLATFORM_FILE_ERROR_FAILED; | 842 return base::PLATFORM_FILE_ERROR_FAILED; |
763 // We use the third- and fourth-to-last digits as the directory. | 843 // We use the third- and fourth-to-last digits as the directory. |
764 int64 directory_number = number % 10000 / 100; | 844 int64 directory_number = number % 10000 / 100; |
765 FilePath path = | 845 FilePath path = |
766 GetDirectoryForOriginAndType(origin_url, type, false); | 846 GetDirectoryForOriginAndType(origin_url, type, false); |
767 if (path.empty()) | 847 if (path.empty()) |
768 return base::PLATFORM_FILE_ERROR_FAILED; | 848 return base::PLATFORM_FILE_ERROR_FAILED; |
769 | 849 |
770 path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); | 850 path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number)); |
771 if (file_util::DirectoryExists(path.DirName())) { | 851 PlatformFileError error; |
772 if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path)) | 852 error = underlying_file_util_->CreateDirectory( |
773 return base::PLATFORM_FILE_ERROR_FAILED; | 853 context, path, false /* exclusive */, false /* recursive */); |
774 } else { | 854 if (base::PLATFORM_FILE_OK != error) |
775 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 855 return error; |
776 } | |
777 path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); | 856 path = path.AppendASCII(StringPrintf("%08" PRIu64, number)); |
778 FilePath data_path = LocalPathToDataPath(origin_url, type, path); | 857 FilePath data_path = LocalPathToDataPath(origin_url, type, path); |
779 if (data_path.empty()) | 858 if (data_path.empty()) |
780 return base::PLATFORM_FILE_ERROR_FAILED; | 859 return base::PLATFORM_FILE_ERROR_FAILED; |
781 PlatformFileError error; | |
782 bool created = false; | 860 bool created = false; |
783 if (!source_path.empty()) { | 861 if (!source_path.empty()) { |
784 DCHECK(!file_flags); | 862 DCHECK(!file_flags); |
785 DCHECK(!handle); | 863 DCHECK(!handle); |
786 error = underlying_file_util_->CopyOrMoveFile( | 864 error = underlying_file_util_->CopyOrMoveFile( |
787 context, source_path, path, true /* copy */); | 865 context, source_path, path, true /* copy */); |
788 created = true; | 866 created = true; |
789 } else { | 867 } else { |
790 if (handle) { | 868 if (handle) { |
791 error = underlying_file_util_->CreateOrOpen( | 869 error = underlying_file_util_->CreateOrOpen( |
(...skipping 20 matching lines...) Expand all Loading... |
812 file_info->data_path = data_path; | 890 file_info->data_path = data_path; |
813 FileId file_id; | 891 FileId file_id; |
814 if (!db->AddFileInfo(*file_info, &file_id)) { | 892 if (!db->AddFileInfo(*file_info, &file_id)) { |
815 if (handle) { | 893 if (handle) { |
816 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); | 894 DCHECK_NE(base::kInvalidPlatformFileValue, *handle); |
817 base::ClosePlatformFile(*handle); | 895 base::ClosePlatformFile(*handle); |
818 } | 896 } |
819 underlying_file_util_->DeleteFile(context, path); | 897 underlying_file_util_->DeleteFile(context, path); |
820 return base::PLATFORM_FILE_ERROR_FAILED; | 898 return base::PLATFORM_FILE_ERROR_FAILED; |
821 } | 899 } |
| 900 UpdatePathQuotaUsage(context, origin_url, type, 1, file_info->name.size()); |
822 | 901 |
823 return base::PLATFORM_FILE_OK; | 902 return base::PLATFORM_FILE_OK; |
824 } | 903 } |
825 | 904 |
826 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( | 905 FilePath ObfuscatedFileSystemFileUtil::GetLocalPath( |
827 const GURL& origin_url, | 906 const GURL& origin_url, |
828 FileSystemType type, | 907 FileSystemType type, |
829 const FilePath& virtual_path) { | 908 const FilePath& virtual_path) { |
830 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 909 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
831 origin_url, type, false); | 910 origin_url, type, false); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 &ObfuscatedFileSystemFileUtil::DropDatabases); | 1130 &ObfuscatedFileSystemFileUtil::DropDatabases); |
1052 } | 1131 } |
1053 | 1132 |
1054 void ObfuscatedFileSystemFileUtil::DropDatabases() { | 1133 void ObfuscatedFileSystemFileUtil::DropDatabases() { |
1055 origin_database_.reset(); | 1134 origin_database_.reset(); |
1056 STLDeleteContainerPairSecondPointers( | 1135 STLDeleteContainerPairSecondPointers( |
1057 directories_.begin(), directories_.end()); | 1136 directories_.begin(), directories_.end()); |
1058 directories_.clear(); | 1137 directories_.clear(); |
1059 } | 1138 } |
1060 | 1139 |
| 1140 // static |
| 1141 int64 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(const FilePath& path) { |
| 1142 return GetPathQuotaUsage(1, path.BaseName().value().size()); |
| 1143 } |
| 1144 |
1061 bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase( | 1145 bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase( |
1062 const GURL& origin, FileSystemType type) { | 1146 const GURL& origin, FileSystemType type) { |
1063 std::string type_string = | 1147 std::string type_string = |
1064 FileSystemPathManager::GetFileSystemTypeString(type); | 1148 FileSystemPathManager::GetFileSystemTypeString(type); |
1065 if (type_string.empty()) { | 1149 if (type_string.empty()) { |
1066 LOG(WARNING) << "Unknown filesystem type requested:" << type; | 1150 LOG(WARNING) << "Unknown filesystem type requested:" << type; |
1067 return true; | 1151 return true; |
1068 } | 1152 } |
1069 std::string key = GetOriginIdentifierFromURL(origin) + type_string; | 1153 std::string key = GetOriginIdentifierFromURL(origin) + type_string; |
1070 DirectoryMap::iterator iter = directories_.find(key); | 1154 DirectoryMap::iterator iter = directories_.find(key); |
(...skipping 22 matching lines...) Expand all Loading... |
1093 return false; | 1177 return false; |
1094 } | 1178 } |
1095 origin_database_.reset( | 1179 origin_database_.reset( |
1096 new FileSystemOriginDatabase( | 1180 new FileSystemOriginDatabase( |
1097 file_system_directory_.AppendASCII(kOriginDatabaseName))); | 1181 file_system_directory_.AppendASCII(kOriginDatabaseName))); |
1098 } | 1182 } |
1099 return true; | 1183 return true; |
1100 } | 1184 } |
1101 | 1185 |
1102 } // namespace fileapi | 1186 } // namespace fileapi |
OLD | NEW |