| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/sync_file_system/local/local_file_change_tracker.h" | 5 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // object must be destructed on file_task_runner. | 43 // object must be destructed on file_task_runner. |
| 44 class LocalFileChangeTracker::TrackerDB { | 44 class LocalFileChangeTracker::TrackerDB { |
| 45 public: | 45 public: |
| 46 TrackerDB(const base::FilePath& base_path, | 46 TrackerDB(const base::FilePath& base_path, |
| 47 leveldb::Env* env_override); | 47 leveldb::Env* env_override); |
| 48 | 48 |
| 49 SyncStatusCode MarkDirty(const std::string& url); | 49 SyncStatusCode MarkDirty(const std::string& url); |
| 50 SyncStatusCode ClearDirty(const std::string& url); | 50 SyncStatusCode ClearDirty(const std::string& url); |
| 51 SyncStatusCode GetDirtyEntries( | 51 SyncStatusCode GetDirtyEntries( |
| 52 std::queue<FileSystemURL>* dirty_files); | 52 std::queue<FileSystemURL>* dirty_files); |
| 53 SyncStatusCode WriteBatch(scoped_ptr<leveldb::WriteBatch> batch); | 53 SyncStatusCode WriteBatch(std::unique_ptr<leveldb::WriteBatch> batch); |
| 54 | 54 |
| 55 private: | 55 private: |
| 56 enum RecoveryOption { | 56 enum RecoveryOption { |
| 57 REPAIR_ON_CORRUPTION, | 57 REPAIR_ON_CORRUPTION, |
| 58 FAIL_ON_CORRUPTION, | 58 FAIL_ON_CORRUPTION, |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 SyncStatusCode Init(RecoveryOption recovery_option); | 61 SyncStatusCode Init(RecoveryOption recovery_option); |
| 62 SyncStatusCode Repair(const std::string& db_path); | 62 SyncStatusCode Repair(const std::string& db_path); |
| 63 void HandleError(const tracked_objects::Location& from_here, | 63 void HandleError(const tracked_objects::Location& from_here, |
| 64 const leveldb::Status& status); | 64 const leveldb::Status& status); |
| 65 | 65 |
| 66 const base::FilePath base_path_; | 66 const base::FilePath base_path_; |
| 67 leveldb::Env* env_override_; | 67 leveldb::Env* env_override_; |
| 68 scoped_ptr<leveldb::DB> db_; | 68 std::unique_ptr<leveldb::DB> db_; |
| 69 SyncStatusCode db_status_; | 69 SyncStatusCode db_status_; |
| 70 | 70 |
| 71 DISALLOW_COPY_AND_ASSIGN(TrackerDB); | 71 DISALLOW_COPY_AND_ASSIGN(TrackerDB); |
| 72 }; | 72 }; |
| 73 | 73 |
| 74 LocalFileChangeTracker::ChangeInfo::ChangeInfo() : change_seq(-1) {} | 74 LocalFileChangeTracker::ChangeInfo::ChangeInfo() : change_seq(-1) {} |
| 75 LocalFileChangeTracker::ChangeInfo::~ChangeInfo() {} | 75 LocalFileChangeTracker::ChangeInfo::~ChangeInfo() {} |
| 76 | 76 |
| 77 // LocalFileChangeTracker ------------------------------------------------------ | 77 // LocalFileChangeTracker ------------------------------------------------------ |
| 78 | 78 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 | 270 |
| 271 SyncStatusCode status = CollectLastDirtyChanges(file_system_context); | 271 SyncStatusCode status = CollectLastDirtyChanges(file_system_context); |
| 272 if (status == SYNC_STATUS_OK) | 272 if (status == SYNC_STATUS_OK) |
| 273 initialized_ = true; | 273 initialized_ = true; |
| 274 return status; | 274 return status; |
| 275 } | 275 } |
| 276 | 276 |
| 277 void LocalFileChangeTracker::ResetForFileSystem(const GURL& origin, | 277 void LocalFileChangeTracker::ResetForFileSystem(const GURL& origin, |
| 278 storage::FileSystemType type) { | 278 storage::FileSystemType type) { |
| 279 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | 279 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 280 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); | 280 std::unique_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); |
| 281 for (FileChangeMap::iterator iter = changes_.begin(); | 281 for (FileChangeMap::iterator iter = changes_.begin(); |
| 282 iter != changes_.end();) { | 282 iter != changes_.end();) { |
| 283 storage::FileSystemURL url = iter->first; | 283 storage::FileSystemURL url = iter->first; |
| 284 int change_seq = iter->second.change_seq; | 284 int change_seq = iter->second.change_seq; |
| 285 // Advance |iter| before calling ResetForURL to avoid the iterator | 285 // Advance |iter| before calling ResetForURL to avoid the iterator |
| 286 // invalidation in it. | 286 // invalidation in it. |
| 287 ++iter; | 287 ++iter; |
| 288 if (url.origin() == origin && url.type() == type) | 288 if (url.origin() == origin && url.type() == type) |
| 289 ResetForURL(url, change_seq, batch.get()); | 289 ResetForURL(url, change_seq, batch.get()); |
| 290 } | 290 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | 351 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 352 | 352 |
| 353 std::queue<FileSystemURL> dirty_files; | 353 std::queue<FileSystemURL> dirty_files; |
| 354 const SyncStatusCode status = tracker_db_->GetDirtyEntries(&dirty_files); | 354 const SyncStatusCode status = tracker_db_->GetDirtyEntries(&dirty_files); |
| 355 if (status != SYNC_STATUS_OK) | 355 if (status != SYNC_STATUS_OK) |
| 356 return status; | 356 return status; |
| 357 | 357 |
| 358 FileSystemFileUtil* file_util = | 358 FileSystemFileUtil* file_util = |
| 359 file_system_context->sandbox_delegate()->sync_file_util(); | 359 file_system_context->sandbox_delegate()->sync_file_util(); |
| 360 DCHECK(file_util); | 360 DCHECK(file_util); |
| 361 scoped_ptr<FileSystemOperationContext> context( | 361 std::unique_ptr<FileSystemOperationContext> context( |
| 362 new FileSystemOperationContext(file_system_context)); | 362 new FileSystemOperationContext(file_system_context)); |
| 363 | 363 |
| 364 base::File::Info file_info; | 364 base::File::Info file_info; |
| 365 base::FilePath platform_path; | 365 base::FilePath platform_path; |
| 366 | 366 |
| 367 while (!dirty_files.empty()) { | 367 while (!dirty_files.empty()) { |
| 368 const FileSystemURL url = dirty_files.front(); | 368 const FileSystemURL url = dirty_files.front(); |
| 369 dirty_files.pop(); | 369 dirty_files.pop(); |
| 370 DCHECK_EQ(url.type(), storage::kFileSystemTypeSyncable); | 370 DCHECK_EQ(url.type(), storage::kFileSystemTypeSyncable); |
| 371 | 371 |
| 372 switch (file_util->GetFileInfo(context.get(), url, | 372 switch (file_util->GetFileInfo(context.get(), url, |
| 373 &file_info, &platform_path)) { | 373 &file_info, &platform_path)) { |
| 374 case base::File::FILE_OK: { | 374 case base::File::FILE_OK: { |
| 375 if (!file_info.is_directory) { | 375 if (!file_info.is_directory) { |
| 376 RecordChange(url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, | 376 RecordChange(url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, |
| 377 SYNC_FILE_TYPE_FILE)); | 377 SYNC_FILE_TYPE_FILE)); |
| 378 break; | 378 break; |
| 379 } | 379 } |
| 380 | 380 |
| 381 RecordChange(url, FileChange( | 381 RecordChange(url, FileChange( |
| 382 FileChange::FILE_CHANGE_ADD_OR_UPDATE, | 382 FileChange::FILE_CHANGE_ADD_OR_UPDATE, |
| 383 SYNC_FILE_TYPE_DIRECTORY)); | 383 SYNC_FILE_TYPE_DIRECTORY)); |
| 384 | 384 |
| 385 // Push files and directories in this directory into |dirty_files|. | 385 // Push files and directories in this directory into |dirty_files|. |
| 386 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( | 386 std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( |
| 387 file_util->CreateFileEnumerator(context.get(), url)); | 387 file_util->CreateFileEnumerator(context.get(), url)); |
| 388 base::FilePath path_each; | 388 base::FilePath path_each; |
| 389 while (!(path_each = enumerator->Next()).empty()) { | 389 while (!(path_each = enumerator->Next()).empty()) { |
| 390 dirty_files.push(CreateSyncableFileSystemURL( | 390 dirty_files.push(CreateSyncableFileSystemURL( |
| 391 url.origin(), path_each)); | 391 url.origin(), path_each)); |
| 392 } | 392 } |
| 393 break; | 393 break; |
| 394 } | 394 } |
| 395 case base::File::FILE_ERROR_NOT_FOUND: { | 395 case base::File::FILE_ERROR_NOT_FOUND: { |
| 396 // File represented by |url| has already been deleted. Since we cannot | 396 // File represented by |url| has already been deleted. Since we cannot |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 std::queue<FileSystemURL>* dirty_files) { | 584 std::queue<FileSystemURL>* dirty_files) { |
| 585 if (db_status_ != SYNC_STATUS_OK) | 585 if (db_status_ != SYNC_STATUS_OK) |
| 586 return db_status_; | 586 return db_status_; |
| 587 | 587 |
| 588 db_status_ = Init(REPAIR_ON_CORRUPTION); | 588 db_status_ = Init(REPAIR_ON_CORRUPTION); |
| 589 if (db_status_ != SYNC_STATUS_OK) { | 589 if (db_status_ != SYNC_STATUS_OK) { |
| 590 db_.reset(); | 590 db_.reset(); |
| 591 return db_status_; | 591 return db_status_; |
| 592 } | 592 } |
| 593 | 593 |
| 594 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); | 594 std::unique_ptr<leveldb::Iterator> iter( |
| 595 db_->NewIterator(leveldb::ReadOptions())); |
| 595 iter->SeekToFirst(); | 596 iter->SeekToFirst(); |
| 596 FileSystemURL url; | 597 FileSystemURL url; |
| 597 while (iter->Valid()) { | 598 while (iter->Valid()) { |
| 598 if (!DeserializeSyncableFileSystemURL(iter->key().ToString(), &url)) { | 599 if (!DeserializeSyncableFileSystemURL(iter->key().ToString(), &url)) { |
| 599 LOG(WARNING) << "Failed to deserialize an URL. " | 600 LOG(WARNING) << "Failed to deserialize an URL. " |
| 600 << "TrackerDB might be corrupted."; | 601 << "TrackerDB might be corrupted."; |
| 601 db_status_ = SYNC_DATABASE_ERROR_CORRUPTION; | 602 db_status_ = SYNC_DATABASE_ERROR_CORRUPTION; |
| 602 iter.reset(); // Must delete before closing the database. | 603 iter.reset(); // Must delete before closing the database. |
| 603 db_.reset(); | 604 db_.reset(); |
| 604 return db_status_; | 605 return db_status_; |
| 605 } | 606 } |
| 606 dirty_files->push(url); | 607 dirty_files->push(url); |
| 607 iter->Next(); | 608 iter->Next(); |
| 608 } | 609 } |
| 609 return SYNC_STATUS_OK; | 610 return SYNC_STATUS_OK; |
| 610 } | 611 } |
| 611 | 612 |
| 612 SyncStatusCode LocalFileChangeTracker::TrackerDB::WriteBatch( | 613 SyncStatusCode LocalFileChangeTracker::TrackerDB::WriteBatch( |
| 613 scoped_ptr<leveldb::WriteBatch> batch) { | 614 std::unique_ptr<leveldb::WriteBatch> batch) { |
| 614 if (db_status_ != SYNC_STATUS_OK) | 615 if (db_status_ != SYNC_STATUS_OK) |
| 615 return db_status_; | 616 return db_status_; |
| 616 | 617 |
| 617 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch.get()); | 618 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch.get()); |
| 618 if (!status.ok() && !status.IsNotFound()) { | 619 if (!status.ok() && !status.IsNotFound()) { |
| 619 HandleError(FROM_HERE, status); | 620 HandleError(FROM_HERE, status); |
| 620 db_status_ = LevelDBStatusToSyncStatusCode(status); | 621 db_status_ = LevelDBStatusToSyncStatusCode(status); |
| 621 db_.reset(); | 622 db_.reset(); |
| 622 return db_status_; | 623 return db_status_; |
| 623 } | 624 } |
| 624 return SYNC_STATUS_OK; | 625 return SYNC_STATUS_OK; |
| 625 } | 626 } |
| 626 | 627 |
| 627 } // namespace sync_file_system | 628 } // namespace sync_file_system |
| OLD | NEW |