Bug 1290481 - P10: Update padding size to the direcotry padding file. r=bkelly
authorTom Tung <shes050117@gmail.com>
Tue, 18 Jul 2017 19:00:09 +0800
changeset 429030 69c4ad5e1f2db67c9857dcbc8f176dd5443f42a5
parent 429029 885e9a3b821e752a8df0a97a456d02bb1138076c
child 429031 851077b7eb92324d9212a5a521e1dd0f07f8c626
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1290481
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1290481 - P10: Update padding size to the direcotry padding file. r=bkelly MozReview-Commit-ID: KlVsaGhpABk
dom/cache/DBAction.cpp
dom/cache/FileUtils.cpp
dom/cache/FileUtils.h
dom/cache/Manager.cpp
dom/cache/QuotaClient.cpp
dom/cache/QuotaClient.h
--- a/dom/cache/DBAction.cpp
+++ b/dom/cache/DBAction.cpp
@@ -4,16 +4,17 @@
  * 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/. */
 
 #include "mozilla/dom/cache/DBAction.h"
 
 #include "mozilla/dom/cache/Connection.h"
 #include "mozilla/dom/cache/DBSchema.h"
 #include "mozilla/dom/cache/FileUtils.h"
+#include "mozilla/dom/cache/QuotaClient.h"
 #include "mozilla/dom/quota/PersistenceType.h"
 #include "mozilla/net/nsFileProtocolHandler.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageService.h"
 #include "mozStorageCID.h"
 #include "nsIFile.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
@@ -199,16 +200,19 @@ DBAction::WipeDatabase(const QuotaInfo& 
 
   // Note, the -wal journal file will be automatically deleted by sqlite when
   // the new database is created.  No need to explicitly delete it here.
 
   // Delete the morgue as well.
   rv = BodyDeleteDir(aQuotaInfo, aDBDir);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
+  rv = WipePaddingFile(aQuotaInfo, aDBDir);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
   return rv;
 }
 
 SyncDBAction::SyncDBAction(Mode aMode)
   : DBAction(aMode)
 {
 }
 
--- a/dom/cache/FileUtils.cpp
+++ b/dom/cache/FileUtils.cpp
@@ -769,42 +769,30 @@ LockedDirectoryPaddingInit(nsIFile* aBas
   nsresult rv = LockedDirectoryPaddingWrite(aBaseDir, DirPaddingFile::FILE, 0);
   Unused << NS_WARN_IF(NS_FAILED(rv));
 
   return rv;
 }
 
 // static
 nsresult
