Check IDB quota usage through QuotaManager
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2019 21:47:13 +0000 (21:47 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2019 21:47:13 +0000 (21:47 +0000)
commite1449cdb08d57f58755ad5caa2165b8d7062af30
treeb2971e4c54f74d7e0a9d8ff6dbeb56ffa9ed36bd
parent368f333da895537da3238ad3d6e89cc248e0348e
Check IDB quota usage through QuotaManager
https://bugs.webkit.org/show_bug.cgi?id=195302

Reviewed by Chris Dumez.

Source/WebCore:

For every write operation, compute an estimate size and check for quota before proceeding.
When proceeding, store the estimate size in a map.
If size of the database is to be computed when the task is not done,
the estimate size will be added to the current size of the databases.
At the end of the task, the estimate size is removed from the map,
and the databases size is refreshed.

This patch implements size estimation for write tasks.
Put/add operations might overestimate the size
when an old value will be replaced by a new value.
In that case, we do not substract the old value size since we do not know it.

This patch implements database opening by adding a fixed small cost,
as we do not know whether the database is new or not.

For the first IDB request, we have not computed the size of the database.
To do so, we need to go to a background thread and do that file size computation.
For that purpose, we add support for being-initialized quota user.
Quota manager is calling whenInitialized on its quota user and will
delay any quota check requests until its quota user is answering this callback.

For in process IDB, use the default storage quota per origin and do not increase it.
Future work should move it to NetworkProcess and implement some quota checking.

Cache API and IDB quota management are not yet fully unified.
If IDB is used on start-up, we should check for Cache API storage size.
Conversely, on Cache API first wite task, even if IDB is not being used,
we should compute the size of the IDB data for the given origin.

Test: http/tests/IndexedDB/storage-limit.https.html

* Modules/indexeddb/server/IDBBackingStore.h:
* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::create):
(WebCore::IDBServer::IDBServer::IDBServer):
(WebCore::IDBServer::m_quotaManagerGetter):
(WebCore::IDBServer::IDBServer::QuotaUser::QuotaUser):
(WebCore::IDBServer::IDBServer::QuotaUser::~QuotaUser):
(WebCore::IDBServer::IDBServer::QuotaUser::clearSpaceUsed):
(WebCore::IDBServer::IDBServer::QuotaUser::whenInitialized):
(WebCore::IDBServer::IDBServer::QuotaUser::initializeSpaceUsed):
(WebCore::IDBServer::IDBServer::quotaUser):
(WebCore::IDBServer::IDBServer::startComputingSpaceUsedForOrigin):
(WebCore::IDBServer::IDBServer::computeSpaceUsedForOrigin):
(WebCore::IDBServer::IDBServer::finishComputingSpaceUsedForOrigin):
(WebCore::IDBServer::IDBServer::requestSpace):
(WebCore::IDBServer::IDBServer::clearSpaceUsed):
(WebCore::IDBServer::IDBServer::setSpaceUsed):
(WebCore::IDBServer::IDBServer::increasePotentialSpaceUsed):
(WebCore::IDBServer::IDBServer::decreasePotentialSpaceUsed):
* Modules/indexeddb/server/IDBServer.h:
(WebCore::IDBServer::IDBServer::create):
* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::databasesSizeForOrigin const):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:
* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForFolder):
(WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForOrigin const):
(WebCore::IDBServer::SQLiteIDBBackingStore::maximumSize const):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::estimateSize):
(WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase):
(WebCore::IDBServer::quotaErrorMessageName):
(WebCore::IDBServer::UniqueIDBDatabase::requestSpace):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation):
(WebCore::IDBServer::UniqueIDBDatabase::storeCallbackOrFireError):
(WebCore::IDBServer::UniqueIDBDatabase::createObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::createObjectStoreAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::renameObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::createIndex):
(WebCore::IDBServer::UniqueIDBDatabase::createIndexAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::renameIndex):
(WebCore::IDBServer::UniqueIDBDatabase::renameIndexAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabase::putOrAddAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::postDatabaseTaskReply):
(WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete):
(WebCore::IDBServer::UniqueIDBDatabase::updateSpaceUsedIfNeeded):
(WebCore::IDBServer::UniqueIDBDatabase::performErrorCallback):
(WebCore::IDBServer::UniqueIDBDatabase::performKeyDataCallback):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
(WebCore::IDBServer::UniqueIDBDatabase::server):
* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::create):
(WebCore::InProcessIDBServer::quotaManager):
(WebCore::storageQuotaManagerGetter):
(WebCore::InProcessIDBServer::InProcessIDBServer):
* Modules/indexeddb/shared/InProcessIDBServer.h:
* loader/EmptyClients.cpp:
* storage/StorageQuotaManager.cpp:
(WebCore::StorageQuotaManager::addUser):
(WebCore::StorageQuotaManager::requestSpace):
* storage/StorageQuotaManager.h:
(WebCore::StorageQuotaManager::defaultQuota):
(WebCore::StorageQuotaManager::removeUser):
* storage/StorageQuotaUser.h:
(WebCore::StorageQuotaUser::whenInitialized):

Source/WebKit:

Set the quota manager getter for IDBServer at creation time.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::createIDBServer):
(WebKit::NetworkProcess::idbServer):
* NetworkProcess/NetworkProcess.h:
* WebProcess/Databases/WebDatabaseProvider.cpp:
(WebKit::WebDatabaseProvider::idbConnectionToServerForSession):

Source/WebKitLegacy:

* Storage/WebDatabaseProvider.cpp:
(WebDatabaseProvider::idbConnectionToServerForSession):

LayoutTests:

Update IDB quota test according quota limit of 400ko.
Update WK1 test expectations to skip quota check tests.

* http/tests/IndexedDB/resources/shared.js: Added.
* http/tests/IndexedDB/resources/storage-limit.js: Added.
* http/tests/IndexedDB/storage-limit.https-expected.txt: Added.
* http/tests/IndexedDB/storage-limit.https.html: Added.
* platform/mac-wk1/TestExpectations:
* platform/win/TestExpectations:
* storage/indexeddb/resources/storage-limit.js:
* storage/indexeddb/storage-limit-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242911 268f45cc-cd09-0410-ab3c-d52691b4dbfc
31 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/IndexedDB/resources/shared.js [new file with mode: 0644]
LayoutTests/http/tests/IndexedDB/resources/storage-limit.js [new file with mode: 0644]
LayoutTests/http/tests/IndexedDB/storage-limit.https-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/IndexedDB/storage-limit.https.html [new file with mode: 0644]
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/win/TestExpectations
LayoutTests/storage/indexeddb/resources/storage-limit.js
LayoutTests/storage/indexeddb/storage-limit-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/IDBServer.h
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h
Source/WebCore/loader/EmptyClients.cpp
Source/WebCore/storage/StorageQuotaManager.cpp
Source/WebCore/storage/StorageQuotaManager.h
Source/WebCore/storage/StorageQuotaUser.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/WebProcess/Databases/WebDatabaseProvider.cpp
Source/WebKitLegacy/ChangeLog
Source/WebKitLegacy/Storage/WebDatabaseProvider.cpp