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