-LockedMaybeUpdateDirectoryPaddingFile(nsIFile* aBaseDir,
-                                      mozIStorageConnection* aConn,
-                                      const int64_t aIncreaseSize,
-                                      const int64_t aDecreaseSize,
-                                      bool* aUpdatedOut)
+LockedUpdateDirectoryPaddingFile(nsIFile* aBaseDir,
+                                 mozIStorageConnection* aConn,
+                                 const int64_t aIncreaseSize,
+                                 const int64_t aDecreaseSize,
+                                 const bool aTemporaryFileExist)
 {
   MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
   MOZ_DIAGNOSTIC_ASSERT(aConn);
   MOZ_DIAGNOSTIC_ASSERT(aIncreaseSize >= 0);
   MOZ_DIAGNOSTIC_ASSERT(aDecreaseSize >= 0);
-  MOZ_DIAGNOSTIC_ASSERT(aUpdatedOut);
-
-  // Temporary should be removed at the end of each action. If not, it means the
-  // failure happened.
-  bool temporaryFileExisted =
-    DirectoryPaddingFileExists(aBaseDir, DirPaddingFile::TMP_FILE);
-
-  nsresult rv = NS_OK;
-
-  if (aIncreaseSize == aDecreaseSize && !temporaryFileExisted) {
-    return rv;
-  }
 
   int64_t currentPaddingSize = 0;
-  rv = LockedDirectoryPaddingGet(aBaseDir, &currentPaddingSize);
-  if (NS_WARN_IF(NS_FAILED(rv)) || temporaryFileExisted) {
+  nsresult rv = LockedDirectoryPaddingGet(aBaseDir, &currentPaddingSize);
+  if (NS_WARN_IF(NS_FAILED(rv)) || aTemporaryFileExist) {
     // Fail to read padding size from the dir padding file, so try to restore.
     if (rv != NS_ERROR_FILE_NOT_FOUND &&
         rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
       // Not delete the temporary padding file here, because we're going to
       // overwrite it below anyway.
       rv = LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     }
@@ -833,18 +821,16 @@ LockedMaybeUpdateDirectoryPaddingFile(ns
 #endif // DEBUG
   }
 
   MOZ_DIAGNOSTIC_ASSERT(currentPaddingSize >= 0);
 
   rv = LockedDirectoryPaddingTemporaryWrite(aBaseDir, currentPaddingSize);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  *aUpdatedOut = true;
-
   return rv;
 }
 
 // static
 nsresult
 LockedDirectoryPaddingTemporaryWrite(nsIFile* aBaseDir, int64_t aPaddingSize)
 {
   MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
--- a/dom/cache/FileUtils.h
+++ b/dom/cache/FileUtils.h
@@ -103,21 +103,21 @@ DirectoryPaddingFileExists(nsIFile* aBas
 
 nsresult
 LockedDirectoryPaddingGet(nsIFile* aBaseDir, int64_t* aPaddingSizeOut);
 
 nsresult
 LockedDirectoryPaddingInit(nsIFile* aBaseDir);
 
 nsresult
-LockedMaybeUpdateDirectoryPaddingFile(nsIFile* aBaseDir,
-                                      mozIStorageConnection* aConn,
-                                      const int64_t aIncreaseSize,
-                                      const int64_t aDecreaseSize,
-                                      bool* aUpdatedOut);
+LockedUpdateDirectoryPaddingFile(nsIFile* aBaseDir,
+                                 mozIStorageConnection* aConn,
+                                 const int64_t aIncreaseSize,
+                                 const int64_t aDecreaseSize,
+                                 const bool aTemporaryFileExist);
 
 nsresult
 LockedDirectoryPaddingTemporaryWrite(nsIFile* aBaseDir, int64_t aPaddingSize);
 
 nsresult
 LockedDirectoryPaddingFinalizeWrite(nsIFile* aBaseDir);
 
 nsresult
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/dom/cache/DBAction.h"
 #include "mozilla/dom/cache/DBSchema.h"
 #include "mozilla/dom/cache/FileUtils.h"
 #include "mozilla/dom/cache/ManagerId.h"
 #include "mozilla/dom/cache/CacheTypes.h"
 #include "mozilla/dom/cache/SavedTypes.h"
 #include "mozilla/dom/cache/StreamList.h"
 #include "mozilla/dom/cache/Types.h"
+#include "mozilla/dom/cache/QuotaClient.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozStorageHelper.h"
 #include "nsIInputStream.h"
 #include "nsID.h"
 #include "nsIFile.h"
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
 #include "nsTObserverArray.h"
@@ -45,16 +46,18 @@ public:
   SetupAction()
     : SyncDBAction(DBAction::Create)
   { }
 
   virtual nsresult
   RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
                         mozIStorageConnection* aConn) override
   {
+    MOZ_DIAGNOSTIC_ASSERT(aDBDir);
+
     nsresult rv = BodyCreateDir(aDBDir);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     // executes in its own transaction
     rv = db::CreateOrMigrateSchema(aConn);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     // If the Context marker file exists, then the last session was
@@ -72,37 +75,56 @@ public:
       mozStorageTransaction trans(aConn, false,
                                   mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
       // Clean up orphaned Cache objects
       AutoTArray<CacheId, 8> orphanedCacheIdList;
       nsresult rv = db::FindOrphanedCacheIds(aConn, orphanedCacheIdList);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
+      int64_t overallDeletedPaddingSize = 0;
       for (uint32_t i = 0; i < orphanedCacheIdList.Length(); ++i) {
         AutoTArray<nsID, 16> deletedBodyIdList;
         int64_t deletedPaddingSize = 0;
         rv = db::DeleteCacheId(aConn, orphanedCacheIdList[i], deletedBodyIdList,
                                &deletedPaddingSize);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
         rv = BodyDeleteFiles(aQuotaInfo, aDBDir, deletedBodyIdList);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
         if (deletedPaddingSize > 0) {
           DecreaseUsageForQuotaInfo(aQuotaInfo, deletedPaddingSize);
         }
+
+        MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - deletedPaddingSize >=
+                              overallDeletedPaddingSize);
+        overallDeletedPaddingSize += deletedPaddingSize;
       }
 
       // Clean up orphaned body objects
       AutoTArray<nsID, 64> knownBodyIdList;
       rv = db::GetKnownBodyIds(aConn, knownBodyIdList);
 
       rv = BodyDeleteOrphanedFiles(aQuotaInfo, aDBDir, knownBodyIdList);
       if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+      // Commit() explicitly here, because we want to ensure the padding file
+      // has the correct content.
+      rv = MaybeUpdatePaddingFile(aDBDir, aConn, /* aIncreaceSize */ 0,
+                                  overallDeletedPaddingSize,
+                                  [&trans]() mutable { return trans.Commit(); });
+      // We'll restore padding file below, so just warn here if failure happens.
+      Unused << NS_WARN_IF(NS_FAILED(rv));
+    }
+
+    if (DirectoryPaddingFileExists(aDBDir, DirPaddingFile::TMP_FILE) ||
+        !DirectoryPaddingFileExists(aDBDir, DirPaddingFile::FILE)) {
+      rv = RestorePaddingFile(aDBDir, aConn);
+      if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     }
 
     return rv;
   }
 };
 
 // ----------------------------------------------------------------------------
 
@@ -457,18 +479,20 @@ public:
 
     mozStorageTransaction trans(aConn, false,
                                 mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
     nsresult rv = db::DeleteCacheId(aConn, mCacheId, mDeletedBodyIdList,
                                     &mDeletedPaddingSize);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-    rv = trans.Commit();
-    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+    rv = MaybeUpdatePaddingFile(aDBDir, aConn, /* aIncreaceSize */ 0,
+                                mDeletedPaddingSize,
+                                [&trans]() mutable { return trans.Commit(); });
+    Unused << NS_WARN_IF(NS_FAILED(rv));
 
     return rv;
   }
 
   virtual void
   CompleteOnInitiatingThread(nsresult aRv) override
   {
     mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
@@ -815,20 +839,20 @@ private:
         return;
       }
 
       MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - mDeletedPaddingSize >=
                             deletedPaddingSize);
       mDeletedPaddingSize += deletedPaddingSize;
     }
 
