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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <map> 12 #include <memory> 13 #include <set> 14 #include <string> 15 #include <utility> 16 #include <vector> 17 18 #include "base/files/file_path.h" 19 #include "base/gtest_prod_util.h" 20 #include "base/macros.h" 21 #include "base/memory/ref_counted.h" 22 #include "base/memory/weak_ptr.h" 23 #include "base/sequence_checker.h" 24 #include "base/strings/string_piece.h" 25 #include "base/time/time.h" 26 #include "base/timer/timer.h" 27 #include "components/services/storage/indexed_db/scopes/scope_lock.h" 28 #include "components/services/storage/public/mojom/native_file_system_context.mojom-forward.h" 29 #include "content/browser/indexed_db/indexed_db.h" 30 #include "content/browser/indexed_db/indexed_db_external_object.h" 31 #include "content/browser/indexed_db/indexed_db_external_object_storage.h" 32 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 33 #include "content/common/content_export.h" 34 #include "storage/browser/blob/blob_data_handle.h" 35 #include "storage/browser/blob/mojom/blob_storage_context.mojom-forward.h" 36 #include "storage/common/file_system/file_system_mount_option.h" 37 #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" 38 #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" 39 #include "third_party/leveldatabase/src/include/leveldb/status.h" 40 #include "url/gurl.h" 41 #include "url/origin.h" 42 43 namespace base { 44 class SequencedTaskRunner; 45 } 46 47 namespace blink { 48 class IndexedDBKeyRange; 49 struct IndexedDBDatabaseMetadata; 50 } // namespace blink 51 52 namespace content { 53 class IndexedDBActiveBlobRegistry; 54 class LevelDBWriteBatch; 55 class TransactionalLevelDBDatabase; 56 class TransactionalLevelDBFactory; 57 class TransactionalLevelDBIterator; 58 class TransactionalLevelDBTransaction; 59 struct IndexedDBValue; 60 61 namespace indexed_db_backing_store_unittest { 62 class IndexedDBBackingStoreTest; 63 FORWARD_DECLARE_TEST(IndexedDBBackingStoreTest, ReadCorruptionInfo); 64 } // namespace indexed_db_backing_store_unittest 65 66 enum class V2SchemaCorruptionStatus { 67 kUnknown = 0, // Due to other unknown/critical errors. 68 kNo = 1, 69 kYes = 2, 70 }; 71 72 // All interaction with this class should be done on the task runner given to 73 // Open. 74 class CONTENT_EXPORT IndexedDBBackingStore { 75 public: 76 class CONTENT_EXPORT RecordIdentifier { 77 public: 78 RecordIdentifier(const std::string& primary_key, int64_t version); 79 RecordIdentifier(); 80 ~RecordIdentifier(); 81 primary_key()82 const std::string& primary_key() const { return primary_key_; } version()83 int64_t version() const { return version_; } Reset(const std::string & primary_key,int64_t version)84 void Reset(const std::string& primary_key, int64_t version) { 85 primary_key_ = primary_key; 86 version_ = version; 87 } 88 89 private: 90 // TODO(jsbell): Make it more clear that this is the *encoded* version of 91 // the key. 92 std::string primary_key_; 93 int64_t version_; 94 DISALLOW_COPY_AND_ASSIGN(RecordIdentifier); 95 }; 96 97 class CONTENT_EXPORT Transaction { 98 public: 99 struct BlobWriteState { 100 BlobWriteState(); 101 explicit BlobWriteState(int calls_left, BlobWriteCallback on_complete); 102 ~BlobWriteState(); 103 int calls_left = 0; 104 BlobWriteCallback on_complete; 105 }; 106 107 Transaction(base::WeakPtr<IndexedDBBackingStore> backing_store, 108 blink::mojom::IDBTransactionDurability durability, 109 blink::mojom::IDBTransactionMode mode); 110 virtual ~Transaction(); 111 112 virtual void Begin(std::vector<ScopeLock> locks); 113 114 // CommitPhaseOne determines what blobs (if any) need to be written to disk 115 // and updates the primary blob journal, and kicks off the async writing 116 // of the blob files. In case of crash/rollback, the journal indicates what 117 // files should be cleaned up. 118 // The callback will be called eventually on success or failure, or 119 // immediately if phase one is complete due to lack of any blobs to write. 120 virtual leveldb::Status CommitPhaseOne(BlobWriteCallback callback); 121 122 // CommitPhaseTwo is called once the blob files (if any) have been written 123 // to disk, and commits the actual transaction to the backing store, 124 // including blob journal updates, then deletes any blob files deleted 125 // by the transaction and not referenced by running scripts. 126 virtual leveldb::Status CommitPhaseTwo(); 127 128 // When LevelDBScopes is in single-sequence mode then this will return the 129 // result of the rollback. Otherwise leveldb::Status::OK() is returned. 130 virtual leveldb::Status Rollback(); 131 132 void Reset(); 133 leveldb::Status PutExternalObjectsIfNeeded( 134 int64_t database_id, 135 const std::string& object_store_data_key, 136 std::vector<IndexedDBExternalObject>*); 137 void PutExternalObjects(int64_t database_id, 138 const std::string& object_store_data_key, 139 std::vector<IndexedDBExternalObject>*); 140 transaction()141 TransactionalLevelDBTransaction* transaction() { 142 return transaction_.get(); 143 } 144 145 virtual uint64_t GetTransactionSize(); 146 147 leveldb::Status GetExternalObjectsForRecord( 148 int64_t database_id, 149 const std::string& object_store_data_key, 150 IndexedDBValue* value); 151 152 base::WeakPtr<Transaction> AsWeakPtr(); 153 mode()154 blink::mojom::IDBTransactionMode mode() const { return mode_; } 155 backing_store()156 IndexedDBBackingStore* backing_store() { return backing_store_.get(); } 157 158 private: 159 // Called by CommitPhaseOne: Identifies the blob entries to write and adds 160 // them to the recovery blob journal directly (i.e. not as part of the 161 // transaction). Populates blobs_to_write_. 162 leveldb::Status HandleBlobPreTransaction(); 163 164 // Called by CommitPhaseOne: Populates blob_files_to_remove_ by 165 // determining which blobs are deleted as part of the transaction, and 166 // adds blob entry cleanup operations to the transaction. Returns true on 167 // success, false on failure. 168 bool CollectBlobFilesToRemove(); 169 170 // Called by CommitPhaseOne: Kicks off the asynchronous writes of blobs 171 // identified in HandleBlobPreTransaction. The callback will be called 172 // eventually on success or failure. 173 leveldb::Status WriteNewBlobs(BlobWriteCallback callback); 174 175 // Called by CommitPhaseTwo: Partition blob references in blobs_to_remove_ 176 // into live (active references) and dead (no references). 177 void PartitionBlobsToRemove(BlobJournalType* dead_blobs, 178 BlobJournalType* live_blobs) const; 179 180 SEQUENCE_CHECKER(idb_sequence_checker_); 181 182 // This does NOT mean that this class can outlive the IndexedDBBackingStore. 183 // This is only to protect against security issues before this class is 184 // refactored away and this isn't necessary. 185 // https://crbug.com/1012918 186 base::WeakPtr<IndexedDBBackingStore> backing_store_; 187 TransactionalLevelDBFactory* const transactional_leveldb_factory_; 188 scoped_refptr<TransactionalLevelDBTransaction> transaction_; 189 std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>> 190 external_object_change_map_; 191 std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>> 192 incognito_external_object_map_; 193 int64_t database_id_; 194 195 // List of blob files being newly written as part of this transaction. 196 // These will be added to the recovery blob journal prior to commit, then 197 // removed after a successful commit. 198 BlobJournalType blobs_to_write_; 199 200 // List of blob files being deleted as part of this transaction. These will 201 // be added to either the recovery or live blob journal as appropriate 202 // following a successful commit. 203 BlobJournalType blobs_to_remove_; 204 205 // Populated when blobs are being written to disk. This is saved here (as 206 // opposed to being ephemeral and owned by the WriteBlobToFile callbacks) 207 // because the transaction needs to be able to cancel this operation in 208 // Rollback(). 209 base::Optional<BlobWriteState> write_state_; 210 211 // Set to true between CommitPhaseOne and CommitPhaseTwo/Rollback, to 212 // indicate that the committing_transaction_count_ on the backing store 213 // has been bumped, and journal cleaning should be deferred. 214 bool committing_; 215 216 // This flag is passed to LevelDBScopes as |sync_on_commit|, converted 217 // via ShouldSyncOnCommit. 218 blink::mojom::IDBTransactionDurability durability_; 219 const blink::mojom::IDBTransactionMode mode_; 220 221 base::WeakPtrFactory<Transaction> ptr_factory_{this}; 222 223 DISALLOW_COPY_AND_ASSIGN(Transaction); 224 }; 225 226 class Cursor { 227 public: 228 enum IteratorState { READY = 0, SEEK }; 229 230 virtual ~Cursor(); 231 232 struct CursorOptions { 233 CursorOptions(); 234 CursorOptions(const CursorOptions& other); 235 ~CursorOptions(); 236 int64_t database_id; 237 int64_t object_store_id; 238 int64_t index_id; 239 std::string low_key; 240 bool low_open; 241 std::string high_key; 242 bool high_open; 243 bool forward; 244 bool unique; 245 blink::mojom::IDBTransactionMode mode = 246 blink::mojom::IDBTransactionMode::ReadWrite; 247 }; 248 key()249 const blink::IndexedDBKey& key() const { return *current_key_; } Continue(leveldb::Status * s)250 bool Continue(leveldb::Status* s) { 251 return Continue(nullptr, nullptr, SEEK, s); 252 } Continue(const blink::IndexedDBKey * key,IteratorState state,leveldb::Status * s)253 bool Continue(const blink::IndexedDBKey* key, 254 IteratorState state, 255 leveldb::Status* s) { 256 return Continue(key, nullptr, state, s); 257 } 258 bool Continue(const blink::IndexedDBKey* key, 259 const blink::IndexedDBKey* primary_key, 260 IteratorState state, 261 leveldb::Status*); 262 bool Advance(uint32_t count, leveldb::Status*); 263 bool FirstSeek(leveldb::Status*); 264 265 virtual std::unique_ptr<Cursor> Clone() const = 0; 266 virtual const blink::IndexedDBKey& primary_key() const; 267 virtual IndexedDBValue* value() = 0; 268 virtual const RecordIdentifier& record_identifier() const; 269 virtual bool LoadCurrentRow(leveldb::Status* s) = 0; 270 271 protected: 272 Cursor(base::WeakPtr<Transaction> transaction, 273 int64_t database_id, 274 const CursorOptions& cursor_options); 275 explicit Cursor(const IndexedDBBackingStore::Cursor* other); 276 277 virtual std::string EncodeKey(const blink::IndexedDBKey& key) = 0; 278 virtual std::string EncodeKey(const blink::IndexedDBKey& key, 279 const blink::IndexedDBKey& primary_key) = 0; 280 281 bool IsPastBounds() const; 282 bool HaveEnteredRange() const; 283 284 SEQUENCE_CHECKER(idb_sequence_checker_); 285 286 // This does NOT mean that this class can outlive the Transaction. 287 // This is only to protect against security issues before this class is 288 // refactored away and this isn't necessary. 289 // https://crbug.com/1012918 290 base::WeakPtr<Transaction> transaction_; 291 int64_t database_id_; 292 const CursorOptions cursor_options_; 293 std::unique_ptr<TransactionalLevelDBIterator> iterator_; 294 std::unique_ptr<blink::IndexedDBKey> current_key_; 295 IndexedDBBackingStore::RecordIdentifier record_identifier_; 296 297 private: 298 enum class ContinueResult { LEVELDB_ERROR, DONE, OUT_OF_BOUNDS }; 299 300 // For cursors with direction Next or NextNoDuplicate. 301 ContinueResult ContinueNext(const blink::IndexedDBKey* key, 302 const blink::IndexedDBKey* primary_key, 303 IteratorState state, 304 leveldb::Status*); 305 // For cursors with direction Prev or PrevNoDuplicate. The PrevNoDuplicate 306 // case has additional complexity of not being symmetric with 307 // NextNoDuplicate. 308 ContinueResult ContinuePrevious(const blink::IndexedDBKey* key, 309 const blink::IndexedDBKey* primary_key, 310 IteratorState state, 311 leveldb::Status*); 312 313 base::WeakPtrFactory<Cursor> weak_factory_{this}; 314 315 DISALLOW_COPY_AND_ASSIGN(Cursor); 316 }; 317 318 using BlobFilesCleanedCallback = base::RepeatingClosure; 319 using ReportOutstandingBlobsCallback = 320 base::RepeatingCallback<void(/*outstanding_blobs=*/bool)>; 321 322 enum class Mode { kInMemory, kOnDisk }; 323 324 // Schedule an immediate blob journal cleanup if we reach this number of 325 // requests. 326 static constexpr const int kMaxJournalCleanRequests = 50; 327 // Wait for a maximum of 5 seconds from the first call to the timer since the 328 // last journal cleaning. 329 static constexpr const base::TimeDelta kMaxJournalCleaningWindowTime = 330 base::TimeDelta::FromSeconds(5); 331 // Default to a 2 second timer delay before we clean up blobs. 332 static constexpr const base::TimeDelta kInitialJournalCleaningWindowTime = 333 base::TimeDelta::FromSeconds(2); 334 335 IndexedDBBackingStore( 336 Mode backing_store_mode, 337 TransactionalLevelDBFactory* transactional_leveldb_factory, 338 const url::Origin& origin, 339 const base::FilePath& blob_path, 340 std::unique_ptr<TransactionalLevelDBDatabase> db, 341 storage::mojom::BlobStorageContext* blob_storage_context, 342 storage::mojom::NativeFileSystemContext* native_file_system_context, 343 BlobFilesCleanedCallback blob_files_cleaned, 344 ReportOutstandingBlobsCallback report_outstanding_blobs, 345 scoped_refptr<base::SequencedTaskRunner> idb_task_runner, 346 scoped_refptr<base::SequencedTaskRunner> io_task_runner); 347 virtual ~IndexedDBBackingStore(); 348 349 // Initializes the backing store. This must be called before doing any 350 // operations or method calls on this object. 351 leveldb::Status Initialize(bool clean_active_blob_journal); 352 origin()353 const url::Origin& origin() const { return origin_; } idb_task_runner()354 base::SequencedTaskRunner* idb_task_runner() const { 355 return idb_task_runner_.get(); 356 } active_blob_registry()357 IndexedDBActiveBlobRegistry* active_blob_registry() { 358 return active_blob_registry_.get(); 359 } 360 361 // Compact is public for testing. 362 virtual void Compact(); 363 virtual leveldb::Status DeleteDatabase( 364 const base::string16& name, 365 TransactionalLevelDBTransaction* transaction); 366 367 static bool RecordCorruptionInfo(const base::FilePath& path_base, 368 const url::Origin& origin, 369 const std::string& message); 370 371 virtual leveldb::Status GetRecord( 372 IndexedDBBackingStore::Transaction* transaction, 373 int64_t database_id, 374 int64_t object_store_id, 375 const blink::IndexedDBKey& key, 376 IndexedDBValue* record) WARN_UNUSED_RESULT; 377 virtual leveldb::Status PutRecord( 378 IndexedDBBackingStore::Transaction* transaction, 379 int64_t database_id, 380 int64_t object_store_id, 381 const blink::IndexedDBKey& key, 382 IndexedDBValue* value, 383 RecordIdentifier* record) WARN_UNUSED_RESULT; 384 virtual leveldb::Status ClearObjectStore( 385 IndexedDBBackingStore::Transaction* transaction, 386 int64_t database_id, 387 int64_t object_store_id) WARN_UNUSED_RESULT; 388 virtual leveldb::Status DeleteRecord( 389 IndexedDBBackingStore::Transaction* transaction, 390 int64_t database_id, 391 int64_t object_store_id, 392 const RecordIdentifier& record) WARN_UNUSED_RESULT; 393 virtual leveldb::Status DeleteRange( 394 IndexedDBBackingStore::Transaction* transaction, 395 int64_t database_id, 396 int64_t object_store_id, 397 const blink::IndexedDBKeyRange&) WARN_UNUSED_RESULT; 398 virtual leveldb::Status GetKeyGeneratorCurrentNumber( 399 IndexedDBBackingStore::Transaction* transaction, 400 int64_t database_id, 401 int64_t object_store_id, 402 int64_t* current_number) WARN_UNUSED_RESULT; 403 virtual leveldb::Status MaybeUpdateKeyGeneratorCurrentNumber( 404 IndexedDBBackingStore::Transaction* transaction, 405 int64_t database_id, 406 int64_t object_store_id, 407 int64_t new_state, 408 bool check_current) WARN_UNUSED_RESULT; 409 virtual leveldb::Status KeyExistsInObjectStore( 410 IndexedDBBackingStore::Transaction* transaction, 411 int64_t database_id, 412 int64_t object_store_id, 413 const blink::IndexedDBKey& key, 414 RecordIdentifier* found_record_identifier, 415 bool* found) WARN_UNUSED_RESULT; 416 417 virtual leveldb::Status ClearIndex( 418 IndexedDBBackingStore::Transaction* transaction, 419 int64_t database_id, 420 int64_t object_store_id, 421 int64_t index_id) WARN_UNUSED_RESULT; 422 virtual leveldb::Status PutIndexDataForRecord( 423 IndexedDBBackingStore::Transaction* transaction, 424 int64_t database_id, 425 int64_t object_store_id, 426 int64_t index_id, 427 const blink::IndexedDBKey& key, 428 const RecordIdentifier& record) WARN_UNUSED_RESULT; 429 virtual leveldb::Status GetPrimaryKeyViaIndex( 430 IndexedDBBackingStore::Transaction* transaction, 431 int64_t database_id, 432 int64_t object_store_id, 433 int64_t index_id, 434 const blink::IndexedDBKey& key, 435 std::unique_ptr<blink::IndexedDBKey>* primary_key) WARN_UNUSED_RESULT; 436 virtual leveldb::Status KeyExistsInIndex( 437 IndexedDBBackingStore::Transaction* transaction, 438 int64_t database_id, 439 int64_t object_store_id, 440 int64_t index_id, 441 const blink::IndexedDBKey& key, 442 std::unique_ptr<blink::IndexedDBKey>* found_primary_key, 443 bool* exists) WARN_UNUSED_RESULT; 444 445 // Public for IndexedDBActiveBlobRegistry::MarkBlobInactive. 446 virtual void ReportBlobUnused(int64_t database_id, int64_t blob_number); 447 448 base::FilePath GetBlobFileName(int64_t database_id, int64_t key) const; 449 450 virtual std::unique_ptr<Cursor> OpenObjectStoreKeyCursor( 451 IndexedDBBackingStore::Transaction* transaction, 452 int64_t database_id, 453 int64_t object_store_id, 454 const blink::IndexedDBKeyRange& key_range, 455 blink::mojom::IDBCursorDirection, 456 leveldb::Status*); 457 virtual std::unique_ptr<Cursor> OpenObjectStoreCursor( 458 IndexedDBBackingStore::Transaction* transaction, 459 int64_t database_id, 460 int64_t object_store_id, 461 const blink::IndexedDBKeyRange& key_range, 462 blink::mojom::IDBCursorDirection, 463 leveldb::Status*); 464 virtual std::unique_ptr<Cursor> OpenIndexKeyCursor( 465 IndexedDBBackingStore::Transaction* transaction, 466 int64_t database_id, 467 int64_t object_store_id, 468 int64_t index_id, 469 const blink::IndexedDBKeyRange& key_range, 470 blink::mojom::IDBCursorDirection, 471 leveldb::Status*); 472 virtual std::unique_ptr<Cursor> OpenIndexCursor( 473 IndexedDBBackingStore::Transaction* transaction, 474 int64_t database_id, 475 int64_t object_store_id, 476 int64_t index_id, 477 const blink::IndexedDBKeyRange& key_range, 478 blink::mojom::IDBCursorDirection, 479 leveldb::Status*); 480 db()481 TransactionalLevelDBDatabase* db() { return db_.get(); } 482 origin_identifier()483 const std::string& origin_identifier() { return origin_identifier_; } 484 485 // Returns true if a blob cleanup job is pending on journal_cleaning_timer_. 486 bool IsBlobCleanupPending(); 487 488 int64_t GetInMemoryBlobSize() const; 489 490 #if DCHECK_IS_ON() NumBlobFilesDeletedForTesting()491 int NumBlobFilesDeletedForTesting() { return num_blob_files_deleted_; } NumAggregatedJournalCleaningRequestsForTesting()492 int NumAggregatedJournalCleaningRequestsForTesting() const { 493 return num_aggregated_journal_cleaning_requests_; 494 } 495 #endif 496 497 // Stops the journal_cleaning_timer_ and runs its pending task. 498 void ForceRunBlobCleanup(); 499 500 // HasV2SchemaCorruption() returns whether the backing store is v2 and 501 // has blob references. 502 V2SchemaCorruptionStatus HasV2SchemaCorruption(); 503 504 // RevertSchemaToV2() updates a backing store state on disk to override its 505 // metadata version to 2. This allows triggering https://crbug.com/829141 on 506 // an otherwise healthy backing store. 507 leveldb::Status RevertSchemaToV2(); 508 is_incognito()509 bool is_incognito() const { return backing_store_mode_ == Mode::kInMemory; } 510 511 virtual std::unique_ptr<Transaction> CreateTransaction( 512 blink::mojom::IDBTransactionDurability durability, 513 blink::mojom::IDBTransactionMode mode); 514 AsWeakPtr()515 base::WeakPtr<IndexedDBBackingStore> AsWeakPtr() { 516 return weak_factory_.GetWeakPtr(); 517 } 518 519 static bool ShouldSyncOnCommit( 520 blink::mojom::IDBTransactionDurability durability); 521 522 protected: 523 friend class IndexedDBOriginState; 524 525 leveldb::Status AnyDatabaseContainsBlobs( 526 TransactionalLevelDBDatabase* database, 527 bool* blobs_exist); 528 529 leveldb::Status UpgradeBlobEntriesToV4( 530 TransactionalLevelDBDatabase* database, 531 LevelDBWriteBatch* write_batch, 532 std::vector<base::FilePath>* empty_blobs_to_delete); 533 534 // TODO(dmurph): Move this completely to IndexedDBMetadataFactory. 535 leveldb::Status GetCompleteMetadata( 536 std::vector<blink::IndexedDBDatabaseMetadata>* output); 537 538 // Remove the referenced file on disk. 539 virtual bool RemoveBlobFile(int64_t database_id, int64_t key) const; 540 541 // Schedule a call to CleanRecoveryJournalIgnoreReturn() via 542 // an owned timer. If this object is destroyed, the timer 543 // will automatically be cancelled. 544 virtual void StartJournalCleaningTimer(); 545 546 // Attempt to clean the recovery journal. This will remove 547 // any referenced files and delete the journal entry. If any 548 // transaction is currently committing this will be deferred 549 // via StartJournalCleaningTimer(). 550 void CleanRecoveryJournalIgnoreReturn(); 551 552 private: 553 leveldb::Status FindKeyInIndex( 554 IndexedDBBackingStore::Transaction* transaction, 555 int64_t database_id, 556 int64_t object_store_id, 557 int64_t index_id, 558 const blink::IndexedDBKey& key, 559 std::string* found_encoded_primary_key, 560 bool* found); 561 562 // Remove the blob directory for the specified database and all contained 563 // blob files. 564 bool RemoveBlobDirectory(int64_t database_id) const; 565 566 // Synchronously read the key-specified blob journal entry from the backing 567 // store, delete all referenced blob files, and erase the journal entry. 568 // This must not be used while temporary entries are present e.g. during 569 // a two-stage transaction commit with blobs. 570 leveldb::Status CleanUpBlobJournal(const std::string& level_db_key) const; 571 572 // Synchronously delete the files and/or directories on disk referenced by 573 // the blob journal. 574 leveldb::Status CleanUpBlobJournalEntries( 575 const BlobJournalType& journal) const; 576 577 void WillCommitTransaction(); 578 // Can run a journal cleaning job if one is pending. 579 void DidCommitTransaction(); 580 581 SEQUENCE_CHECKER(idb_sequence_checker_); 582 583 Mode backing_store_mode_; 584 TransactionalLevelDBFactory* const transactional_leveldb_factory_; 585 const url::Origin origin_; 586 base::FilePath blob_path_; 587 588 // IndexedDB can store blobs and native file system handles. These mojo 589 // interfaces are used to make this possible by communicating with the 590 // relevant subsystems. 591 // Raw pointers are safe because the bindings are owned by 592 // IndexedDBContextImpl. 593 storage::mojom::BlobStorageContext* blob_storage_context_; 594 storage::mojom::NativeFileSystemContext* native_file_system_context_; 595 596 // The origin identifier is a key prefix unique to the origin used in the 597 // leveldb backing store to partition data by origin. It is a normalized 598 // version of the origin URL with a versioning suffix appended, e.g. 599 // "http_localhost_81@1" Since only one origin is stored per backing store 600 // this is redundant but necessary for backwards compatibility; the suffix 601 // provides for future flexibility. 602 const std::string origin_identifier_; 603 604 scoped_refptr<base::SequencedTaskRunner> idb_task_runner_; 605 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; 606 std::set<int> child_process_ids_granted_; 607 std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>> 608 incognito_external_object_map_; 609 610 bool execute_journal_cleaning_on_no_txns_ = false; 611 int num_aggregated_journal_cleaning_requests_ = 0; 612 base::OneShotTimer journal_cleaning_timer_; 613 base::TimeTicks journal_cleaning_timer_window_start_; 614 615 #if DCHECK_IS_ON() 616 mutable int num_blob_files_deleted_ = 0; 617 #endif 618 619 std::unique_ptr<TransactionalLevelDBDatabase> db_; 620 621 BlobFilesCleanedCallback blob_files_cleaned_; 622 623 // Whenever blobs are registered in active_blob_registry_, 624 // indexed_db_factory_ will hold a reference to this backing store. 625 std::unique_ptr<IndexedDBActiveBlobRegistry> active_blob_registry_; 626 627 // Incremented whenever a transaction starts committing, decremented when 628 // complete. While > 0, temporary journal entries may exist so out-of-band 629 // journal cleaning must be deferred. 630 size_t committing_transaction_count_ = 0; 631 632 #if DCHECK_IS_ON() 633 bool initialized_ = false; 634 #endif 635 base::WeakPtrFactory<IndexedDBBackingStore> weak_factory_{this}; 636 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStore); 637 }; 638 639 } // namespace content 640 641 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ 642