Bug 1672140 - Change cache::ClientMetadata's base class from quota::OriginMetadata to quota::ClientMetadata; r=dom-storage-reviewers,janv

Depends on D125583

Differential Revision: https://phabricator.services.mozilla.com/D126056
This commit is contained in:
hxu 2021-11-24 20:50:37 +00:00
parent 2dbd17aeac
commit 93316dde65
11 changed files with 105 additions and 57 deletions

2
dom/cache/Action.h vendored
View File

@ -56,7 +56,7 @@ class Action : public SafeRefCounted<Action> {
// Note: The "target" thread is determined when the Action is scheduled on
// Context. The Action should not assume any particular thread is used.
virtual void RunOnTarget(SafeRefPtr<Resolver> aResolver,
const ClientMetadata& aClientMetadata,
const Maybe<ClientMetadata>& aClientMetadata,
Data* aOptionalData) = 0;
// Called on initiating thread when the Action is canceled. The Action is

33
dom/cache/Context.cpp vendored
View File

@ -32,7 +32,8 @@ class NullAction final : public Action {
NullAction() = default;
virtual void RunOnTarget(mozilla::SafeRefPtr<Resolver> aResolver,
const ClientMetadata&, Data*) override {
const mozilla::Maybe<ClientMetadata>&,
Data*) override {
// Resolve success immediately. This Action does no actual work.
MOZ_DIAGNOSTIC_ASSERT(aResolver);
aResolver->Resolve(NS_OK);
@ -215,7 +216,7 @@ class Context::QuotaInitRunnable final : public nsIRunnable,
SafeRefPtr<Action> mInitAction;
nsCOMPtr<nsIEventTarget> mInitiatingEventTarget;
nsresult mResult;
ClientMetadata mClientMetadata;
Maybe<ClientMetadata> mClientMetadata;
RefPtr<DirectoryLock> mDirectoryLock;
State mState;
Atomic<bool> mCanceled;
@ -233,7 +234,7 @@ void Context::QuotaInitRunnable::OpenDirectory() {
RefPtr<DirectoryLock> directoryLock =
QuotaManager::Get()->CreateDirectoryLock(
PERSISTENCE_TYPE_DEFAULT, mClientMetadata, quota::Client::DOMCACHE,
PERSISTENCE_TYPE_DEFAULT, *mClientMetadata, quota::Client::DOMCACHE,
/* aExclusive */ false);
// DirectoryLock::Acquire() will hold a reference to us as a listener. We will
@ -252,7 +253,7 @@ void Context::QuotaInitRunnable::DirectoryLockAcquired(DirectoryLock* aLock) {
mDirectoryLock = aLock;
MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock->Id() >= 0);
mClientMetadata.mDirectoryLockId = mDirectoryLock->Id();
mClientMetadata->mDirectoryLockId = mDirectoryLock->Id();
if (mCanceled) {
Complete(NS_ERROR_ABORT);
@ -352,8 +353,7 @@ Context::QuotaInitRunnable::Run() {
QM_TRY_UNWRAP(auto principalMetadata,
QuotaManager::GetInfoFromPrincipal(principal));
static_cast<quota::OriginMetadata&>(mClientMetadata) = {
std::move(principalMetadata), PERSISTENCE_TYPE_DEFAULT};
mClientMetadata.emplace(std::move(principalMetadata));
mState = STATE_CREATE_QUOTA_MANAGER;
@ -416,10 +416,10 @@ Context::QuotaInitRunnable::Run() {
QM_TRY(
MOZ_TO_RESULT(quotaManager->EnsureTemporaryStorageIsInitialized()));
QM_TRY_UNWRAP(mClientMetadata.mDir,
QM_TRY_UNWRAP(mClientMetadata->mDir,
quotaManager
->EnsureTemporaryOriginIsInitialized(
PERSISTENCE_TYPE_DEFAULT, mClientMetadata)
PERSISTENCE_TYPE_DEFAULT, *mClientMetadata)
.map([](const auto& res) { return res.first; }));
mState = STATE_RUN_ON_TARGET;
@ -453,7 +453,7 @@ Context::QuotaInitRunnable::Run() {
// the marker file. If it wasn't opened successfully, then no need to
// create a marker file anyway.
if (NS_SUCCEEDED(resolver->Result())) {
MOZ_ALWAYS_SUCCEEDS(CreateMarkerFile(mClientMetadata));
MOZ_ALWAYS_SUCCEEDS(CreateMarkerFile(*mClientMetadata));
}
break;
@ -493,7 +493,7 @@ class Context::ActionRunnable final : public nsIRunnable,
public:
ActionRunnable(SafeRefPtr<Context> aContext, Data* aData,
nsISerialEventTarget* aTarget, SafeRefPtr<Action> aAction,
const ClientMetadata& aClientMetadata)
const Maybe<ClientMetadata>& aClientMetadata)
: mContext(std::move(aContext)),
mData(aData),
mTarget(aTarget),
@ -587,7 +587,7 @@ class Context::ActionRunnable final : public nsIRunnable,
RefPtr<Data> mData;
nsCOMPtr<nsISerialEventTarget> mTarget;
SafeRefPtr<Action> mAction;
const ClientMetadata mClientMetadata;
const Maybe<ClientMetadata> mClientMetadata;
nsCOMPtr<nsIEventTarget> mInitiatingThread;
State mState;
nsresult mResult;
@ -921,8 +921,8 @@ Context::~Context() {
// Note, this may set the mOrphanedData flag.
mManager->RemoveContext(*this);
if (mClientMetadata.mDir && !mOrphanedData) {
MOZ_ALWAYS_SUCCEEDS(DeleteMarkerFile(mClientMetadata));
if (mClientMetadata && mClientMetadata->mDir && !mOrphanedData) {
MOZ_ALWAYS_SUCCEEDS(DeleteMarkerFile(*mClientMetadata));
}
if (mNextContext) {
@ -994,14 +994,17 @@ void Context::DispatchAction(SafeRefPtr<Action> aAction, bool aDoomData) {
AddActivity(*runnable);
}
void Context::OnQuotaInit(nsresult aRv, const ClientMetadata& aClientMetadata,
void Context::OnQuotaInit(nsresult aRv,
const Maybe<ClientMetadata>& aClientMetadata,
already_AddRefed<DirectoryLock> aDirectoryLock) {
NS_ASSERT_OWNINGTHREAD(Context);
MOZ_DIAGNOSTIC_ASSERT(mInitRunnable);
mInitRunnable = nullptr;
mClientMetadata = aClientMetadata;
if (aClientMetadata) {
mClientMetadata.emplace(*aClientMetadata);
}
// Always save the directory lock to ensure QuotaManager does not shutdown
// before the Context has gone away.

6
dom/cache/Context.h vendored
View File

@ -152,8 +152,6 @@ class Context final : public SafeRefCounted<Context> {
void AddActivity(Activity& aActivity);
void RemoveActivity(Activity& aActivity);
const ClientMetadata& GetClientMetadata() const { return mClientMetadata; }
// Tell the Context that some state information has been orphaned in the
// data store and won't be cleaned up. The Context will leave the marker
// in place to trigger cleanup the next times its opened.
@ -179,7 +177,7 @@ class Context final : public SafeRefCounted<Context> {
void Init(Maybe<Context&> aOldContext);
void Start();
void DispatchAction(SafeRefPtr<Action> aAction, bool aDoomData = false);
void OnQuotaInit(nsresult aRv, const ClientMetadata& aClientMetadata,
void OnQuotaInit(nsresult aRv, const Maybe<ClientMetadata>& aClientMetadata,
already_AddRefed<DirectoryLock> aDirectoryLock);
SafeRefPtr<ThreadsafeHandle> CreateThreadsafeHandle();
@ -193,7 +191,7 @@ class Context final : public SafeRefCounted<Context> {
RefPtr<Data> mData;
State mState;
bool mOrphanedData;
ClientMetadata mClientMetadata;
Maybe<ClientMetadata> mClientMetadata;
RefPtr<QuotaInitRunnable> mInitRunnable;
SafeRefPtr<Action> mInitAction;
nsTArray<PendingAction> mPendingActions;

View File

@ -56,11 +56,12 @@ DBAction::DBAction(Mode aMode) : mMode(aMode) {}
DBAction::~DBAction() = default;
void DBAction::RunOnTarget(SafeRefPtr<Resolver> aResolver,
const ClientMetadata& aClientMetadata,
const Maybe<ClientMetadata>& aClientMetadata,
Data* aOptionalData) {
MOZ_ASSERT(!NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(aResolver);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata.mDir);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata->mDir);
if (IsCanceled()) {
aResolver->Resolve(NS_ERROR_ABORT);
@ -72,7 +73,7 @@ void DBAction::RunOnTarget(SafeRefPtr<Resolver> aResolver,
};
QM_TRY_INSPECT(const auto& dbDir,
CloneFileAndAppend(*aClientMetadata.mDir, u"cache"_ns),
CloneFileAndAppend(*(aClientMetadata->mDir), u"cache"_ns),
QM_VOID, resolveErr);
nsCOMPtr<mozIStorageConnection> conn;
@ -84,7 +85,7 @@ void DBAction::RunOnTarget(SafeRefPtr<Resolver> aResolver,
// If there is no previous Action, then we must open one.
if (!conn) {
QM_TRY_UNWRAP(conn, OpenConnection(aClientMetadata, *dbDir), QM_VOID,
QM_TRY_UNWRAP(conn, OpenConnection(*aClientMetadata, *dbDir), QM_VOID,
resolveErr);
MOZ_DIAGNOSTIC_ASSERT(conn);
@ -100,7 +101,7 @@ void DBAction::RunOnTarget(SafeRefPtr<Resolver> aResolver,
}
}
RunWithDBOnTarget(std::move(aResolver), aClientMetadata, dbDir, conn);
RunWithDBOnTarget(std::move(aResolver), *aClientMetadata, dbDir, conn);
}
Result<nsCOMPtr<mozIStorageConnection>, nsresult> DBAction::OpenConnection(

View File

@ -42,7 +42,7 @@ class DBAction : public Action {
private:
void RunOnTarget(SafeRefPtr<Resolver> aResolver,
const ClientMetadata& aClientMetadata,
const Maybe<ClientMetadata>& aClientMetadata,
Data* aOptionalData) override;
Result<nsCOMPtr<mozIStorageConnection>, nsresult> OpenConnection(

View File

@ -496,8 +496,12 @@ bool MarkerFileExists(const ClientMetadata& aClientMetadata) {
QM_TRY_RETURN(MOZ_TO_RESULT_INVOKE(marker, Exists), false);
}
nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata,
nsresult RemoveNsIFileRecursively(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aFile, const bool aTrackQuota) {
// XXX This assertion proves that we can remove aTrackQuota and just check
// aClientMetadata
MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata);
QM_TRY_INSPECT(const auto& dirEntryKind, GetDirEntryKind(aFile));
switch (dirEntryKind) {
@ -531,8 +535,12 @@ nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata,
return NS_OK;
}
nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile,
const bool aTrackQuota) {
nsresult RemoveNsIFile(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aFile, const bool aTrackQuota) {
// XXX This assertion proves that we can remove aTrackQuota and just check
// aClientMetadata
MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata);
int64_t fileSize = 0;
if (aTrackQuota) {
QM_TRY_INSPECT(
@ -562,7 +570,7 @@ nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile,
if (fileSize > 0) {
MOZ_ASSERT(aTrackQuota);
DecreaseUsageForClientMetadata(aClientMetadata, fileSize);
DecreaseUsageForClientMetadata(*aClientMetadata, fileSize);
}
return NS_OK;

33
dom/cache/FileUtils.h vendored
View File

@ -65,25 +65,50 @@ nsresult BodyDeleteOrphanedFiles(const ClientMetadata& aClientMetadata,
// created by other threads. Note that if the files are not expected, we should
// be safe to remove them in any case.
template <typename Func>
nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata,
nsresult BodyTraverseFiles(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aBodyDir, const Func& aHandleFileFunc,
bool aCanRemoveFiles, bool aTrackQuota = true);
// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
template <typename Func>
nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata,
nsIFile& aBodyDir, const Func& aHandleFileFunc,
bool aCanRemoveFiles, bool aTrackQuota = true) {
return BodyTraverseFiles(Some(aClientMetadata), aBodyDir, aHandleFileFunc,
aCanRemoveFiles, aTrackQuota);
}
nsresult CreateMarkerFile(const ClientMetadata& aClientMetadata);
nsresult DeleteMarkerFile(const ClientMetadata& aClientMetadata);
bool MarkerFileExists(const ClientMetadata& aClientMetadata);
nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata,
nsresult RemoveNsIFileRecursively(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aFile, bool aTrackQuota = true);
// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
inline nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata,
nsIFile& aFile,
bool aTrackQuota = true) {
return RemoveNsIFileRecursively(Some(aClientMetadata), aFile, aTrackQuota);
}
// Delete a file that you think exists. If the file doesn't exist, an error
// will not be returned, but warning telemetry will be generated! So only call
// this on files that you know exist (idempotent usage, but it's not
// recommended).
nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile,
bool aTrackQuota = true);
nsresult RemoveNsIFile(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aFile, bool aTrackQuota = true);
// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
inline nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata,
nsIFile& aFile, bool aTrackQuota = true) {
return RemoveNsIFile(Some(aClientMetadata), aFile, aTrackQuota);
}
void DecreaseUsageForClientMetadata(const ClientMetadata& aClientMetadata,
int64_t aUpdatingSize);

View File

@ -15,9 +15,13 @@ namespace dom {
namespace cache {
template <typename Func>
nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata,
nsresult BodyTraverseFiles(const Maybe<ClientMetadata>& aClientMetadata,
nsIFile& aBodyDir, const Func& aHandleFileFunc,
const bool aCanRemoveFiles, const bool aTrackQuota) {
// XXX This assertion proves that we can remove aTrackQuota and just check
// aClientMetadata.isSome()
MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
{
nsCOMPtr<nsIFile> parentFile;

24
dom/cache/Manager.cpp vendored
View File

@ -172,9 +172,11 @@ class DeleteOrphanedBodyAction final : public Action {
: mDeletedBodyIdList{aBodyId} {}
void RunOnTarget(SafeRefPtr<Resolver> aResolver,
const ClientMetadata& aClientMetadata, Data*) override {
const Maybe<ClientMetadata>& aClientMetadata,
Data*) override {
MOZ_DIAGNOSTIC_ASSERT(aResolver);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata.mDir);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata);
MOZ_DIAGNOSTIC_ASSERT(aClientMetadata->mDir);
// Note that since DeleteOrphanedBodyAction isn't used while the context is
// being initialized, we don't need to check for cancellation here.
@ -184,11 +186,11 @@ class DeleteOrphanedBodyAction final : public Action {
};
QM_TRY_INSPECT(const auto& dbDir,
CloneFileAndAppend(*aClientMetadata.mDir, u"cache"_ns),
CloneFileAndAppend(*aClientMetadata->mDir, u"cache"_ns),
QM_VOID, resolve);
QM_TRY(MOZ_TO_RESULT(
BodyDeleteFiles(aClientMetadata, *dbDir, mDeletedBodyIdList)),
BodyDeleteFiles(*aClientMetadata, *dbDir, mDeletedBodyIdList)),
QM_VOID, resolve);
aResolver->Resolve(NS_OK);
@ -554,7 +556,7 @@ class Manager::DeleteOrphanedCacheAction final : public SyncDBAction {
mManager->NoteOrphanedBodyIdList(mDeletionInfo.mDeletedBodyIdList);
if (mDeletionInfo.mDeletedPaddingSize > 0) {
DecreaseUsageForClientMetadata(mClientMetadata.ref(),
DecreaseUsageForClientMetadata(*mClientMetadata,
mDeletionInfo.mDeletedPaddingSize);
}
@ -856,7 +858,7 @@ class Manager::CachePutAllAction final : public DBAction {
if (e.mResponse.type() == ResponseType::Opaque) {
// It'll generate padding if we've not set it yet.
QM_TRY(MOZ_TO_RESULT(BodyMaybeUpdatePaddingSize(
mClientMetadata.ref(), *mDBDir, e.mResponseBodyId,
*mClientMetadata, *mDBDir, e.mResponseBodyId,
e.mResponse.paddingInfo(), &e.mResponse.paddingSize())));
MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - e.mResponse.paddingSize() >=
@ -913,8 +915,7 @@ class Manager::CachePutAllAction final : public DBAction {
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {
DecreaseUsageForClientMetadata(mClientMetadata.ref(),
mDeletedPaddingSize);
DecreaseUsageForClientMetadata(*mClientMetadata, mDeletedPaddingSize);
}
Listener* listener = mManager->GetListener(mListenerId);
@ -1033,10 +1034,9 @@ class Manager::CachePutAllAction final : public DBAction {
// Clean up any files we might have written before hitting the error.
if (NS_FAILED(aRv)) {
BodyDeleteFiles(mClientMetadata.ref(), *mDBDir, mBodyIdWrittenList);
BodyDeleteFiles(*mClientMetadata, *mDBDir, mBodyIdWrittenList);
if (mUpdatedPaddingSize > 0) {
DecreaseUsageForClientMetadata(mClientMetadata.ref(),
mUpdatedPaddingSize);
DecreaseUsageForClientMetadata(*mClientMetadata, mUpdatedPaddingSize);
}
}
@ -1137,7 +1137,7 @@ class Manager::CacheDeleteAction final : public Manager::BaseAction {
mManager->NoteOrphanedBodyIdList(mDeletionInfo.mDeletedBodyIdList);
if (mDeletionInfo.mDeletedPaddingSize > 0) {
DecreaseUsageForClientMetadata(mClientMetadata.ref(),
DecreaseUsageForClientMetadata(*mClientMetadata,
mDeletionInfo.mDeletedPaddingSize);
}

View File

@ -64,8 +64,8 @@ Result<UsageInfo, nsresult> GetBodyUsage(nsIFile& aMorgueDir,
if (dirEntryKind != nsIFileKind::ExistsAsDirectory) {
if (dirEntryKind == nsIFileKind::ExistsAsFile) {
const DebugOnly<nsresult> result = RemoveNsIFile(
ClientMetadata{}, *bodyDir, /* aTrackQuota */ false);
const DebugOnly<nsresult> result =
RemoveNsIFile(Nothing(), *bodyDir, /* aTrackQuota */ false);
// Try to remove the unexpected files, and keep moving on even if it
// fails because it might be created by virus or the operation
// system
@ -108,8 +108,7 @@ Result<UsageInfo, nsresult> GetBodyUsage(nsIFile& aMorgueDir,
// warning in the reports is not desired).
QM_TRY(QM_OR_ELSE_LOG_VERBOSE_IF(
// Expression.
MOZ_TO_RESULT(BodyTraverseFiles(ClientMetadata{}, *bodyDir,
getUsage,
MOZ_TO_RESULT(BodyTraverseFiles(Nothing(), *bodyDir, getUsage,
/* aCanRemoveFiles */ true,
/* aTrackQuota */ false)),
// Predicate.
@ -123,8 +122,7 @@ Result<UsageInfo, nsresult> GetBodyUsage(nsIFile& aMorgueDir,
Result<int64_t, nsresult> GetPaddingSizeFromDB(
nsIFile& aDir, nsIFile& aDBFile, const OriginMetadata& aOriginMetadata) {
ClientMetadata clientMetadata;
static_cast<OriginMetadata&>(clientMetadata) = aOriginMetadata;
ClientMetadata clientMetadata(aOriginMetadata);
// clientMetadata.mDirectoryLockId must be -1 (which is default for new
// ClientMetadata) because this method should only be called from
// QuotaClient::InitOrigin when the temporary storage hasn't been initialized
@ -217,9 +215,8 @@ Result<UsageInfo, nsresult> CacheQuotaClient::InitOrigin(
QM_TRY_INSPECT(const auto& morgueDir,
CloneFileAndAppend(*dir, kMorgueDirectoryFilename));
ClientMetadata dummy;
QM_TRY(MOZ_TO_RESULT(mozilla::dom::cache::RemoveNsIFileRecursively(
dummy, *morgueDir,
Nothing(), *morgueDir,
/* aTrackQuota */ false)));
return nsCOMPtr<nsIFile>{nullptr};

16
dom/cache/Types.h vendored
View File

@ -29,10 +29,22 @@ static const Namespace INVALID_NAMESPACE = NUMBER_OF_NAMESPACES;
using CacheId = int64_t;
static const CacheId INVALID_CACHE_ID = -1;
// XXX Consider inheritance from ClientMetadata.
struct ClientMetadata : quota::OriginMetadata {
struct ClientMetadata : quota::ClientMetadata {
nsCOMPtr<nsIFile> mDir;
int64_t mDirectoryLockId = -1;
explicit ClientMetadata(quota::PrincipalMetadata aPrincipalMetadata)
: quota::ClientMetadata(
quota::OriginMetadata{std::move(aPrincipalMetadata),
quota::PERSISTENCE_TYPE_DEFAULT},
quota::Client::Type::DOMCACHE) {}
explicit ClientMetadata(quota::OriginMetadata aOriginMetadata)
: quota::ClientMetadata(std::move(aOriginMetadata),
quota::Client::Type::DOMCACHE) {
MOZ_DIAGNOSTIC_ASSERT(aOriginMetadata.mPersistenceType ==
quota::PERSISTENCE_TYPE_DEFAULT);
}
};
struct DeletionInfo {