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

Side by Side Diff: storage/browser/fileapi/obfuscated_file_util.cc

Issue 442383002: Move storage-related files from webkit/ to new top-level directory storage/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/fileapi/obfuscated_file_util.h" 5 #include "storage/browser/fileapi/obfuscated_file_util.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/strings/sys_string_conversions.h" 19 #include "base/strings/sys_string_conversions.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h" 21 #include "base/time/time.h"
22 #include "url/gurl.h" 22 #include "url/gurl.h"
23 #include "webkit/browser/fileapi/file_observers.h" 23 #include "storage/browser/fileapi/file_observers.h"
24 #include "webkit/browser/fileapi/file_system_context.h" 24 #include "storage/browser/fileapi/file_system_context.h"
25 #include "webkit/browser/fileapi/file_system_operation_context.h" 25 #include "storage/browser/fileapi/file_system_operation_context.h"
26 #include "webkit/browser/fileapi/file_system_url.h" 26 #include "storage/browser/fileapi/file_system_url.h"
27 #include "webkit/browser/fileapi/native_file_util.h" 27 #include "storage/browser/fileapi/native_file_util.h"
28 #include "webkit/browser/fileapi/sandbox_file_system_backend.h" 28 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
29 #include "webkit/browser/fileapi/sandbox_isolated_origin_database.h" 29 #include "storage/browser/fileapi/sandbox_isolated_origin_database.h"
30 #include "webkit/browser/fileapi/sandbox_origin_database.h" 30 #include "storage/browser/fileapi/sandbox_origin_database.h"
31 #include "webkit/browser/fileapi/sandbox_prioritized_origin_database.h" 31 #include "storage/browser/fileapi/sandbox_prioritized_origin_database.h"
32 #include "webkit/browser/fileapi/timed_task_helper.h" 32 #include "storage/browser/fileapi/timed_task_helper.h"
33 #include "webkit/browser/quota/quota_manager.h" 33 #include "storage/browser/quota/quota_manager.h"
34 #include "webkit/common/database/database_identifier.h" 34 #include "storage/common/database/database_identifier.h"
35 #include "webkit/common/fileapi/file_system_util.h" 35 #include "storage/common/fileapi/file_system_util.h"
36 36
37 // Example of various paths: 37 // Example of various paths:
38 // void ObfuscatedFileUtil::DoSomething(const FileSystemURL& url) { 38 // void ObfuscatedFileUtil::DoSomething(const FileSystemURL& url) {
39 // base::FilePath virtual_path = url.path(); 39 // base::FilePath virtual_path = url.path();
40 // base::FilePath local_path = GetLocalFilePath(url); 40 // base::FilePath local_path = GetLocalFilePath(url);
41 // 41 //
42 // NativeFileUtil::DoSomething(local_path); 42 // NativeFileUtil::DoSomething(local_path);
43 // file_util::DoAnother(local_path); 43 // file_util::DoAnother(local_path);
44 // } 44 // }
45 45
46 namespace fileapi { 46 namespace storage {
47 47
48 namespace { 48 namespace {
49 49
50 typedef SandboxDirectoryDatabase::FileId FileId; 50 typedef SandboxDirectoryDatabase::FileId FileId;
51 typedef SandboxDirectoryDatabase::FileInfo FileInfo; 51 typedef SandboxDirectoryDatabase::FileInfo FileInfo;
52 52
53 void InitFileInfo( 53 void InitFileInfo(SandboxDirectoryDatabase::FileInfo* file_info,
54 SandboxDirectoryDatabase::FileInfo* file_info, 54 SandboxDirectoryDatabase::FileId parent_id,
55 SandboxDirectoryDatabase::FileId parent_id, 55 const base::FilePath::StringType& file_name) {
56 const base::FilePath::StringType& file_name) {
57 DCHECK(file_info); 56 DCHECK(file_info);
58 file_info->parent_id = parent_id; 57 file_info->parent_id = parent_id;
59 file_info->name = file_name; 58 file_info->name = file_name;
60 } 59 }
61 60
62 // Costs computed as per crbug.com/86114, based on the LevelDB implementation of 61 // Costs computed as per crbug.com/86114, based on the LevelDB implementation of
63 // path storage under Linux. It's not clear if that will differ on Windows, on 62 // path storage under Linux. It's not clear if that will differ on Windows, on
64 // which base::FilePath uses wide chars [since they're converted to UTF-8 for 63 // which base::FilePath uses wide chars [since they're converted to UTF-8 for
65 // storage anyway], but as long as the cost is high enough that one can't cheat 64 // storage anyway], but as long as the cost is high enough that one can't cheat
66 // on quota by storing data in paths, it doesn't need to be all that accurate. 65 // on quota by storing data in paths, it doesn't need to be all that accurate.
67 const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically. 66 const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically.
68 const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8. 67 const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8.
69 68
70 int64 UsageForPath(size_t length) { 69 int64 UsageForPath(size_t length) {
71 return kPathCreationQuotaCost + 70 return kPathCreationQuotaCost +
72 static_cast<int64>(length) * kPathByteQuotaCost; 71 static_cast<int64>(length) * kPathByteQuotaCost;
73 } 72 }
74 73
75 bool AllocateQuota(FileSystemOperationContext* context, int64 growth) { 74 bool AllocateQuota(FileSystemOperationContext* context, int64 growth) {
76 if (context->allowed_bytes_growth() == quota::QuotaManager::kNoLimit) 75 if (context->allowed_bytes_growth() == quota::QuotaManager::kNoLimit)
77 return true; 76 return true;
78 77
79 int64 new_quota = context->allowed_bytes_growth() - growth; 78 int64 new_quota = context->allowed_bytes_growth() - growth;
80 if (growth > 0 && new_quota < 0) 79 if (growth > 0 && new_quota < 0)
81 return false; 80 return false;
82 context->set_allowed_bytes_growth(new_quota); 81 context->set_allowed_bytes_growth(new_quota);
83 return true; 82 return true;
84 } 83 }
85 84
86 void UpdateUsage( 85 void UpdateUsage(FileSystemOperationContext* context,
87 FileSystemOperationContext* context, 86 const FileSystemURL& url,
88 const FileSystemURL& url, 87 int64 growth) {
89 int64 growth) { 88 context->update_observers()->Notify(&FileUpdateObserver::OnUpdate,
90 context->update_observers()->Notify( 89 MakeTuple(url, growth));
91 &FileUpdateObserver::OnUpdate, MakeTuple(url, growth));
92 } 90 }
93 91
94 void TouchDirectory(SandboxDirectoryDatabase* db, FileId dir_id) { 92 void TouchDirectory(SandboxDirectoryDatabase* db, FileId dir_id) {
95 DCHECK(db); 93 DCHECK(db);
96 if (!db->UpdateModificationTime(dir_id, base::Time::Now())) 94 if (!db->UpdateModificationTime(dir_id, base::Time::Now()))
97 NOTREACHED(); 95 NOTREACHED();
98 } 96 }
99 97
100 enum IsolatedOriginStatus { 98 enum IsolatedOriginStatus {
101 kIsolatedOriginMatch, 99 kIsolatedOriginMatch,
102 kIsolatedOriginDontMatch, 100 kIsolatedOriginDontMatch,
103 kIsolatedOriginStatusMax, 101 kIsolatedOriginStatusMax,
104 }; 102 };
105 103
106 } // namespace 104 } // namespace
107 105
108 class ObfuscatedFileEnumerator 106 class ObfuscatedFileEnumerator
109 : public FileSystemFileUtil::AbstractFileEnumerator { 107 : public FileSystemFileUtil::AbstractFileEnumerator {
110 public: 108 public:
111 ObfuscatedFileEnumerator( 109 ObfuscatedFileEnumerator(SandboxDirectoryDatabase* db,
112 SandboxDirectoryDatabase* db, 110 FileSystemOperationContext* context,
113 FileSystemOperationContext* context, 111 ObfuscatedFileUtil* obfuscated_file_util,
114 ObfuscatedFileUtil* obfuscated_file_util, 112 const FileSystemURL& root_url,
115 const FileSystemURL& root_url, 113 bool recursive)
116 bool recursive)
117 : db_(db), 114 : db_(db),
118 context_(context), 115 context_(context),
119 obfuscated_file_util_(obfuscated_file_util), 116 obfuscated_file_util_(obfuscated_file_util),
120 root_url_(root_url), 117 root_url_(root_url),
121 recursive_(recursive), 118 recursive_(recursive),
122 current_file_id_(0) { 119 current_file_id_(0) {
123 base::FilePath root_virtual_path = root_url.path(); 120 base::FilePath root_virtual_path = root_url.path();
124 FileId file_id; 121 FileId file_id;
125 122
126 if (!db_->GetFileWithPath(root_virtual_path, &file_id)) 123 if (!db_->GetFileWithPath(root_virtual_path, &file_id))
127 return; 124 return;
128 125
129 FileRecord record = { file_id, root_virtual_path }; 126 FileRecord record = {file_id, root_virtual_path};
130 recurse_queue_.push(record); 127 recurse_queue_.push(record);
131 } 128 }
132 129
133 virtual ~ObfuscatedFileEnumerator() {} 130 virtual ~ObfuscatedFileEnumerator() {}
134 131
135 virtual base::FilePath Next() OVERRIDE { 132 virtual base::FilePath Next() OVERRIDE {
136 ProcessRecurseQueue(); 133 ProcessRecurseQueue();
137 if (display_stack_.empty()) 134 if (display_stack_.empty())
138 return base::FilePath(); 135 return base::FilePath();
139 136
140 current_file_id_ = display_stack_.back(); 137 current_file_id_ = display_stack_.back();
141 display_stack_.pop_back(); 138 display_stack_.pop_back();
142 139
143 FileInfo file_info; 140 FileInfo file_info;
144 base::FilePath platform_file_path; 141 base::FilePath platform_file_path;
145 base::File::Error error = 142 base::File::Error error =
146 obfuscated_file_util_->GetFileInfoInternal( 143 obfuscated_file_util_->GetFileInfoInternal(db_,
147 db_, context_, root_url_, current_file_id_, 144 context_,
148 &file_info, &current_platform_file_info_, &platform_file_path); 145 root_url_,
146 current_file_id_,
147 &file_info,
148 &current_platform_file_info_,
149 &platform_file_path);
149 if (error != base::File::FILE_OK) 150 if (error != base::File::FILE_OK)
150 return Next(); 151 return Next();
151 152
152 base::FilePath virtual_path = 153 base::FilePath virtual_path =
153 current_parent_virtual_path_.Append(file_info.name); 154 current_parent_virtual_path_.Append(file_info.name);
154 if (recursive_ && file_info.is_directory()) { 155 if (recursive_ && file_info.is_directory()) {
155 FileRecord record = { current_file_id_, virtual_path }; 156 FileRecord record = {current_file_id_, virtual_path};
156 recurse_queue_.push(record); 157 recurse_queue_.push(record);
157 } 158 }
158 return virtual_path; 159 return virtual_path;
159 } 160 }
160 161
161 virtual int64 Size() OVERRIDE { 162 virtual int64 Size() OVERRIDE { return current_platform_file_info_.size; }
162 return current_platform_file_info_.size;
163 }
164 163
165 virtual base::Time LastModifiedTime() OVERRIDE { 164 virtual base::Time LastModifiedTime() OVERRIDE {
166 return current_platform_file_info_.last_modified; 165 return current_platform_file_info_.last_modified;
167 } 166 }
168 167
169 virtual bool IsDirectory() OVERRIDE { 168 virtual bool IsDirectory() OVERRIDE {
170 return current_platform_file_info_.is_directory; 169 return current_platform_file_info_.is_directory;
171 } 170 }
172 171
173 private: 172 private:
(...skipping 28 matching lines...) Expand all
202 base::FilePath current_parent_virtual_path_; 201 base::FilePath current_parent_virtual_path_;
203 202
204 FileId current_file_id_; 203 FileId current_file_id_;
205 base::File::Info current_platform_file_info_; 204 base::File::Info current_platform_file_info_;
206 }; 205 };
207 206
208 class ObfuscatedOriginEnumerator 207 class ObfuscatedOriginEnumerator
209 : public ObfuscatedFileUtil::AbstractOriginEnumerator { 208 : public ObfuscatedFileUtil::AbstractOriginEnumerator {
210 public: 209 public:
211 typedef SandboxOriginDatabase::OriginRecord OriginRecord; 210 typedef SandboxOriginDatabase::OriginRecord OriginRecord;
212 ObfuscatedOriginEnumerator( 211 ObfuscatedOriginEnumerator(SandboxOriginDatabaseInterface* origin_database,
213 SandboxOriginDatabaseInterface* origin_database, 212 const base::FilePath& base_file_path)
214 const base::FilePath& base_file_path)
215 : base_file_path_(base_file_path) { 213 : base_file_path_(base_file_path) {
216 if (origin_database) 214 if (origin_database)
217 origin_database->ListAllOrigins(&origins_); 215 origin_database->ListAllOrigins(&origins_);
218 } 216 }
219 217
220 virtual ~ObfuscatedOriginEnumerator() {} 218 virtual ~ObfuscatedOriginEnumerator() {}
221 219
222 // Returns the next origin. Returns empty if there are no more origins. 220 // Returns the next origin. Returns empty if there are no more origins.
223 virtual GURL Next() OVERRIDE { 221 virtual GURL Next() OVERRIDE {
224 OriginRecord record; 222 OriginRecord record;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 file_task_runner_(file_task_runner), 262 file_task_runner_(file_task_runner),
265 get_type_string_for_url_(get_type_string_for_url), 263 get_type_string_for_url_(get_type_string_for_url),
266 known_type_strings_(known_type_strings), 264 known_type_strings_(known_type_strings),
267 sandbox_delegate_(sandbox_delegate) { 265 sandbox_delegate_(sandbox_delegate) {
268 } 266 }
269 267
270 ObfuscatedFileUtil::~ObfuscatedFileUtil() { 268 ObfuscatedFileUtil::~ObfuscatedFileUtil() {
271 DropDatabases(); 269 DropDatabases();
272 } 270 }
273 271
274 base::File ObfuscatedFileUtil::CreateOrOpen( 272 base::File ObfuscatedFileUtil::CreateOrOpen(FileSystemOperationContext* context,
275 FileSystemOperationContext* context, 273 const FileSystemURL& url,
276 const FileSystemURL& url, int file_flags) { 274 int file_flags) {
277 base::File file = CreateOrOpenInternal(context, url, file_flags); 275 base::File file = CreateOrOpenInternal(context, url, file_flags);
278 if (file.IsValid() && file_flags & base::File::FLAG_WRITE && 276 if (file.IsValid() && file_flags & base::File::FLAG_WRITE &&
279 context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited && 277 context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited &&
280 sandbox_delegate_) { 278 sandbox_delegate_) {
281 sandbox_delegate_->StickyInvalidateUsageCache(url.origin(), url.type()); 279 sandbox_delegate_->StickyInvalidateUsageCache(url.origin(), url.type());
282 } 280 }
283 return file.Pass(); 281 return file.Pass();
284 } 282 }
285 283
286 base::File::Error ObfuscatedFileUtil::EnsureFileExists( 284 base::File::Error ObfuscatedFileUtil::EnsureFileExists(
(...skipping 15 matching lines...) Expand all
302 return base::File::FILE_ERROR_NOT_A_FILE; 300 return base::File::FILE_ERROR_NOT_A_FILE;
303 if (created) 301 if (created)
304 *created = false; 302 *created = false;
305 return base::File::FILE_OK; 303 return base::File::FILE_OK;
306 } 304 }
307 FileId parent_id; 305 FileId parent_id;
308 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) 306 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id))
309 return base::File::FILE_ERROR_NOT_FOUND; 307 return base::File::FILE_ERROR_NOT_FOUND;
310 308
311 FileInfo file_info; 309 FileInfo file_info;
312 InitFileInfo(&file_info, parent_id, 310 InitFileInfo(
313 VirtualPath::BaseName(url.path()).value()); 311 &file_info, parent_id, VirtualPath::BaseName(url.path()).value());
314 312
315 int64 growth = UsageForPath(file_info.name.size()); 313 int64 growth = UsageForPath(file_info.name.size());
316 if (!AllocateQuota(context, growth)) 314 if (!AllocateQuota(context, growth))
317 return base::File::FILE_ERROR_NO_SPACE; 315 return base::File::FILE_ERROR_NO_SPACE;
318 base::File::Error error = CreateFile(context, base::FilePath(), url, 316 base::File::Error error =
319 &file_info); 317 CreateFile(context, base::FilePath(), url, &file_info);
320 if (created && base::File::FILE_OK == error) { 318 if (created && base::File::FILE_OK == error) {
321 *created = true; 319 *created = true;
322 UpdateUsage(context, url, growth); 320 UpdateUsage(context, url, growth);
323 context->change_observers()->Notify( 321 context->change_observers()->Notify(&FileChangeObserver::OnCreateFile,
324 &FileChangeObserver::OnCreateFile, MakeTuple(url)); 322 MakeTuple(url));
325 } 323 }
326 return error; 324 return error;
327 } 325 }
328 326
329 base::File::Error ObfuscatedFileUtil::CreateDirectory( 327 base::File::Error ObfuscatedFileUtil::CreateDirectory(
330 FileSystemOperationContext* context, 328 FileSystemOperationContext* context,
331 const FileSystemURL& url, 329 const FileSystemURL& url,
332 bool exclusive, 330 bool exclusive,
333 bool recursive) { 331 bool recursive) {
334 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); 332 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 continue; 370 continue;
373 file_info.modification_time = base::Time::Now(); 371 file_info.modification_time = base::Time::Now();
374 file_info.parent_id = parent_id; 372 file_info.parent_id = parent_id;
375 int64 growth = UsageForPath(file_info.name.size()); 373 int64 growth = UsageForPath(file_info.name.size());
376 if (!AllocateQuota(context, growth)) 374 if (!AllocateQuota(context, growth))
377 return base::File::FILE_ERROR_NO_SPACE; 375 return base::File::FILE_ERROR_NO_SPACE;
378 base::File::Error error = db->AddFileInfo(file_info, &parent_id); 376 base::File::Error error = db->AddFileInfo(file_info, &parent_id);
379 if (error != base::File::FILE_OK) 377 if (error != base::File::FILE_OK)
380 return error; 378 return error;
381 UpdateUsage(context, url, growth); 379 UpdateUsage(context, url, growth);
382 context->change_observers()->Notify( 380 context->change_observers()->Notify(&FileChangeObserver::OnCreateDirectory,
383 &FileChangeObserver::OnCreateDirectory, MakeTuple(url)); 381 MakeTuple(url));
384 if (first) { 382 if (first) {
385 first = false; 383 first = false;
386 TouchDirectory(db, file_info.parent_id); 384 TouchDirectory(db, file_info.parent_id);
387 } 385 }
388 } 386 }
389 return base::File::FILE_OK; 387 return base::File::FILE_OK;
390 } 388 }
391 389
392 base::File::Error ObfuscatedFileUtil::GetFileInfo( 390 base::File::Error ObfuscatedFileUtil::GetFileInfo(
393 FileSystemOperationContext* context, 391 FileSystemOperationContext* context,
394 const FileSystemURL& url, 392 const FileSystemURL& url,
395 base::File::Info* file_info, 393 base::File::Info* file_info,
396 base::FilePath* platform_file_path) { 394 base::FilePath* platform_file_path) {
397 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false); 395 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false);
398 if (!db) 396 if (!db)
399 return base::File::FILE_ERROR_NOT_FOUND; 397 return base::File::FILE_ERROR_NOT_FOUND;
400 FileId file_id; 398 FileId file_id;
401 if (!db->GetFileWithPath(url.path(), &file_id)) 399 if (!db->GetFileWithPath(url.path(), &file_id))
402 return base::File::FILE_ERROR_NOT_FOUND; 400 return base::File::FILE_ERROR_NOT_FOUND;
403 FileInfo local_info; 401 FileInfo local_info;
404 return GetFileInfoInternal(db, context, url, 402 return GetFileInfoInternal(
405 file_id, &local_info, 403 db, context, url, file_id, &local_info, file_info, platform_file_path);
406 file_info, platform_file_path);
407 } 404 }
408 405
409 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> 406 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
410 ObfuscatedFileUtil::CreateFileEnumerator( 407 ObfuscatedFileUtil::CreateFileEnumerator(FileSystemOperationContext* context,
411 FileSystemOperationContext* context, 408 const FileSystemURL& root_url) {
412 const FileSystemURL& root_url) {
413 return CreateFileEnumerator(context, root_url, false /* recursive */); 409 return CreateFileEnumerator(context, root_url, false /* recursive */);
414 } 410 }
415 411
416 base::File::Error ObfuscatedFileUtil::GetLocalFilePath( 412 base::File::Error ObfuscatedFileUtil::GetLocalFilePath(
417 FileSystemOperationContext* context, 413 FileSystemOperationContext* context,
418 const FileSystemURL& url, 414 const FileSystemURL& url,
419 base::FilePath* local_path) { 415 base::FilePath* local_path) {
420 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false); 416 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false);
421 if (!db) 417 if (!db)
422 return base::File::FILE_ERROR_NOT_FOUND; 418 return base::File::FILE_ERROR_NOT_FOUND;
(...skipping 28 matching lines...) Expand all
451 FileInfo file_info; 447 FileInfo file_info;
452 if (!db->GetFileInfo(file_id, &file_info)) { 448 if (!db->GetFileInfo(file_id, &file_info)) {
453 NOTREACHED(); 449 NOTREACHED();
454 return base::File::FILE_ERROR_FAILED; 450 return base::File::FILE_ERROR_FAILED;
455 } 451 }
456 if (file_info.is_directory()) { 452 if (file_info.is_directory()) {
457 if (!db->UpdateModificationTime(file_id, last_modified_time)) 453 if (!db->UpdateModificationTime(file_id, last_modified_time))
458 return base::File::FILE_ERROR_FAILED; 454 return base::File::FILE_ERROR_FAILED;
459 return base::File::FILE_OK; 455 return base::File::FILE_OK;
460 } 456 }
461 return NativeFileUtil::Touch( 457 return NativeFileUtil::Touch(DataPathToLocalPath(url, file_info.data_path),
462 DataPathToLocalPath(url, file_info.data_path), 458 last_access_time,
463 last_access_time, last_modified_time); 459 last_modified_time);
464 } 460 }
465 461
466 base::File::Error ObfuscatedFileUtil::Truncate( 462 base::File::Error ObfuscatedFileUtil::Truncate(
467 FileSystemOperationContext* context, 463 FileSystemOperationContext* context,
468 const FileSystemURL& url, 464 const FileSystemURL& url,
469 int64 length) { 465 int64 length) {
470 base::File::Info file_info; 466 base::File::Info file_info;
471 base::FilePath local_path; 467 base::FilePath local_path;
472 base::File::Error error = 468 base::File::Error error = GetFileInfo(context, url, &file_info, &local_path);
473 GetFileInfo(context, url, &file_info, &local_path);
474 if (error != base::File::FILE_OK) 469 if (error != base::File::FILE_OK)
475 return error; 470 return error;
476 471
477 int64 growth = length - file_info.size; 472 int64 growth = length - file_info.size;
478 if (!AllocateQuota(context, growth)) 473 if (!AllocateQuota(context, growth))
479 return base::File::FILE_ERROR_NO_SPACE; 474 return base::File::FILE_ERROR_NO_SPACE;
480 error = NativeFileUtil::Truncate(local_path, length); 475 error = NativeFileUtil::Truncate(local_path, length);
481 if (error == base::File::FILE_OK) { 476 if (error == base::File::FILE_OK) {
482 UpdateUsage(context, url, growth); 477 UpdateUsage(context, url, growth);
483 context->change_observers()->Notify( 478 context->change_observers()->Notify(&FileChangeObserver::OnModifyFile,
484 &FileChangeObserver::OnModifyFile, MakeTuple(url)); 479 MakeTuple(url));
485 } 480 }
486 return error; 481 return error;
487 } 482 }
488 483
489 base::File::Error ObfuscatedFileUtil::CopyOrMoveFile( 484 base::File::Error ObfuscatedFileUtil::CopyOrMoveFile(
490 FileSystemOperationContext* context, 485 FileSystemOperationContext* context,
491 const FileSystemURL& src_url, 486 const FileSystemURL& src_url,
492 const FileSystemURL& dest_url, 487 const FileSystemURL& dest_url,
493 CopyOrMoveOption option, 488 CopyOrMoveOption option,
494 bool copy) { 489 bool copy) {
495 // Cross-filesystem copies and moves should be handled via CopyInForeignFile. 490 // Cross-filesystem copies and moves should be handled via CopyInForeignFile.
496 DCHECK(src_url.origin() == dest_url.origin()); 491 DCHECK(src_url.origin() == dest_url.origin());
497 DCHECK(src_url.type() == dest_url.type()); 492 DCHECK(src_url.type() == dest_url.type());
498 493
499 SandboxDirectoryDatabase* db = GetDirectoryDatabase(src_url, true); 494 SandboxDirectoryDatabase* db = GetDirectoryDatabase(src_url, true);
500 if (!db) 495 if (!db)
501 return base::File::FILE_ERROR_FAILED; 496 return base::File::FILE_ERROR_FAILED;
502 497
503 FileId src_file_id; 498 FileId src_file_id;
504 if (!db->GetFileWithPath(src_url.path(), &src_file_id)) 499 if (!db->GetFileWithPath(src_url.path(), &src_file_id))
505 return base::File::FILE_ERROR_NOT_FOUND; 500 return base::File::FILE_ERROR_NOT_FOUND;
506 501
507 FileId dest_file_id; 502 FileId dest_file_id;
508 bool overwrite = db->GetFileWithPath(dest_url.path(), 503 bool overwrite = db->GetFileWithPath(dest_url.path(), &dest_file_id);
509 &dest_file_id);
510 504
511 FileInfo src_file_info; 505 FileInfo src_file_info;
512 base::File::Info src_platform_file_info; 506 base::File::Info src_platform_file_info;
513 base::FilePath src_local_path; 507 base::FilePath src_local_path;
514 base::File::Error error = GetFileInfoInternal( 508 base::File::Error error = GetFileInfoInternal(db,
515 db, context, src_url, src_file_id, 509 context,
516 &src_file_info, &src_platform_file_info, &src_local_path); 510 src_url,
511 src_file_id,
512 &src_file_info,
513 &src_platform_file_info,
514 &src_local_path);
517 if (error != base::File::FILE_OK) 515 if (error != base::File::FILE_OK)
518 return error; 516 return error;
519 if (src_file_info.is_directory()) 517 if (src_file_info.is_directory())
520 return base::File::FILE_ERROR_NOT_A_FILE; 518 return base::File::FILE_ERROR_NOT_A_FILE;
521 519
522 FileInfo dest_file_info; 520 FileInfo dest_file_info;
523 base::File::Info dest_platform_file_info; // overwrite case only 521 base::File::Info dest_platform_file_info; // overwrite case only
524 base::FilePath dest_local_path; // overwrite case only 522 base::FilePath dest_local_path; // overwrite case only
525 if (overwrite) { 523 if (overwrite) {
526 base::File::Error error = GetFileInfoInternal( 524 base::File::Error error = GetFileInfoInternal(db,
527 db, context, dest_url, dest_file_id, 525 context,
528 &dest_file_info, &dest_platform_file_info, &dest_local_path); 526 dest_url,
527 dest_file_id,
528 &dest_file_info,
529 &dest_platform_file_info,
530 &dest_local_path);
529 if (error == base::File::FILE_ERROR_NOT_FOUND) 531 if (error == base::File::FILE_ERROR_NOT_FOUND)
530 overwrite = false; // fallback to non-overwrite case 532 overwrite = false; // fallback to non-overwrite case
531 else if (error != base::File::FILE_OK) 533 else if (error != base::File::FILE_OK)
532 return error; 534 return error;
533 else if (dest_file_info.is_directory()) 535 else if (dest_file_info.is_directory())
534 return base::File::FILE_ERROR_INVALID_OPERATION; 536 return base::File::FILE_ERROR_INVALID_OPERATION;
535 } 537 }
536 if (!overwrite) { 538 if (!overwrite) {
537 FileId dest_parent_id; 539 FileId dest_parent_id;
538 if (!db->GetFileWithPath(VirtualPath::DirName(dest_url.path()), 540 if (!db->GetFileWithPath(VirtualPath::DirName(dest_url.path()),
539 &dest_parent_id)) { 541 &dest_parent_id)) {
540 return base::File::FILE_ERROR_NOT_FOUND; 542 return base::File::FILE_ERROR_NOT_FOUND;
541 } 543 }
542 544
543 dest_file_info = src_file_info; 545 dest_file_info = src_file_info;
544 dest_file_info.parent_id = dest_parent_id; 546 dest_file_info.parent_id = dest_parent_id;
545 dest_file_info.name = 547 dest_file_info.name = VirtualPath::BaseName(dest_url.path()).value();
546 VirtualPath::BaseName(dest_url.path()).value();
547 } 548 }
548 549
549 int64 growth = 0; 550 int64 growth = 0;
550 if (copy) 551 if (copy)
551 growth += src_platform_file_info.size; 552 growth += src_platform_file_info.size;
552 else 553 else
553 growth -= UsageForPath(src_file_info.name.size()); 554 growth -= UsageForPath(src_file_info.name.size());
554 if (overwrite) 555 if (overwrite)
555 growth -= dest_platform_file_info.size; 556 growth -= dest_platform_file_info.size;
556 else 557 else
(...skipping 15 matching lines...) Expand all
572 * Move-without-overwrite 573 * Move-without-overwrite
573 * Just update metadata 574 * Just update metadata
574 */ 575 */
575 error = base::File::FILE_ERROR_FAILED; 576 error = base::File::FILE_ERROR_FAILED;
576 if (copy) { 577 if (copy) {
577 if (overwrite) { 578 if (overwrite) {
578 error = NativeFileUtil::CopyOrMoveFile( 579 error = NativeFileUtil::CopyOrMoveFile(
579 src_local_path, 580 src_local_path,
580 dest_local_path, 581 dest_local_path,
581 option, 582 option,
582 fileapi::NativeFileUtil::CopyOrMoveModeForDestination( 583 storage::NativeFileUtil::CopyOrMoveModeForDestination(
583 dest_url, true /* copy */)); 584 dest_url, true /* copy */));
584 } else { // non-overwrite 585 } else { // non-overwrite
585 error = CreateFile(context, src_local_path, dest_url, &dest_file_info); 586 error = CreateFile(context, src_local_path, dest_url, &dest_file_info);
586 } 587 }
587 } else { 588 } else {
588 if (overwrite) { 589 if (overwrite) {
589 if (db->OverwritingMoveFile(src_file_id, dest_file_id)) { 590 if (db->OverwritingMoveFile(src_file_id, dest_file_id)) {
590 if (base::File::FILE_OK != 591 if (base::File::FILE_OK != NativeFileUtil::DeleteFile(dest_local_path))
591 NativeFileUtil::DeleteFile(dest_local_path))
592 LOG(WARNING) << "Leaked a backing file."; 592 LOG(WARNING) << "Leaked a backing file.";
593 error = base::File::FILE_OK; 593 error = base::File::FILE_OK;
594 } else { 594 } else {
595 error = base::File::FILE_ERROR_FAILED; 595 error = base::File::FILE_ERROR_FAILED;
596 } 596 }
597 } else { // non-overwrite 597 } else { // non-overwrite
598 if (db->UpdateFileInfo(src_file_id, dest_file_info)) 598 if (db->UpdateFileInfo(src_file_id, dest_file_info))
599 error = base::File::FILE_OK; 599 error = base::File::FILE_OK;
600 else 600 else
601 error = base::File::FILE_ERROR_FAILED; 601 error = base::File::FILE_ERROR_FAILED;
602 } 602 }
603 } 603 }
604 604
605 if (error != base::File::FILE_OK) 605 if (error != base::File::FILE_OK)
606 return error; 606 return error;
607 607
608 if (overwrite) { 608 if (overwrite) {
609 context->change_observers()->Notify( 609 context->change_observers()->Notify(&FileChangeObserver::OnModifyFile,
610 &FileChangeObserver::OnModifyFile, 610 MakeTuple(dest_url));
611 MakeTuple(dest_url));
612 } else { 611 } else {
613 context->change_observers()->Notify( 612 context->change_observers()->Notify(&FileChangeObserver::OnCreateFileFrom,
614 &FileChangeObserver::OnCreateFileFrom, 613 MakeTuple(dest_url, src_url));
615 MakeTuple(dest_url, src_url));
616 } 614 }
617 615
618 if (!copy) { 616 if (!copy) {
619 context->change_observers()->Notify( 617 context->change_observers()->Notify(&FileChangeObserver::OnRemoveFile,
620 &FileChangeObserver::OnRemoveFile, MakeTuple(src_url)); 618 MakeTuple(src_url));
621 TouchDirectory(db, src_file_info.parent_id); 619 TouchDirectory(db, src_file_info.parent_id);
622 } 620 }
623 621
624 TouchDirectory(db, dest_file_info.parent_id); 622 TouchDirectory(db, dest_file_info.parent_id);
625 623
626 UpdateUsage(context, dest_url, growth); 624 UpdateUsage(context, dest_url, growth);
627 return error; 625 return error;
628 } 626 }
629 627
630 base::File::Error ObfuscatedFileUtil::CopyInForeignFile( 628 base::File::Error ObfuscatedFileUtil::CopyInForeignFile(
631 FileSystemOperationContext* context, 629 FileSystemOperationContext* context,
632 const base::FilePath& src_file_path, 630 const base::FilePath& src_file_path,
633 const FileSystemURL& dest_url) { 631 const FileSystemURL& dest_url) {
634 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); 632 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true);
635 if (!db) 633 if (!db)
636 return base::File::FILE_ERROR_FAILED; 634 return base::File::FILE_ERROR_FAILED;
637 635
638 base::File::Info src_platform_file_info; 636 base::File::Info src_platform_file_info;
639 if (!base::GetFileInfo(src_file_path, &src_platform_file_info)) 637 if (!base::GetFileInfo(src_file_path, &src_platform_file_info))
640 return base::File::FILE_ERROR_NOT_FOUND; 638 return base::File::FILE_ERROR_NOT_FOUND;
641 639
642 FileId dest_file_id; 640 FileId dest_file_id;
643 bool overwrite = db->GetFileWithPath(dest_url.path(), 641 bool overwrite = db->GetFileWithPath(dest_url.path(), &dest_file_id);
644 &dest_file_id);
645 642
646 FileInfo dest_file_info; 643 FileInfo dest_file_info;
647 base::File::Info dest_platform_file_info; // overwrite case only 644 base::File::Info dest_platform_file_info; // overwrite case only
648 if (overwrite) { 645 if (overwrite) {
649 base::FilePath dest_local_path; 646 base::FilePath dest_local_path;
650 base::File::Error error = GetFileInfoInternal( 647 base::File::Error error = GetFileInfoInternal(db,
651 db, context, dest_url, dest_file_id, 648 context,
652 &dest_file_info, &dest_platform_file_info, &dest_local_path); 649 dest_url,
650 dest_file_id,
651 &dest_file_info,
652 &dest_platform_file_info,
653 &dest_local_path);
653 if (error == base::File::FILE_ERROR_NOT_FOUND) 654 if (error == base::File::FILE_ERROR_NOT_FOUND)
654 overwrite = false; // fallback to non-overwrite case 655 overwrite = false; // fallback to non-overwrite case
655 else if (error != base::File::FILE_OK) 656 else if (error != base::File::FILE_OK)
656 return error; 657 return error;
657 else if (dest_file_info.is_directory()) 658 else if (dest_file_info.is_directory())
658 return base::File::FILE_ERROR_INVALID_OPERATION; 659 return base::File::FILE_ERROR_INVALID_OPERATION;
659 } 660 }
660 if (!overwrite) { 661 if (!overwrite) {
661 FileId dest_parent_id; 662 FileId dest_parent_id;
662 if (!db->GetFileWithPath(VirtualPath::DirName(dest_url.path()), 663 if (!db->GetFileWithPath(VirtualPath::DirName(dest_url.path()),
663 &dest_parent_id)) { 664 &dest_parent_id)) {
664 return base::File::FILE_ERROR_NOT_FOUND; 665 return base::File::FILE_ERROR_NOT_FOUND;
665 } 666 }
666 if (!dest_file_info.is_directory()) 667 if (!dest_file_info.is_directory())
667 return base::File::FILE_ERROR_FAILED; 668 return base::File::FILE_ERROR_FAILED;
668 InitFileInfo(&dest_file_info, dest_parent_id, 669 InitFileInfo(&dest_file_info,
670 dest_parent_id,
669 VirtualPath::BaseName(dest_url.path()).value()); 671 VirtualPath::BaseName(dest_url.path()).value());
670 } 672 }
671 673
672 int64 growth = src_platform_file_info.size; 674 int64 growth = src_platform_file_info.size;
673 if (overwrite) 675 if (overwrite)
674 growth -= dest_platform_file_info.size; 676 growth -= dest_platform_file_info.size;
675 else 677 else
676 growth += UsageForPath(dest_file_info.name.size()); 678 growth += UsageForPath(dest_file_info.name.size());
677 if (!AllocateQuota(context, growth)) 679 if (!AllocateQuota(context, growth))
678 return base::File::FILE_ERROR_NO_SPACE; 680 return base::File::FILE_ERROR_NO_SPACE;
679 681
680 base::File::Error error; 682 base::File::Error error;
681 if (overwrite) { 683 if (overwrite) {
682 base::FilePath dest_local_path = 684 base::FilePath dest_local_path =
683 DataPathToLocalPath(dest_url, dest_file_info.data_path); 685 DataPathToLocalPath(dest_url, dest_file_info.data_path);
684 error = NativeFileUtil::CopyOrMoveFile( 686 error = NativeFileUtil::CopyOrMoveFile(
685 src_file_path, dest_local_path, 687 src_file_path,
688 dest_local_path,
686 FileSystemOperation::OPTION_NONE, 689 FileSystemOperation::OPTION_NONE,
687 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, 690 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url,
688 true /* copy */)); 691 true /* copy */));
689 } else { 692 } else {
690 error = CreateFile(context, src_file_path, dest_url, &dest_file_info); 693 error = CreateFile(context, src_file_path, dest_url, &dest_file_info);
691 } 694 }
692 695
693 if (error != base::File::FILE_OK) 696 if (error != base::File::FILE_OK)
694 return error; 697 return error;
695 698
696 if (overwrite) { 699 if (overwrite) {
697 context->change_observers()->Notify( 700 context->change_observers()->Notify(&FileChangeObserver::OnModifyFile,
698 &FileChangeObserver::OnModifyFile, MakeTuple(dest_url)); 701 MakeTuple(dest_url));
699 } else { 702 } else {
700 context->change_observers()->Notify( 703 context->change_observers()->Notify(&FileChangeObserver::OnCreateFile,
701 &FileChangeObserver::OnCreateFile, MakeTuple(dest_url)); 704 MakeTuple(dest_url));
702 } 705 }
703 706
704 UpdateUsage(context, dest_url, growth); 707 UpdateUsage(context, dest_url, growth);
705 TouchDirectory(db, dest_file_info.parent_id); 708 TouchDirectory(db, dest_file_info.parent_id);
706 return base::File::FILE_OK; 709 return base::File::FILE_OK;
707 } 710 }
708 711
709 base::File::Error ObfuscatedFileUtil::DeleteFile( 712 base::File::Error ObfuscatedFileUtil::DeleteFile(
710 FileSystemOperationContext* context, 713 FileSystemOperationContext* context,
711 const FileSystemURL& url) { 714 const FileSystemURL& url) {
712 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); 715 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true);
713 if (!db) 716 if (!db)
714 return base::File::FILE_ERROR_FAILED; 717 return base::File::FILE_ERROR_FAILED;
715 FileId file_id; 718 FileId file_id;
716 if (!db->GetFileWithPath(url.path(), &file_id)) 719 if (!db->GetFileWithPath(url.path(), &file_id))
717 return base::File::FILE_ERROR_NOT_FOUND; 720 return base::File::FILE_ERROR_NOT_FOUND;
718 721
719 FileInfo file_info; 722 FileInfo file_info;
720 base::File::Info platform_file_info; 723 base::File::Info platform_file_info;
721 base::FilePath local_path; 724 base::FilePath local_path;
722 base::File::Error error = GetFileInfoInternal( 725 base::File::Error error = GetFileInfoInternal(
723 db, context, url, file_id, &file_info, &platform_file_info, &local_path); 726 db, context, url, file_id, &file_info, &platform_file_info, &local_path);
724 if (error != base::File::FILE_ERROR_NOT_FOUND && 727 if (error != base::File::FILE_ERROR_NOT_FOUND && error != base::File::FILE_OK)
725 error != base::File::FILE_OK)
726 return error; 728 return error;
727 729
728 if (file_info.is_directory()) 730 if (file_info.is_directory())
729 return base::File::FILE_ERROR_NOT_A_FILE; 731 return base::File::FILE_ERROR_NOT_A_FILE;
730 732
731 int64 growth = -UsageForPath(file_info.name.size()) - platform_file_info.size; 733 int64 growth = -UsageForPath(file_info.name.size()) - platform_file_info.size;
732 AllocateQuota(context, growth); 734 AllocateQuota(context, growth);
733 if (!db->RemoveFileInfo(file_id)) { 735 if (!db->RemoveFileInfo(file_id)) {
734 NOTREACHED(); 736 NOTREACHED();
735 return base::File::FILE_ERROR_FAILED; 737 return base::File::FILE_ERROR_FAILED;
736 } 738 }
737 UpdateUsage(context, url, growth); 739 UpdateUsage(context, url, growth);
738 TouchDirectory(db, file_info.parent_id); 740 TouchDirectory(db, file_info.parent_id);
739 741
740 context->change_observers()->Notify( 742 context->change_observers()->Notify(&FileChangeObserver::OnRemoveFile,
741 &FileChangeObserver::OnRemoveFile, MakeTuple(url)); 743 MakeTuple(url));
742 744
743 if (error == base::File::FILE_ERROR_NOT_FOUND) 745 if (error == base::File::FILE_ERROR_NOT_FOUND)
744 return base::File::FILE_OK; 746 return base::File::FILE_OK;
745 747
746 error = NativeFileUtil::DeleteFile(local_path); 748 error = NativeFileUtil::DeleteFile(local_path);
747 if (base::File::FILE_OK != error) 749 if (base::File::FILE_OK != error)
748 LOG(WARNING) << "Leaked a backing file."; 750 LOG(WARNING) << "Leaked a backing file.";
749 return base::File::FILE_OK; 751 return base::File::FILE_OK;
750 } 752 }
751 753
(...skipping 13 matching lines...) Expand all
765 return base::File::FILE_ERROR_FAILED; 767 return base::File::FILE_ERROR_FAILED;
766 } 768 }
767 if (!file_info.is_directory()) 769 if (!file_info.is_directory())
768 return base::File::FILE_ERROR_NOT_A_DIRECTORY; 770 return base::File::FILE_ERROR_NOT_A_DIRECTORY;
769 if (!db->RemoveFileInfo(file_id)) 771 if (!db->RemoveFileInfo(file_id))
770 return base::File::FILE_ERROR_NOT_EMPTY; 772 return base::File::FILE_ERROR_NOT_EMPTY;
771 int64 growth = -UsageForPath(file_info.name.size()); 773 int64 growth = -UsageForPath(file_info.name.size());
772 AllocateQuota(context, growth); 774 AllocateQuota(context, growth);
773 UpdateUsage(context, url, growth); 775 UpdateUsage(context, url, growth);
774 TouchDirectory(db, file_info.parent_id); 776 TouchDirectory(db, file_info.parent_id);
775 context->change_observers()->Notify( 777 context->change_observers()->Notify(&FileChangeObserver::OnRemoveDirectory,
776 &FileChangeObserver::OnRemoveDirectory, MakeTuple(url)); 778 MakeTuple(url));
777 return base::File::FILE_OK; 779 return base::File::FILE_OK;
778 } 780 }
779 781
780 webkit_blob::ScopedFile ObfuscatedFileUtil::CreateSnapshotFile( 782 storage::ScopedFile ObfuscatedFileUtil::CreateSnapshotFile(
781 FileSystemOperationContext* context, 783 FileSystemOperationContext* context,
782 const FileSystemURL& url, 784 const FileSystemURL& url,
783 base::File::Error* error, 785 base::File::Error* error,
784 base::File::Info* file_info, 786 base::File::Info* file_info,
785 base::FilePath* platform_path) { 787 base::FilePath* platform_path) {
786 // We're just returning the local file information. 788 // We're just returning the local file information.
787 *error = GetFileInfo(context, url, file_info, platform_path); 789 *error = GetFileInfo(context, url, file_info, platform_path);
788 if (*error == base::File::FILE_OK && file_info->is_directory) { 790 if (*error == base::File::FILE_OK && file_info->is_directory) {
789 *file_info = base::File::Info(); 791 *file_info = base::File::Info();
790 *error = base::File::FILE_ERROR_NOT_A_FILE; 792 *error = base::File::FILE_ERROR_NOT_A_FILE;
791 } 793 }
792 return webkit_blob::ScopedFile(); 794 return storage::ScopedFile();
793 } 795 }
794 796
795 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> 797 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
796 ObfuscatedFileUtil::CreateFileEnumerator( 798 ObfuscatedFileUtil::CreateFileEnumerator(FileSystemOperationContext* context,
797 FileSystemOperationContext* context, 799 const FileSystemURL& root_url,
798 const FileSystemURL& root_url, 800 bool recursive) {
799 bool recursive) {
800 SandboxDirectoryDatabase* db = GetDirectoryDatabase(root_url, false); 801 SandboxDirectoryDatabase* db = GetDirectoryDatabase(root_url, false);
801 if (!db) { 802 if (!db) {
802 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); 803 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator());
803 } 804 }
804 return scoped_ptr<AbstractFileEnumerator>( 805 return scoped_ptr<AbstractFileEnumerator>(
805 new ObfuscatedFileEnumerator(db, context, this, root_url, recursive)); 806 new ObfuscatedFileEnumerator(db, context, this, root_url, recursive));
806 } 807 }
807 808
808 bool ObfuscatedFileUtil::IsDirectoryEmpty( 809 bool ObfuscatedFileUtil::IsDirectoryEmpty(FileSystemOperationContext* context,
809 FileSystemOperationContext* context, 810 const FileSystemURL& url) {
810 const FileSystemURL& url) {
811 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false); 811 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, false);
812 if (!db) 812 if (!db)
813 return true; // Not a great answer, but it's what others do. 813 return true; // Not a great answer, but it's what others do.
814 FileId file_id; 814 FileId file_id;
815 if (!db->GetFileWithPath(url.path(), &file_id)) 815 if (!db->GetFileWithPath(url.path(), &file_id))
816 return true; // Ditto. 816 return true; // Ditto.
817 FileInfo file_info; 817 FileInfo file_info;
818 if (!db->GetFileInfo(file_id, &file_info)) { 818 if (!db->GetFileInfo(file_id, &file_info)) {
819 DCHECK(!file_id); 819 DCHECK(!file_id);
820 // It's the root directory and the database hasn't been initialized yet. 820 // It's the root directory and the database hasn't been initialized yet.
(...skipping 15 matching lines...) Expand all
836 base::File::Error* error_code) { 836 base::File::Error* error_code) {
837 base::FilePath origin_dir = GetDirectoryForOrigin(origin, create, error_code); 837 base::FilePath origin_dir = GetDirectoryForOrigin(origin, create, error_code);
838 if (origin_dir.empty()) 838 if (origin_dir.empty())
839 return base::FilePath(); 839 return base::FilePath();
840 if (type_string.empty()) 840 if (type_string.empty())
841 return origin_dir; 841 return origin_dir;
842 base::FilePath path = origin_dir.AppendASCII(type_string); 842 base::FilePath path = origin_dir.AppendASCII(type_string);
843 base::File::Error error = base::File::FILE_OK; 843 base::File::Error error = base::File::FILE_OK;
844 if (!base::DirectoryExists(path) && 844 if (!base::DirectoryExists(path) &&
845 (!create || !base::CreateDirectory(path))) { 845 (!create || !base::CreateDirectory(path))) {
846 error = create ? 846 error = create ? base::File::FILE_ERROR_FAILED
847 base::File::FILE_ERROR_FAILED : 847 : base::File::FILE_ERROR_NOT_FOUND;
848 base::File::FILE_ERROR_NOT_FOUND;
849 } 848 }
850 849
851 if (error_code) 850 if (error_code)
852 *error_code = error; 851 *error_code = error;
853 return path; 852 return path;
854 } 853 }
855 854
856 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( 855 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
857 const GURL& origin, 856 const GURL& origin,
858 const std::string& type_string) { 857 const std::string& type_string) {
859 base::File::Error error = base::File::FILE_OK; 858 base::File::Error error = base::File::FILE_OK;
860 base::FilePath origin_type_path = GetDirectoryForOriginAndType( 859 base::FilePath origin_type_path =
861 origin, type_string, false, &error); 860 GetDirectoryForOriginAndType(origin, type_string, false, &error);
862 if (origin_type_path.empty()) 861 if (origin_type_path.empty())
863 return true; 862 return true;
864 if (error != base::File::FILE_ERROR_NOT_FOUND) { 863 if (error != base::File::FILE_ERROR_NOT_FOUND) {
865 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase. 864 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase.
866 // We ignore its error now since 1) it doesn't matter the final result, and 865 // We ignore its error now since 1) it doesn't matter the final result, and
867 // 2) it always returns false in Windows because of LevelDB's 866 // 2) it always returns false in Windows because of LevelDB's
868 // implementation. 867 // implementation.
869 // Information about failure would be useful for debugging. 868 // Information about failure would be useful for debugging.
870 if (!type_string.empty()) 869 if (!type_string.empty())
871 DestroyDirectoryDatabase(origin, type_string); 870 DestroyDirectoryDatabase(origin, type_string);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 return false; 902 return false;
904 903
905 return true; 904 return true;
906 } 905 }
907 906
908 ObfuscatedFileUtil::AbstractOriginEnumerator* 907 ObfuscatedFileUtil::AbstractOriginEnumerator*
909 ObfuscatedFileUtil::CreateOriginEnumerator() { 908 ObfuscatedFileUtil::CreateOriginEnumerator() {
910 std::vector<SandboxOriginDatabase::OriginRecord> origins; 909 std::vector<SandboxOriginDatabase::OriginRecord> origins;
911 910
912 InitOriginDatabase(GURL(), false); 911 InitOriginDatabase(GURL(), false);
913 return new ObfuscatedOriginEnumerator( 912 return new ObfuscatedOriginEnumerator(origin_database_.get(),
914 origin_database_.get(), file_system_directory_); 913 file_system_directory_);
915 } 914 }
916 915
917 bool ObfuscatedFileUtil::DestroyDirectoryDatabase( 916 bool ObfuscatedFileUtil::DestroyDirectoryDatabase(
918 const GURL& origin, 917 const GURL& origin,
919 const std::string& type_string) { 918 const std::string& type_string) {
920 std::string key = GetDirectoryDatabaseKey(origin, type_string); 919 std::string key = GetDirectoryDatabaseKey(origin, type_string);
921 if (key.empty()) 920 if (key.empty())
922 return true; 921 return true;
923 DirectoryMap::iterator iter = directories_.find(key); 922 DirectoryMap::iterator iter = directories_.find(key);
924 if (iter != directories_.end()) { 923 if (iter != directories_.end()) {
925 SandboxDirectoryDatabase* database = iter->second; 924 SandboxDirectoryDatabase* database = iter->second;
926 directories_.erase(iter); 925 directories_.erase(iter);
927 delete database; 926 delete database;
928 } 927 }
929 928
930 base::File::Error error = base::File::FILE_OK; 929 base::File::Error error = base::File::FILE_OK;
931 base::FilePath path = GetDirectoryForOriginAndType( 930 base::FilePath path =
932 origin, type_string, false, &error); 931 GetDirectoryForOriginAndType(origin, type_string, false, &error);
933 if (path.empty() || error == base::File::FILE_ERROR_NOT_FOUND) 932 if (path.empty() || error == base::File::FILE_ERROR_NOT_FOUND)
934 return true; 933 return true;
935 return SandboxDirectoryDatabase::DestroyDatabase(path, env_override_); 934 return SandboxDirectoryDatabase::DestroyDatabase(path, env_override_);
936 } 935 }
937 936
938 // static 937 // static
939 int64 ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) { 938 int64 ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) {
940 return UsageForPath(VirtualPath::BaseName(path).value().size()); 939 return UsageForPath(VirtualPath::BaseName(path).value().size());
941 } 940 }
942 941
943 void ObfuscatedFileUtil::MaybePrepopulateDatabase( 942 void ObfuscatedFileUtil::MaybePrepopulateDatabase(
944 const std::vector<std::string>& type_strings_to_prepopulate) { 943 const std::vector<std::string>& type_strings_to_prepopulate) {
945 SandboxPrioritizedOriginDatabase database(file_system_directory_, 944 SandboxPrioritizedOriginDatabase database(file_system_directory_,
946 env_override_); 945 env_override_);
947 std::string origin_string = database.GetPrimaryOrigin(); 946 std::string origin_string = database.GetPrimaryOrigin();
948 if (origin_string.empty() || !database.HasOriginPath(origin_string)) 947 if (origin_string.empty() || !database.HasOriginPath(origin_string))
949 return; 948 return;
950 const GURL origin = webkit_database::GetOriginFromIdentifier(origin_string); 949 const GURL origin = webkit_database::GetOriginFromIdentifier(origin_string);
951 950
952 // Prepopulate the directory database(s) if and only if this instance 951 // Prepopulate the directory database(s) if and only if this instance
953 // has primary origin and the directory database is already there. 952 // has primary origin and the directory database is already there.
954 for (size_t i = 0; i < type_strings_to_prepopulate.size(); ++i) { 953 for (size_t i = 0; i < type_strings_to_prepopulate.size(); ++i) {
955 const std::string type_string = type_strings_to_prepopulate[i]; 954 const std::string type_string = type_strings_to_prepopulate[i];
956 // Only handles known types. 955 // Only handles known types.
957 if (!ContainsKey(known_type_strings_, type_string)) 956 if (!ContainsKey(known_type_strings_, type_string))
958 continue; 957 continue;
959 base::File::Error error = base::File::FILE_ERROR_FAILED; 958 base::File::Error error = base::File::FILE_ERROR_FAILED;
960 base::FilePath path = GetDirectoryForOriginAndType( 959 base::FilePath path =
961 origin, type_string, false, &error); 960 GetDirectoryForOriginAndType(origin, type_string, false, &error);
962 if (error != base::File::FILE_OK) 961 if (error != base::File::FILE_OK)
963 continue; 962 continue;
964 scoped_ptr<SandboxDirectoryDatabase> db( 963 scoped_ptr<SandboxDirectoryDatabase> db(
965 new SandboxDirectoryDatabase(path, env_override_)); 964 new SandboxDirectoryDatabase(path, env_override_));
966 if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { 965 if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) {
967 directories_[GetDirectoryDatabaseKey(origin, type_string)] = db.release(); 966 directories_[GetDirectoryDatabaseKey(origin, type_string)] = db.release();
968 MarkUsed(); 967 MarkUsed();
969 // Don't populate more than one database, as it may rather hurt 968 // Don't populate more than one database, as it may rather hurt
970 // performance. 969 // performance.
971 break; 970 break;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 file_info->is_directory = true; 1009 file_info->is_directory = true;
1011 file_info->is_symbolic_link = false; 1010 file_info->is_symbolic_link = false;
1012 file_info->last_modified = local_info->modification_time; 1011 file_info->last_modified = local_info->modification_time;
1013 *platform_file_path = base::FilePath(); 1012 *platform_file_path = base::FilePath();
1014 // We don't fill in ctime or atime. 1013 // We don't fill in ctime or atime.
1015 return base::File::FILE_OK; 1014 return base::File::FILE_OK;
1016 } 1015 }
1017 if (local_info->data_path.empty()) 1016 if (local_info->data_path.empty())
1018 return base::File::FILE_ERROR_INVALID_OPERATION; 1017 return base::File::FILE_ERROR_INVALID_OPERATION;
1019 base::FilePath local_path = DataPathToLocalPath(url, local_info->data_path); 1018 base::FilePath local_path = DataPathToLocalPath(url, local_info->data_path);
1020 base::File::Error error = NativeFileUtil::GetFileInfo( 1019 base::File::Error error = NativeFileUtil::GetFileInfo(local_path, file_info);
1021 local_path, file_info);
1022 // We should not follow symbolic links in sandboxed file system. 1020 // We should not follow symbolic links in sandboxed file system.
1023 if (base::IsLink(local_path)) { 1021 if (base::IsLink(local_path)) {
1024 LOG(WARNING) << "Found a symbolic file."; 1022 LOG(WARNING) << "Found a symbolic file.";
1025 error = base::File::FILE_ERROR_NOT_FOUND; 1023 error = base::File::FILE_ERROR_NOT_FOUND;
1026 } 1024 }
1027 if (error == base::File::FILE_OK) { 1025 if (error == base::File::FILE_OK) {
1028 *platform_file_path = local_path; 1026 *platform_file_path = local_path;
1029 } else if (error == base::File::FILE_ERROR_NOT_FOUND) { 1027 } else if (error == base::File::FILE_ERROR_NOT_FOUND) {
1030 LOG(WARNING) << "Lost a backing file."; 1028 LOG(WARNING) << "Lost a backing file.";
1031 InvalidateUsageCache(context, url.origin(), url.type()); 1029 InvalidateUsageCache(context, url.origin(), url.type());
1032 if (!db->RemoveFileInfo(file_id)) 1030 if (!db->RemoveFileInfo(file_id))
1033 return base::File::FILE_ERROR_FAILED; 1031 return base::File::FILE_ERROR_FAILED;
1034 } 1032 }
1035 return error; 1033 return error;
1036 } 1034 }
1037 1035
1038 base::File ObfuscatedFileUtil::CreateAndOpenFile( 1036 base::File ObfuscatedFileUtil::CreateAndOpenFile(
1039 FileSystemOperationContext* context, 1037 FileSystemOperationContext* context,
1040 const FileSystemURL& dest_url, 1038 const FileSystemURL& dest_url,
1041 FileInfo* dest_file_info, int file_flags) { 1039 FileInfo* dest_file_info,
1040 int file_flags) {
1042 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); 1041 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true);
1043 1042
1044 base::FilePath root, dest_local_path; 1043 base::FilePath root, dest_local_path;
1045 base::File::Error error = GenerateNewLocalPath(db, context, dest_url, &root, 1044 base::File::Error error =
1046 &dest_local_path); 1045 GenerateNewLocalPath(db, context, dest_url, &root, &dest_local_path);
1047 if (error != base::File::FILE_OK) 1046 if (error != base::File::FILE_OK)
1048 return base::File(error); 1047 return base::File(error);
1049 1048
1050 if (base::PathExists(dest_local_path)) { 1049 if (base::PathExists(dest_local_path)) {
1051 if (!base::DeleteFile(dest_local_path, true /* recursive */)) 1050 if (!base::DeleteFile(dest_local_path, true /* recursive */))
1052 return base::File(base::File::FILE_ERROR_FAILED); 1051 return base::File(base::File::FILE_ERROR_FAILED);
1053 LOG(WARNING) << "A stray file detected"; 1052 LOG(WARNING) << "A stray file detected";
1054 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); 1053 InvalidateUsageCache(context, dest_url.origin(), dest_url.type());
1055 } 1054 }
1056 1055
(...skipping 18 matching lines...) Expand all
1075 } 1074 }
1076 1075
1077 base::File::Error ObfuscatedFileUtil::CreateFile( 1076 base::File::Error ObfuscatedFileUtil::CreateFile(
1078 FileSystemOperationContext* context, 1077 FileSystemOperationContext* context,
1079 const base::FilePath& src_file_path, 1078 const base::FilePath& src_file_path,
1080 const FileSystemURL& dest_url, 1079 const FileSystemURL& dest_url,
1081 FileInfo* dest_file_info) { 1080 FileInfo* dest_file_info) {
1082 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true); 1081 SandboxDirectoryDatabase* db = GetDirectoryDatabase(dest_url, true);
1083 1082
1084 base::FilePath root, dest_local_path; 1083 base::FilePath root, dest_local_path;
1085 base::File::Error error = GenerateNewLocalPath(db, context, dest_url, &root, 1084 base::File::Error error =
1086 &dest_local_path); 1085 GenerateNewLocalPath(db, context, dest_url, &root, &dest_local_path);
1087 if (error != base::File::FILE_OK) 1086 if (error != base::File::FILE_OK)
1088 return error; 1087 return error;
1089 1088
1090 bool created = false; 1089 bool created = false;
1091 if (src_file_path.empty()) { 1090 if (src_file_path.empty()) {
1092 if (base::PathExists(dest_local_path)) { 1091 if (base::PathExists(dest_local_path)) {
1093 if (!base::DeleteFile(dest_local_path, true /* recursive */)) 1092 if (!base::DeleteFile(dest_local_path, true /* recursive */))
1094 return base::File::FILE_ERROR_FAILED; 1093 return base::File::FILE_ERROR_FAILED;
1095 LOG(WARNING) << "A stray file detected"; 1094 LOG(WARNING) << "A stray file detected";
1096 InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); 1095 InvalidateUsageCache(context, dest_url.origin(), dest_url.type());
1097 } 1096 }
1098 1097
1099 error = NativeFileUtil::EnsureFileExists(dest_local_path, &created); 1098 error = NativeFileUtil::EnsureFileExists(dest_local_path, &created);
1100 } else { 1099 } else {
1101 error = NativeFileUtil::CopyOrMoveFile( 1100 error = NativeFileUtil::CopyOrMoveFile(
1102 src_file_path, dest_local_path, 1101 src_file_path,
1102 dest_local_path,
1103 FileSystemOperation::OPTION_NONE, 1103 FileSystemOperation::OPTION_NONE,
1104 fileapi::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, 1104 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url,
1105 true /* copy */)); 1105 true /* copy */));
1106 created = true; 1106 created = true;
1107 } 1107 }
1108 if (error != base::File::FILE_OK) 1108 if (error != base::File::FILE_OK)
1109 return error; 1109 return error;
1110 if (!created) 1110 if (!created)
1111 return base::File::FILE_ERROR_FAILED; 1111 return base::File::FILE_ERROR_FAILED;
1112 1112
1113 return CommitCreateFile(root, dest_local_path, db, dest_file_info); 1113 return CommitCreateFile(root, dest_local_path, db, dest_file_info);
1114 } 1114 }
1115 1115
1116 base::File::Error ObfuscatedFileUtil::CommitCreateFile( 1116 base::File::Error ObfuscatedFileUtil::CommitCreateFile(
1117 const base::FilePath& root, 1117 const base::FilePath& root,
1118 const base::FilePath& local_path, 1118 const base::FilePath& local_path,
1119 SandboxDirectoryDatabase* db, 1119 SandboxDirectoryDatabase* db,
1120 FileInfo* dest_file_info) { 1120 FileInfo* dest_file_info) {
1121 // This removes the root, including the trailing slash, leaving a relative 1121 // This removes the root, including the trailing slash, leaving a relative
1122 // path. 1122 // path.
1123 dest_file_info->data_path = base::FilePath( 1123 dest_file_info->data_path =
1124 local_path.value().substr(root.value().length() + 1)); 1124 base::FilePath(local_path.value().substr(root.value().length() + 1));
1125 1125
1126 FileId file_id; 1126 FileId file_id;
1127 base::File::Error error = db->AddFileInfo(*dest_file_info, &file_id); 1127 base::File::Error error = db->AddFileInfo(*dest_file_info, &file_id);
1128 if (error != base::File::FILE_OK) 1128 if (error != base::File::FILE_OK)
1129 return error; 1129 return error;
1130 1130
1131 TouchDirectory(db, dest_file_info->parent_id); 1131 TouchDirectory(db, dest_file_info->parent_id);
1132 return base::File::FILE_OK; 1132 return base::File::FILE_OK;
1133 } 1133 }
1134 1134
1135 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( 1135 base::FilePath ObfuscatedFileUtil::DataPathToLocalPath(
1136 const FileSystemURL& url, const base::FilePath& data_path) { 1136 const FileSystemURL& url,
1137 const base::FilePath& data_path) {
1137 base::File::Error error = base::File::FILE_OK; 1138 base::File::Error error = base::File::FILE_OK;
1138 base::FilePath root = GetDirectoryForURL(url, false, &error); 1139 base::FilePath root = GetDirectoryForURL(url, false, &error);
1139 if (error != base::File::FILE_OK) 1140 if (error != base::File::FILE_OK)
1140 return base::FilePath(); 1141 return base::FilePath();
1141 return root.Append(data_path); 1142 return root.Append(data_path);
1142 } 1143 }
1143 1144
1144 std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey( 1145 std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey(
1145 const GURL& origin, const std::string& type_string) { 1146 const GURL& origin,
1147 const std::string& type_string) {
1146 if (type_string.empty()) { 1148 if (type_string.empty()) {
1147 LOG(WARNING) << "Unknown filesystem type requested:" << type_string; 1149 LOG(WARNING) << "Unknown filesystem type requested:" << type_string;
1148 return std::string(); 1150 return std::string();
1149 } 1151 }
1150 // For isolated origin we just use a type string as a key. 1152 // For isolated origin we just use a type string as a key.
1151 return webkit_database::GetIdentifierFromOrigin(origin) + 1153 return webkit_database::GetIdentifierFromOrigin(origin) + type_string;
1152 type_string;
1153 } 1154 }
1154 1155
1155 // TODO(ericu): How to do the whole validation-without-creation thing? 1156 // TODO(ericu): How to do the whole validation-without-creation thing?
1156 // We may not have quota even to create the database. 1157 // We may not have quota even to create the database.
1157 // Ah, in that case don't even get here? 1158 // Ah, in that case don't even get here?
1158 // Still doesn't answer the quota issue, though. 1159 // Still doesn't answer the quota issue, though.
1159 SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( 1160 SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
1160 const FileSystemURL& url, bool create) { 1161 const FileSystemURL& url,
1161 std::string key = GetDirectoryDatabaseKey( 1162 bool create) {
1162 url.origin(), CallGetTypeStringForURL(url)); 1163 std::string key =
1164 GetDirectoryDatabaseKey(url.origin(), CallGetTypeStringForURL(url));
1163 if (key.empty()) 1165 if (key.empty())
1164 return NULL; 1166 return NULL;
1165 1167
1166 DirectoryMap::iterator iter = directories_.find(key); 1168 DirectoryMap::iterator iter = directories_.find(key);
1167 if (iter != directories_.end()) { 1169 if (iter != directories_.end()) {
1168 MarkUsed(); 1170 MarkUsed();
1169 return iter->second; 1171 return iter->second;
1170 } 1172 }
1171 1173
1172 base::File::Error error = base::File::FILE_OK; 1174 base::File::Error error = base::File::FILE_OK;
1173 base::FilePath path = GetDirectoryForURL(url, create, &error); 1175 base::FilePath path = GetDirectoryForURL(url, create, &error);
1174 if (error != base::File::FILE_OK) { 1176 if (error != base::File::FILE_OK) {
1175 LOG(WARNING) << "Failed to get origin+type directory: " 1177 LOG(WARNING) << "Failed to get origin+type directory: " << url.DebugString()
1176 << url.DebugString() << " error:" << error; 1178 << " error:" << error;
1177 return NULL; 1179 return NULL;
1178 } 1180 }
1179 MarkUsed(); 1181 MarkUsed();
1180 SandboxDirectoryDatabase* database = 1182 SandboxDirectoryDatabase* database =
1181 new SandboxDirectoryDatabase(path, env_override_); 1183 new SandboxDirectoryDatabase(path, env_override_);
1182 directories_[key] = database; 1184 directories_[key] = database;
1183 return database; 1185 return database;
1184 } 1186 }
1185 1187
1186 base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( 1188 base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin(
1187 const GURL& origin, bool create, base::File::Error* error_code) { 1189 const GURL& origin,
1190 bool create,
1191 base::File::Error* error_code) {
1188 if (!InitOriginDatabase(origin, create)) { 1192 if (!InitOriginDatabase(origin, create)) {
1189 if (error_code) { 1193 if (error_code) {
1190 *error_code = create ? 1194 *error_code = create ? base::File::FILE_ERROR_FAILED
1191 base::File::FILE_ERROR_FAILED : 1195 : base::File::FILE_ERROR_NOT_FOUND;
1192 base::File::FILE_ERROR_NOT_FOUND;
1193 } 1196 }
1194 return base::FilePath(); 1197 return base::FilePath();
1195 } 1198 }
1196 base::FilePath directory_name; 1199 base::FilePath directory_name;
1197 std::string id = webkit_database::GetIdentifierFromOrigin(origin); 1200 std::string id = webkit_database::GetIdentifierFromOrigin(origin);
1198 1201
1199 bool exists_in_db = origin_database_->HasOriginPath(id); 1202 bool exists_in_db = origin_database_->HasOriginPath(id);
1200 if (!exists_in_db && !create) { 1203 if (!exists_in_db && !create) {
1201 if (error_code) 1204 if (error_code)
1202 *error_code = base::File::FILE_ERROR_NOT_FOUND; 1205 *error_code = base::File::FILE_ERROR_NOT_FOUND;
(...skipping 12 matching lines...) Expand all
1215 if (error_code) 1218 if (error_code)
1216 *error_code = base::File::FILE_ERROR_FAILED; 1219 *error_code = base::File::FILE_ERROR_FAILED;
1217 return base::FilePath(); 1220 return base::FilePath();
1218 } 1221 }
1219 exists_in_fs = false; 1222 exists_in_fs = false;
1220 } 1223 }
1221 1224
1222 if (!exists_in_fs) { 1225 if (!exists_in_fs) {
1223 if (!create || !base::CreateDirectory(path)) { 1226 if (!create || !base::CreateDirectory(path)) {
1224 if (error_code) 1227 if (error_code)
1225 *error_code = create ? 1228 *error_code = create ? base::File::FILE_ERROR_FAILED
1226 base::File::FILE_ERROR_FAILED : 1229 : base::File::FILE_ERROR_NOT_FOUND;
1227 base::File::FILE_ERROR_NOT_FOUND;
1228 return base::FilePath(); 1230 return base::FilePath();
1229 } 1231 }
1230 } 1232 }
1231 1233
1232 if (error_code) 1234 if (error_code)
1233 *error_code = base::File::FILE_OK; 1235 *error_code = base::File::FILE_OK;
1234 1236
1235 return path; 1237 return path;
1236 } 1238 }
1237 1239
1238 void ObfuscatedFileUtil::InvalidateUsageCache( 1240 void ObfuscatedFileUtil::InvalidateUsageCache(
1239 FileSystemOperationContext* context, 1241 FileSystemOperationContext* context,
1240 const GURL& origin, 1242 const GURL& origin,
1241 FileSystemType type) { 1243 FileSystemType type) {
1242 if (sandbox_delegate_) 1244 if (sandbox_delegate_)
1243 sandbox_delegate_->InvalidateUsageCache(origin, type); 1245 sandbox_delegate_->InvalidateUsageCache(origin, type);
1244 } 1246 }
1245 1247
1246 void ObfuscatedFileUtil::MarkUsed() { 1248 void ObfuscatedFileUtil::MarkUsed() {
1247 if (!timer_) 1249 if (!timer_)
1248 timer_.reset(new TimedTaskHelper(file_task_runner_.get())); 1250 timer_.reset(new TimedTaskHelper(file_task_runner_.get()));
1249 1251
1250 if (timer_->IsRunning()) { 1252 if (timer_->IsRunning()) {
1251 timer_->Reset(); 1253 timer_->Reset();
1252 } else { 1254 } else {
1253 timer_->Start(FROM_HERE, 1255 timer_->Start(
1254 base::TimeDelta::FromSeconds(db_flush_delay_seconds_), 1256 FROM_HERE,
1255 base::Bind(&ObfuscatedFileUtil::DropDatabases, 1257 base::TimeDelta::FromSeconds(db_flush_delay_seconds_),
1256 base::Unretained(this))); 1258 base::Bind(&ObfuscatedFileUtil::DropDatabases, base::Unretained(this)));
1257 } 1259 }
1258 } 1260 }
1259 1261
1260 void ObfuscatedFileUtil::DropDatabases() { 1262 void ObfuscatedFileUtil::DropDatabases() {
1261 origin_database_.reset(); 1263 origin_database_.reset();
1262 STLDeleteContainerPairSecondPointers( 1264 STLDeleteContainerPairSecondPointers(directories_.begin(),
1263 directories_.begin(), directories_.end()); 1265 directories_.end());
1264 directories_.clear(); 1266 directories_.clear();
1265 timer_.reset(); 1267 timer_.reset();
1266 } 1268 }
1267 1269
1268 bool ObfuscatedFileUtil::InitOriginDatabase(const GURL& origin_hint, 1270 bool ObfuscatedFileUtil::InitOriginDatabase(const GURL& origin_hint,
1269 bool create) { 1271 bool create) {
1270 if (origin_database_) 1272 if (origin_database_)
1271 return true; 1273 return true;
1272 1274
1273 if (!create && !base::DirectoryExists(file_system_directory_)) 1275 if (!create && !base::DirectoryExists(file_system_directory_))
1274 return false; 1276 return false;
1275 if (!base::CreateDirectory(file_system_directory_)) { 1277 if (!base::CreateDirectory(file_system_directory_)) {
1276 LOG(WARNING) << "Failed to create FileSystem directory: " << 1278 LOG(WARNING) << "Failed to create FileSystem directory: "
1277 file_system_directory_.value(); 1279 << file_system_directory_.value();
1278 return false; 1280 return false;
1279 } 1281 }
1280 1282
1281 SandboxPrioritizedOriginDatabase* prioritized_origin_database = 1283 SandboxPrioritizedOriginDatabase* prioritized_origin_database =
1282 new SandboxPrioritizedOriginDatabase(file_system_directory_, 1284 new SandboxPrioritizedOriginDatabase(file_system_directory_,
1283 env_override_); 1285 env_override_);
1284 origin_database_.reset(prioritized_origin_database); 1286 origin_database_.reset(prioritized_origin_database);
1285 1287
1286 if (origin_hint.is_empty() || !HasIsolatedStorage(origin_hint)) 1288 if (origin_hint.is_empty() || !HasIsolatedStorage(origin_hint))
1287 return true; 1289 return true;
1288 1290
1289 const std::string isolated_origin_string = 1291 const std::string isolated_origin_string =
1290 webkit_database::GetIdentifierFromOrigin(origin_hint); 1292 webkit_database::GetIdentifierFromOrigin(origin_hint);
1291 1293
1292 // TODO(kinuko): Deprecate this after a few release cycles, e.g. around M33. 1294 // TODO(kinuko): Deprecate this after a few release cycles, e.g. around M33.
1293 base::FilePath isolated_origin_dir = file_system_directory_.Append( 1295 base::FilePath isolated_origin_dir = file_system_directory_.Append(
1294 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory); 1296 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory);
1295 if (base::DirectoryExists(isolated_origin_dir) && 1297 if (base::DirectoryExists(isolated_origin_dir) &&
1296 prioritized_origin_database->GetSandboxOriginDatabase()) { 1298 prioritized_origin_database->GetSandboxOriginDatabase()) {
1297 SandboxIsolatedOriginDatabase::MigrateBackFromObsoleteOriginDatabase( 1299 SandboxIsolatedOriginDatabase::MigrateBackFromObsoleteOriginDatabase(
1298 isolated_origin_string, 1300 isolated_origin_string,
1299 file_system_directory_, 1301 file_system_directory_,
1300 prioritized_origin_database->GetSandboxOriginDatabase()); 1302 prioritized_origin_database->GetSandboxOriginDatabase());
1301 } 1303 }
1302 1304
1303 prioritized_origin_database->InitializePrimaryOrigin( 1305 prioritized_origin_database->InitializePrimaryOrigin(isolated_origin_string);
1304 isolated_origin_string);
1305 1306
1306 return true; 1307 return true;
1307 } 1308 }
1308 1309
1309 base::File::Error ObfuscatedFileUtil::GenerateNewLocalPath( 1310 base::File::Error ObfuscatedFileUtil::GenerateNewLocalPath(
1310 SandboxDirectoryDatabase* db, 1311 SandboxDirectoryDatabase* db,
1311 FileSystemOperationContext* context, 1312 FileSystemOperationContext* context,
1312 const FileSystemURL& url, 1313 const FileSystemURL& url,
1313 base::FilePath* root, 1314 base::FilePath* root,
1314 base::FilePath* local_path) { 1315 base::FilePath* local_path) {
1315 DCHECK(local_path); 1316 DCHECK(local_path);
1316 int64 number; 1317 int64 number;
1317 if (!db || !db->GetNextInteger(&number)) 1318 if (!db || !db->GetNextInteger(&number))
1318 return base::File::FILE_ERROR_FAILED; 1319 return base::File::FILE_ERROR_FAILED;
1319 1320
1320 base::File::Error error = base::File::FILE_OK; 1321 base::File::Error error = base::File::FILE_OK;
1321 *root = GetDirectoryForURL(url, false, &error); 1322 *root = GetDirectoryForURL(url, false, &error);
1322 if (error != base::File::FILE_OK) 1323 if (error != base::File::FILE_OK)
1323 return error; 1324 return error;
1324 1325
1325 // We use the third- and fourth-to-last digits as the directory. 1326 // We use the third- and fourth-to-last digits as the directory.
1326 int64 directory_number = number % 10000 / 100; 1327 int64 directory_number = number % 10000 / 100;
1327 base::FilePath new_local_path = root->AppendASCII( 1328 base::FilePath new_local_path =
1328 base::StringPrintf("%02" PRId64, directory_number)); 1329 root->AppendASCII(base::StringPrintf("%02" PRId64, directory_number));
1329 1330
1330 error = NativeFileUtil::CreateDirectory( 1331 error = NativeFileUtil::CreateDirectory(
1331 new_local_path, false /* exclusive */, false /* recursive */); 1332 new_local_path, false /* exclusive */, false /* recursive */);
1332 if (error != base::File::FILE_OK) 1333 if (error != base::File::FILE_OK)
1333 return error; 1334 return error;
1334 1335
1335 *local_path = 1336 *local_path =
1336 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); 1337 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number));
1337 return base::File::FILE_OK; 1338 return base::File::FILE_OK;
1338 } 1339 }
1339 1340
1340 base::File ObfuscatedFileUtil::CreateOrOpenInternal( 1341 base::File ObfuscatedFileUtil::CreateOrOpenInternal(
1341 FileSystemOperationContext* context, 1342 FileSystemOperationContext* context,
1342 const FileSystemURL& url, int file_flags) { 1343 const FileSystemURL& url,
1343 DCHECK(!(file_flags & (base::File::FLAG_DELETE_ON_CLOSE | 1344 int file_flags) {
1344 base::File::FLAG_HIDDEN | base::File::FLAG_EXCLUSIVE_READ | 1345 DCHECK(
1345 base::File::FLAG_EXCLUSIVE_WRITE))); 1346 !(file_flags &
1347 (base::File::FLAG_DELETE_ON_CLOSE | base::File::FLAG_HIDDEN |
1348 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE)));
1346 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true); 1349 SandboxDirectoryDatabase* db = GetDirectoryDatabase(url, true);
1347 if (!db) 1350 if (!db)
1348 return base::File(base::File::FILE_ERROR_FAILED); 1351 return base::File(base::File::FILE_ERROR_FAILED);
1349 FileId file_id; 1352 FileId file_id;
1350 if (!db->GetFileWithPath(url.path(), &file_id)) { 1353 if (!db->GetFileWithPath(url.path(), &file_id)) {
1351 // The file doesn't exist. 1354 // The file doesn't exist.
1352 if (!(file_flags & (base::File::FLAG_CREATE | 1355 if (!(file_flags &
1353 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_ALWAYS))) { 1356 (base::File::FLAG_CREATE | base::File::FLAG_CREATE_ALWAYS |
1357 base::File::FLAG_OPEN_ALWAYS))) {
1354 return base::File(base::File::FILE_ERROR_NOT_FOUND); 1358 return base::File(base::File::FILE_ERROR_NOT_FOUND);
1355 } 1359 }
1356 FileId parent_id; 1360 FileId parent_id;
1357 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id)) 1361 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), &parent_id))
1358 return base::File(base::File::FILE_ERROR_NOT_FOUND); 1362 return base::File(base::File::FILE_ERROR_NOT_FOUND);
1359 FileInfo file_info; 1363 FileInfo file_info;
1360 InitFileInfo(&file_info, parent_id, 1364 InitFileInfo(
1361 VirtualPath::BaseName(url.path()).value()); 1365 &file_info, parent_id, VirtualPath::BaseName(url.path()).value());
1362 1366
1363 int64 growth = UsageForPath(file_info.name.size()); 1367 int64 growth = UsageForPath(file_info.name.size());
1364 if (!AllocateQuota(context, growth)) 1368 if (!AllocateQuota(context, growth))
1365 return base::File(base::File::FILE_ERROR_NO_SPACE); 1369 return base::File(base::File::FILE_ERROR_NO_SPACE);
1366 base::File file = CreateAndOpenFile(context, url, &file_info, file_flags); 1370 base::File file = CreateAndOpenFile(context, url, &file_info, file_flags);
1367 if (file.IsValid()) { 1371 if (file.IsValid()) {
1368 UpdateUsage(context, url, growth); 1372 UpdateUsage(context, url, growth);
1369 context->change_observers()->Notify( 1373 context->change_observers()->Notify(&FileChangeObserver::OnCreateFile,
1370 &FileChangeObserver::OnCreateFile, MakeTuple(url)); 1374 MakeTuple(url));
1371 } 1375 }
1372 return file.Pass(); 1376 return file.Pass();
1373 } 1377 }
1374 1378
1375 if (file_flags & base::File::FLAG_CREATE) 1379 if (file_flags & base::File::FLAG_CREATE)
1376 return base::File(base::File::FILE_ERROR_EXISTS); 1380 return base::File(base::File::FILE_ERROR_EXISTS);
1377 1381
1378 base::File::Info platform_file_info; 1382 base::File::Info platform_file_info;
1379 base::FilePath local_path; 1383 base::FilePath local_path;
1380 FileInfo file_info; 1384 FileInfo file_info;
1381 base::File::Error error = GetFileInfoInternal( 1385 base::File::Error error = GetFileInfoInternal(
1382 db, context, url, file_id, &file_info, &platform_file_info, &local_path); 1386 db, context, url, file_id, &file_info, &platform_file_info, &local_path);
1383 if (error != base::File::FILE_OK) 1387 if (error != base::File::FILE_OK)
1384 return base::File(error); 1388 return base::File(error);
1385 if (file_info.is_directory()) 1389 if (file_info.is_directory())
1386 return base::File(base::File::FILE_ERROR_NOT_A_FILE); 1390 return base::File(base::File::FILE_ERROR_NOT_A_FILE);
1387 1391
1388 int64 delta = 0; 1392 int64 delta = 0;
1389 if (file_flags & (base::File::FLAG_CREATE_ALWAYS | 1393 if (file_flags &
1390 base::File::FLAG_OPEN_TRUNCATED)) { 1394 (base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_TRUNCATED)) {
1391 // The file exists and we're truncating. 1395 // The file exists and we're truncating.
1392 delta = -platform_file_info.size; 1396 delta = -platform_file_info.size;
1393 AllocateQuota(context, delta); 1397 AllocateQuota(context, delta);
1394 } 1398 }
1395 1399
1396 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags); 1400 base::File file = NativeFileUtil::CreateOrOpen(local_path, file_flags);
1397 if (!file.IsValid()) { 1401 if (!file.IsValid()) {
1398 error = file.error_details(); 1402 error = file.error_details();
1399 if (error == base::File::FILE_ERROR_NOT_FOUND) { 1403 if (error == base::File::FILE_ERROR_NOT_FOUND) {
1400 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. 1404 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker.
1401 // TODO(tzik): Delete database entry after ensuring the file lost. 1405 // TODO(tzik): Delete database entry after ensuring the file lost.
1402 InvalidateUsageCache(context, url.origin(), url.type()); 1406 InvalidateUsageCache(context, url.origin(), url.type());
1403 LOG(WARNING) << "Lost a backing file."; 1407 LOG(WARNING) << "Lost a backing file.";
1404 return base::File(base::File::FILE_ERROR_FAILED); 1408 return base::File(base::File::FILE_ERROR_FAILED);
1405 } 1409 }
1406 return file.Pass(); 1410 return file.Pass();
1407 } 1411 }
1408 1412
1409 // If truncating we need to update the usage. 1413 // If truncating we need to update the usage.
1410 if (delta) { 1414 if (delta) {
1411 UpdateUsage(context, url, delta); 1415 UpdateUsage(context, url, delta);
1412 context->change_observers()->Notify( 1416 context->change_observers()->Notify(&FileChangeObserver::OnModifyFile,
1413 &FileChangeObserver::OnModifyFile, MakeTuple(url)); 1417 MakeTuple(url));
1414 } 1418 }
1415 return file.Pass(); 1419 return file.Pass();
1416 } 1420 }
1417 1421
1418 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { 1422 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) {
1419 return special_storage_policy_.get() && 1423 return special_storage_policy_.get() &&
1420 special_storage_policy_->HasIsolatedStorage(origin); 1424 special_storage_policy_->HasIsolatedStorage(origin);
1421 } 1425 }
1422 1426
1423 } // namespace fileapi 1427 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/fileapi/obfuscated_file_util.h ('k') | storage/browser/fileapi/open_file_system_mode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698