Bug 1068787 - Quota usage not decreased when removing unsuccessfully copied files; r=bent
authorJan Varga <jan.varga@gmail.com>
Tue, 28 Oct 2014 20:06:54 +0100
changeset 212829 1ef63ad2684246520d2044dfe16bc10e41641294
parent 212828 581049146676e44f28440d0393cfb9d0d96b5820
child 212830 df5359e8c82c986d681429a1f7fc6be717253ddf
push id27730
push usercbook@mozilla.com
push dateWed, 29 Oct 2014 12:26:03 +0000
treeherdermozilla-central@fe5c1cb8075a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs1068787
milestone36.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 1068787 - Quota usage not decreased when removing unsuccessfully copied files; r=bent
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/FileManager.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/SerializationHelpers.h
dom/quota/QuotaManager.cpp
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -41,17 +41,16 @@
 #include "mozilla/dom/indexedDB/PBackgroundIDBTransactionParent.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionParent.h"
 #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestParent.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/dom/quota/Client.h"
 #include "mozilla/dom/quota/FileStreams.h"
 #include "mozilla/dom/quota/OriginOrPatternString.h"
 #include "mozilla/dom/quota/QuotaManager.h"
-#include "mozilla/dom/quota/StoragePrivilege.h"
 #include "mozilla/dom/quota/UsageInfo.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/InputStreamParams.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/PBackground.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsClassHashtable.h"
@@ -3880,17 +3879,16 @@ protected:
 
   nsTArray<MaybeBlockedDatabaseInfo> mMaybeBlockedDatabases;
 
   const CommonFactoryRequestParams mCommonParams;
   nsCString mGroup;
   nsCString mOrigin;
   nsCString mDatabaseId;
   State mState;
-  StoragePrivilege mStoragePrivilege;
   bool mEnforcingQuota;
   const bool mDeleting;
   bool mBlockedQuotaManager;
   bool mChromeWriteAccessAllowed;
 
 public:
   void
   NoteDatabaseBlocked(Database* aDatabase);
@@ -8585,24 +8583,24 @@ Cursor::RecvContinue(const CursorRequest
 
 /*******************************************************************************
  * FileManager
  ******************************************************************************/
 
 FileManager::FileManager(PersistenceType aPersistenceType,
                          const nsACString& aGroup,
                          const nsACString& aOrigin,
-                         StoragePrivilege aPrivilege,
-                         const nsAString& aDatabaseName)
+                         const nsAString& aDatabaseName,
+                         bool aEnforcingQuota)
   : mPersistenceType(aPersistenceType)
   , mGroup(aGroup)
   , mOrigin(aOrigin)
-  , mPrivilege(aPrivilege)
   , mDatabaseName(aDatabaseName)
   , mLastFileId(0)
+  , mEnforcingQuota(aEnforcingQuota)
   , mInvalidated(false)
 { }
 
 FileManager::~FileManager()
 { }
 
 nsresult
 FileManager::Init(nsIFile* aDirectory,
@@ -10431,17 +10429,16 @@ AutoSetProgressHandler::Register(
 FactoryOp::FactoryOp(Factory* aFactory,
                      already_AddRefed<ContentParent> aContentParent,
                      const CommonFactoryRequestParams& aCommonParams,
                      bool aDeleting)
   : mFactory(aFactory)
   , mContentParent(Move(aContentParent))
   , mCommonParams(aCommonParams)
   , mState(State_Initial)
-  , mStoragePrivilege(mozilla::dom::quota::Content)
   , mEnforcingQuota(true)
   , mDeleting(aDeleting)
   , mBlockedQuotaManager(false)
   , mChromeWriteAccessAllowed(false)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aFactory);
   MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
@@ -10730,19 +10727,17 @@ FactoryOp::CheckPermission(ContentParent
       }
 
       mChromeWriteAccessAllowed = canWrite;
     } else {
       mChromeWriteAccessAllowed = true;
     }
 
     if (State_Initial == mState) {
-      QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, &mStoragePrivilege,
-                                     nullptr);
-      MOZ_ASSERT(mStoragePrivilege == mozilla::dom::quota::Chrome);
+      QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, nullptr, nullptr);
       mEnforcingQuota = false;
     }
 
     *aPermission = PermissionRequestBase::kPermissionAllowed;
     return NS_OK;
   }
 
   MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
