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/sandbox_mount_point_provider.h" | 5 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_callback_factory.h" | 9 #include "base/memory/scoped_callback_factory.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
16 #include "googleurl/src/gurl.h" | 16 #include "googleurl/src/gurl.h" |
17 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" |
18 #include "webkit/fileapi/file_system_operation_context.h" | 18 #include "webkit/fileapi/file_system_operation_context.h" |
19 #include "webkit/fileapi/file_system_path_manager.h" | 19 #include "webkit/fileapi/file_system_path_manager.h" |
20 #include "webkit/fileapi/file_system_types.h" | 20 #include "webkit/fileapi/file_system_types.h" |
21 #include "webkit/fileapi/file_system_usage_cache.h" | 21 #include "webkit/fileapi/file_system_usage_cache.h" |
22 #include "webkit/fileapi/file_system_util.h" | 22 #include "webkit/fileapi/file_system_util.h" |
23 #include "webkit/fileapi/local_file_system_file_util.h" | 23 #include "webkit/fileapi/obfuscated_file_util.h" |
24 #include "webkit/fileapi/obfuscated_file_system_file_util.h" | |
25 #include "webkit/fileapi/quota_file_util.h" | 24 #include "webkit/fileapi/quota_file_util.h" |
26 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 25 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
27 #include "webkit/glue/webkit_glue.h" | 26 #include "webkit/glue/webkit_glue.h" |
28 #include "webkit/quota/quota_manager.h" | 27 #include "webkit/quota/quota_manager.h" |
29 | 28 |
30 using quota::QuotaManagerProxy; | 29 using quota::QuotaManagerProxy; |
31 | 30 |
32 namespace { | 31 namespace { |
33 | 32 |
34 static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = | 33 static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 89 } |
91 if (unique->empty()) | 90 if (unique->empty()) |
92 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 91 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
93 return base::PLATFORM_FILE_OK; | 92 return base::PLATFORM_FILE_OK; |
94 } | 93 } |
95 | 94 |
96 class ObfuscatedOriginEnumerator | 95 class ObfuscatedOriginEnumerator |
97 : public fileapi::SandboxMountPointProvider::OriginEnumerator { | 96 : public fileapi::SandboxMountPointProvider::OriginEnumerator { |
98 public: | 97 public: |
99 explicit ObfuscatedOriginEnumerator( | 98 explicit ObfuscatedOriginEnumerator( |
100 fileapi::ObfuscatedFileSystemFileUtil* file_util) { | 99 fileapi::ObfuscatedFileUtil* file_util) { |
101 enum_.reset(file_util->CreateOriginEnumerator()); | 100 enum_.reset(file_util->CreateOriginEnumerator()); |
102 } | 101 } |
103 virtual ~ObfuscatedOriginEnumerator() {} | 102 virtual ~ObfuscatedOriginEnumerator() {} |
104 | 103 |
105 virtual GURL Next() OVERRIDE { | 104 virtual GURL Next() OVERRIDE { |
106 return enum_->Next(); | 105 return enum_->Next(); |
107 } | 106 } |
108 | 107 |
109 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { | 108 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { |
110 return enum_->HasFileSystemType(type); | 109 return enum_->HasFileSystemType(type); |
111 } | 110 } |
112 | 111 |
113 private: | 112 private: |
114 scoped_ptr<fileapi::ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator> | 113 scoped_ptr<fileapi::ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; |
115 enum_; | |
116 }; | 114 }; |
117 | 115 |
118 class OldSandboxOriginEnumerator | 116 class OldSandboxOriginEnumerator |
119 : public fileapi::SandboxMountPointProvider::OriginEnumerator { | 117 : public fileapi::SandboxMountPointProvider::OriginEnumerator { |
120 public: | 118 public: |
121 explicit OldSandboxOriginEnumerator(const FilePath& base_path) | 119 explicit OldSandboxOriginEnumerator(const FilePath& base_path) |
122 : enumerator_(base_path, false /* recursive */, | 120 : enumerator_(base_path, false /* recursive */, |
123 file_util::FileEnumerator::DIRECTORIES) {} | 121 file_util::FileEnumerator::DIRECTORIES) {} |
124 virtual ~OldSandboxOriginEnumerator() {} | 122 virtual ~OldSandboxOriginEnumerator() {} |
125 | 123 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 FilePath base_path = OldGetBaseDirectoryForOrigin( | 164 FilePath base_path = OldGetBaseDirectoryForOrigin( |
167 old_base_path, origin_url); | 165 old_base_path, origin_url); |
168 if (base_path.empty()) { | 166 if (base_path.empty()) { |
169 NOTREACHED(); | 167 NOTREACHED(); |
170 return FilePath(); | 168 return FilePath(); |
171 } | 169 } |
172 return base_path.AppendASCII(type_string); | 170 return base_path.AppendASCII(type_string); |
173 } | 171 } |
174 | 172 |
175 bool MigrateOneOldFileSystem( | 173 bool MigrateOneOldFileSystem( |
176 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 174 fileapi::ObfuscatedFileUtil* file_util, |
177 const FilePath& old_base_path, const GURL& origin, | 175 const FilePath& old_base_path, const GURL& origin, |
178 fileapi::FileSystemType type) { | 176 fileapi::FileSystemType type) { |
179 FilePath base_path = OldGetBaseDirectoryForOriginAndType( | 177 FilePath base_path = OldGetBaseDirectoryForOriginAndType( |
180 old_base_path, origin, type); | 178 old_base_path, origin, type); |
181 if (base_path.empty()) | 179 if (base_path.empty()) |
182 return false; | 180 return false; |
183 | 181 |
184 FilePath root; | 182 FilePath root; |
185 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root); | 183 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root); |
186 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result) | 184 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result) |
187 return true; // There was nothing to migrate; call that a success. | 185 return true; // There was nothing to migrate; call that a success. |
188 | 186 |
189 // If we found more than one filesystem [a problem we don't know how to | 187 // If we found more than one filesystem [a problem we don't know how to |
190 // solve], the data is already not accessible through Chrome, so it won't do | 188 // solve], the data is already not accessible through Chrome, so it won't do |
191 // any harm not to migrate it. Just flag it as an error, so that we don't | 189 // any harm not to migrate it. Just flag it as an error, so that we don't |
192 // delete it. | 190 // delete it. |
193 if (base::PLATFORM_FILE_OK != result) | 191 if (base::PLATFORM_FILE_OK != result) |
194 return false; | 192 return false; |
195 | 193 |
196 if (!file_util->MigrateFromOldSandbox(origin, type, root)) { | 194 if (!file_util->MigrateFromOldSandbox(origin, type, root)) { |
197 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin << | 195 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin << |
198 " and type " << type; | 196 " and type " << type; |
199 return false; | 197 return false; |
200 } | 198 } |
201 return true; | 199 return true; |
202 } | 200 } |
203 | 201 |
204 void MigrateAllOldFileSystems( | 202 void MigrateAllOldFileSystems( |
205 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 203 fileapi::ObfuscatedFileUtil* file_util, |
206 const FilePath& old_base_path) { | 204 const FilePath& old_base_path) { |
207 scoped_ptr<OldSandboxOriginEnumerator> old_origins( | 205 scoped_ptr<OldSandboxOriginEnumerator> old_origins( |
208 new OldSandboxOriginEnumerator(old_base_path)); | 206 new OldSandboxOriginEnumerator(old_base_path)); |
209 GURL origin; | 207 GURL origin; |
210 int failures = 0; | 208 int failures = 0; |
211 while (!(origin = old_origins->Next()).is_empty()) { | 209 while (!(origin = old_origins->Next()).is_empty()) { |
212 int failures_this_origin = 0; | 210 int failures_this_origin = 0; |
213 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) && | 211 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) && |
214 !MigrateOneOldFileSystem( | 212 !MigrateOneOldFileSystem( |
215 file_util, old_base_path, origin, | 213 file_util, old_base_path, origin, |
(...skipping 28 matching lines...) Expand all Loading... |
244 } | 242 } |
245 } | 243 } |
246 | 244 |
247 // A migration, whether successful or not, will try to move this directory out | 245 // A migration, whether successful or not, will try to move this directory out |
248 // of the way so that we never try to migrate it again. We need to do this | 246 // of the way so that we never try to migrate it again. We need to do this |
249 // check on all public entry points in this file, so that it's guaranteed to be | 247 // check on all public entry points in this file, so that it's guaranteed to be |
250 // done before anyone looks up a filesystem. Most entry points start by trying | 248 // done before anyone looks up a filesystem. Most entry points start by trying |
251 // to look up the filesystem's root, so we can take care of most of them by | 249 // to look up the filesystem's root, so we can take care of most of them by |
252 // putting a check there. | 250 // putting a check there. |
253 void MigrateIfNeeded( | 251 void MigrateIfNeeded( |
254 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 252 fileapi::ObfuscatedFileUtil* file_util, |
255 const FilePath& old_base_path) { | 253 const FilePath& old_base_path) { |
256 if (file_util::DirectoryExists(old_base_path)) | 254 if (file_util::DirectoryExists(old_base_path)) |
257 MigrateAllOldFileSystems(file_util, old_base_path); | 255 MigrateAllOldFileSystems(file_util, old_base_path); |
258 } | 256 } |
259 | 257 |
260 } // anonymous namespace | 258 } // anonymous namespace |
261 | 259 |
262 namespace fileapi { | 260 namespace fileapi { |
263 | 261 |
264 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = | 262 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = |
265 FILE_PATH_LITERAL("FileSystem"); | 263 FILE_PATH_LITERAL("FileSystem"); |
266 | 264 |
267 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = | 265 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = |
268 FILE_PATH_LITERAL("File System"); | 266 FILE_PATH_LITERAL("File System"); |
269 | 267 |
270 const FilePath::CharType | 268 const FilePath::CharType |
271 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = | 269 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = |
272 FILE_PATH_LITERAL("FS.old"); | 270 FILE_PATH_LITERAL("FS.old"); |
273 | 271 |
274 SandboxMountPointProvider::SandboxMountPointProvider( | 272 SandboxMountPointProvider::SandboxMountPointProvider( |
275 FileSystemPathManager* path_manager, | 273 FileSystemPathManager* path_manager, |
276 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 274 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
277 const FilePath& profile_path) | 275 const FilePath& profile_path) |
278 : FileSystemQuotaUtil(file_message_loop), | 276 : FileSystemQuotaUtil(file_message_loop), |
279 path_manager_(path_manager), | 277 path_manager_(path_manager), |
280 file_message_loop_(file_message_loop), | 278 file_message_loop_(file_message_loop), |
281 profile_path_(profile_path), | 279 profile_path_(profile_path), |
282 sandbox_file_util_( | 280 sandbox_file_util_( |
283 new ObfuscatedFileSystemFileUtil( | 281 new ObfuscatedFileUtil( |
284 profile_path.Append(kNewFileSystemDirectory), | 282 profile_path.Append(kNewFileSystemDirectory), |
285 QuotaFileUtil::CreateDefault())) { | 283 QuotaFileUtil::CreateDefault())) { |
286 } | 284 } |
287 | 285 |
288 SandboxMountPointProvider::~SandboxMountPointProvider() { | 286 SandboxMountPointProvider::~SandboxMountPointProvider() { |
289 if (!file_message_loop_->BelongsToCurrentThread()) | 287 if (!file_message_loop_->BelongsToCurrentThread()) |
290 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); | 288 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); |
291 } | 289 } |
292 | 290 |
293 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, | 291 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, |
294 FileSystemType type, | 292 FileSystemType type, |
295 const FilePath& unused) { | 293 const FilePath& unused) { |
296 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) | 294 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) |
297 return false; | 295 return false; |
298 // We essentially depend on quota to do our access controls. | 296 // We essentially depend on quota to do our access controls. |
299 return path_manager_->IsAllowedScheme(origin_url); | 297 return path_manager_->IsAllowedScheme(origin_url); |
300 } | 298 } |
301 | 299 |
302 class SandboxMountPointProvider::GetFileSystemRootPathTask | 300 class SandboxMountPointProvider::GetFileSystemRootPathTask |
303 : public base::RefCountedThreadSafe< | 301 : public base::RefCountedThreadSafe< |
304 SandboxMountPointProvider::GetFileSystemRootPathTask> { | 302 SandboxMountPointProvider::GetFileSystemRootPathTask> { |
305 public: | 303 public: |
306 GetFileSystemRootPathTask( | 304 GetFileSystemRootPathTask( |
307 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 305 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
308 const GURL& origin_url, | 306 const GURL& origin_url, |
309 FileSystemType type, | 307 FileSystemType type, |
310 ObfuscatedFileSystemFileUtil* file_util, | 308 ObfuscatedFileUtil* file_util, |
311 const FilePath& old_base_path, | 309 const FilePath& old_base_path, |
312 FileSystemPathManager::GetRootPathCallback* callback) | 310 FileSystemPathManager::GetRootPathCallback* callback) |
313 : file_message_loop_(file_message_loop), | 311 : file_message_loop_(file_message_loop), |
314 origin_message_loop_proxy_( | 312 origin_message_loop_proxy_( |
315 base::MessageLoopProxy::current()), | 313 base::MessageLoopProxy::current()), |
316 origin_url_(origin_url), | 314 origin_url_(origin_url), |
317 type_(type), | 315 type_(type), |
318 file_util_(file_util), | 316 file_util_(file_util), |
319 old_base_path_(old_base_path), | 317 old_base_path_(old_base_path), |
320 callback_(callback) { | 318 callback_(callback) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 DCHECK(!type_string.empty()); | 352 DCHECK(!type_string.empty()); |
355 std::string name = origin_identifier + ":" + type_string; | 353 std::string name = origin_identifier + ":" + type_string; |
356 callback_->Run(!root_path.empty(), root_path, name); | 354 callback_->Run(!root_path.empty(), root_path, name); |
357 callback_.reset(); | 355 callback_.reset(); |
358 } | 356 } |
359 | 357 |
360 scoped_refptr<base::MessageLoopProxy> file_message_loop_; | 358 scoped_refptr<base::MessageLoopProxy> file_message_loop_; |
361 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | 359 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; |
362 GURL origin_url_; | 360 GURL origin_url_; |
363 FileSystemType type_; | 361 FileSystemType type_; |
364 scoped_refptr<ObfuscatedFileSystemFileUtil> file_util_; | 362 scoped_refptr<ObfuscatedFileUtil> file_util_; |
365 FilePath old_base_path_; | 363 FilePath old_base_path_; |
366 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_; | 364 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_; |
367 }; | 365 }; |
368 | 366 |
369 FilePath SandboxMountPointProvider::old_base_path() const { | 367 FilePath SandboxMountPointProvider::old_base_path() const { |
370 return profile_path_.Append(kOldFileSystemDirectory); | 368 return profile_path_.Append(kOldFileSystemDirectory); |
371 } | 369 } |
372 | 370 |
373 FilePath SandboxMountPointProvider::new_base_path() const { | 371 FilePath SandboxMountPointProvider::new_base_path() const { |
374 return profile_path_.Append(kNewFileSystemDirectory); | 372 return profile_path_.Append(kNewFileSystemDirectory); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 base::PlatformFileInfo file_info; | 553 base::PlatformFileInfo file_info; |
556 FilePath platform_file_path; | 554 FilePath platform_file_path; |
557 if (!enumerator->IsDirectory()) { | 555 if (!enumerator->IsDirectory()) { |
558 base::PlatformFileError error = sandbox_file_util_->GetFileInfo( | 556 base::PlatformFileError error = sandbox_file_util_->GetFileInfo( |
559 &context, file_path_each, &file_info, &platform_file_path); | 557 &context, file_path_each, &file_info, &platform_file_path); |
560 if (error != base::PLATFORM_FILE_OK) | 558 if (error != base::PLATFORM_FILE_OK) |
561 NOTREACHED(); | 559 NOTREACHED(); |
562 else | 560 else |
563 usage += file_info.size; | 561 usage += file_info.size; |
564 } | 562 } |
565 usage += ObfuscatedFileSystemFileUtil::ComputeFilePathCost(file_path_each); | 563 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); |
566 } | 564 } |
567 // This clears the dirty flag too. | 565 // This clears the dirty flag too. |
568 FileSystemUsageCache::UpdateUsage(usage_file_path, usage); | 566 FileSystemUsageCache::UpdateUsage(usage_file_path, usage); |
569 return usage; | 567 return usage; |
570 } | 568 } |
571 | 569 |
572 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread( | 570 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread( |
573 QuotaManagerProxy* proxy, const GURL& origin_url, | 571 QuotaManagerProxy* proxy, const GURL& origin_url, |
574 fileapi::FileSystemType type) { | 572 fileapi::FileSystemType type) { |
575 DCHECK(type == fileapi::kFileSystemTypeTemporary || | 573 DCHECK(type == fileapi::kFileSystemTypeTemporary || |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 | 610 |
613 void SandboxMountPointProvider::EndUpdateOriginOnFileThread( | 611 void SandboxMountPointProvider::EndUpdateOriginOnFileThread( |
614 const GURL& origin_url, fileapi::FileSystemType type) { | 612 const GURL& origin_url, fileapi::FileSystemType type) { |
615 DCHECK(type == fileapi::kFileSystemTypeTemporary || | 613 DCHECK(type == fileapi::kFileSystemTypeTemporary || |
616 type == fileapi::kFileSystemTypePersistent); | 614 type == fileapi::kFileSystemTypePersistent); |
617 FilePath usage_file_path = GetUsageCachePathForOriginAndType( | 615 FilePath usage_file_path = GetUsageCachePathForOriginAndType( |
618 origin_url, type); | 616 origin_url, type); |
619 FileSystemUsageCache::DecrementDirty(usage_file_path); | 617 FileSystemUsageCache::DecrementDirty(usage_file_path); |
620 } | 618 } |
621 | 619 |
622 FileSystemFileUtil* SandboxMountPointProvider::GetFileSystemFileUtil() { | 620 FileSystemFileUtil* SandboxMountPointProvider::GetFileUtil() { |
623 return sandbox_file_util_.get(); | 621 return sandbox_file_util_.get(); |
624 } | 622 } |
625 | 623 |
626 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType( | 624 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType( |
627 const GURL& origin_url, fileapi::FileSystemType type) const { | 625 const GURL& origin_url, fileapi::FileSystemType type) const { |
628 FilePath base_path = | 626 FilePath base_path = |
629 GetBaseDirectoryForOriginAndType(origin_url, type, false); | 627 GetBaseDirectoryForOriginAndType(origin_url, type, false); |
630 if (base_path.empty()) | 628 if (base_path.empty()) |
631 return FilePath(); | 629 return FilePath(); |
632 return base_path.AppendASCII(FileSystemUsageCache::kUsageFileName); | 630 return base_path.AppendASCII(FileSystemUsageCache::kUsageFileName); |
(...skipping 18 matching lines...) Expand all Loading... |
651 | 649 |
652 // Creates the root directory. | 650 // Creates the root directory. |
653 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); | 651 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); |
654 if (!file_util::CreateDirectory(root)) | 652 if (!file_util::CreateDirectory(root)) |
655 return FilePath(); | 653 return FilePath(); |
656 | 654 |
657 return root; | 655 return root; |
658 } | 656 } |
659 | 657 |
660 } // namespace fileapi | 658 } // namespace fileapi |
OLD | NEW |