Bug 234925 - Manage IndexedDB storage by origin
Summary: Manage IndexedDB storage by origin
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Sihui Liu
URL:
Keywords: InRadar
Depends on: 235236
Blocks:
  Show dependency treegraph
 
Reported: 2022-01-06 09:43 PST by Sihui Liu
Modified: 2022-03-31 16:56 PDT (History)
13 users (show)

See Also:


Attachments
WIP (236.11 KB, patch)
2022-01-06 12:28 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (280.17 KB, patch)
2022-01-11 17:43 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (277.13 KB, patch)
2022-02-03 09:15 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (279.22 KB, patch)
2022-02-03 13:02 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (278.76 KB, patch)
2022-02-03 21:12 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (279.18 KB, patch)
2022-02-03 22:31 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (279.23 KB, patch)
2022-02-03 23:02 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (279.76 KB, patch)
2022-02-06 17:12 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (278.20 KB, patch)
2022-02-07 17:16 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (278.21 KB, patch)
2022-02-07 18:43 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (278.27 KB, patch)
2022-02-07 19:37 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (278.15 KB, patch)
2022-02-08 00:43 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch (278.19 KB, patch)
2022-02-08 09:04 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (278.36 KB, patch)
2022-02-08 11:00 PST, Sihui Liu
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (278.29 KB, patch)
2022-02-08 15:48 PST, Sihui Liu
no flags Details | Formatted Diff | Diff
Patch for landing (278.23 KB, patch)
2022-02-09 08:12 PST, Sihui Liu
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sihui Liu 2022-01-06 09:43:06 PST
...
Comment 1 Sihui Liu 2022-01-06 12:28:21 PST
Created attachment 448525 [details]
WIP
Comment 2 Sihui Liu 2022-01-11 17:43:28 PST
Created attachment 448895 [details]
Patch
Comment 3 Radar WebKit Bug Importer 2022-01-13 09:44:17 PST
<rdar://problem/87555014>
Comment 4 Sihui Liu 2022-02-03 09:15:26 PST
Created attachment 450778 [details]
Patch
Comment 5 Sihui Liu 2022-02-03 13:02:54 PST
Created attachment 450805 [details]
Patch
Comment 6 Sihui Liu 2022-02-03 21:12:52 PST
Created attachment 450863 [details]
Patch
Comment 7 Sihui Liu 2022-02-03 22:31:35 PST
Created attachment 450867 [details]
Patch
Comment 8 Sihui Liu 2022-02-03 23:02:38 PST
Created attachment 450868 [details]
Patch
Comment 9 Sihui Liu 2022-02-06 17:12:13 PST
Created attachment 451054 [details]
Patch
Comment 10 Chris Dumez 2022-02-07 09:05:23 PST
Comment on attachment 451054 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=451054&action=review

Only a partial review for now as I need to go to a meeting. Will resume later today unless someone else beats me to it.

> Source/WTF/wtf/FileSystem.cpp:663
> +String getSymbolicLinkTarget(const String& symbolicLinkPath)

Why can't you use the existing FileSystem::realPath() function which already resolves symlinks if present?

Also, no "get" prefix please. And we should add API test coverage (we already have plenty for the FileSytem API) if we do really need a new function here for some reason.

> Source/WTF/wtf/FileSystem.cpp:666
> +    if (!std::filesystem::is_symlink(fileSystemPath))

You need to pass an 'ec' parameter to is_symlink() or the function call may throw.

> Source/WTF/wtf/FileSystem.cpp:669
> +    return fromStdFileSystemPath(std::filesystem::read_symlink(fileSystemPath));

You need to pass an 'ec' parameter to std::filesystem::read_symlink() or it may throw exceptions.

> Source/WebCore/Modules/indexeddb/server/IDBServer.cpp:742
> +void IDBServer::requestSpace(const ClientOrigin& origin, uint64_t taskSize, CompletionHandler<void(bool)>&& completionHandler) WTF_IGNORES_THREAD_SAFETY_ANALYSIS

Since it is synchronous, it is unclear to me why adding a completion handler is better.

> Source/WebCore/Modules/indexeddb/server/IDBServer.h:91
> +    void registerConnection(UniqueIDBDatabaseConnection&) final;

We usually have a `// UniqueIDBDatabaseManager.` comment before the flow of functions to indicate that those are overrides for UniqueIDBDatabaseManager.

> Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h:43
> +    WEBCORE_EXPORT MemoryIDBBackingStore(const IDBDatabaseIdentifier&);

Can we please mark this as explicit now that it has a single parameter?

> Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:920
>      filename.replace('.', "%2E");

replaceWithLiteral() would probably be more efficient here.

> Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:928
> +        return { };

This returns a null String, not an empty string, did you mean to return emptyString() here?

Otherwise, it doesn't match the encodeDatabaseName() function, which is confusing.

> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp:840
> +static int myCount = 0;

