| 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 context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited) { |
| 269 if (!db) | 269 DCHECK_EQ(base::PLATFORM_FILE_OK, error); |
| 270 return base::PLATFORM_FILE_ERROR_FAILED; | 270 DCHECK_EQ(kFileSystemTypePersistent, url.type()); |
| 271 FileId file_id; | 271 context->file_system_context()->GetQuotaUtil(url.type())-> |
| 272 if (!db->GetFileWithPath(url.path(), &file_id)) { | 272 StickyInvalidateUsageCache(url.origin(), url.type()); |
| 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 } | 273 } |
| 339 return error; | 274 return error; |
| 340 } | 275 } |
| 341 | 276 |
| 342 PlatformFileError ObfuscatedFileUtil::Close( | 277 PlatformFileError ObfuscatedFileUtil::Close( |
| 343 FileSystemOperationContext* context, | 278 FileSystemOperationContext* context, |
| 344 base::PlatformFile file) { | 279 base::PlatformFile file) { |
| 345 return NativeFileUtil::Close(file); | 280 return NativeFileUtil::Close(file); |
| 346 } | 281 } |
| 347 | 282 |
| (...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 error = NativeFileUtil::CreateDirectory( | 1265 error = NativeFileUtil::CreateDirectory( |
| 1331 new_local_path, false /* exclusive */, false /* recursive */); | 1266 new_local_path, false /* exclusive */, false /* recursive */); |
| 1332 if (error != base::PLATFORM_FILE_OK) | 1267 if (error != base::PLATFORM_FILE_OK) |
| 1333 return error; | 1268 return error; |
| 1334 | 1269 |
| 1335 *local_path = | 1270 *local_path = |
| 1336 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); | 1271 new_local_path.AppendASCII(base::StringPrintf("%08" PRId64, number)); |
| 1337 return base::PLATFORM_FILE_OK; | 1272 return base::PLATFORM_FILE_OK; |
| 1338 } | 1273 } |
| 1339 | 1274 |
| 1275 PlatformFileError ObfuscatedFileUtil::CreateOrOpenInternal( |
| 1276 FileSystemOperationContext* context, |
| 1277 const FileSystemURL& url, int file_flags, |
| 1278 PlatformFile* file_handle, bool* created) { |
| 1279 DCHECK(!(file_flags & (base::PLATFORM_FILE_DELETE_ON_CLOSE | |
| 1280 base::PLATFORM_FILE_HIDDEN | base::PLATFORM_FILE_EXCLUSIVE_READ | |
| 1281 base::PLATFORM_FILE_EXCLUSIVE_WRITE))); |
| 1282 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 1283 url.origin(), url.type(), true); |
| 1284 if (!db) |
| 1285 return base::PLATFORM_FILE_ERROR_FAILED; |
| 1286 FileId file_id; |
| 1287 if (!db->GetFileWithPath(url.path(), &file_id)) { |
| 1288 // The file doesn't exist. |
| 1289 if (!(file_flags & (base::PLATFORM_FILE_CREATE | |
| 1290 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS))) |
| 1291 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1292 FileId parent_id; |
| 1293 if (!db->GetFileWithPath(VirtualPath::DirName(url.path()), |
| 1294 &parent_id)) |
| 1295 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1296 FileInfo file_info; |
| 1297 InitFileInfo(&file_info, parent_id, |
| 1298 VirtualPath::BaseName(url.path()).value()); |
| 1299 |
| 1300 int64 growth = UsageForPath(file_info.name.size()); |
| 1301 if (!AllocateQuota(context, growth)) |
| 1302 return base::PLATFORM_FILE_ERROR_NO_SPACE; |
| 1303 PlatformFileError error = CreateFile( |
| 1304 context, base::FilePath(), |
| 1305 url.origin(), url.type(), &file_info, |
| 1306 file_flags, file_handle); |
| 1307 if (created && base::PLATFORM_FILE_OK == error) { |
| 1308 *created = true; |
| 1309 UpdateUsage(context, url, growth); |
| 1310 context->change_observers()->Notify( |
| 1311 &FileChangeObserver::OnCreateFile, MakeTuple(url)); |
| 1312 } |
| 1313 return error; |
| 1314 } |
| 1315 |
| 1316 if (file_flags & base::PLATFORM_FILE_CREATE) |
| 1317 return base::PLATFORM_FILE_ERROR_EXISTS; |
| 1318 |
| 1319 base::PlatformFileInfo platform_file_info; |
| 1320 base::FilePath local_path; |
| 1321 FileInfo file_info; |
| 1322 base::PlatformFileError error = GetFileInfoInternal( |
| 1323 db, context, url.origin(), url.type(), file_id, |
| 1324 &file_info, &platform_file_info, &local_path); |
| 1325 if (error != base::PLATFORM_FILE_OK) |
| 1326 return error; |
| 1327 if (file_info.is_directory()) |
| 1328 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 1329 |
| 1330 int64 delta = 0; |
| 1331 if (file_flags & (base::PLATFORM_FILE_CREATE_ALWAYS | |
| 1332 base::PLATFORM_FILE_OPEN_TRUNCATED)) { |
| 1333 // The file exists and we're truncating. |
| 1334 delta = -platform_file_info.size; |
| 1335 AllocateQuota(context, delta); |
| 1336 } |
| 1337 |
| 1338 error = NativeFileUtil::CreateOrOpen( |
| 1339 local_path, file_flags, file_handle, created); |
| 1340 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { |
| 1341 // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. |
| 1342 // TODO(tzik): Delete database entry after ensuring the file lost. |
| 1343 InvalidateUsageCache(context, url.origin(), url.type()); |
| 1344 LOG(WARNING) << "Lost a backing file."; |
| 1345 error = base::PLATFORM_FILE_ERROR_FAILED; |
| 1346 } |
| 1347 |
| 1348 // If truncating we need to update the usage. |
| 1349 if (error == base::PLATFORM_FILE_OK && delta) { |
| 1350 UpdateUsage(context, url, delta); |
| 1351 context->change_observers()->Notify( |
| 1352 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
| 1353 } |
| 1354 return error; |
| 1355 } |
| 1356 |
| 1340 } // namespace fileapi | 1357 } // namespace fileapi |
| OLD | NEW |