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 |