| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 #include "storage/common/database/database_identifier.h" | 46 #include "storage/common/database/database_identifier.h" |
| 47 #include "storage/common/fileapi/file_system_mount_option.h" | 47 #include "storage/common/fileapi/file_system_mount_option.h" |
| 48 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" | 48 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" |
| 49 #include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h" | 49 #include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h" |
| 50 #include "third_party/leveldatabase/env_chromium.h" | 50 #include "third_party/leveldatabase/env_chromium.h" |
| 51 | 51 |
| 52 using base::FilePath; | 52 using base::FilePath; |
| 53 using base::StringPiece; | 53 using base::StringPiece; |
| 54 using std::string; | 54 using std::string; |
| 55 using storage::FileWriterDelegate; | 55 using storage::FileWriterDelegate; |
| 56 using url::Origin; |
| 56 | 57 |
| 57 namespace content { | 58 namespace content { |
| 58 | 59 |
| 59 namespace { | 60 namespace { |
| 60 | 61 |
| 61 FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) { | 62 FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) { |
| 62 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id)); | 63 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id)); |
| 63 } | 64 } |
| 64 | 65 |
| 65 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base, | 66 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 79 return path; | 80 return path; |
| 80 } | 81 } |
| 81 | 82 |
| 82 bool MakeIDBBlobDirectory(const FilePath& path_base, | 83 bool MakeIDBBlobDirectory(const FilePath& path_base, |
| 83 int64_t database_id, | 84 int64_t database_id, |
| 84 int64_t key) { | 85 int64_t key) { |
| 85 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); | 86 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); |
| 86 return base::CreateDirectory(path); | 87 return base::CreateDirectory(path); |
| 87 } | 88 } |
| 88 | 89 |
| 89 static std::string ComputeOriginIdentifier(const GURL& origin_url) { | 90 static std::string ComputeOriginIdentifier(const Origin& origin) { |
| 90 return storage::GetIdentifierFromOrigin(origin_url) + "@1"; | 91 return storage::GetIdentifierFromOrigin(GURL(origin.Serialize())) + "@1"; |
| 91 } | 92 } |
| 92 | 93 |
| 93 static FilePath ComputeCorruptionFileName(const GURL& origin_url) { | 94 static FilePath ComputeCorruptionFileName(const Origin& origin) { |
| 94 return IndexedDBContextImpl::GetLevelDBFileName(origin_url) | 95 return IndexedDBContextImpl::GetLevelDBFileName(origin).Append( |
| 95 .Append(FILE_PATH_LITERAL("corruption_info.json")); | 96 FILE_PATH_LITERAL("corruption_info.json")); |
| 96 } | 97 } |
| 97 | 98 |
| 98 } // namespace | 99 } // namespace |
| 99 | 100 |
| 100 static const int64_t kKeyGeneratorInitialNumber = | 101 static const int64_t kKeyGeneratorInitialNumber = |
| 101 1; // From the IndexedDB specification. | 102 1; // From the IndexedDB specification. |
| 102 | 103 |
| 103 enum IndexedDBBackingStoreErrorSource { | 104 enum IndexedDBBackingStoreErrorSource { |
| 104 // 0 - 2 are no longer used. | 105 // 0 - 2 are no longer used. |
| 105 FIND_KEY_IN_INDEX = 3, | 106 FIND_KEY_IN_INDEX = 3, |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64_t>(size), key)); | 739 ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64_t>(size), key)); |
| 739 } | 740 } |
| 740 } | 741 } |
| 741 output->swap(ret); | 742 output->swap(ret); |
| 742 | 743 |
| 743 return true; | 744 return true; |
| 744 } | 745 } |
| 745 | 746 |
| 746 IndexedDBBackingStore::IndexedDBBackingStore( | 747 IndexedDBBackingStore::IndexedDBBackingStore( |
| 747 IndexedDBFactory* indexed_db_factory, | 748 IndexedDBFactory* indexed_db_factory, |
| 748 const GURL& origin_url, | 749 const Origin& origin, |
| 749 const base::FilePath& blob_path, | 750 const base::FilePath& blob_path, |
| 750 net::URLRequestContext* request_context, | 751 net::URLRequestContext* request_context, |
| 751 std::unique_ptr<LevelDBDatabase> db, | 752 std::unique_ptr<LevelDBDatabase> db, |
| 752 std::unique_ptr<LevelDBComparator> comparator, | 753 std::unique_ptr<LevelDBComparator> comparator, |
| 753 base::SequencedTaskRunner* task_runner) | 754 base::SequencedTaskRunner* task_runner) |
| 754 : indexed_db_factory_(indexed_db_factory), | 755 : indexed_db_factory_(indexed_db_factory), |
| 755 origin_url_(origin_url), | 756 origin_(origin), |
| 756 blob_path_(blob_path), | 757 blob_path_(blob_path), |
| 757 origin_identifier_(ComputeOriginIdentifier(origin_url)), | 758 origin_identifier_(ComputeOriginIdentifier(origin)), |
| 758 request_context_(request_context), | 759 request_context_(request_context), |
| 759 task_runner_(task_runner), | 760 task_runner_(task_runner), |
| 760 db_(std::move(db)), | 761 db_(std::move(db)), |
| 761 comparator_(std::move(comparator)), | 762 comparator_(std::move(comparator)), |
| 762 active_blob_registry_(this), | 763 active_blob_registry_(this), |
| 763 committing_transaction_count_(0) {} | 764 committing_transaction_count_(0) {} |
| 764 | 765 |
| 765 IndexedDBBackingStore::~IndexedDBBackingStore() { | 766 IndexedDBBackingStore::~IndexedDBBackingStore() { |
| 766 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { | 767 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { |
| 767 ChildProcessSecurityPolicyImpl* policy = | 768 ChildProcessSecurityPolicyImpl* policy = |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 809 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, |
| 809 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, | 810 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, |
| 810 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, | 811 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, |
| 811 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, | 812 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, |
| 812 INDEXED_DB_BACKING_STORE_OPEN_MAX, | 813 INDEXED_DB_BACKING_STORE_OPEN_MAX, |
| 813 }; | 814 }; |
| 814 | 815 |
| 815 // static | 816 // static |
| 816 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 817 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 817 IndexedDBFactory* indexed_db_factory, | 818 IndexedDBFactory* indexed_db_factory, |
| 818 const GURL& origin_url, | 819 const Origin& origin, |
| 819 const base::FilePath& path_base, | 820 const base::FilePath& path_base, |
| 820 net::URLRequestContext* request_context, | 821 net::URLRequestContext* request_context, |
| 821 blink::WebIDBDataLoss* data_loss, | 822 blink::WebIDBDataLoss* data_loss, |
| 822 std::string* data_loss_message, | 823 std::string* data_loss_message, |
| 823 bool* disk_full, | 824 bool* disk_full, |
| 824 base::SequencedTaskRunner* task_runner, | 825 base::SequencedTaskRunner* task_runner, |
| 825 bool clean_journal, | 826 bool clean_journal, |
| 826 leveldb::Status* status) { | 827 leveldb::Status* status) { |
| 827 *data_loss = blink::WebIDBDataLossNone; | 828 *data_loss = blink::WebIDBDataLossNone; |
| 828 DefaultLevelDBFactory leveldb_factory; | 829 DefaultLevelDBFactory leveldb_factory; |
| 829 return IndexedDBBackingStore::Open(indexed_db_factory, | 830 return IndexedDBBackingStore::Open( |
| 830 origin_url, | 831 indexed_db_factory, origin, path_base, request_context, data_loss, |
| 831 path_base, | 832 data_loss_message, disk_full, &leveldb_factory, task_runner, |
| 832 request_context, | 833 clean_journal, status); |
| 833 data_loss, | |
| 834 data_loss_message, | |
| 835 disk_full, | |
| 836 &leveldb_factory, | |
| 837 task_runner, | |
| 838 clean_journal, | |
| 839 status); | |
| 840 } | 834 } |
| 841 | 835 |
| 842 static std::string OriginToCustomHistogramSuffix(const GURL& origin_url) { | 836 static std::string OriginToCustomHistogramSuffix(const Origin& origin) { |
| 843 if (origin_url.host() == "docs.google.com") | 837 if (origin.host() == "docs.google.com") |
| 844 return ".Docs"; | 838 return ".Docs"; |
| 845 return std::string(); | 839 return std::string(); |
| 846 } | 840 } |
| 847 | 841 |
| 848 static void HistogramOpenStatus(IndexedDBBackingStoreOpenResult result, | 842 static void HistogramOpenStatus(IndexedDBBackingStoreOpenResult result, |
| 849 const GURL& origin_url) { | 843 const Origin& origin) { |
| 850 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.BackingStore.OpenStatus", | 844 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 851 result, | 845 result, |
| 852 INDEXED_DB_BACKING_STORE_OPEN_MAX); | 846 INDEXED_DB_BACKING_STORE_OPEN_MAX); |
| 853 const std::string suffix = OriginToCustomHistogramSuffix(origin_url); | 847 const std::string suffix = OriginToCustomHistogramSuffix(origin); |
| 854 // Data from the WebCore.IndexedDB.BackingStore.OpenStatus histogram is used | 848 // Data from the WebCore.IndexedDB.BackingStore.OpenStatus histogram is used |
| 855 // to generate a graph. So as not to alter the meaning of that graph, | 849 // to generate a graph. So as not to alter the meaning of that graph, |
| 856 // continue to collect all stats there (above) but also now collect docs stats | 850 // continue to collect all stats there (above) but also now collect docs stats |
| 857 // separately (below). | 851 // separately (below). |
| 858 if (!suffix.empty()) { | 852 if (!suffix.empty()) { |
| 859 base::LinearHistogram::FactoryGet( | 853 base::LinearHistogram::FactoryGet( |
| 860 "WebCore.IndexedDB.BackingStore.OpenStatus" + suffix, | 854 "WebCore.IndexedDB.BackingStore.OpenStatus" + suffix, |
| 861 1, | 855 1, |
| 862 INDEXED_DB_BACKING_STORE_OPEN_MAX, | 856 INDEXED_DB_BACKING_STORE_OPEN_MAX, |
| 863 INDEXED_DB_BACKING_STORE_OPEN_MAX + 1, | 857 INDEXED_DB_BACKING_STORE_OPEN_MAX + 1, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 890 min, | 884 min, |
| 891 max, | 885 max, |
| 892 num_buckets); | 886 num_buckets); |
| 893 return true; | 887 return true; |
| 894 } | 888 } |
| 895 return false; | 889 return false; |
| 896 } | 890 } |
| 897 | 891 |
| 898 leveldb::Status IndexedDBBackingStore::DestroyBackingStore( | 892 leveldb::Status IndexedDBBackingStore::DestroyBackingStore( |
| 899 const base::FilePath& path_base, | 893 const base::FilePath& path_base, |
| 900 const GURL& origin_url) { | 894 const Origin& origin) { |
| 901 const base::FilePath file_path = | 895 const base::FilePath file_path = |
| 902 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin_url)); | 896 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin)); |
| 903 DefaultLevelDBFactory leveldb_factory; | 897 DefaultLevelDBFactory leveldb_factory; |
| 904 return leveldb_factory.DestroyLevelDB(file_path); | 898 return leveldb_factory.DestroyLevelDB(file_path); |
| 905 } | 899 } |
| 906 | 900 |
| 907 bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base, | 901 bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base, |
| 908 const GURL& origin_url, | 902 const Origin& origin, |
| 909 std::string* message) { | 903 std::string* message) { |
| 910 const base::FilePath info_path = | 904 const base::FilePath info_path = |
| 911 path_base.Append(ComputeCorruptionFileName(origin_url)); | 905 path_base.Append(ComputeCorruptionFileName(origin)); |
| 912 | 906 |
| 913 if (IsPathTooLong(info_path)) | 907 if (IsPathTooLong(info_path)) |
| 914 return false; | 908 return false; |
| 915 | 909 |
| 916 const int64_t max_json_len = 4096; | 910 const int64_t max_json_len = 4096; |
| 917 int64_t file_size(0); | 911 int64_t file_size(0); |
| 918 if (!GetFileSize(info_path, &file_size) || file_size > max_json_len) | 912 if (!GetFileSize(info_path, &file_size) || file_size > max_json_len) |
| 919 return false; | 913 return false; |
| 920 if (!file_size) { | 914 if (!file_size) { |
| 921 NOTREACHED(); | 915 NOTREACHED(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 939 file.Close(); | 933 file.Close(); |
| 940 } | 934 } |
| 941 | 935 |
| 942 base::DeleteFile(info_path, false); | 936 base::DeleteFile(info_path, false); |
| 943 | 937 |
| 944 return success; | 938 return success; |
| 945 } | 939 } |
| 946 | 940 |
| 947 bool IndexedDBBackingStore::RecordCorruptionInfo( | 941 bool IndexedDBBackingStore::RecordCorruptionInfo( |
| 948 const base::FilePath& path_base, | 942 const base::FilePath& path_base, |
| 949 const GURL& origin_url, | 943 const Origin& origin, |
| 950 const std::string& message) { | 944 const std::string& message) { |
| 951 const base::FilePath info_path = | 945 const base::FilePath info_path = |
| 952 path_base.Append(ComputeCorruptionFileName(origin_url)); | 946 path_base.Append(ComputeCorruptionFileName(origin)); |
| 953 if (IsPathTooLong(info_path)) | 947 if (IsPathTooLong(info_path)) |
| 954 return false; | 948 return false; |
| 955 | 949 |
| 956 base::DictionaryValue root_dict; | 950 base::DictionaryValue root_dict; |
| 957 root_dict.SetString("message", message); | 951 root_dict.SetString("message", message); |
| 958 std::string output_js; | 952 std::string output_js; |
| 959 base::JSONWriter::Write(root_dict, &output_js); | 953 base::JSONWriter::Write(root_dict, &output_js); |
| 960 | 954 |
| 961 base::File file(info_path, | 955 base::File file(info_path, |
| 962 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); | 956 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); |
| 963 if (!file.IsValid()) | 957 if (!file.IsValid()) |
| 964 return false; | 958 return false; |
| 965 int written = file.Write(0, output_js.c_str(), output_js.length()); | 959 int written = file.Write(0, output_js.c_str(), output_js.length()); |
| 966 return size_t(written) == output_js.length(); | 960 return size_t(written) == output_js.length(); |
| 967 } | 961 } |
| 968 | 962 |
| 969 // static | 963 // static |
| 970 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 964 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 971 IndexedDBFactory* indexed_db_factory, | 965 IndexedDBFactory* indexed_db_factory, |
| 972 const GURL& origin_url, | 966 const Origin& origin, |
| 973 const base::FilePath& path_base, | 967 const base::FilePath& path_base, |
| 974 net::URLRequestContext* request_context, | 968 net::URLRequestContext* request_context, |
| 975 blink::WebIDBDataLoss* data_loss, | 969 blink::WebIDBDataLoss* data_loss, |
| 976 std::string* data_loss_message, | 970 std::string* data_loss_message, |
| 977 bool* is_disk_full, | 971 bool* is_disk_full, |
| 978 LevelDBFactory* leveldb_factory, | 972 LevelDBFactory* leveldb_factory, |
| 979 base::SequencedTaskRunner* task_runner, | 973 base::SequencedTaskRunner* task_runner, |
| 980 bool clean_journal, | 974 bool clean_journal, |
| 981 leveldb::Status* status) { | 975 leveldb::Status* status) { |
| 982 IDB_TRACE("IndexedDBBackingStore::Open"); | 976 IDB_TRACE("IndexedDBBackingStore::Open"); |
| 983 DCHECK(!path_base.empty()); | 977 DCHECK(!path_base.empty()); |
| 984 *data_loss = blink::WebIDBDataLossNone; | 978 *data_loss = blink::WebIDBDataLossNone; |
| 985 *data_loss_message = ""; | 979 *data_loss_message = ""; |
| 986 *is_disk_full = false; | 980 *is_disk_full = false; |
| 987 | 981 |
| 988 *status = leveldb::Status::OK(); | 982 *status = leveldb::Status::OK(); |
| 989 | 983 |
| 990 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); | 984 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); |
| 991 | 985 |
| 992 if (!base::IsStringASCII(path_base.AsUTF8Unsafe())) { | 986 if (!base::IsStringASCII(path_base.AsUTF8Unsafe())) { |
| 993 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, | 987 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, |
| 994 origin_url); | 988 origin); |
| 995 } | 989 } |
| 996 if (!base::CreateDirectory(path_base)) { | 990 if (!base::CreateDirectory(path_base)) { |
| 997 *status = | 991 *status = |
| 998 leveldb::Status::IOError("Unable to create IndexedDB database path"); | 992 leveldb::Status::IOError("Unable to create IndexedDB database path"); |
| 999 LOG(ERROR) << status->ToString() << ": \"" << path_base.AsUTF8Unsafe() | 993 LOG(ERROR) << status->ToString() << ": \"" << path_base.AsUTF8Unsafe() |
| 1000 << "\""; | 994 << "\""; |
| 1001 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, | 995 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, origin); |
| 1002 origin_url); | |
| 1003 return scoped_refptr<IndexedDBBackingStore>(); | 996 return scoped_refptr<IndexedDBBackingStore>(); |
| 1004 } | 997 } |
| 1005 | 998 |
| 1006 const FilePath file_path = | 999 const FilePath file_path = |
| 1007 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin_url)); | 1000 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin)); |
| 1008 const FilePath blob_path = | 1001 const FilePath blob_path = |
| 1009 path_base.Append(IndexedDBContextImpl::GetBlobStoreFileName(origin_url)); | 1002 path_base.Append(IndexedDBContextImpl::GetBlobStoreFileName(origin)); |
| 1010 | 1003 |
| 1011 if (IsPathTooLong(file_path)) { | 1004 if (IsPathTooLong(file_path)) { |
| 1012 *status = leveldb::Status::IOError("File path too long"); | 1005 *status = leveldb::Status::IOError("File path too long"); |
| 1013 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 1006 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, origin); |
| 1014 origin_url); | |
| 1015 return scoped_refptr<IndexedDBBackingStore>(); | 1007 return scoped_refptr<IndexedDBBackingStore>(); |
| 1016 } | 1008 } |
| 1017 | 1009 |
| 1018 std::unique_ptr<LevelDBDatabase> db; | 1010 std::unique_ptr<LevelDBDatabase> db; |
| 1019 *status = leveldb_factory->OpenLevelDB( | 1011 *status = leveldb_factory->OpenLevelDB( |
| 1020 file_path, comparator.get(), &db, is_disk_full); | 1012 file_path, comparator.get(), &db, is_disk_full); |
| 1021 | 1013 |
| 1022 DCHECK(!db == !status->ok()); | 1014 DCHECK(!db == !status->ok()); |
| 1023 if (!status->ok()) { | 1015 if (!status->ok()) { |
| 1024 if (leveldb_env::IndicatesDiskFull(*status)) { | 1016 if (leveldb_env::IndicatesDiskFull(*status)) { |
| 1025 *is_disk_full = true; | 1017 *is_disk_full = true; |
| 1026 } else if (status->IsCorruption()) { | 1018 } else if (status->IsCorruption()) { |
| 1027 *data_loss = blink::WebIDBDataLossTotal; | 1019 *data_loss = blink::WebIDBDataLossTotal; |
| 1028 *data_loss_message = leveldb_env::GetCorruptionMessage(*status); | 1020 *data_loss_message = leveldb_env::GetCorruptionMessage(*status); |
| 1029 } | 1021 } |
| 1030 } | 1022 } |
| 1031 | 1023 |
| 1032 bool is_schema_known = false; | 1024 bool is_schema_known = false; |
| 1033 if (db) { | 1025 if (db) { |
| 1034 std::string corruption_message; | 1026 std::string corruption_message; |
| 1035 if (ReadCorruptionInfo(path_base, origin_url, &corruption_message)) { | 1027 if (ReadCorruptionInfo(path_base, origin, &corruption_message)) { |
| 1036 LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " | 1028 LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " |
| 1037 "database."; | 1029 "database."; |
| 1038 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, | 1030 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, |
| 1039 origin_url); | 1031 origin); |
| 1040 db.reset(); | 1032 db.reset(); |
| 1041 *data_loss = blink::WebIDBDataLossTotal; | 1033 *data_loss = blink::WebIDBDataLossTotal; |
| 1042 *data_loss_message = | 1034 *data_loss_message = |
| 1043 "IndexedDB (database was corrupt): " + corruption_message; | 1035 "IndexedDB (database was corrupt): " + corruption_message; |
| 1044 } else if (!IsSchemaKnown(db.get(), &is_schema_known)) { | 1036 } else if (!IsSchemaKnown(db.get(), &is_schema_known)) { |
| 1045 LOG(ERROR) << "IndexedDB had IO error checking schema, treating it as " | 1037 LOG(ERROR) << "IndexedDB had IO error checking schema, treating it as " |
| 1046 "failure to open"; | 1038 "failure to open"; |
| 1047 HistogramOpenStatus( | 1039 HistogramOpenStatus( |
| 1048 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, | 1040 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, |
| 1049 origin_url); | 1041 origin); |
| 1050 db.reset(); | 1042 db.reset(); |
| 1051 *data_loss = blink::WebIDBDataLossTotal; | 1043 *data_loss = blink::WebIDBDataLossTotal; |
| 1052 *data_loss_message = "I/O error checking schema"; | 1044 *data_loss_message = "I/O error checking schema"; |
| 1053 } else if (!is_schema_known) { | 1045 } else if (!is_schema_known) { |
| 1054 LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it " | 1046 LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it " |
| 1055 "as failure to open"; | 1047 "as failure to open"; |
| 1056 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, | 1048 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, |
| 1057 origin_url); | 1049 origin); |
| 1058 db.reset(); | 1050 db.reset(); |
| 1059 *data_loss = blink::WebIDBDataLossTotal; | 1051 *data_loss = blink::WebIDBDataLossTotal; |
| 1060 *data_loss_message = "Unknown schema"; | 1052 *data_loss_message = "Unknown schema"; |
| 1061 } | 1053 } |
| 1062 } | 1054 } |
| 1063 | 1055 |
| 1064 DCHECK(status->ok() || !is_schema_known || status->IsIOError() || | 1056 DCHECK(status->ok() || !is_schema_known || status->IsIOError() || |
| 1065 status->IsCorruption()); | 1057 status->IsCorruption()); |
| 1066 | 1058 |
| 1067 if (db) { | 1059 if (db) { |
| 1068 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin_url); | 1060 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin); |
| 1069 } else if (status->IsIOError()) { | 1061 } else if (status->IsIOError()) { |
| 1070 LOG(ERROR) << "Unable to open backing store, not trying to recover - " | 1062 LOG(ERROR) << "Unable to open backing store, not trying to recover - " |
| 1071 << status->ToString(); | 1063 << status->ToString(); |
| 1072 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, origin_url); | 1064 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, origin); |
| 1073 return scoped_refptr<IndexedDBBackingStore>(); | 1065 return scoped_refptr<IndexedDBBackingStore>(); |
| 1074 } else { | 1066 } else { |
| 1075 DCHECK(!is_schema_known || status->IsCorruption()); | 1067 DCHECK(!is_schema_known || status->IsCorruption()); |
| 1076 LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup"; | 1068 LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup"; |
| 1077 *status = leveldb_factory->DestroyLevelDB(file_path); | 1069 *status = leveldb_factory->DestroyLevelDB(file_path); |
| 1078 if (!status->ok()) { | 1070 if (!status->ok()) { |
| 1079 LOG(ERROR) << "IndexedDB backing store cleanup failed"; | 1071 LOG(ERROR) << "IndexedDB backing store cleanup failed"; |
| 1080 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED, | 1072 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED, |
| 1081 origin_url); | 1073 origin); |
| 1082 return scoped_refptr<IndexedDBBackingStore>(); | 1074 return scoped_refptr<IndexedDBBackingStore>(); |
| 1083 } | 1075 } |
| 1084 | 1076 |
| 1085 LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening"; | 1077 LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening"; |
| 1086 *status = | 1078 *status = |
| 1087 leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL); | 1079 leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL); |
| 1088 if (!status->ok()) { | 1080 if (!status->ok()) { |
| 1089 DCHECK(!db); | 1081 DCHECK(!db); |
| 1090 LOG(ERROR) << "IndexedDB backing store reopen after recovery failed"; | 1082 LOG(ERROR) << "IndexedDB backing store reopen after recovery failed"; |
| 1091 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, | 1083 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, |
| 1092 origin_url); | 1084 origin); |
| 1093 return scoped_refptr<IndexedDBBackingStore>(); | 1085 return scoped_refptr<IndexedDBBackingStore>(); |
| 1094 } | 1086 } |
| 1095 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, | 1087 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, |
| 1096 origin_url); | 1088 origin); |
| 1097 } | 1089 } |
| 1098 | 1090 |
| 1099 base::trace_event::MemoryDumpManager::GetInstance() | 1091 base::trace_event::MemoryDumpManager::GetInstance() |
| 1100 ->RegisterDumpProviderWithSequencedTaskRunner( | 1092 ->RegisterDumpProviderWithSequencedTaskRunner( |
| 1101 db.get(), "IndexedDBBackingStore", task_runner, | 1093 db.get(), "IndexedDBBackingStore", task_runner, |
| 1102 base::trace_event::MemoryDumpProvider::Options()); | 1094 base::trace_event::MemoryDumpProvider::Options()); |
| 1103 | 1095 |
| 1104 scoped_refptr<IndexedDBBackingStore> backing_store = | 1096 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 1105 Create(indexed_db_factory, origin_url, blob_path, request_context, | 1097 Create(indexed_db_factory, origin, blob_path, request_context, |
| 1106 std::move(db), std::move(comparator), task_runner, status); | 1098 std::move(db), std::move(comparator), task_runner, status); |
| 1107 | 1099 |
| 1108 if (clean_journal && backing_store.get()) { | 1100 if (clean_journal && backing_store.get()) { |
| 1109 *status = backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()); | 1101 *status = backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()); |
| 1110 if (!status->ok()) { | 1102 if (!status->ok()) { |
| 1111 HistogramOpenStatus( | 1103 HistogramOpenStatus( |
| 1112 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, | 1104 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, origin); |
| 1113 origin_url); | |
| 1114 return scoped_refptr<IndexedDBBackingStore>(); | 1105 return scoped_refptr<IndexedDBBackingStore>(); |
| 1115 } | 1106 } |
| 1116 } | 1107 } |
| 1117 return backing_store; | 1108 return backing_store; |
| 1118 } | 1109 } |
| 1119 | 1110 |
| 1120 // static | 1111 // static |
| 1121 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 1112 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 1122 const GURL& origin_url, | 1113 const Origin& origin, |
| 1123 base::SequencedTaskRunner* task_runner, | 1114 base::SequencedTaskRunner* task_runner, |
| 1124 leveldb::Status* status) { | 1115 leveldb::Status* status) { |
| 1125 DefaultLevelDBFactory leveldb_factory; | 1116 DefaultLevelDBFactory leveldb_factory; |
| 1126 return IndexedDBBackingStore::OpenInMemory( | 1117 return IndexedDBBackingStore::OpenInMemory(origin, &leveldb_factory, |
| 1127 origin_url, &leveldb_factory, task_runner, status); | 1118 task_runner, status); |
| 1128 } | 1119 } |
| 1129 | 1120 |
| 1130 // static | 1121 // static |
| 1131 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 1122 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 1132 const GURL& origin_url, | 1123 const Origin& origin, |
| 1133 LevelDBFactory* leveldb_factory, | 1124 LevelDBFactory* leveldb_factory, |
| 1134 base::SequencedTaskRunner* task_runner, | 1125 base::SequencedTaskRunner* task_runner, |
| 1135 leveldb::Status* status) { | 1126 leveldb::Status* status) { |
| 1136 IDB_TRACE("IndexedDBBackingStore::OpenInMemory"); | 1127 IDB_TRACE("IndexedDBBackingStore::OpenInMemory"); |
| 1137 | 1128 |
| 1138 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); | 1129 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); |
| 1139 std::unique_ptr<LevelDBDatabase> db = | 1130 std::unique_ptr<LevelDBDatabase> db = |
| 1140 LevelDBDatabase::OpenInMemory(comparator.get()); | 1131 LevelDBDatabase::OpenInMemory(comparator.get()); |
| 1141 if (!db) { | 1132 if (!db) { |
| 1142 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; | 1133 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; |
| 1143 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, | 1134 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, origin); |
| 1144 origin_url); | |
| 1145 return scoped_refptr<IndexedDBBackingStore>(); | 1135 return scoped_refptr<IndexedDBBackingStore>(); |
| 1146 } | 1136 } |
| 1147 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url); | 1137 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin); |
| 1148 base::trace_event::MemoryDumpManager::GetInstance() | 1138 base::trace_event::MemoryDumpManager::GetInstance() |
| 1149 ->RegisterDumpProviderWithSequencedTaskRunner( | 1139 ->RegisterDumpProviderWithSequencedTaskRunner( |
| 1150 db.get(), "IndexedDBBackingStore", task_runner, | 1140 db.get(), "IndexedDBBackingStore", task_runner, |
| 1151 base::trace_event::MemoryDumpProvider::Options()); | 1141 base::trace_event::MemoryDumpProvider::Options()); |
| 1152 | 1142 |
| 1153 return Create(NULL /* indexed_db_factory */, origin_url, base::FilePath(), | 1143 return Create(NULL /* indexed_db_factory */, origin, base::FilePath(), |
| 1154 NULL /* request_context */, std::move(db), | 1144 NULL /* request_context */, std::move(db), |
| 1155 std::move(comparator), task_runner, status); | 1145 std::move(comparator), task_runner, status); |
| 1156 } | 1146 } |
| 1157 | 1147 |
| 1158 // static | 1148 // static |
| 1159 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( | 1149 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
| 1160 IndexedDBFactory* indexed_db_factory, | 1150 IndexedDBFactory* indexed_db_factory, |
| 1161 const GURL& origin_url, | 1151 const Origin& origin, |
| 1162 const base::FilePath& blob_path, | 1152 const base::FilePath& blob_path, |
| 1163 net::URLRequestContext* request_context, | 1153 net::URLRequestContext* request_context, |
| 1164 std::unique_ptr<LevelDBDatabase> db, | 1154 std::unique_ptr<LevelDBDatabase> db, |
| 1165 std::unique_ptr<LevelDBComparator> comparator, | 1155 std::unique_ptr<LevelDBComparator> comparator, |
| 1166 base::SequencedTaskRunner* task_runner, | 1156 base::SequencedTaskRunner* task_runner, |
| 1167 leveldb::Status* status) { | 1157 leveldb::Status* status) { |
| 1168 // TODO(jsbell): Handle comparator name changes. | 1158 // TODO(jsbell): Handle comparator name changes. |
| 1169 scoped_refptr<IndexedDBBackingStore> backing_store(new IndexedDBBackingStore( | 1159 scoped_refptr<IndexedDBBackingStore> backing_store(new IndexedDBBackingStore( |
| 1170 indexed_db_factory, origin_url, blob_path, request_context, std::move(db), | 1160 indexed_db_factory, origin, blob_path, request_context, std::move(db), |
| 1171 std::move(comparator), task_runner)); | 1161 std::move(comparator), task_runner)); |
| 1172 *status = backing_store->SetUpMetadata(); | 1162 *status = backing_store->SetUpMetadata(); |
| 1173 if (!status->ok()) | 1163 if (!status->ok()) |
| 1174 return scoped_refptr<IndexedDBBackingStore>(); | 1164 return scoped_refptr<IndexedDBBackingStore>(); |
| 1175 | 1165 |
| 1176 return backing_store; | 1166 return backing_store; |
| 1177 } | 1167 } |
| 1178 | 1168 |
| 1179 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { | 1169 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { |
| 1180 if (!child_process_ids_granted_.count(child_process_id)) { | 1170 if (!child_process_ids_granted_.count(child_process_id)) { |
| (...skipping 3292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4473 | 4463 |
| 4474 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 4464 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 4475 const WriteDescriptor& other) = default; | 4465 const WriteDescriptor& other) = default; |
| 4476 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = | 4466 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = |
| 4477 default; | 4467 default; |
| 4478 IndexedDBBackingStore::Transaction::WriteDescriptor& | 4468 IndexedDBBackingStore::Transaction::WriteDescriptor& |
| 4479 IndexedDBBackingStore::Transaction::WriteDescriptor:: | 4469 IndexedDBBackingStore::Transaction::WriteDescriptor:: |
| 4480 operator=(const WriteDescriptor& other) = default; | 4470 operator=(const WriteDescriptor& other) = default; |
| 4481 | 4471 |
| 4482 } // namespace content | 4472 } // namespace content |
| OLD | NEW |