@@ -10784,22 +10779,20 @@ FactoryOp::CheckPermission(ContentParent
         return rv;
       }
     }
   }
 
   if (permission != PermissionRequestBase::kPermissionDenied &&
       State_Initial == mState) {
     rv = QuotaManager::GetInfoFromPrincipal(principal, &mGroup, &mOrigin,
-                                            &mStoragePrivilege, nullptr);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    MOZ_ASSERT(mStoragePrivilege != mozilla::dom::quota::Chrome);
+                                            nullptr, nullptr);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
   }
 
   if (permission == PermissionRequestBase::kPermissionAllowed &&
       mEnforcingQuota)
   {
     // If we're running from a window then we should check the quota permission
     // as well.
     uint32_t quotaPermission = CheckQuotaHelper::GetQuotaPermission(principal);
@@ -11321,18 +11314,18 @@ OpenDatabaseOp::DoDatabaseWork()
   MOZ_ASSERT(mgr);
 
   nsRefPtr<FileManager> fileManager =
     mgr->GetFileManager(persistenceType, mOrigin, databaseName);
   if (!fileManager) {
     fileManager = new FileManager(persistenceType,
                                   mGroup,
                                   mOrigin,
-                                  mStoragePrivilege,
-                                  databaseName);
+                                  databaseName,
+                                  mEnforcingQuota);
 
     rv = fileManager->Init(fmDirectory, connection);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     mgr->AddFileManager(fileManager);
   }
@@ -12699,29 +12692,29 @@ VersionChangeOp::RunOnIOThread()
     mDeleteDatabaseOp->mCommonParams.metadata().persistenceType();
 
   QuotaManager* quotaManager = QuotaManager::Get();
   MOZ_ASSERT(quotaManager);
 
   if (exists) {
     int64_t fileSize;
 
-    if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
+    if (mDeleteDatabaseOp->mEnforcingQuota) {
       rv = dbFile->GetFileSize(&fileSize);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     rv = dbFile->Remove(false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
+    if (mDeleteDatabaseOp->mEnforcingQuota) {
       quotaManager->DecreaseUsageForOrigin(persistenceType,
                                            mDeleteDatabaseOp->mGroup,
                                            mDeleteDatabaseOp->mOrigin,
                                            fileSize);
     }
   }
 
   nsCOMPtr<nsIFile> dbJournalFile;
@@ -12776,29 +12769,29 @@ VersionChangeOp::RunOnIOThread()
 
     if (NS_WARN_IF(!isDirectory)) {
       IDB_REPORT_INTERNAL_ERR();
       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
 
     uint64_t usage = 0;
 
-    if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
+    if (mDeleteDatabaseOp->mEnforcingQuota) {
       rv = FileManager::GetUsage(fmDirectory, &usage);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     rv = fmDirectory->Remove(true);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
+    if (mDeleteDatabaseOp->mEnforcingQuota) {
       quotaManager->DecreaseUsageForOrigin(persistenceType,
                                            mDeleteDatabaseOp->mGroup,
                                            mDeleteDatabaseOp->mOrigin,
                                            usage);
     }
   }
 
   IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
@@ -14420,22 +14413,24 @@ ObjectStoreAddOrPutRequestOp::CopyFileDa
     }
 
     if (NS_WARN_IF(numWrite != numRead)) {
       rv = NS_ERROR_FAILURE;
       break;
     }
   } while (true);
 
-  nsresult rv2 = aOutputStream->Flush();
-  if (NS_WARN_IF(NS_FAILED(rv2))) {
-    return NS_SUCCEEDED(rv) ? rv2 : rv;
-  }
-
-  rv2 = aOutputStream->Close();
+  if (NS_SUCCEEDED(rv)) {
+    rv = aOutputStream->Flush();
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+  }
+
+  nsresult rv2 = aOutputStream->Close();
   if (NS_WARN_IF(NS_FAILED(rv2))) {
     return NS_SUCCEEDED(rv) ? rv2 : rv;
   }
 
   return rv;
 }
 
 bool