-    // XXXtt: Write .padding file to the cache directory
-    // UpdateDirectoryFile(mDBDir);
-
-    rv = trans.Commit();
+    // Update padding file when it's necessary
+    rv = MaybeUpdatePaddingFile(mDBDir, mConn, mUpdatedPaddingSize,
+                                mDeletedPaddingSize,
+                                [&trans]() mutable { return trans.Commit(); });
     Unused << NS_WARN_IF(NS_FAILED(rv));
 
     DoResolve(rv);
   }
 
   virtual void
   CompleteOnInitiatingThread(nsresult aRv) override
   {
@@ -1060,29 +1084,36 @@ public:
     mozStorageTransaction trans(aConn, false,
                                 mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
     nsresult rv = db::CacheDelete(aConn, mCacheId, mArgs.request(),
                                   mArgs.params(), mDeletedBodyIdList,
                                   &mDeletedPaddingSize, &mSuccess);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-    rv = trans.Commit();
+    rv = MaybeUpdatePaddingFile(aDBDir, aConn, /* aIncreaceSize */ 0,
+                                mDeletedPaddingSize,
+                                [&trans]() mutable { return trans.Commit(); });
     if (NS_WARN_IF(NS_FAILED(rv))) {
       mSuccess = false;
       return rv;
     }
 
     return rv;
   }
 
   virtual void
   Complete(Listener* aListener, ErrorResult&& aRv) override
   {
     mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
+
+    if (mDeletedPaddingSize > 0) {
+      DecreaseUsageForQuotaInfo(mQuotaInfo.ref(), mDeletedPaddingSize);
+    }
+
     aListener->OnOpComplete(Move(aRv), CacheDeleteResult(mSuccess));
   }
 
   virtual bool MatchesCacheId(CacheId aCacheId) const override
   {
     return aCacheId == mCacheId;
   }
 
--- a/dom/cache/QuotaClient.cpp
+++ b/dom/cache/QuotaClient.cpp
@@ -13,23 +13,27 @@
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
 #include "nsThreadUtils.h"
 
 namespace {
 
 using mozilla::Atomic;
 using mozilla::dom::ContentParentId;
+using mozilla::dom::cache::DirPaddingFile;
 using mozilla::dom::cache::Manager;
+using mozilla::dom::cache::QuotaInfo;
 using mozilla::dom::quota::AssertIsOnIOThread;
 using mozilla::dom::quota::Client;
 using mozilla::dom::quota::PersistenceType;
 using mozilla::dom::quota::QuotaManager;
 using mozilla::dom::quota::UsageInfo;
 using mozilla::ipc::AssertIsOnBackgroundThread;
+using mozilla::MutexAutoLock;
+using mozilla::Unused;
 
 static nsresult
 GetBodyUsage(nsIFile* aDir, const Atomic<bool>& aCanceled,
              UsageInfo* aUsageInfo)
 {
   nsCOMPtr<nsISimpleEnumerator> entries;
   nsresult rv = aDir->GetDirectoryEntries(getter_AddRefs(entries));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@@ -61,20 +65,33 @@ GetBodyUsage(nsIFile* aDir, const Atomic
     aUsageInfo->AppendToFileUsage(fileSize);
   }
 
   return NS_OK;
 }
 
 class CacheQuotaClient final : public Client
 {
+  static CacheQuotaClient* sInstance;
+
 public:
   CacheQuotaClient()
   : mDirPaddingFileMutex("DOMCacheQuotaClient.mDirPaddingFileMutex")
-  { }
+  {
+    AssertIsOnBackgroundThread();
+    MOZ_DIAGNOSTIC_ASSERT(!sInstance);
+    sInstance = this;
+  }
+
+  static CacheQuotaClient*
+  Get()
+  {
+    MOZ_DIAGNOSTIC_ASSERT(sInstance);
+    return sInstance;
+  }
 
   virtual Type
   GetType() override
   {
     return DOMCACHE;
   }
 
   virtual nsresult
@@ -221,154 +238,228 @@ public:
   }
 
   nsresult
   UpgradeStorageFrom2_0To3_0(nsIFile* aDirectory) override
   {
     AssertIsOnIOThread();
     MOZ_DIAGNOSTIC_ASSERT(aDirectory);
 
-    nsresult rv = mozilla::dom::cache::InitPaddingFile(aDirectory);
+    MutexAutoLock lock(mDirPaddingFileMutex);
+
+    nsresult rv = mozilla::dom::cache::LockedDirectoryPaddingInit(aDirectory);
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     return rv;
   }
 
+  // static
+  template<typename Callable>
+  nsresult
+  MaybeUpdatePaddingFileInternal(nsIFile* aBaseDir,
+                                 mozIStorageConnection* aConn,
+                                 const int64_t aIncreaseSize,
+                                 const int64_t aDecreaseSize,
+                                 Callable aCommitHook)
+  {
+    MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
+    MOZ_DIAGNOSTIC_ASSERT(aConn);
+    MOZ_DIAGNOSTIC_ASSERT(aIncreaseSize >= 0);
+    MOZ_DIAGNOSTIC_ASSERT(aDecreaseSize >= 0);
+
+    nsresult rv;
+
+    // Temporary should be removed at the end of each action. If not, it means
+    // the failure happened.
+    bool temporaryPaddingFileExist =
+      mozilla::dom::cache::DirectoryPaddingFileExists(aBaseDir,
+                                                      DirPaddingFile::TMP_FILE);
+
+    if (aIncreaseSize == aDecreaseSize && !temporaryPaddingFileExist) {
+      // Early return here, since most cache actions won't modify padding size.
+      rv = aCommitHook();
+      Unused << NS_WARN_IF(NS_FAILED(rv));
+      return rv;
+    }
+
+    {
+      MutexAutoLock lock(mDirPaddingFileMutex);
+      rv =
+        mozilla::dom::cache::
+        LockedUpdateDirectoryPaddingFile(aBaseDir, aConn, aIncreaseSize,
+                                         aDecreaseSize,
+                                         temporaryPaddingFileExist);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        mozilla::dom::cache::
+        LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
+        return rv;
+      }
+
+      rv = aCommitHook();
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        mozilla::dom::cache::
+        LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
+        return rv;
+      }
+
+      rv = mozilla::dom::cache::LockedDirectoryPaddingFinalizeWrite(aBaseDir);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        // Force restore file next time.
+        mozilla::dom::cache::
+        LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
+      }
+    }
+
+    return rv;
+  }
+
+  // static
+  nsresult
+  RestorePaddingFileInternal(nsIFile* aBaseDir, mozIStorageConnection* aConn)
+  {
+    MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
+    MOZ_DIAGNOSTIC_ASSERT(aConn);
+
+    MutexAutoLock lock(mDirPaddingFileMutex);
+
+    nsresult rv =
+      mozilla::dom::cache::LockedDirectoryPaddingRestore(aBaseDir, aConn);
+    Unused << NS_WARN_IF(NS_FAILED(rv));
+
+    return rv;
+  }
+
+  // static
+  nsresult
+  WipePaddingFileInternal(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir)
+  {
+    MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
+
+    MutexAutoLock lock(mDirPaddingFileMutex);
+
+    // Remove temporary file if we have one.
+    nsresult rv =
+      mozilla::dom::cache::
+      LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    MOZ_DIAGNOSTIC_ASSERT(mozilla::dom::cache::
+                          DirectoryPaddingFileExists(aBaseDir,
+                                                     DirPaddingFile::FILE));
+
+    int64_t paddingSize = 0;
+    rv = mozilla::dom::cache::LockedDirectoryPaddingGet(aBaseDir, &paddingSize);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      // If read file fail, there is nothing we can do to recover the file.
+      NS_WARNING("Cannnot read padding size from file!");
+      paddingSize = 0;
+    }
+
+    if (paddingSize > 0) {
+      mozilla::dom::cache::DecreaseUsageForQuotaInfo(aQuotaInfo, paddingSize);
+    }
+
+    rv = mozilla::dom::cache::
+         LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = mozilla::dom::cache::LockedDirectoryPaddingInit(aBaseDir);
+    Unused << NS_WARN_IF(NS_FAILED(rv));
+
+    return rv;
+  }
+
 private:
   ~CacheQuotaClient()
   {
     AssertIsOnBackgroundThread();
+    MOZ_DIAGNOSTIC_ASSERT(sInstance == this);
+
+    sInstance = nullptr;
   }
 
