From 89be6a3e1d6df516766bffeb27ada5ffc8fb3602 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 20 May 2014 17:19:59 -0500 Subject: [PATCH] Bug 968272 - use less conservative temporary storage policy in QuotaManager (r=janv) --HG-- extra : rebase_source : 40739bd10fa31c813303328e48bff371fbe6224c --- dom/quota/QuotaManager.cpp | 134 +++++++++++-------------------------- dom/quota/QuotaManager.h | 5 +- 2 files changed, 40 insertions(+), 99 deletions(-) diff --git a/dom/quota/QuotaManager.cpp b/dom/quota/QuotaManager.cpp index d575742ae67..31e4abe9853 100644 --- a/dom/quota/QuotaManager.cpp +++ b/dom/quota/QuotaManager.cpp @@ -68,13 +68,7 @@ // Preference that users can set to override temporary storage smart limit // calculation. #define PREF_FIXED_LIMIT "dom.quotaManager.temporaryStorage.fixedLimit" - -// Preferences that are used during temporary storage smart limit calculation -#define PREF_SMART_LIMIT_PREFIX "dom.quotaManager.temporaryStorage.smartLimit." -#define PREF_SMART_LIMIT_MIN PREF_SMART_LIMIT_PREFIX "min" -#define PREF_SMART_LIMIT_MAX PREF_SMART_LIMIT_PREFIX "max" -#define PREF_SMART_LIMIT_CHUNK PREF_SMART_LIMIT_PREFIX "chunk" -#define PREF_SMART_LIMIT_RATIO PREF_SMART_LIMIT_PREFIX "ratio" +#define PREF_CHUNK_SIZE "dom.quotaManager.temporaryStorage.chunkSize" // Preference that is used to enable testing features #define PREF_TESTING_FEATURES "dom.quotaManager.testing" @@ -88,6 +82,10 @@ #define PERMISSION_DEFAUT_PERSISTENT_STORAGE "default-persistent-storage" +#define KB * 1024ULL +#define MB * 1024ULL KB +#define GB * 1024ULL MB + USING_QUOTA_NAMESPACE using namespace mozilla::dom; using mozilla::dom::FileService; @@ -480,33 +478,17 @@ namespace { // Amount of space that storages may use by default in megabytes. static const int32_t kDefaultQuotaMB = 50; -// Constants for temporary storage limit computing. -static const int32_t kDefaultFixedLimitKB = -1; -#ifdef ANDROID -// On Android, smaller/older devices may have very little storage and -// device owners may be sensitive to storage footprint: Use a smaller -// percentage of available space and a smaller minimum/maximum. -static const uint32_t kDefaultSmartLimitMinKB = 10 * 1024; -static const uint32_t kDefaultSmartLimitMaxKB = 200 * 1024; -static const uint32_t kDefaultSmartLimitChunkKB = 2 * 1024; -static const float kDefaultSmartLimitRatio = .2f; -#else -static const uint64_t kDefaultSmartLimitMinKB = 50 * 1024; -static const uint64_t kDefaultSmartLimitMaxKB = 1024 * 1024; -static const uint32_t kDefaultSmartLimitChunkKB = 10 * 1024; -static const float kDefaultSmartLimitRatio = .4f; -#endif QuotaManager* gInstance = nullptr; mozilla::Atomic gShutdown(false); int32_t gStorageQuotaMB = kDefaultQuotaMB; +// Constants for temporary storage limit computing. +static const int32_t kDefaultFixedLimitKB = -1; +static const uint32_t kDefaultChunkSizeKB = 10 * 1024; int32_t gFixedLimitKB = kDefaultFixedLimitKB; -uint32_t gSmartLimitMinKB = kDefaultSmartLimitMinKB; -uint32_t gSmartLimitMaxKB = kDefaultSmartLimitMaxKB; -uint32_t gSmartLimitChunkKB = kDefaultSmartLimitChunkKB; -float gSmartLimitRatio = kDefaultSmartLimitRatio; +uint32_t gChunkSizeKB = kDefaultChunkSizeKB; bool gTestingEnabled = false; @@ -857,12 +839,7 @@ MaybeUpgradeOriginDirectory(nsIFile* aDirectory) // This method computes and returns our best guess for the temporary storage // limit (in bytes), based on the amount of space users have free on their hard -// drive and on given temporary storage usage (also in bytes). We use a tiered -// scheme: the more space available, the larger the temporary storage will be. -// However, we do not want to enable the temporary storage to grow to an -// unbounded size, so the larger the user's available space is, the smaller of -// a percentage we take. We set a lower bound of gTemporaryStorageLimitMinKB -// and an upper bound of gTemporaryStorageLimitMaxKB. +// drive and on given temporary storage usage (also in bytes). nsresult GetTemporaryStorageLimit(nsIFile* aDirectory, uint64_t aCurrentUsage, uint64_t* aLimit) @@ -877,55 +854,15 @@ GetTemporaryStorageLimit(nsIFile* aDirectory, uint64_t aCurrentUsage, uint64_t availableKB = static_cast((bytesAvailable + aCurrentUsage) / 1024); - // Grow/shrink in gTemporaryStorageLimitChunkKB units, deliberately, so that - // in the common case we don't shrink temporary storage and evict origin data - // every time we initialize. - availableKB = (availableKB / gSmartLimitChunkKB) * gSmartLimitChunkKB; + // Grow/shrink in gChunkSizeKB units, deliberately, so that in the common case + // we don't shrink temporary storage and evict origin data every time we + // initialize. + availableKB = (availableKB / gChunkSizeKB) * gChunkSizeKB; - // The tier scheme: - // .5 % of space above 25 GB - // 1 % of space between 7GB -> 25 GB - // 5 % of space between 500 MB -> 7 GB - // gTemporaryStorageLimitRatio of space up to 500 MB + // Allow temporary storage to consume up to half the available space. + uint64_t resultKB = availableKB * .50; - static const uint64_t _25GB = 25 * 1024 * 1024; - static const uint64_t _7GB = 7 * 1024 * 1024; - static const uint64_t _500MB = 500 * 1024; - -#define PERCENTAGE(a, b, c) ((a - b) * c) - - uint64_t resultKB; - if (availableKB > _25GB) { - resultKB = static_cast( - PERCENTAGE(availableKB, _25GB, .005) + - PERCENTAGE(_25GB, _7GB, .01) + - PERCENTAGE(_7GB, _500MB, .05) + - PERCENTAGE(_500MB, 0, gSmartLimitRatio) - ); - } - else if (availableKB > _7GB) { - resultKB = static_cast( - PERCENTAGE(availableKB, _7GB, .01) + - PERCENTAGE(_7GB, _500MB, .05) + - PERCENTAGE(_500MB, 0, gSmartLimitRatio) - ); - } - else if (availableKB > _500MB) { - resultKB = static_cast( - PERCENTAGE(availableKB, _500MB, .05) + - PERCENTAGE(_500MB, 0, gSmartLimitRatio) - ); - } - else { - resultKB = static_cast( - PERCENTAGE(availableKB, 0, gSmartLimitRatio) - ); - } - -#undef PERCENTAGE - - *aLimit = 1024 * mozilla::clamped(resultKB, gSmartLimitMinKB, - gSmartLimitMaxKB); + *aLimit = resultKB * 1024; return NS_OK; } @@ -1082,19 +1019,10 @@ QuotaManager::Init() } if (NS_FAILED(Preferences::AddIntVarCache(&gFixedLimitKB, PREF_FIXED_LIMIT, - kDefaultFixedLimitKB)) || - NS_FAILED(Preferences::AddUintVarCache(&gSmartLimitMinKB, - PREF_SMART_LIMIT_MIN, - kDefaultSmartLimitMinKB)) || - NS_FAILED(Preferences::AddUintVarCache(&gSmartLimitMaxKB, - PREF_SMART_LIMIT_MAX, - kDefaultSmartLimitMaxKB)) || - NS_FAILED(Preferences::AddUintVarCache(&gSmartLimitChunkKB, - PREF_SMART_LIMIT_CHUNK, - kDefaultSmartLimitChunkKB)) || - NS_FAILED(Preferences::AddFloatVarCache(&gSmartLimitRatio, - PREF_SMART_LIMIT_RATIO, - kDefaultSmartLimitRatio))) { + kDefaultFixedLimitKB)) || + NS_FAILED(Preferences::AddUintVarCache(&gChunkSizeKB, + PREF_CHUNK_SIZE, + kDefaultChunkSizeKB))) { NS_WARNING("Unable to respond to temp storage pref changes!"); } @@ -1941,9 +1869,9 @@ QuotaManager::EnsureOriginIsInitialized(PersistenceType aPersistenceType, NS_ENSURE_SUCCESS(rv, rv); } - CheckTemporaryStorageLimits(); - mTemporaryStorageInitialized = true; + + CheckTemporaryStorageLimits(); } bool created; @@ -2009,6 +1937,22 @@ QuotaManager::GetClient(Client::Type aClientType) return client.forget(); } +uint64_t +QuotaManager::GetGroupLimit() const +{ + MOZ_ASSERT(mTemporaryStorageInitialized); + + // To avoid one group evicting all the rest, limit the amount any one group + // can use to 20%. To prevent individual sites from using exorbitant amounts + // of storage where there is a lot of free space, cap the group limit to 2GB. + uint64_t x = std::min(mTemporaryStorageLimit * .20, 2 GB); + + // In low-storage situations, make an exception (while not exceeding the total + // storage limit). + return std::min(mTemporaryStorageLimit, + std::max(x, 10 MB)); +} + // static uint32_t QuotaManager::GetStorageQuotaMB() diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 90c506b2fd8..011a6f8aa47 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -279,10 +279,7 @@ public: } uint64_t - GetGroupLimit() const - { - return mTemporaryStorageLimit / 5; - } + GetGroupLimit() const; static uint32_t GetStorageQuotaMB();