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 |