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 |