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

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

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

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

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

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

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

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

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

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

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