/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::dom::quota::AssertIsOnIOThread; using mozilla::dom::quota::Client; using mozilla::dom::quota::CloneFileAndAppend; using mozilla::dom::quota::DatabaseUsageType; using mozilla::dom::quota::GetDirEntryKind; using mozilla::dom::quota::nsIFileKind; using mozilla::dom::quota::OriginMetadata; using mozilla::dom::quota::PrincipalMetadata; using mozilla::dom::quota::QuotaManager; using mozilla::dom::quota::UsageInfo; using mozilla::ipc::AssertIsOnBackgroundThread;
Result<int64_t, nsresult> GetPaddingSizeFromDB(
nsIFile& aDir, nsIFile& aDBFile, const OriginMetadata& aOriginMetadata, const Maybe<CipherKey>& aMaybeCipherKey) {
CacheDirectoryMetadata directoryMetadata(aOriginMetadata); // directoryMetadata.mDirectoryLockId must be -1 (which is default for new // CacheDirectoryMetadata) because this method should only be called from // QuotaClient::InitOrigin when the temporary storage hasn't been initialized // yet. At that time, the in-memory objects (e.g. OriginInfo) are only being // created so it doesn't make sense to tunnel quota information to QuotaVFS // to get corresponding QuotaObject instance for the SQLite file).
MOZ_DIAGNOSTIC_ASSERT(directoryMetadata.mDirectoryLockId == -1);
// Make sure that the database has the latest schema before we try to read // from it. We have to do this because GetPaddingSizeFromDB is called // by InitOrigin. And it means that SetupAction::RunSyncWithDBOnTarget hasn't // checked the schema for the given origin yet).
QM_TRY(MOZ_TO_RESULT(db::CreateOrMigrateSchema(aDir, *conn)));
Result<int64_t, nsresult> GetTotalDiskUsageFromDB(
nsIFile& aDir, nsIFile& aDBFile, const OriginMetadata& aOriginMetadata, const Maybe<CipherKey>& aMaybeCipherKey) {
CacheDirectoryMetadata directoryMetadata(aOriginMetadata); // directoryMetadata.mDirectoryLockId must be -1 (which is default for new // CacheDirectoryMetadata) because this method should only be called from // QuotaClient::InitOrigin when the temporary storage hasn't been initialized // yet. At that time, the in-memory objects (e.g. OriginInfo) are only being // created so it doesn't make sense to tunnel quota information to QuotaVFS // to get corresponding QuotaObject instance for the SQLite file).
MOZ_DIAGNOSTIC_ASSERT(directoryMetadata.mDirectoryLockId == -1);
// Make sure that the database has the latest schema before we try to read // from it. We have to do this because GetTotalDiskUsageFromDB is called // by InitOrigin. And it means that SetupAction::RunSyncWithDBOnTarget hasn't // checked the schema for the given origin yet).
QM_TRY(MOZ_TO_RESULT(db::CreateOrMigrateSchema(aDir, *conn)));
// IsDirectory is used to check if caches.sqlite exists or not. Another // benefit of this is that we can test the failed cases by creating a // directory named "caches.sqlite".
QM_TRY_INSPECT(constauto& dirEntryKind,
GetDirEntryKind(*cachesSQLite)); if (dirEntryKind == nsIFileKind::DoesNotExist) { // We only ensure padding files and morgue directory get removed like // WipeDatabase in DBAction.cpp. The -wal journal file will be // automatically deleted by sqlite when the new database is created. // XXX Ideally, we would delete the -wal journal file as well (here // and also in WipeDatabase). // XXX We should have something like WipeDatabaseNoQuota for this. // XXX Long term, we might even think about removing entire origin // directory because missing caches.sqlite while other files exist can // be interpreted as database corruption.
QM_TRY(MOZ_TO_RESULT(mozilla::dom::cache::DirectoryPaddingDeleteFile(
*dir, DirPaddingFile::TMP_FILE)));
// If the caches.sqlite doesn't exist, then padding files and morgue directory // should have been removed if they existed. We ignore the rest of known files // because we assume that they will be removed when a new database is created. // XXX Ensure the -wel file is removed if the caches.sqlite doesn't exist.
QM_TRY(OkIf(!!cachesSQLiteFile), UsageInfo{});
// If the temporary file still exists or failing to get the padding size // from the padding file, then we need to get the padding size from the // database and restore the padding file.
QM_TRY_RETURN(GetPaddingSizeFromDB(*dir, *cachesSQLiteFile,
aOriginMetadata, maybeCipherKey));
}()));
case nsIFileKind::DoesNotExist: // Ignore files that got removed externally while iterating. break;
}
return UsageInfo{};
}));
// FIXME: Separate file usage and database usage in OriginInfo so that the // workaround for treating padding file size as database usage can be removed. return UsageInfo{DatabaseUsageType(Some(paddingSize))} +
UsageInfo{DatabaseUsageType(Some(totalDiskUsage))} + innerUsageInfo;
}
// This is called when a storage/permanent/${origin}/cache directory exists. // Even though this shouldn't happen with a "good" profile, we shouldn't // return an error here, since that would cause origin initialization to fail. // We just warn and otherwise ignore that.
UNKNOWN_FILE_WARNING(NS_LITERAL_STRING_FROM_CSTRING(DOMCACHE_DIRECTORY_NAME)); return NS_OK;
}
void CacheQuotaClient::AbortOperationsForProcess(
ContentParentId aContentParentId) { // The Cache and Context can be shared by multiple client processes. They // are not exclusively owned by a single process. // // As far as I can tell this is used by QuotaManager to abort operations // when a particular process goes away. We definitely don't want this // since we are shared. Also, the Cache actor code already properly // handles asynchronous actor destruction when the child process dies. // // Therefore, do nothing here.
}
if (temporaryPaddingFileExist || !directoryPaddingGetResult) { // XXXtt: Maybe have a method in the QuotaManager to clean the usage // under the quota client and the origin. There is nothing we can do // to recover the file.
NS_WARNING("Cannnot read padding size from file!"); return 0;
}
return *directoryPaddingGetResult;
}()));
if (paddingSize > 0) {
DecreaseUsageForDirectoryMetadata(aDirectoryMetadata, paddingSize);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.