@@ -14799,19 +14794,41 @@ ObjectStoreAddOrPutRequestOp::DoDatabase
           rv = CopyFileData(inputStream, outputStream);
           if (NS_FAILED(rv) &&
               NS_ERROR_GET_MODULE(rv) != NS_ERROR_MODULE_DOM_INDEXEDDB) {
             IDB_REPORT_INTERNAL_ERR();
             rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
           }
           if (NS_WARN_IF(NS_FAILED(rv))) {
             // Try to remove the file if the copy failed.
-            if (NS_FAILED(diskFile->Remove(false))) {
-              NS_WARNING("Failed to remove file after copying failed!");
+            nsresult rv2;
+            int64_t fileSize;
+
+            if (mFileManager->EnforcingQuota()) {
+              rv2 = diskFile->GetFileSize(&fileSize);
+              if (NS_WARN_IF(NS_FAILED(rv2))) {
+                return rv;
+              }
             }
+
+            rv2 = diskFile->Remove(false);
+            if (NS_WARN_IF(NS_FAILED(rv2))) {
+              return rv;
+            }
+
+            if (mFileManager->EnforcingQuota()) {
+              QuotaManager* quotaManager = QuotaManager::Get();
+              MOZ_ASSERT(quotaManager);
+
+              quotaManager->DecreaseUsageForOrigin(mFileManager->Type(),
+                                                   mFileManager->Group(),
+                                                   mFileManager->Origin(),
+                                                   fileSize);
+            }
+
             return rv;
           }
 
           storedFileInfo.mCopiedSuccessfully = true;
         }
       }
 
       if (index) {
--- a/dom/indexedDB/FileManager.h
+++ b/dom/indexedDB/FileManager.h
@@ -4,17 +4,16 @@
  * 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/. */
 
 #ifndef mozilla_dom_indexeddb_filemanager_h__
 #define mozilla_dom_indexeddb_filemanager_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/quota/PersistenceType.h"
-#include "mozilla/dom/quota/StoragePrivilege.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsISupportsImpl.h"
 
 class nsIFile;
 class mozIStorageConnection;
 
 namespace mozilla {
@@ -24,32 +23,31 @@ namespace indexedDB {
 class FileInfo;
 
 // Implemented in ActorsParent.cpp.
 class FileManager MOZ_FINAL
 {
   friend class FileInfo;
 
   typedef mozilla::dom::quota::PersistenceType PersistenceType;
-  typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
 
   PersistenceType mPersistenceType;
   nsCString mGroup;
   nsCString mOrigin;
-  StoragePrivilege mPrivilege;
   nsString mDatabaseName;
 
   nsString mDirectoryPath;
   nsString mJournalDirectoryPath;
 
   int64_t mLastFileId;
 
   // Protected by IndexedDatabaseManager::FileMutex()
   nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
 
+  const bool mEnforcingQuota;
   bool mInvalidated;
 
 public:
   static already_AddRefed<nsIFile>
   GetFileForId(nsIFile* aDirectory, int64_t aId);
 
   static nsresult
   InitDirectory(nsIFile* aDirectory,
@@ -59,18 +57,18 @@ public:
                 const nsACString& aOrigin);
 
   static nsresult
   GetUsage(nsIFile* aDirectory, uint64_t* aUsage);
 
   FileManager(PersistenceType aPersistenceType,
               const nsACString& aGroup,
               const nsACString& aOrigin,
-              StoragePrivilege aPrivilege,
-              const nsAString& aDatabaseName);
+              const nsAString& aDatabaseName,
+              bool aEnforcingQuota);
 
   PersistenceType
   Type() const
   {
     return mPersistenceType;
   }
 
   const nsACString&
@@ -80,29 +78,29 @@ public:
   }
 
   const nsACString&
   Origin() const
   {
     return mOrigin;
   }
 
-  const StoragePrivilege&
-  Privilege() const
-  {
-    return mPrivilege;
-  }
-
   const nsAString&
   DatabaseName() const
   {
     return mDatabaseName;
   }
 
   bool
+  EnforcingQuota() const
+  {
+    return mEnforcingQuota;
+  }
+
+  bool
   Invalidated() const
   {
     return mInvalidated;
   }
 
   nsresult
   Init(nsIFile* aDirectory, mozIStorageConnection* aConnection);
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -843,25 +843,25 @@ AsyncDeleteFileRunnable::Run()
   NS_ENSURE_TRUE(directory, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIFile> file = mFileManager->GetFileForId(directory, mFileId);
   NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
 
   nsresult rv;
   int64_t fileSize;
 
-  if (mFileManager->Privilege() != Chrome) {
+  if (mFileManager->EnforcingQuota()) {
     rv = file->GetFileSize(&fileSize);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   }
 
   rv = file->Remove(false);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
-  if (mFileManager->Privilege() != Chrome) {
+  if (mFileManager->EnforcingQuota()) {
     QuotaManager* quotaManager = QuotaManager::Get();
     NS_ASSERTION(quotaManager, "Shouldn't be null!");
 
     quotaManager->DecreaseUsageForOrigin(mFileManager->Type(),
                                          mFileManager->Group(),
                                          mFileManager->Origin(), fileSize);
   }
 
--- a/dom/indexedDB/SerializationHelpers.h
+++ b/dom/indexedDB/SerializationHelpers.h
@@ -7,36 +7,28 @@
 
 #include "ipc/IPCMessageUtils.h"
 
 #include "mozilla/dom/indexedDB/Key.h"
 #include "mozilla/dom/indexedDB/KeyPath.h"
 #include "mozilla/dom/indexedDB/IDBCursor.h"
 #include "mozilla/dom/indexedDB/IDBTransaction.h"
 #include "mozilla/dom/quota/PersistenceType.h"
-#include "mozilla/dom/quota/StoragePrivilege.h"
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::dom::quota::PersistenceType> :
   public ContiguousEnumSerializer<
                                mozilla::dom::quota::PersistenceType,
                                mozilla::dom::quota::PERSISTENCE_TYPE_PERSISTENT,
                                mozilla::dom::quota::PERSISTENCE_TYPE_INVALID>
 { };
 
 template <>
-struct ParamTraits<mozilla::dom::quota::StoragePrivilege> :
-  public ContiguousEnumSerializer<mozilla::dom::quota::StoragePrivilege,
-                                  mozilla::dom::quota::Chrome,
-                                  mozilla::dom::quota::Invalid>
-{ };
-
-template <>
 struct ParamTraits<mozilla::dom::indexedDB::Key>
 {
   typedef mozilla::dom::indexedDB::Key paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mBuffer);
   }
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -1096,17 +1096,17 @@ QuotaManager::InitQuotaForOrigin(Persist
 }
 
 void
 QuotaManager::DecreaseUsageForOrigin(PersistenceType aPersistenceType,
                                      const nsACString& aGroup,
                                      const nsACString& aOrigin,
                                      int64_t aSize)
 {
-  AssertIsOnIOThread();
+  MOZ_ASSERT(!NS_IsMainThread());
 
   MutexAutoLock lock(mQuotaMutex);
 
   GroupInfoPair* pair;
   if (!mGroupInfoPairs.Get(aGroup, &pair)) {
     return;
   }