-  NS_INLINE_DECL_REFCOUNTING(CacheQuotaClient, override)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheQuotaClient, override)
 
   // Mutex lock to protect directroy padding files. It should only be acquired
   // in DOM Cache IO threads and Quota IO thread.
   mozilla::Mutex mDirPaddingFileMutex;
 };
 
+// static
+CacheQuotaClient* CacheQuotaClient::sInstance = nullptr;
+
 } // namespace
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 // static
 already_AddRefed<quota::Client> CreateQuotaClient()
 {
   AssertIsOnBackgroundThread();
 
   RefPtr<CacheQuotaClient> ref = new CacheQuotaClient();
   return ref.forget();
 }
 
-
-// static
-nsresult
-InitPaddingFile(nsIFile* aBaseDir)
-{
-  MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
-
-  // XXXtt: Acquire lock here
-
-  nsresult rv = LockedDirectoryPaddingInit(aBaseDir);
-  Unused << NS_WARN_IF(NS_FAILED(rv));
-
-  return rv;
-}
-
 // static
 template<typename Callable>
 nsresult
 MaybeUpdatePaddingFile(nsIFile* aBaseDir,
                        mozIStorageConnection* aConn,
                        const int64_t aIncreaseSize,
                        const int64_t aDecreaseSize,
                        Callable aCommitHook)
 {
   MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
   MOZ_DIAGNOSTIC_ASSERT(aConn);
   MOZ_DIAGNOSTIC_ASSERT(aIncreaseSize >= 0);
   MOZ_DIAGNOSTIC_ASSERT(aDecreaseSize >= 0);
 
-  // XXXtt: Acquire lock here
-
-  bool updated = false;
-  nsresult rv =
-    LockedMaybeUpdateDirectoryPaddingFile(aBaseDir, aConn, aIncreaseSize,
-                                          aDecreaseSize, &updated);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
-    return rv;
-  }
+  RefPtr<CacheQuotaClient> cacheQuotaClient = CacheQuotaClient::Get();
+  MOZ_DIAGNOSTIC_ASSERT(cacheQuotaClient);
 