Unused? Please remove.

> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp:893
> +        indexKeys = generateIndexKeyMapForValue(globalObject, objectStoreInfo, key, value);

What's the type of indexKeys? Don't we need to crossThreadCopy() it?

> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h:84
> +    using SpaceCheckResult = std::optional<bool>;

Personally, I find std::optional<bool> a little confusing, especially with a typedef. I find it makes the code using it a little opaque. 
It might look better with an enum class that has 3 values?
Comment 11 Chris Dumez 2022-02-07 11:52:14 PST
Comment on attachment 451054 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=451054&action=review

r=me with fixes.

> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:51
> +        m_manager = WeakPtr { *manager };

WeakPtr { } is not needed, you can just assign `*manager`.

> Source/WebKit/NetworkProcess/NetworkProcess.cpp:2212
> +    if (auto* storageManager = session->storageManager())

You are failing to call the completion handler in the else case.

> Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp:248
> +    if (auto* storageManager = session->storageManager())

Callback is not getting called in the else case.

> Source/WebKit/NetworkProcess/storage/IDBStorageManager.cpp:45
> +    for (auto name : fileNames) {

auto&, assuming this is a String.

> Source/WebKit/NetworkProcess/storage/IDBStorageManager.cpp:244
> +    if (identifier.isTransient())

Probably can merge with the previous if condition given that the return is the same.

> Source/WebKit/NetworkProcess/storage/IDBStorageManager.h:53
> +    ~IDBStorageManager() final { }

Seem we shouldn't need this?

> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:47
> +    WebCore::IDBServer::IDBConnectionToClient& getOrCreateConnectionToClient(IPC::Connection::UniqueID, WebCore::IDBConnectionIdentifier);

Maybe ensureConnectionToClient() would look better?

> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:51
> +    WebCore::IDBServer::UniqueIDBDatabaseConnection* getConnection(uint64_t identifier);

No "get" prefixes in getters.

> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:54
> +    WebCore::IDBServer::UniqueIDBDatabaseTransaction* getTransaction(WebCore::IDBResourceIdentifier);

ditto.

> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:59
> +    auto clearIsHandlingRequests = makeScopeExit([&] {

I think this is a clear use case for SetForScope?

SetForScope<bool> isHandlingRequests(m_isHandlingRequests, true);

> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:83
> +    bool shouldUpdateQuotaBasedonUsage = !m_usage;

OnUsage (case issue)

> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:125
> +    m_quotaCountdown = 0;

Maybe this could call resetQuotaForTesting()?

> Source/WebKit/NetworkProcess/storage/QuotaManager.h:41
> +    enum class Decision { Deny, Grant };

enum class Decision : bool { Deny, Grant };

> Tools/ChangeLog:17
> +2022-02-03  Sihui Liu  <sihui_liu@apple.com>

Double changelog issue.
Comment 12 Sihui Liu 2022-02-07 17:01:51 PST
Comment on attachment 451054 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=451054&action=review

>> Source/WTF/wtf/FileSystem.cpp:663
>> +String getSymbolicLinkTarget(const String& symbolicLinkPath)
> 
> Why can't you use the existing FileSystem::realPath() function which already resolves symlinks if present?
> 
> Also, no "get" prefix please. And we should add API test coverage (we already have plenty for the FileSytem API) if we do really need a new function here for some reason.

Didn't see that. I will use realPath instead.

>> Source/WTF/wtf/FileSystem.cpp:666
>> +    if (!std::filesystem::is_symlink(fileSystemPath))
> 
> You need to pass an 'ec' parameter to is_symlink() or the function call may throw.

Will remove this change.

>> Source/WTF/wtf/FileSystem.cpp:669
>> +    return fromStdFileSystemPath(std::filesystem::read_symlink(fileSystemPath));
> 
> You need to pass an 'ec' parameter to std::filesystem::read_symlink() or it may throw exceptions.

Will remove this change.

>> Source/WebCore/Modules/indexeddb/server/IDBServer.cpp:742
>> +void IDBServer::requestSpace(const ClientOrigin& origin, uint64_t taskSize, CompletionHandler<void(bool)>&& completionHandler) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
> 
> Since it is synchronous, it is unclear to me why adding a completion handler is better.

This is the virtual function in UniqueIDBDatabaseManager; IDBServer just implements the function in a synchronous way now.

>> Source/WebCore/Modules/indexeddb/server/IDBServer.h:91
>> +    void registerConnection(UniqueIDBDatabaseConnection&) final;
> 
> We usually have a `// UniqueIDBDatabaseManager.` comment before the flow of functions to indicate that those are overrides for UniqueIDBDatabaseManager.

Sure.

>> Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h:43
>> +    WEBCORE_EXPORT MemoryIDBBackingStore(const IDBDatabaseIdentifier&);
> 
> Can we please mark this as explicit now that it has a single parameter?

Sure.

>> Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:920
>>      filename.replace('.', "%2E");
> 
> replaceWithLiteral() would probably be more efficient here.

Sure.

>> Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:928
>> +        return { };
> 
> This returns a null String, not an empty string, did you mean to return emptyString() here?
> 
> Otherwise, it doesn't match the encodeDatabaseName() function, which is confusing.

Sure, will change to emptyString().

>> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp:840
>> +static int myCount = 0;
> 
> Unused? Please remove.

ouch.. will remove

>> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp:893
>> +        indexKeys = generateIndexKeyMapForValue(globalObject, objectStoreInfo, key, value);
> 
> What's the type of indexKeys? Don't we need to crossThreadCopy() it?

It's map of IDBKeyDatas. Will add crossThreadCopy().

>> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h:84
>> +    using SpaceCheckResult = std::optional<bool>;
> 
> Personally, I find std::optional<bool> a little confusing, especially with a typedef. I find it makes the code using it a little opaque. 
> It might look better with an enum class that has 3 values?

Okay, will change it to a enum class.

>> Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:51
>> +        m_manager = WeakPtr { *manager };
> 
> WeakPtr { } is not needed, you can just assign `*manager`.

Will change.

>> Source/WebKit/NetworkProcess/NetworkProcess.cpp:2212
>> +    if (auto* storageManager = session->storageManager())
> 
> You are failing to call the completion handler in the else case.

Will add!

>> Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp:248
>> +    if (auto* storageManager = session->storageManager())
> 
> Callback is not getting called in the else case.

Oops, wil change.

>> Source/WebKit/NetworkProcess/storage/IDBStorageManager.cpp:45
>> +    for (auto name : fileNames) {
> 
> auto&, assuming this is a String.

Okay.

>> Source/WebKit/NetworkProcess/storage/IDBStorageManager.cpp:244
>> +    if (identifier.isTransient())
> 
> Probably can merge with the previous if condition given that the return is the same.

Sure.

>> Source/WebKit/NetworkProcess/storage/IDBStorageManager.h:53
>> +    ~IDBStorageManager() final { }
> 
> Seem we shouldn't need this?

Will remove.

>> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:47
>> +    WebCore::IDBServer::IDBConnectionToClient& getOrCreateConnectionToClient(IPC::Connection::UniqueID, WebCore::IDBConnectionIdentifier);
> 
> Maybe ensureConnectionToClient() would look better?

Sure.

>> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:51
>> +    WebCore::IDBServer::UniqueIDBDatabaseConnection* getConnection(uint64_t identifier);
> 
> No "get" prefixes in getters.

Will remove.

>> Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.h:54
>> +    WebCore::IDBServer::UniqueIDBDatabaseTransaction* getTransaction(WebCore::IDBResourceIdentifier);
> 
> ditto.

Will remove.

>> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:59
>> +    auto clearIsHandlingRequests = makeScopeExit([&] {
> 
> I think this is a clear use case for SetForScope?
> 
> SetForScope<bool> isHandlingRequests(m_isHandlingRequests, true);

Yes!

>> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:83
>> +    bool shouldUpdateQuotaBasedonUsage = !m_usage;
> 
> OnUsage (case issue)

Will update.

>> Source/WebKit/NetworkProcess/storage/QuotaManager.cpp:125
>> +    m_quotaCountdown = 0;
> 
> Maybe this could call resetQuotaForTesting()?

Sure.

>> Source/WebKit/NetworkProcess/storage/QuotaManager.h:41
>> +    enum class Decision { Deny, Grant };
> 
> enum class Decision : bool { Deny, Grant };

Sure.

>> Tools/ChangeLog:17
>> +2022-02-03  Sihui Liu  <sihui_liu@apple.com>
> 
> Double changelog issue.

Will remove.
Comment 13 Sihui Liu 2022-02-07 17:16:48 PST
Created attachment 451180 [details]
Patch
Comment 14 Sihui Liu 2022-02-07 18:43:48 PST
Created attachment 451190 [details]
Patch
Comment 15 Sihui Liu 2022-02-07 19:37:17 PST
Created attachment 451197 [details]
Patch
Comment 16 Sihui Liu 2022-02-08 00:43:34 PST
Created attachment 451216 [details]
Patch
Comment 17 Sihui Liu 2022-02-08 09:04:54 PST
Created attachment 451257 [details]
Patch
Comment 18 Sihui Liu 2022-02-08 11:00:48 PST
Created attachment 451278 [details]
Patch
Comment 19 Sihui Liu 2022-02-08 15:48:19 PST
Created attachment 451316 [details]
Patch
Comment 20 Sihui Liu 2022-02-09 08:12:31 PST
Created attachment 451380 [details]
Patch for landing
Comment 21 EWS 2022-02-09 08:56:30 PST
Committed r289474 (247017@main): <https://commits.webkit.org/247017@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 451380 [details].