Bug 1290481 - P4: Update padding size to the QuotaManager. r=bkelly, janv

MozReview-Commit-ID: 6poDeyErBjc

--HG--
extra : rebase_source : c7f556ad5c4516c0509a998c16c086795e5fa4b2
This commit is contained in:
Tom Tung 2017-07-10 17:02:44 +08:00
Родитель 280d7fa36c
Коммит 29522efbef
6 изменённых файлов: 197 добавлений и 31 удалений

68
dom/cache/FileUtils.cpp поставляемый
Просмотреть файл

@ -6,6 +6,7 @@
#include "mozilla/dom/cache/FileUtils.h"
#include "mozilla/dom/InternalResponse.h"
#include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/SnappyCompressOutputStream.h"
@ -26,6 +27,7 @@ using mozilla::dom::quota::FileInputStream;
using mozilla::dom::quota::FileOutputStream;
using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
using mozilla::dom::quota::QuotaManager;
using mozilla::dom::quota::QuotaObject;
namespace {
@ -39,6 +41,9 @@ nsresult
BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
nsIFile** aBodyFileOut);
int64_t
BodyGeneratePadding(const int64_t aBodyFileSize);
} // namespace
// static
@ -246,6 +251,44 @@ BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
return rv;
}
// static
nsresult
BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
const nsID& aId, int64_t* aPaddingSizeOut)
{
MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
MOZ_DIAGNOSTIC_ASSERT(aPaddingSizeOut);
nsCOMPtr<nsIFile> bodyFile;
nsresult rv =
BodyIdToFile(aBaseDir, aId, BODY_FILE_TMP, getter_AddRefs(bodyFile));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
MOZ_DIAGNOSTIC_ASSERT(bodyFile);
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_DIAGNOSTIC_ASSERT(quotaManager);
int64_t fileSize = 0;
RefPtr<QuotaObject> quotaObject =
quotaManager->GetQuotaObject(PERSISTENCE_TYPE_DEFAULT, aQuotaInfo.mGroup,
aQuotaInfo.mOrigin, bodyFile, &fileSize);
MOZ_DIAGNOSTIC_ASSERT(quotaObject);
MOZ_DIAGNOSTIC_ASSERT(fileSize >= 0);
if (*aPaddingSizeOut == InternalResponse::UNKNOWN_PADDING_SIZE) {
*aPaddingSizeOut = BodyGeneratePadding(fileSize);
}
MOZ_DIAGNOSTIC_ASSERT(*aPaddingSizeOut >= 0);
if (!quotaObject->IncreaseSize(*aPaddingSizeOut)) {
return NS_ERROR_FILE_NO_DEVICE_SPACE;
}
return rv;
}
// static
nsresult
BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
@ -310,6 +353,13 @@ BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
return rv;
}
int64_t
BodyGeneratePadding(const int64_t aBodyFileSize)
{
// XXXtt: Will deal with it in the next patch.
return 0;
}
} // namespace
nsresult
@ -548,14 +598,26 @@ RemoveNsIFile(const QuotaInfo& aQuotaInfo, nsIFile* aFile)
rv = aFile->Remove( /* recursive */ false);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
if (fileSize > 0) {
DecreaseUsageForQuotaInfo(aQuotaInfo, fileSize);
}
return rv;
}
// static
void
DecreaseUsageForQuotaInfo(const QuotaInfo& aQuotaInfo,
const int64_t& aUpdatingSize)
{
MOZ_DIAGNOSTIC_ASSERT(aUpdatingSize > 0);
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_DIAGNOSTIC_ASSERT(quotaManager);
quotaManager->DecreaseUsageForOrigin(PERSISTENCE_TYPE_DEFAULT,
aQuotaInfo.mGroup, aQuotaInfo.mOrigin,
fileSize);
return rv;
aUpdatingSize);
}
} // namespace cache

7
dom/cache/FileUtils.h поставляемый
Просмотреть файл

@ -47,6 +47,10 @@ nsresult
BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
nsIInputStream** aStreamOut);
nsresult
BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
const nsID& aId, int64_t* aPaddingSizeOut);
nsresult
BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
const nsTArray<nsID>& aIdList);
@ -70,6 +74,9 @@ RemoveNsIFileRecursively(const QuotaInfo& aQuotaInfo, nsIFile* aFile);
nsresult
RemoveNsIFile(const QuotaInfo& aQuotaInfo, nsIFile* aFile);
void
DecreaseUsageForQuotaInfo(const QuotaInfo& aQuotaInfo,
const int64_t& aUpdatingSize);
} // namespace cache
} // namespace dom
} // namespace mozilla