-  rv = aCommitHook();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
-    return rv;
-  }
-
-  if (updated) {
-    rv = LockedDirectoryPaddingFinalizeWrite(aBaseDir);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      // Force restore file next time.
-      LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
-      return rv;
-    }
-  }
+  nsresult rv =
+    cacheQuotaClient->MaybeUpdatePaddingFileInternal(aBaseDir, aConn,
+                                                     aIncreaseSize,
+                                                     aDecreaseSize,
+                                                     aCommitHook);
+  Unused << NS_WARN_IF(NS_FAILED(rv));
 
   return rv;
 }
 
 // static
 nsresult
 RestorePaddingFile(nsIFile* aBaseDir, mozIStorageConnection* aConn)
 {
   MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
   MOZ_DIAGNOSTIC_ASSERT(aConn);
 
-  // XXXtt: Acquire lock here
+  RefPtr<CacheQuotaClient> cacheQuotaClient = CacheQuotaClient::Get();
+  MOZ_DIAGNOSTIC_ASSERT(cacheQuotaClient);
 
-  nsresult rv = LockedDirectoryPaddingRestore(aBaseDir, aConn);
+  nsresult rv =
+    cacheQuotaClient->RestorePaddingFileInternal(aBaseDir, aConn);
   Unused << NS_WARN_IF(NS_FAILED(rv));
 
   return rv;
 }
 
 // static
 nsresult
 WipePaddingFile(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir)
 {
   MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
 
-  // XXXtt: Acquire lock here
-
-  // Remove temporary file if we have one.
-  nsresult rv = LockedDirectoryPaddingDeleteFile(aBaseDir,
-                                                 DirPaddingFile::TMP_FILE);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-
-  MOZ_DIAGNOSTIC_ASSERT(DirectoryPaddingFileExists(aBaseDir,
-                                                   DirPaddingFile::FILE));
+  RefPtr<CacheQuotaClient> cacheQuotaClient = CacheQuotaClient::Get();
+  MOZ_DIAGNOSTIC_ASSERT(cacheQuotaClient);
 
-  int64_t paddingSize = 0;
-  rv = LockedDirectoryPaddingGet(aBaseDir, &paddingSize);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    // If read file fail, there is nothing we can do to recover the file.
-    NS_WARNING("Cannnot read padding size from file!");
-    paddingSize = 0;
-  }
-
-  if (paddingSize > 0) {
-    DecreaseUsageForQuotaInfo(aQuotaInfo, paddingSize);
-  }
-
-  rv = LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-
-  rv = LockedDirectoryPaddingInit(aBaseDir);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+  nsresult rv =
+    cacheQuotaClient->WipePaddingFileInternal(aQuotaInfo, aBaseDir);
+  Unused << NS_WARN_IF(NS_FAILED(rv));
 
   return rv;
 }
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/dom/cache/QuotaClient.h
+++ b/dom/cache/QuotaClient.h
@@ -32,19 +32,16 @@ CreateQuotaClient();
  *
  * Each padding file should only take 8 bytes (int64_t) to record the overall
  * padding size. Besides, we use the temporary padding file to indicate if the
  * previous action is completed successfully. If the temporary file exists, it
  * represents that the previous action is failed and the content of padding file
  * cannot be trusted, and we need to restore the padding file from the database.
  */
 
-nsresult
-InitPaddingFile(nsIFile* aBaseDir);
-
 /**
  * Note: The aCommitHook argument will be invoked while a lock is held. Callers
  * should be careful not to pass a hook that might lock on something else and
  * trigger a deadlock.
  */
 template<typename Callable>
 nsresult
 MaybeUpdatePaddingFile(nsIFile* aBaseDir,