Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/fileapi/obfuscated_file_util.h" | 5 #include "webkit/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 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 } | 254 } |
| 255 | 255 |
| 256 ObfuscatedFileUtil::~ObfuscatedFileUtil() { | 256 ObfuscatedFileUtil::~ObfuscatedFileUtil() { |
| 257 DropDatabases(); | 257 DropDatabases(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 PlatformFileError ObfuscatedFileUtil::CreateOrOpen( | 260 PlatformFileError ObfuscatedFileUtil::CreateOrOpen( |
| 261 FileSystemOperationContext* context, | 261 FileSystemOperationContext* context, |
| 262 const FileSystemURL& url, int file_flags, | 262 const FileSystemURL& url, int file_flags, |
| 263 PlatformFile* file_handle, bool* created) { | 263 PlatformFile* file_handle, bool* created) { |
| 264 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | | 264 PlatformFileError error = CreateOrOpenInternal(context, url, file_flags, |
| 265 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | | 265 file_handle, created); |
| 266 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); | 266 if (*file_handle != base::kInvalidPlatformFileValue && |
| 267 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 267 file_flags & base::PLATFORM_FILE_WRITE && |
| 268 url.origin(), url.type(), true); | 268 url.type() == kFileSystemTypePersistent) { |
|
kinuko
2013/04/30 05:14:23
instead should we check context->quota_limit_type(
tzik
2013/04/30 05:26:22
Done.
| |
| 269 if (!db) | 269 DCHECK_EQ(base::PLATFORM_FILE_OK, error); |
| 270 return base::PLATFORM_FILE_ERROR_FAILED; | 270 context->file_system_context()->GetQuotaUtil(url.type())-> |
| 271 FileId file_id; | 271 StickyInvalidateUsageCache(url.origin(), url.type()); |
| 272 if (!db->GetFileWithPath(url.path(), &file_id)) { | |
| 273 // The file doesn't exist. | |
| 274 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | |
| 275 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) | |
| 276 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 277 FileId parent_id; | |
| 278 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), | |
| 279 &parent_id)) | |
| 280 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 281 FileInfo file_info; | |
| 282 InitFileInfo(&file_info, parent_id, | |
| 283 VirtualPath::BaseName(url.path()).value()); | |
| 284 | |
| 285 int64 growth = UsageForPath(file_info.name.size()); | |
| 286 if (!AllocateQuota(context, growth)) | |
| 287 return base::PLATFORM_FILE_ERROR_NO_SPACE; | |
| 288 PlatformFileError error = CreateFile( | |
| 289 context, base::FilePath(), | |
| 290 url.origin(), url.type(), &file_info, | |
| 291 file_flags, file_handle); | |
| 292 if (created && base::PLATFORM_FILE_OK == error) { | |
| 293 *created = true; | |
| 294 UpdateUsage(context, url, growth); | |
| 295 context->change_observers()->Notify( | |
| 296 &FileChangeObserver::OnCreateFile, MakeTuple(url)); | |
| 297 } | |
| 298 return error; | |
| 299 } | |
| 300 | |
| 301 if (file_flags & base::PLATFORM_FILE_CREATE) | |
| 302 return base::PLATFORM_FILE_ERROR_EXISTS; | |
| 303 | |
| 304 base::PlatformFileInfo platform_file_info; | |
| 305 base::FilePath local_path; | |
| 306 FileInfo file_info; | |
| 307 base::PlatformFileError error = GetFileInfoInternal( | |
| 308 db, context, url.origin(), url.type(), file_id, | |
| 309 &file_info, &platform_file_info, &local_path); | |
| 310 if (error != base::PLATFORM_FILE_OK) | |
| 311 return error; | |
| 312 if (file_info.is_directory()) | |
| 313 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
| 314 | |
| 315 int64 delta = 0; | |
| 316 if (file_flags & (base::PLATFORM_FILE_CREATE_ALWAYS | | |
| 317 base::PLATFORM_FILE_OPEN_TRUNCATED)) { | |
| 318 // The file exists and we're truncating. | |
| 319 delta = -platform_file_info.size; | |
| 320 AllocateQuota(context, delta); | |
| 321 } | |
| 322 | |
| 323 error = NativeFileUtil::CreateOrOpen( | |
| 324 local_path, file_flags, file_handle, created); | |
| 325 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { | |
| 326 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. | |
| 327 // TODO(tzik): Delete database entry after ensuring the file lost. | |
| 328 InvalidateUsageCache(context, url.origin(), url.type()); | |
| 329 LOG(WARNING) << "Lost a backing file."; | |
| 330 error = base::PLATFORM_FILE_ERROR_FAILED; | |
| 331 } | |
| 332 | |
| 333 // If truncating we need to update the usage. | |
| 334 if (error == base::PLATFORM_FILE_OK && delta) { | |
| 335 UpdateUsage(context, url, delta); | |
| 336 context->change_observers()->Notify( | |
| 337 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | |
| 338 } | 272 } |
| 339 return error; | 273 return error; |
| 340 } | 274 } |
| 341 | 275 |
| 342 PlatformFileError ObfuscatedFileUtil::Close( | 276 PlatformFileError ObfuscatedFileUtil::Close( |
| 343 FileSystemOperationContext* context, | 277 FileSystemOperationContext* context, |
| 344 base::PlatformFile file) { | 278 base::PlatformFile file) { |
| 345 return NativeFileUtil::Close(file); | 279 return NativeFileUtil::Close(file); |
| 346 } | 280 } |
| 347 | 281 |
| (...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1330 error = NativeFileUtil::CreateDirectory( | 1264 error = NativeFileUtil::CreateDirectory( |
| 1331 new_local_path, false /* exclusive */, false /* recursive */); | 1265 new_local_path, false /* exclusive */, false /* recursive */); |
| 1332 if (error != base::PLATFORM_FILE_OK) | 1266 if (error != base::PLATFORM_FILE_OK) |
| 1333 return error; | 1267 return error; |
| 1334 | 1268 |
| 1335 *local_path = | 1269 *local_path = |
| 1336 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); | 1270 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); |
| 1337 return base::PLATFORM_FILE_OK; | 1271 return base::PLATFORM_FILE_OK; |
| 1338 } | 1272 } |
| 1339 | 1273 |
| 1274 PlatformFileError ObfuscatedFileUtil::CreateOrOpenInternal( | |
| 1275 FileSystemOperationContext* context, | |
| 1276 const FileSystemURL& url, int file_flags, | |
| 1277 PlatformFile* file_handle, bool* created) { | |
| 1278 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | | |
| 1279 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | | |
| 1280 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); | |
| 1281 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | |
| 1282 url.origin(), url.type(), true); | |
| 1283 if (!db) | |
| 1284 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 1285 FileId file_id; | |
| 1286 if (!db->GetFileWithPath(url.path(), &file_id)) { | |
| 1287 // The file doesn't exist. | |
| 1288 if (!(file_flags & (base::PLATFORM_FILE_CREATE | | |
| 1289 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) | |
| 1290 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 1291 FileId parent_id; | |
| 1292 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), | |
| 1293 &parent_id)) | |
| 1294 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 1295 FileInfo file_info; | |
| 1296 InitFileInfo(&file_info, parent_id, | |
| 1297 VirtualPath::BaseName(url.path()).value()); | |
| 1298 | |
| 1299 int64 growth = UsageForPath(file_info.name.size()); | |
| 1300 if (!AllocateQuota(context, growth)) | |
| 1301 return base::PLATFORM_FILE_ERROR_NO_SPACE; | |
| 1302 PlatformFileError error = CreateFile( | |
| 1303 context, base::FilePath(), | |
| 1304 url.origin(), url.type(), &file_info, | |
| 1305 file_flags, file_handle); | |
| 1306 if (created && base::PLATFORM_FILE_OK == error) { | |
| 1307 *created = true; | |
| 1308 UpdateUsage(context, url, growth); | |
| 1309 context->change_observers()->Notify( | |
| 1310 &FileChangeObserver::OnCreateFile, MakeTuple(url)); | |
| 1311 } | |
| 1312 return error; | |
| 1313 } | |
| 1314 | |
| 1315 if (file_flags & base::PLATFORM_FILE_CREATE) | |
| 1316 return base::PLATFORM_FILE_ERROR_EXISTS; | |
| 1317 | |
| 1318 base::PlatformFileInfo platform_file_info; | |
| 1319 base::FilePath local_path; | |
| 1320 FileInfo file_info; | |
| 1321 base::PlatformFileError error = GetFileInfoInternal( | |
| 1322 db, context, url.origin(), url.type(), file_id, | |
| 1323 &file_info, &platform_file_info, &local_path); | |
| 1324 if (error != base::PLATFORM_FILE_OK) | |
| 1325 return error; | |
| 1326 if (file_info.is_directory()) | |
| 1327 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
| 1328 | |
| 1329 int64 delta = 0; | |
| 1330 if (file_flags & (base::PLATFORM_FILE_CREATE_ALWAYS | | |
| 1331 base::PLATFORM_FILE_OPEN_TRUNCATED)) { | |
| 1332 // The file exists and we're truncating. | |
| 1333 delta = -platform_file_info.size; | |
| 1334 AllocateQuota(context, delta); | |
| 1335 } | |
| 1336 | |
| 1337 error = NativeFileUtil::CreateOrOpen( | |
| 1338 local_path, file_flags, file_handle, created); | |
| 1339 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { | |
| 1340 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. | |
| 1341 // TODO(tzik): Delete database entry after ensuring the file lost. | |
| 1342 InvalidateUsageCache(context, url.origin(), url.type()); | |
| 1343 LOG(WARNING) << "Lost a backing file."; | |
| 1344 error = base::PLATFORM_FILE_ERROR_FAILED; | |
| 1345 } | |
| 1346 | |
| 1347 // If truncating we need to update the usage. | |
| 1348 if (error == base::PLATFORM_FILE_OK && delta) { | |
| 1349 UpdateUsage(context, url, delta); | |
| 1350 context->change_observers()->Notify( | |
| 1351 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | |
| 1352 } | |
| 1353 return error; | |
| 1354 } | |
| 1355 | |
| 1340 } // namespace fileapi | 1356 } // namespace fileapi |
| OLD | NEW |