48
dom/cache/Manager.cpp поставляемый
Просмотреть файл

@ -86,6 +86,10 @@ public:
rv = BodyDeleteFiles(aQuotaInfo, aDBDir, deletedBodyIdList);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
if (deletedPaddingSize > 0) {
DecreaseUsageForQuotaInfo(aQuotaInfo, deletedPaddingSize);
}
}
// Clean up orphaned body objects
@ -449,6 +453,8 @@ public:
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
mozIStorageConnection* aConn) override
{
mQuotaInfo.emplace(aQuotaInfo);
mozStorageTransaction trans(aConn, false,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
@ -467,6 +473,10 @@ public:
{
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {
DecreaseUsageForQuotaInfo(mQuotaInfo.ref(), mDeletedPaddingSize);
}
// ensure we release the manager on the initiating thread
mManager = nullptr;
}
@ -475,6 +485,7 @@ private:
RefPtr<Manager> mManager;
const CacheId mCacheId;
nsTArray<nsID> mDeletedBodyIdList;
Maybe<QuotaInfo> mQuotaInfo;
// Track any pad amount associated with orphaned entries.
int64_t mDeletedPaddingSize;
};
@ -627,6 +638,7 @@ public:
, mExpectedAsyncCopyCompletions(1)
, mAsyncResult(NS_OK)
, mMutex("cache::Manager::CachePutAllAction")
, mUpdatedPaddingSize(0)
, mDeletedPaddingSize(0)
{
MOZ_DIAGNOSTIC_ASSERT(!aPutList.IsEmpty());
@ -768,6 +780,22 @@ private:
}
}
if (e.mResponseStream) {
// Gerenate padding size for opaque response if needed.
if (e.mResponse.type() == ResponseType::Opaque) {
// It'll generate padding if we've not set it yet.
rv = BodyMaybeUpdatePaddingSize(mQuotaInfo.ref(), mDBDir,
e.mResponseBodyId,
&e.mResponse.paddingSize());
if (NS_WARN_IF(NS_FAILED(rv))) {
DoResolve(rv);
return;
}
MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - e.mResponse.paddingSize() >=
mUpdatedPaddingSize);
mUpdatedPaddingSize += e.mResponse.paddingSize();
}
rv = BodyFinalizeWrite(mDBDir, e.mResponseBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) {
DoResolve(rv);
@ -775,15 +803,20 @@ private:
}
}
int64_t deletedPaddingSize = 0;
rv = db::CachePut(mConn, mCacheId, e.mRequest,
e.mRequestStream ? &e.mRequestBodyId : nullptr,
e.mResponse,
e.mResponseStream ? &e.mResponseBodyId : nullptr,
mDeletedBodyIdList, &mDeletedPaddingSize);
mDeletedBodyIdList, &deletedPaddingSize);
if (NS_WARN_IF(NS_FAILED(rv))) {
DoResolve(rv);
return;
}
MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - mDeletedPaddingSize >=
deletedPaddingSize);
mDeletedPaddingSize += deletedPaddingSize;
}
// XXXtt: Write .padding file to the cache directory
@ -807,6 +840,10 @@ private:
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {
DecreaseUsageForQuotaInfo(mQuotaInfo.ref(), mDeletedPaddingSize);
}
Listener* listener = mManager->GetListener(mListenerId);
mManager = nullptr;
if (listener) {
@ -946,6 +983,9 @@ private:
// Clean up any files we might have written before hitting the error.
if (NS_FAILED(aRv)) {
BodyDeleteFiles(mQuotaInfo.ref(), mDBDir, mBodyIdWrittenList);
if (mUpdatedPaddingSize > 0) {
DecreaseUsageForQuotaInfo(mQuotaInfo.ref(), mUpdatedPaddingSize);
}
}
// Must be released on the target thread where it was opened.
@ -989,6 +1029,9 @@ private:
nsTArray<nsCOMPtr<nsISupports>> mCopyContextList;
Maybe<QuotaInfo> mQuotaInfo;
// Track how much pad amount has been added for new entries so that it can be
// removed if an error occurs.
int64_t mUpdatedPaddingSize;
// Track any pad amount associated with overwritten entries.
int64_t mDeletedPaddingSize;
};
@ -1011,6 +1054,8 @@ public:
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
mozIStorageConnection* aConn) override
{
mQuotaInfo.emplace(aQuotaInfo);
mozStorageTransaction trans(aConn, false,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
@ -1045,6 +1090,7 @@ private:
const CacheDeleteArgs mArgs;
bool mSuccess;
nsTArray<nsID> mDeletedBodyIdList;
Maybe<QuotaInfo> mQuotaInfo;
// Track any pad amount associated with deleted entries.
int64_t mDeletedPaddingSize;
};

Просмотреть файл

@ -2929,6 +2929,55 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
MutexAutoLock lock(quotaManager->mQuotaMutex);
return LockedMaybeUpdateSize(aSize, aTruncate);
}
bool
QuotaObject::IncreaseSize(int64_t aDelta)
{
MOZ_ASSERT(aDelta >= 0);
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
MutexAutoLock lock(quotaManager->mQuotaMutex);
AssertNoOverflow(mSize, aDelta);
int64_t size = mSize + aDelta;
return LockedMaybeUpdateSize(size, /* aTruncate */ false);
}
void
QuotaObject::DisableQuotaCheck()
{
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
MutexAutoLock lock(quotaManager->mQuotaMutex);
mQuotaCheckDisabled = true;
}
void
QuotaObject::EnableQuotaCheck()
{
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
MutexAutoLock lock(quotaManager->mQuotaMutex);
mQuotaCheckDisabled = false;
}
bool
QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate)
{
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
quotaManager->mQuotaMutex.AssertCurrentThreadOwns();
if (mQuotaCheckDisabled) {
return true;
}
@ -3127,28 +3176,6 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
return true;
}
void
QuotaObject::DisableQuotaCheck()
{
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
MutexAutoLock lock(quotaManager->mQuotaMutex);
mQuotaCheckDisabled = true;
}
void
QuotaObject::EnableQuotaCheck()
{
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
MutexAutoLock lock(quotaManager->mQuotaMutex);
mQuotaCheckDisabled = false;
}
/*******************************************************************************
* Quota manager
******************************************************************************/
@ -3774,10 +3801,15 @@ already_AddRefed<QuotaObject>
QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
nsIFile* aFile)
nsIFile* aFile,
int64_t* aFileSizeOut /* = nullptr */)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
if (aFileSizeOut) {
*aFileSizeOut = 0;
}
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
return nullptr;
}
@ -3849,6 +3881,10 @@ QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
result = quotaObject->LockedAddRef();
}
if (aFileSizeOut) {
*aFileSizeOut = fileSize;
}
// The caller becomes the owner of the QuotaObject, that is, the caller is
// is responsible to delete it when the last reference is removed.
return result.forget();
@ -3858,8 +3894,15 @@ already_AddRefed<QuotaObject>
QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
const nsAString& aPath)
const nsAString& aPath,
int64_t* aFileSizeOut /* = nullptr */)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
if (aFileSizeOut) {
*aFileSizeOut = 0;
}
nsresult rv;
nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, nullptr);
@ -3867,7 +3910,7 @@ QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
rv = file->InitWithPath(aPath);
NS_ENSURE_SUCCESS(rv, nullptr);
return GetQuotaObject(aPersistenceType, aGroup, aOrigin, file);
return GetQuotaObject(aPersistenceType, aGroup, aOrigin, file, aFileSizeOut);
}
Nullable<bool>

Просмотреть файл

@ -177,13 +177,15 @@ public:
GetQuotaObject(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
nsIFile* aFile);
nsIFile* aFile,
int64_t* aFileSizeOut = nullptr);
already_AddRefed<QuotaObject>
GetQuotaObject(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
const nsAString& aPath);
const nsAString& aPath,
int64_t* aFileSizeOut = nullptr);
Nullable<bool>
OriginPersisted(const nsACString& aGroup,

Просмотреть файл

@ -41,6 +41,9 @@ public:
bool
MaybeUpdateSize(int64_t aSize, bool aTruncate);
bool
IncreaseSize(int64_t aDelta);
void
DisableQuotaCheck();
@ -73,6 +76,9 @@ private:
return result.forget();
}
bool
LockedMaybeUpdateSize(int64_t aSize, bool aTruncate);
mozilla::ThreadSafeAutoRefCnt mRefCnt;
OriginInfo* mOriginInfo;