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