mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1563023 - Part 1: Implement per client usage tracking; r=asuth
This patch adds a fixed-size array of client usages to OriginInfo and modifies quota tracking APIs to require the client type to be passed in. A new method ResetUsageForClient is implemented. The method is used during client-specific origin clearing. ResetUsageForClient is much faster than calling GetUsageForOrigin and calling DecreaseUsageForOrigin after that. LockedUsage now has an assertion that verifies that the total sum of client usages matches total origin usage. This method should be called instead of touching mUsage directly. A new assertion is added to GetQuotaObject which verifies that passed file belongs to the given persistence type, origin, and client. Differential Revision: https://phabricator.services.mozilla.com/D38028 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
bb991b5d3a
commit
9f906cd7c4
5
dom/cache/DBAction.cpp
vendored
5
dom/cache/DBAction.cpp
vendored
@ -26,6 +26,7 @@ namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::dom::quota::AssertIsOnIOThread;
|
||||
using mozilla::dom::quota::Client;
|
||||
using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
|
||||
using mozilla::dom::quota::PersistenceType;
|
||||
|
||||
@ -210,10 +211,14 @@ nsresult OpenDBConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
nsAutoCString type;
|
||||
PersistenceTypeToText(PERSISTENCE_TYPE_DEFAULT, type);
|
||||
|
||||
nsAutoCString clientType;
|
||||
Client::TypeToText(Client::DOMCACHE, clientType);
|
||||
|
||||
rv = NS_MutateURI(mutator)
|
||||
.SetQuery(NS_LITERAL_CSTRING("persistenceType=") + type +
|
||||
NS_LITERAL_CSTRING("&group=") + aQuotaInfo.mGroup +
|
||||
NS_LITERAL_CSTRING("&origin=") + aQuotaInfo.mOrigin +
|
||||
NS_LITERAL_CSTRING("&clientType=") + clientType +
|
||||
NS_LITERAL_CSTRING("&cache=private"))
|
||||
.Finalize(dbFileUrl);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
16
dom/cache/FileUtils.cpp
vendored
16
dom/cache/FileUtils.cpp
vendored
@ -27,6 +27,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::dom::quota::Client;
|
||||
using mozilla::dom::quota::FileInputStream;
|
||||
using mozilla::dom::quota::FileOutputStream;
|
||||
using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
|
||||
@ -205,8 +206,9 @@ nsresult BodyStartWriteStream(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
return NS_ERROR_FILE_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOutputStream> fileStream = CreateFileOutputStream(
|
||||
PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup, aQuotaInfo.mOrigin, tmpFile);
|
||||
nsCOMPtr<nsIOutputStream> fileStream =
|
||||
CreateFileOutputStream(PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup,
|
||||
aQuotaInfo.mOrigin, Client::DOMCACHE, tmpFile);
|
||||
if (NS_WARN_IF(!fileStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -298,7 +300,7 @@ nsresult BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
|
||||
nsCOMPtr<nsIInputStream> fileStream =
|
||||
CreateFileInputStream(PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup,
|
||||
aQuotaInfo.mOrigin, finalFile);
|
||||
aQuotaInfo.mOrigin, Client::DOMCACHE, finalFile);
|
||||
if (NS_WARN_IF(!fileStream)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -329,9 +331,9 @@ nsresult BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo,
|
||||
MOZ_DIAGNOSTIC_ASSERT(quotaManager);
|
||||
|
||||
int64_t fileSize = 0;
|
||||
RefPtr<QuotaObject> quotaObject =
|
||||
quotaManager->GetQuotaObject(PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup,
|
||||
aQuotaInfo.mOrigin, bodyFile, -1, &fileSize);
|
||||
RefPtr<QuotaObject> quotaObject = quotaManager->GetQuotaObject(
|
||||
PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup, aQuotaInfo.mOrigin,
|
||||
Client::DOMCACHE, bodyFile, -1, &fileSize);
|
||||
MOZ_DIAGNOSTIC_ASSERT(quotaObject);
|
||||
MOZ_DIAGNOSTIC_ASSERT(fileSize >= 0);
|
||||
// XXXtt: bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1422815
|
||||
@ -740,7 +742,7 @@ void DecreaseUsageForQuotaInfo(const QuotaInfo& aQuotaInfo,
|
||||
|
||||
quotaManager->DecreaseUsageForOrigin(PERSISTENCE_TYPE_DEFAULT,
|
||||
aQuotaInfo.mGroup, aQuotaInfo.mOrigin,
|
||||
aUpdatingSize);
|
||||
Client::DOMCACHE, aUpdatingSize);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -3895,6 +3895,9 @@ nsresult GetDatabaseFileURL(nsIFile* aDatabaseFile,
|
||||
nsAutoCString type;
|
||||
PersistenceTypeToText(aPersistenceType, type);
|
||||
|
||||
nsAutoCString clientType;
|
||||
Client::TypeToText(Client::IDB, clientType);
|
||||
|
||||
nsAutoCString telemetryFilenameClause;
|
||||
if (aTelemetryId) {
|
||||
telemetryFilenameClause.AssignLiteral("&telemetryFilename=indexedDB-");
|
||||
@ -3906,6 +3909,7 @@ nsresult GetDatabaseFileURL(nsIFile* aDatabaseFile,
|
||||
.SetQuery(NS_LITERAL_CSTRING("persistenceType=") + type +
|
||||
NS_LITERAL_CSTRING("&group=") + aGroup +
|
||||
NS_LITERAL_CSTRING("&origin=") + aOrigin +
|
||||
NS_LITERAL_CSTRING("&clientType=") + clientType +
|
||||
NS_LITERAL_CSTRING("&cache=private") +
|
||||
telemetryFilenameClause)
|
||||
.Finalize(fileUrl);
|
||||
@ -8709,7 +8713,7 @@ nsresult DeleteFile(nsIFile* aDirectory, const nsAString& aFilename,
|
||||
|
||||
if (aQuotaManager && fileSize > 0) {
|
||||
aQuotaManager->DecreaseUsageForOrigin(aPersistenceType, aGroup, aOrigin,
|
||||
fileSize);
|
||||
Client::IDB, fileSize);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -8930,7 +8934,7 @@ nsresult RemoveDatabaseFilesAndDirectory(nsIFile* aBaseDirectory,
|
||||
|
||||
if (aQuotaManager && usage) {
|
||||
aQuotaManager->DecreaseUsageForOrigin(aPersistenceType, aGroup, aOrigin,
|
||||
usage);
|
||||
Client::IDB, usage);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -10271,9 +10275,9 @@ void DatabaseConnection::UpdateRefcountFunction::Reset() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
quotaManager->DecreaseUsageForOrigin(aFileManager->Type(),
|
||||
aFileManager->Group(),
|
||||
aFileManager->Origin(), fileSize);
|
||||
quotaManager->DecreaseUsageForOrigin(
|
||||
aFileManager->Type(), aFileManager->Group(), aFileManager->Origin(),
|
||||
Client::IDB, fileSize);
|
||||
}
|
||||
|
||||
file = FileManager::GetFileForId(mJournalDirectory, aId);
|
||||
@ -16690,9 +16694,9 @@ nsresult DeleteFilesRunnable::DeleteFile(int64_t aFileId) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
NS_ASSERTION(quotaManager, "Shouldn't be null!");
|
||||
|
||||
quotaManager->DecreaseUsageForOrigin(mFileManager->Type(),
|
||||
mFileManager->Group(),
|
||||
mFileManager->Origin(), fileSize);
|
||||
quotaManager->DecreaseUsageForOrigin(
|
||||
mFileManager->Type(), mFileManager->Group(), mFileManager->Origin(),
|
||||
Client::IDB, fileSize);
|
||||
}
|
||||
|
||||
file = mFileManager->GetFileForId(mJournalDirectory, aFileId);
|
||||
@ -19024,13 +19028,13 @@ already_AddRefed<nsISupports> MutableFile::CreateStream(bool aReadOnly) {
|
||||
|
||||
if (aReadOnly) {
|
||||
RefPtr<FileInputStream> stream =
|
||||
CreateFileInputStream(persistenceType, group, origin, mFile, -1, -1,
|
||||
nsIFileInputStream::DEFER_OPEN);
|
||||
CreateFileInputStream(persistenceType, group, origin, Client::IDB,
|
||||
mFile, -1, -1, nsIFileInputStream::DEFER_OPEN);
|
||||
result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream);
|
||||
} else {
|
||||
RefPtr<FileStream> stream =
|
||||
CreateFileStream(persistenceType, group, origin, mFile, -1, -1,
|
||||
nsIFileStream::DEFER_OPEN);
|
||||
CreateFileStream(persistenceType, group, origin, Client::IDB, mFile, -1,
|
||||
-1, nsIFileStream::DEFER_OPEN);
|
||||
result = NS_ISUPPORTS_CAST(nsIFileStream*, stream);
|
||||
}
|
||||
if (NS_WARN_IF(!result)) {
|
||||
@ -27022,7 +27026,7 @@ nsresult FileHelper::CreateFileFromStream(nsIFile* aFile, nsIFile* aJournalFile,
|
||||
// Now try to copy the stream.
|
||||
RefPtr<FileOutputStream> fileOutputStream =
|
||||
CreateFileOutputStream(mFileManager->Type(), mFileManager->Group(),
|
||||
mFileManager->Origin(), aFile);
|
||||
mFileManager->Origin(), Client::IDB, aFile);
|
||||
if (NS_WARN_IF(!fileOutputStream)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -27068,9 +27072,9 @@ nsresult FileHelper::RemoveFile(nsIFile* aFile, nsIFile* aJournalFile) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
quotaManager->DecreaseUsageForOrigin(mFileManager->Type(),
|
||||
mFileManager->Group(),
|
||||
mFileManager->Origin(), fileSize);
|
||||
quotaManager->DecreaseUsageForOrigin(
|
||||
mFileManager->Type(), mFileManager->Group(), mFileManager->Origin(),
|
||||
Client::IDB, fileSize);
|
||||
}
|
||||
|
||||
rv = aJournalFile->Remove(false);
|
||||
|
@ -7455,7 +7455,8 @@ already_AddRefed<QuotaObject> PrepareDatastoreOp::GetQuotaObject() {
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
RefPtr<QuotaObject> quotaObject = quotaManager->GetQuotaObject(
|
||||
PERSISTENCE_TYPE_DEFAULT, mGroup, mOrigin, mDatabaseFilePath, mUsage);
|
||||
PERSISTENCE_TYPE_DEFAULT, mGroup, mOrigin,
|
||||
mozilla::dom::quota::Client::LS, mDatabaseFilePath, mUsage);
|
||||
MOZ_ASSERT(quotaObject);
|
||||
|
||||
return quotaObject.forget();
|
||||
|
@ -128,6 +128,9 @@ const char QuotaManager::kReplaceChars[] = CONTROL_CHARACTERS "/:*?\"<>|\\";
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void AssertNoOverflow(uint64_t aDest, T aArg);
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants
|
||||
******************************************************************************/
|
||||
@ -601,13 +604,23 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
class ClientUsageArray final : public AutoTArray<uint64_t, Client::TYPE_MAX> {
|
||||
public:
|
||||
ClientUsageArray() {
|
||||
for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
|
||||
AppendElement(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class OriginInfo final {
|
||||
friend class GroupInfo;
|
||||
friend class QuotaManager;
|
||||
friend class QuotaObject;
|
||||
|
||||
public:
|
||||
OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin, uint64_t aUsage,
|
||||
OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
|
||||
const ClientUsageArray& aClientUsages, uint64_t aUsage,
|
||||
int64_t aAccessTime, bool aPersisted, bool aDirectoryExists);
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OriginInfo)
|
||||
@ -619,6 +632,15 @@ class OriginInfo final {
|
||||
int64_t LockedUsage() const {
|
||||
AssertCurrentThreadOwnsQuotaMutex();
|
||||
|
||||
#ifdef DEBUG
|
||||
uint64_t usage = 0;
|
||||
for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
|
||||
AssertNoOverflow(usage, mClientUsages[index]);
|
||||
usage += mClientUsages[index];
|
||||
}
|
||||
MOZ_ASSERT(mUsage == usage);
|
||||
#endif
|
||||
|
||||
return mUsage;
|
||||
}
|
||||
|
||||
@ -642,7 +664,9 @@ class OriginInfo final {
|
||||
MOZ_ASSERT(!mQuotaObjects.Count());
|
||||
}
|
||||
|
||||
void LockedDecreaseUsage(int64_t aSize);
|
||||
void LockedDecreaseUsage(Client::Type aClientType, int64_t aSize);
|
||||
|
||||
void LockedResetUsageForClient(Client::Type aClientType);
|
||||
|
||||
void LockedUpdateAccessTime(int64_t aAccessTime) {
|
||||
AssertCurrentThreadOwnsQuotaMutex();
|
||||
@ -653,7 +677,7 @@ class OriginInfo final {
|
||||
void LockedPersist();
|
||||
|
||||
nsDataHashtable<nsStringHashKey, QuotaObject*> mQuotaObjects;
|
||||
|
||||
ClientUsageArray mClientUsages;
|
||||
GroupInfo* mGroupInfo;
|
||||
const nsCString mOrigin;
|
||||
uint64_t mUsage;
|
||||
@ -2825,6 +2849,9 @@ bool QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate) {
|
||||
AssertNoUnderflow(mOriginInfo->mUsage, delta);
|
||||
mOriginInfo->mUsage -= delta;
|
||||
|
||||
AssertNoUnderflow(mOriginInfo->mClientUsages[mClientType], delta);
|
||||
mOriginInfo->mClientUsages[mClientType] -= delta;
|
||||
|
||||
mSize = aSize;
|
||||
}
|
||||
return true;
|
||||
@ -2838,6 +2865,9 @@ bool QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate) {
|
||||
|
||||
uint64_t delta = aSize - mSize;
|
||||
|
||||
AssertNoOverflow(mOriginInfo->mClientUsages[mClientType], delta);
|
||||
uint64_t newClientUsage = mOriginInfo->mClientUsages[mClientType] + delta;
|
||||
|
||||
AssertNoOverflow(mOriginInfo->mUsage, delta);
|
||||
uint64_t newUsage = mOriginInfo->mUsage + delta;
|
||||
|
||||
@ -2932,6 +2962,9 @@ bool QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate) {
|
||||
AssertNoUnderflow(aSize, mSize);
|
||||
delta = aSize - mSize;
|
||||
|
||||
AssertNoOverflow(mOriginInfo->mClientUsages[mClientType], delta);
|
||||
newClientUsage = mOriginInfo->mClientUsages[mClientType] + delta;
|
||||
|
||||
AssertNoOverflow(mOriginInfo->mUsage, delta);
|
||||
newUsage = mOriginInfo->mUsage + delta;
|
||||
|
||||
@ -2969,6 +3002,8 @@ bool QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate) {
|
||||
|
||||
// Ok, we successfully freed enough space and the operation can continue
|
||||
// without throwing the quota error.
|
||||
mOriginInfo->mClientUsages[mClientType] = newClientUsage;
|
||||
|
||||
mOriginInfo->mUsage = newUsage;
|
||||
if (!mOriginInfo->LockedPersisted()) {
|
||||
groupInfo->mUsage = newGroupUsage;
|
||||
@ -2990,6 +3025,8 @@ bool QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mOriginInfo->mClientUsages[mClientType] = newClientUsage;
|
||||
|
||||
mOriginInfo->mUsage = newUsage;
|
||||
if (!mOriginInfo->LockedPersisted()) {
|
||||
groupInfo->mUsage = newGroupUsage;
|
||||
@ -3346,7 +3383,7 @@ uint64_t QuotaManager::CollectOriginsForEviction(
|
||||
break;
|
||||
}
|
||||
|
||||
sizeToBeFreed += inactiveOrigins[index]->mUsage;
|
||||
sizeToBeFreed += inactiveOrigins[index]->LockedUsage();
|
||||
}
|
||||
|
||||
if (sizeToBeFreed >= aMinSizeToBeFreed) {
|
||||
@ -3517,6 +3554,7 @@ void QuotaManager::Shutdown() {
|
||||
void QuotaManager::InitQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const ClientUsageArray& aClientUsages,
|
||||
uint64_t aUsageBytes, int64_t aAccessTime,
|
||||
bool aPersisted) {
|
||||
AssertIsOnIOThread();
|
||||
@ -3527,9 +3565,9 @@ void QuotaManager::InitQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
RefPtr<GroupInfo> groupInfo =
|
||||
LockedGetOrCreateGroupInfo(aPersistenceType, aGroup);
|
||||
|
||||
RefPtr<OriginInfo> originInfo =
|
||||
new OriginInfo(groupInfo, aOrigin, aUsageBytes, aAccessTime, aPersisted,
|
||||
/* aDirectoryExists */ true);
|
||||
RefPtr<OriginInfo> originInfo = new OriginInfo(
|
||||
groupInfo, aOrigin, aClientUsages, aUsageBytes, aAccessTime, aPersisted,
|
||||
/* aDirectoryExists */ true);
|
||||
groupInfo->LockedAddOriginInfo(originInfo);
|
||||
}
|
||||
|
||||
@ -3547,8 +3585,9 @@ void QuotaManager::EnsureQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
RefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(aOrigin);
|
||||
if (!originInfo) {
|
||||
originInfo = new OriginInfo(
|
||||
groupInfo, aOrigin, /* aUsageBytes */ 0, /* aAccessTime */ PR_Now(),
|
||||
/* aPersisted */ false, /* aDirectoryExists */ false);
|
||||
groupInfo, aOrigin, ClientUsageArray(), /* aUsageBytes */ 0,
|
||||
/* aAccessTime */ PR_Now(), /* aPersisted */ false,
|
||||
/* aDirectoryExists */ false);
|
||||
groupInfo->LockedAddOriginInfo(originInfo);
|
||||
}
|
||||
}
|
||||
@ -3576,8 +3615,8 @@ void QuotaManager::NoteOriginDirectoryCreated(PersistenceType aPersistenceType,
|
||||
} else {
|
||||
timestamp = PR_Now();
|
||||
RefPtr<OriginInfo> originInfo = new OriginInfo(
|
||||
groupInfo, aOrigin, /* aUsageBytes */ 0, /* aAccessTime */ timestamp,
|
||||
aPersisted, /* aDirectoryExists */ true);
|
||||
groupInfo, aOrigin, ClientUsageArray(), /* aUsageBytes */ 0,
|
||||
/* aAccessTime */ timestamp, aPersisted, /* aDirectoryExists */ true);
|
||||
groupInfo->LockedAddOriginInfo(originInfo);
|
||||
}
|
||||
|
||||
@ -3587,6 +3626,7 @@ void QuotaManager::NoteOriginDirectoryCreated(PersistenceType aPersistenceType,
|
||||
void QuotaManager::DecreaseUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
Client::Type aClientType,
|
||||
int64_t aSize) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT);
|
||||
@ -3605,7 +3645,32 @@ void QuotaManager::DecreaseUsageForOrigin(PersistenceType aPersistenceType,
|
||||
|
||||
RefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(aOrigin);
|
||||
if (originInfo) {
|
||||
originInfo->LockedDecreaseUsage(aSize);
|
||||
originInfo->LockedDecreaseUsage(aClientType, aSize);
|
||||
}
|
||||
}
|
||||
|
||||
void QuotaManager::ResetUsageForClient(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
Client::Type aClientType) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT);
|
||||
|
||||
MutexAutoLock lock(mQuotaMutex);
|
||||
|
||||
GroupInfoPair* pair;
|
||||
if (!mGroupInfoPairs.Get(aGroup, &pair)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<GroupInfo> groupInfo = pair->LockedGetGroupInfo(aPersistenceType);
|
||||
if (!groupInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(aOrigin);
|
||||
if (originInfo) {
|
||||
originInfo->LockedResetUsageForClient(aClientType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3671,8 +3736,8 @@ void QuotaManager::RemoveQuota() {
|
||||
|
||||
already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int64_t aFileSize,
|
||||
int64_t* aFileSizeOut /* = nullptr */) {
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int64_t aFileSize, int64_t* aFileSizeOut /* = nullptr */) {
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (aFileSizeOut) {
|
||||
@ -3687,6 +3752,34 @@ already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
nsresult rv = aFile->GetPath(path);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
rv = GetDirectoryForOrigin(aPersistenceType, aOrigin,
|
||||
getter_AddRefs(directory));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoString clientType;
|
||||
rv = Client::TypeToText(aClientType, clientType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = directory->Append(clientType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsString directoryPath;
|
||||
rv = directory->GetPath(directoryPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(StringBeginsWith(path, directoryPath));
|
||||
#endif
|
||||
|
||||
int64_t fileSize;
|
||||
|
||||
if (aFileSize == -1) {
|
||||
@ -3731,7 +3824,7 @@ already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
QuotaObject* quotaObject;
|
||||
if (!originInfo->mQuotaObjects.Get(path, "aObject)) {
|
||||
// Create a new QuotaObject.
|
||||
quotaObject = new QuotaObject(originInfo, path, fileSize);
|
||||
quotaObject = new QuotaObject(originInfo, aClientType, path, fileSize);
|
||||
|
||||
// Put it to the hashtable. The hashtable is not responsible to delete
|
||||
// the QuotaObject.
|
||||
@ -3754,8 +3847,8 @@ already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
|
||||
already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, const nsAString& aPath, int64_t aFileSize,
|
||||
int64_t* aFileSizeOut /* = nullptr */) {
|
||||
const nsACString& aOrigin, Client::Type aClientType, const nsAString& aPath,
|
||||
int64_t aFileSize, int64_t* aFileSizeOut /* = nullptr */) {
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (aFileSizeOut) {
|
||||
@ -3766,8 +3859,8 @@ already_AddRefed<QuotaObject> QuotaManager::GetQuotaObject(
|
||||
nsresult rv = NS_NewLocalFile(aPath, false, getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return GetQuotaObject(aPersistenceType, aGroup, aOrigin, file, aFileSize,
|
||||
aFileSizeOut);
|
||||
return GetQuotaObject(aPersistenceType, aGroup, aOrigin, aClientType, file,
|
||||
aFileSize, aFileSizeOut);
|
||||
}
|
||||
|
||||
Nullable<bool> QuotaManager::OriginPersisted(const nsACString& aGroup,
|
||||
@ -4171,10 +4264,10 @@ nsresult QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
|
||||
|
||||
// We need to initialize directories of all clients if they exists and also
|
||||
// get the total usage to initialize the quota.
|
||||
nsAutoPtr<UsageInfo> usageInfo;
|
||||
if (trackQuota) {
|
||||
usageInfo = new UsageInfo();
|
||||
}
|
||||
|
||||
ClientUsageArray clientUsages;
|
||||
|
||||
uint64_t usage = 0;
|
||||
|
||||
// A keeper to defer the return only in Nightly, so that the telemetry data
|
||||
// for whole profile can be collected
|
||||
@ -4274,15 +4367,25 @@ nsresult QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
|
||||
CONTINUE_IN_NIGHTLY_RETURN_IN_OTHERS(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
Atomic<bool> dummy(false);
|
||||
UsageInfo usageInfo;
|
||||
rv = mClients[clientType]->InitOrigin(aPersistenceType, aGroup, aOrigin,
|
||||
/* aCanceled */ dummy, usageInfo,
|
||||
/* aCanceled */ Atomic<bool>(false),
|
||||
trackQuota ? &usageInfo : nullptr,
|
||||
/* aForGetUsage */ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// error should have reported in InitOrigin
|
||||
RECORD_IN_NIGHTLY(statusKeeper, rv);
|
||||
CONTINUE_IN_NIGHTLY_RETURN_IN_OTHERS(rv);
|
||||
}
|
||||
|
||||
if (trackQuota) {
|
||||
uint64_t clientUsage = usageInfo.TotalUsage();
|
||||
|
||||
clientUsages[clientType] = clientUsage;
|
||||
|
||||
AssertNoOverflow(usage, clientUsage);
|
||||
usage += clientUsage;
|
||||
}
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
REPORT_TELEMETRY_INIT_ERR(kQuotaInternalError, Ori_GetNextFile);
|
||||
@ -4299,8 +4402,8 @@ nsresult QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
|
||||
#endif
|
||||
|
||||
if (trackQuota) {
|
||||
InitQuotaForOrigin(aPersistenceType, aGroup, aOrigin,
|
||||
usageInfo->TotalUsage(), aAccessTime, aPersisted);
|
||||
InitQuotaForOrigin(aPersistenceType, aGroup, aOrigin, clientUsages, usage,
|
||||
aAccessTime, aPersisted);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -6410,7 +6513,7 @@ void QuotaManager::CheckTemporaryStorageLimits() {
|
||||
}
|
||||
|
||||
doomedOriginInfos.AppendElement(originInfo);
|
||||
groupUsage -= originInfo->mUsage;
|
||||
groupUsage -= originInfo->LockedUsage();
|
||||
|
||||
if (groupUsage <= quotaManager->GetGroupLimit()) {
|
||||
break;
|
||||
@ -6422,7 +6525,7 @@ void QuotaManager::CheckTemporaryStorageLimits() {
|
||||
|
||||
uint64_t usage = 0;
|
||||
for (uint32_t index = 0; index < doomedOriginInfos.Length(); index++) {
|
||||
usage += doomedOriginInfos[index]->mUsage;
|
||||
usage += doomedOriginInfos[index]->LockedUsage();
|
||||
}
|
||||
|
||||
if (mTemporaryStorageUsage - usage > mTemporaryStorageLimit) {
|
||||
@ -6461,7 +6564,7 @@ void QuotaManager::CheckTemporaryStorageLimits() {
|
||||
break;
|
||||
}
|
||||
|
||||
usage += originInfos[i]->mUsage;
|
||||
usage += originInfos[i]->LockedUsage();
|
||||
}
|
||||
|
||||
doomedOriginInfos.AppendElements(originInfos);
|
||||
@ -6600,24 +6703,39 @@ bool QuotaManager::IsSanitizedOriginValid(const nsACString& aSanitizedOrigin) {
|
||||
******************************************************************************/
|
||||
|
||||
OriginInfo::OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
|
||||
uint64_t aUsage, int64_t aAccessTime, bool aPersisted,
|
||||
const ClientUsageArray& aClientUsages, uint64_t aUsage,
|
||||
int64_t aAccessTime, bool aPersisted,
|
||||
bool aDirectoryExists)
|
||||
: mGroupInfo(aGroupInfo),
|
||||
: mClientUsages(aClientUsages),
|
||||
mGroupInfo(aGroupInfo),
|
||||
mOrigin(aOrigin),
|
||||
mUsage(aUsage),
|
||||
mAccessTime(aAccessTime),
|
||||
mPersisted(aPersisted),
|
||||
mDirectoryExists(aDirectoryExists) {
|
||||
MOZ_ASSERT(aGroupInfo);
|
||||
MOZ_ASSERT(aClientUsages.Length() == Client::TypeMax());
|
||||
MOZ_ASSERT_IF(aPersisted,
|
||||
aGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
|
||||
|
||||
#ifdef DEBUG
|
||||
uint64_t usage = 0;
|
||||
for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
|
||||
AssertNoOverflow(usage, aClientUsages[index]);
|
||||
usage += aClientUsages[index];
|
||||
}
|
||||
MOZ_ASSERT(aUsage == usage);
|
||||
#endif
|
||||
|
||||
MOZ_COUNT_CTOR(OriginInfo);
|
||||
}
|
||||
|
||||
void OriginInfo::LockedDecreaseUsage(int64_t aSize) {
|
||||
void OriginInfo::LockedDecreaseUsage(Client::Type aClientType, int64_t aSize) {
|
||||
AssertCurrentThreadOwnsQuotaMutex();
|
||||
|
||||
AssertNoUnderflow(mClientUsages[aClientType], aSize);
|
||||
mClientUsages[aClientType] -= aSize;
|
||||
|
||||
AssertNoUnderflow(mUsage, aSize);
|
||||
mUsage -= aSize;
|
||||
|
||||
@ -6633,6 +6751,28 @@ void OriginInfo::LockedDecreaseUsage(int64_t aSize) {
|
||||
quotaManager->mTemporaryStorageUsage -= aSize;
|
||||
}
|
||||
|
||||
void OriginInfo::LockedResetUsageForClient(Client::Type aClientType) {
|
||||
AssertCurrentThreadOwnsQuotaMutex();
|
||||
|
||||
uint64_t size = mClientUsages[aClientType];
|
||||
|
||||
mClientUsages[aClientType] = 0;
|
||||
|
||||
AssertNoUnderflow(mUsage, size);
|
||||
mUsage -= size;
|
||||
|
||||
if (!LockedPersisted()) {
|
||||
AssertNoUnderflow(mGroupInfo->mUsage, size);
|
||||
mGroupInfo->mUsage -= size;
|
||||
}
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, size);
|
||||
quotaManager->mTemporaryStorageUsage -= size;
|
||||
}
|
||||
|
||||
void OriginInfo::LockedPersist() {
|
||||
AssertCurrentThreadOwnsQuotaMutex();
|
||||
MOZ_ASSERT(mGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
|
||||
@ -6666,16 +6806,18 @@ void GroupInfo::LockedAddOriginInfo(OriginInfo* aOriginInfo) {
|
||||
"Replacing an existing entry!");
|
||||
mOriginInfos.AppendElement(aOriginInfo);
|
||||
|
||||
uint64_t usage = aOriginInfo->LockedUsage();
|
||||
|
||||
if (!aOriginInfo->LockedPersisted()) {
|
||||
AssertNoOverflow(mUsage, aOriginInfo->mUsage);
|
||||
mUsage += aOriginInfo->mUsage;
|
||||
AssertNoOverflow(mUsage, usage);
|
||||
mUsage += usage;
|
||||
}
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
AssertNoOverflow(quotaManager->mTemporaryStorageUsage, aOriginInfo->mUsage);
|
||||
quotaManager->mTemporaryStorageUsage += aOriginInfo->mUsage;
|
||||
AssertNoOverflow(quotaManager->mTemporaryStorageUsage, usage);
|
||||
quotaManager->mTemporaryStorageUsage += usage;
|
||||
}
|
||||
|
||||
void GroupInfo::LockedRemoveOriginInfo(const nsACString& aOrigin) {
|
||||
@ -6683,17 +6825,18 @@ void GroupInfo::LockedRemoveOriginInfo(const nsACString& aOrigin) {
|
||||
|
||||
for (uint32_t index = 0; index < mOriginInfos.Length(); index++) {
|
||||
if (mOriginInfos[index]->mOrigin == aOrigin) {
|
||||
uint64_t usage = mOriginInfos[index]->LockedUsage();
|
||||
|
||||
if (!mOriginInfos[index]->LockedPersisted()) {
|
||||
AssertNoUnderflow(mUsage, mOriginInfos[index]->mUsage);
|
||||
mUsage -= mOriginInfos[index]->mUsage;
|
||||
AssertNoUnderflow(mUsage, usage);
|
||||
mUsage -= usage;
|
||||
}
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage,
|
||||
mOriginInfos[index]->mUsage);
|
||||
quotaManager->mTemporaryStorageUsage -= mOriginInfos[index]->mUsage;
|
||||
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, usage);
|
||||
quotaManager->mTemporaryStorageUsage -= usage;
|
||||
|
||||
mOriginInfos.RemoveElementAt(index);
|
||||
|
||||
@ -6711,13 +6854,15 @@ void GroupInfo::LockedRemoveOriginInfos() {
|
||||
for (uint32_t index = mOriginInfos.Length(); index > 0; index--) {
|
||||
OriginInfo* originInfo = mOriginInfos[index - 1];
|
||||
|
||||
uint64_t usage = originInfo->LockedUsage();
|
||||
|
||||
if (!originInfo->LockedPersisted()) {
|
||||
AssertNoUnderflow(mUsage, originInfo->mUsage);
|
||||
mUsage -= originInfo->mUsage;
|
||||
AssertNoUnderflow(mUsage, usage);
|
||||
mUsage -= usage;
|
||||
}
|
||||
|
||||
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, originInfo->mUsage);
|
||||
quotaManager->mTemporaryStorageUsage -= originInfo->mUsage;
|
||||
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, usage);
|
||||
quotaManager->mTemporaryStorageUsage -= usage;
|
||||
|
||||
mOriginInfos.RemoveElementAt(index - 1);
|
||||
}
|
||||
@ -8199,17 +8344,8 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
return;
|
||||
}
|
||||
|
||||
bool initialized;
|
||||
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
initialized = aQuotaManager->IsOriginInitialized(origin);
|
||||
} else {
|
||||
initialized = aQuotaManager->IsTemporaryStorageInitialized();
|
||||
}
|
||||
|
||||
bool hasOtherClient = false;
|
||||
|
||||
UsageInfo usageInfo;
|
||||
|
||||
if (!mClientType.IsNull()) {
|
||||
// Checking whether there is any other client in the directory is needed.
|
||||
// If there is not, removing whole directory is needed.
|
||||
@ -8275,18 +8411,6 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (initialized) {
|
||||
Client* client = aQuotaManager->GetClient(mClientType.Value());
|
||||
MOZ_ASSERT(client);
|
||||
|
||||
Atomic<bool> dummy(false);
|
||||
rv = client->GetUsageForOrigin(aPersistenceType, group, origin, dummy,
|
||||
&usageInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < 10; index++) {
|
||||
@ -8304,6 +8428,13 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
NS_WARNING("Failed to remove directory, giving up!");
|
||||
}
|
||||
|
||||
bool initialized;
|
||||
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
initialized = aQuotaManager->IsOriginInitialized(origin);
|
||||
} else {
|
||||
initialized = aQuotaManager->IsTemporaryStorageInitialized();
|
||||
}
|
||||
|
||||
// If it hasn't been initialized, we don't need to update the quota and
|
||||
// notify the removing client.
|
||||
if (!initialized) {
|
||||
@ -8314,8 +8445,8 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
if (hasOtherClient) {
|
||||
MOZ_ASSERT(!mClientType.IsNull());
|
||||
|
||||
aQuotaManager->DecreaseUsageForOrigin(aPersistenceType, group, origin,
|
||||
usageInfo.TotalUsage());
|
||||
aQuotaManager->ResetUsageForClient(aPersistenceType, group, origin,
|
||||
mClientType.Value());
|
||||
} else {
|
||||
aQuotaManager->RemoveQuotaForOrigin(aPersistenceType, group, origin);
|
||||
}
|
||||
|
@ -58,6 +58,33 @@ class Client {
|
||||
|
||||
virtual Type GetType() = 0;
|
||||
|
||||
static void TypeToText(Type aType, nsACString& aText) {
|
||||
switch (aType) {
|
||||
case IDB:
|
||||
aText.AssignLiteral(IDB_DIRECTORY_NAME);
|
||||
return;
|
||||
|
||||
case DOMCACHE:
|
||||
aText.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
|
||||
return;
|
||||
|
||||
case SDB:
|
||||
aText.AssignLiteral(SDB_DIRECTORY_NAME);
|
||||
return;
|
||||
|
||||
case LS:
|
||||
if (CachedNextGenLocalStorageEnabled()) {
|
||||
aText.AssignLiteral(LS_DIRECTORY_NAME);
|
||||
return;
|
||||
}
|
||||
MOZ_FALLTHROUGH;
|
||||
|
||||
case TYPE_MAX:
|
||||
default:
|
||||
MOZ_CRASH("Bad client type value!");
|
||||
}
|
||||
}
|
||||
|
||||
static nsresult TypeToText(Type aType, nsAString& aText) {
|
||||
switch (aType) {
|
||||
case IDB:
|
||||
@ -88,6 +115,27 @@ class Client {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static Type TypeFromText(const nsACString& aText) {
|
||||
if (aText.EqualsLiteral(IDB_DIRECTORY_NAME)) {
|
||||
return IDB;
|
||||
}
|
||||
|
||||
if (aText.EqualsLiteral(DOMCACHE_DIRECTORY_NAME)) {
|
||||
return DOMCACHE;
|
||||
}
|
||||
|
||||
if (aText.EqualsLiteral(SDB_DIRECTORY_NAME)) {
|
||||
return SDB;
|
||||
}
|
||||
|
||||
if (CachedNextGenLocalStorageEnabled() &&
|
||||
aText.EqualsLiteral(LS_DIRECTORY_NAME)) {
|
||||
return LS;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
static nsresult TypeFromText(const nsAString& aText, Type& aType) {
|
||||
if (aText.EqualsLiteral(IDB_DIRECTORY_NAME)) {
|
||||
aType = IDB;
|
||||
|
@ -44,7 +44,8 @@ nsresult FileQuotaStream<FileStreamBase>::DoOpen() {
|
||||
|
||||
NS_ASSERTION(!mQuotaObject, "Creating quota object more than once?");
|
||||
mQuotaObject = quotaManager->GetQuotaObject(
|
||||
mPersistenceType, mGroup, mOrigin, FileStreamBase::mOpenParams.localFile);
|
||||
mPersistenceType, mGroup, mOrigin, mClientType,
|
||||
FileStreamBase::mOpenParams.localFile);
|
||||
|
||||
nsresult rv = FileStreamBase::DoOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -83,10 +84,10 @@ NS_IMETHODIMP FileQuotaStreamWithWrite<FileStreamBase>::Write(
|
||||
|
||||
already_AddRefed<FileInputStream> CreateFileInputStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
|
||||
int32_t aBehaviorFlags) {
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags, int32_t aPerm, int32_t aBehaviorFlags) {
|
||||
RefPtr<FileInputStream> stream =
|
||||
new FileInputStream(aPersistenceType, aGroup, aOrigin);
|
||||
new FileInputStream(aPersistenceType, aGroup, aOrigin, aClientType);
|
||||
nsresult rv = stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return stream.forget();
|
||||
@ -94,22 +95,21 @@ already_AddRefed<FileInputStream> CreateFileInputStream(
|
||||
|
||||
already_AddRefed<FileOutputStream> CreateFileOutputStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
|
||||
int32_t aBehaviorFlags) {
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags, int32_t aPerm, int32_t aBehaviorFlags) {
|
||||
RefPtr<FileOutputStream> stream =
|
||||
new FileOutputStream(aPersistenceType, aGroup, aOrigin);
|
||||
new FileOutputStream(aPersistenceType, aGroup, aOrigin, aClientType);
|
||||
nsresult rv = stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<FileStream> CreateFileStream(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
nsIFile* aFile, int32_t aIOFlags,
|
||||
int32_t aPerm,
|
||||
int32_t aBehaviorFlags) {
|
||||
RefPtr<FileStream> stream = new FileStream(aPersistenceType, aGroup, aOrigin);
|
||||
already_AddRefed<FileStream> CreateFileStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags, int32_t aPerm, int32_t aBehaviorFlags) {
|
||||
RefPtr<FileStream> stream =
|
||||
new FileStream(aPersistenceType, aGroup, aOrigin, aClientType);
|
||||
nsresult rv = stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return stream.forget();
|
||||
|
@ -28,8 +28,11 @@ class FileQuotaStream : public FileStreamBase {
|
||||
|
||||
protected:
|
||||
FileQuotaStream(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
: mPersistenceType(aPersistenceType), mGroup(aGroup), mOrigin(aOrigin) {}
|
||||
const nsACString& aOrigin, Client::Type aClientType)
|
||||
: mPersistenceType(aPersistenceType),
|
||||
mGroup(aGroup),
|
||||
mOrigin(aOrigin),
|
||||
mClientType(aClientType) {}
|
||||
|
||||
// nsFileStreamBase override
|
||||
virtual nsresult DoOpen() override;
|
||||
@ -37,6 +40,7 @@ class FileQuotaStream : public FileStreamBase {
|
||||
PersistenceType mPersistenceType;
|
||||
nsCString mGroup;
|
||||
nsCString mOrigin;
|
||||
Client::Type mClientType;
|
||||
RefPtr<QuotaObject> mQuotaObject;
|
||||
};
|
||||
|
||||
@ -49,8 +53,10 @@ class FileQuotaStreamWithWrite : public FileQuotaStream<FileStreamBase> {
|
||||
|
||||
protected:
|
||||
FileQuotaStreamWithWrite(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup, const nsACString& aOrigin)
|
||||
: FileQuotaStream<FileStreamBase>(aPersistenceType, aGroup, aOrigin) {}
|
||||
const nsACString& aGroup, const nsACString& aOrigin,
|
||||
Client::Type aClientType)
|
||||
: FileQuotaStream<FileStreamBase>(aPersistenceType, aGroup, aOrigin,
|
||||
aClientType) {}
|
||||
};
|
||||
|
||||
class FileInputStream : public FileQuotaStream<nsFileInputStream> {
|
||||
@ -59,8 +65,9 @@ class FileInputStream : public FileQuotaStream<nsFileInputStream> {
|
||||
FileQuotaStream<nsFileInputStream>)
|
||||
|
||||
FileInputStream(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
: FileQuotaStream<nsFileInputStream>(aPersistenceType, aGroup, aOrigin) {}
|
||||
const nsACString& aOrigin, Client::Type aClientType)
|
||||
: FileQuotaStream<nsFileInputStream>(aPersistenceType, aGroup, aOrigin,
|
||||
aClientType) {}
|
||||
|
||||
private:
|
||||
virtual ~FileInputStream() { Close(); }
|
||||
@ -72,9 +79,9 @@ class FileOutputStream : public FileQuotaStreamWithWrite<nsFileOutputStream> {
|
||||
FileOutputStream, FileQuotaStreamWithWrite<nsFileOutputStream>);
|
||||
|
||||
FileOutputStream(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
const nsACString& aOrigin, Client::Type aClientType)
|
||||
: FileQuotaStreamWithWrite<nsFileOutputStream>(aPersistenceType, aGroup,
|
||||
aOrigin) {}
|
||||
aOrigin, aClientType) {}
|
||||
|
||||
private:
|
||||
virtual ~FileOutputStream() { Close(); }
|
||||
@ -86,9 +93,9 @@ class FileStream : public FileQuotaStreamWithWrite<nsFileStream> {
|
||||
FileQuotaStreamWithWrite<nsFileStream>)
|
||||
|
||||
FileStream(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
const nsACString& aOrigin, Client::Type aClientType)
|
||||
: FileQuotaStreamWithWrite<nsFileStream>(aPersistenceType, aGroup,
|
||||
aOrigin) {}
|
||||
aOrigin, aClientType) {}
|
||||
|
||||
private:
|
||||
virtual ~FileStream() { Close(); }
|
||||
@ -96,18 +103,18 @@ class FileStream : public FileQuotaStreamWithWrite<nsFileStream> {
|
||||
|
||||
already_AddRefed<FileInputStream> CreateFileInputStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int32_t aIOFlags = -1,
|
||||
int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags = -1, int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
|
||||
already_AddRefed<FileOutputStream> CreateFileOutputStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int32_t aIOFlags = -1,
|
||||
int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags = -1, int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
|
||||
already_AddRefed<FileStream> CreateFileStream(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, nsIFile* aFile, int32_t aIOFlags = -1,
|
||||
int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int32_t aIOFlags = -1, int32_t aPerm = -1, int32_t aBehaviorFlags = 0);
|
||||
|
||||
END_QUOTA_NAMESPACE
|
||||
|
||||
|
@ -46,6 +46,7 @@ class PrincipalInfo;
|
||||
|
||||
BEGIN_QUOTA_NAMESPACE
|
||||
|
||||
class ClientUsageArray;
|
||||
class DirectoryLockImpl;
|
||||
class GroupInfo;
|
||||
class GroupInfoPair;
|
||||
@ -153,6 +154,7 @@ class QuotaManager final : public BackgroundThreadObject {
|
||||
*/
|
||||
void InitQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup, const nsACString& aOrigin,
|
||||
const ClientUsageArray& aClientUsages,
|
||||
uint64_t aUsageBytes, int64_t aAccessTime,
|
||||
bool aPersisted);
|
||||
|
||||
@ -181,9 +183,15 @@ class QuotaManager final : public BackgroundThreadObject {
|
||||
const nsACString& aOrigin, bool aPersisted,
|
||||
int64_t& aTimestamp);
|
||||
|
||||
// XXX clients can use QuotaObject instead of calling this method directly.
|
||||
void DecreaseUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin, int64_t aSize);
|
||||
const nsACString& aOrigin,
|
||||
Client::Type aClientType, int64_t aSize);
|
||||
|
||||
void ResetUsageForClient(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup, const nsACString& aOrigin,
|
||||
Client::Type aClientType);
|
||||
|
||||
void UpdateOriginAccessTime(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
@ -198,16 +206,15 @@ class QuotaManager final : public BackgroundThreadObject {
|
||||
LockedRemoveQuotaForOrigin(aPersistenceType, aGroup, aOrigin);
|
||||
}
|
||||
|
||||
already_AddRefed<QuotaObject> GetQuotaObject(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
nsIFile* aFile,
|
||||
int64_t aFileSize = -1,
|
||||
int64_t* aFileSizeOut = nullptr);
|
||||
already_AddRefed<QuotaObject> GetQuotaObject(
|
||||
PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
||||
int64_t aFileSize = -1, int64_t* aFileSizeOut = nullptr);
|
||||
|
||||
already_AddRefed<QuotaObject> GetQuotaObject(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
Client::Type aClientType,
|
||||
const nsAString& aPath,
|
||||
int64_t aFileSize = -1,
|
||||
int64_t* aFileSizeOut = nullptr);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
#include "Client.h"
|
||||
#include "PersistenceType.h"
|
||||
|
||||
BEGIN_QUOTA_NAMESPACE
|
||||
@ -40,10 +41,12 @@ class QuotaObject {
|
||||
void EnableQuotaCheck();
|
||||
|
||||
private:
|
||||
QuotaObject(OriginInfo* aOriginInfo, const nsAString& aPath, int64_t aSize)
|
||||
QuotaObject(OriginInfo* aOriginInfo, Client::Type aClientType,
|
||||
const nsAString& aPath, int64_t aSize)
|
||||
: mOriginInfo(aOriginInfo),
|
||||
mPath(aPath),
|
||||
mSize(aSize),
|
||||
mClientType(aClientType),
|
||||
mQuotaCheckDisabled(false),
|
||||
mWritingDone(false) {
|
||||
MOZ_COUNT_CTOR(QuotaObject);
|
||||
@ -67,7 +70,7 @@ class QuotaObject {
|
||||
OriginInfo* mOriginInfo;
|
||||
nsString mPath;
|
||||
int64_t mSize;
|
||||
|
||||
Client::Type mClientType;
|
||||
bool mQuotaCheckDisabled;
|
||||
bool mWritingDone;
|
||||
};
|
||||
|
@ -1119,7 +1119,8 @@ nsresult OpenOp::SendToIOThread() {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mFileStream = new FileStream(PERSISTENCE_TYPE_DEFAULT, mGroup, mOrigin);
|
||||
mFileStream = new FileStream(PERSISTENCE_TYPE_DEFAULT, mGroup, mOrigin,
|
||||
mozilla::dom::quota::Client::SDB);
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
@ -319,6 +319,15 @@ already_AddRefed<QuotaObject> GetQuotaObjectFromNameAndParameters(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* clientType =
|
||||
sqlite3_uri_parameter(zURIParameterKey, "clientType");
|
||||
if (!clientType) {
|
||||
NS_WARNING(
|
||||
"SQLite URI had 'persistenceType', 'group' and 'origin' but not "
|
||||
"'clientType'?!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Re-escape group and origin to make sure we get the right quota group and
|
||||
// origin.
|
||||
nsAutoCString escGroup;
|
||||
@ -339,7 +348,8 @@ already_AddRefed<QuotaObject> GetQuotaObjectFromNameAndParameters(
|
||||
|
||||
return quotaManager->GetQuotaObject(
|
||||
PersistenceTypeFromText(nsDependentCString(persistenceType)), escGroup,
|
||||
escOrigin, NS_ConvertUTF8toUTF16(zName));
|
||||
escOrigin, Client::TypeFromText(nsDependentCString(clientType)),
|
||||
NS_ConvertUTF8toUTF16(zName));
|
||||
}
|
||||
|
||||
void MaybeEstablishQuotaControl(const char* zName, telemetry_file* pFile,
|
||||
|
Loading…
Reference in New Issue
Block a user