Bug 968272 - use less conservative temporary storage policy in QuotaManager (r=janv)

--HG--
extra : rebase_source : 40739bd10fa31c813303328e48bff371fbe6224c
This commit is contained in:
Luke Wagner 2014-05-20 17:19:59 -05:00
parent eb9b45ebca
commit 89be6a3e1d
2 changed files with 40 additions and 99 deletions

View File

@ -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<bool> 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<uint64_t>((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<uint64_t>(
PERCENTAGE(availableKB, _25GB, .005) +
PERCENTAGE(_25GB, _7GB, .01) +
PERCENTAGE(_7GB, _500MB, .05) +
PERCENTAGE(_500MB, 0, gSmartLimitRatio)
);
}
else if (availableKB > _7GB) {
resultKB = static_cast<uint64_t>(
PERCENTAGE(availableKB, _7GB, .01) +
PERCENTAGE(_7GB, _500MB, .05) +
PERCENTAGE(_500MB, 0, gSmartLimitRatio)
);
}
else if (availableKB > _500MB) {
resultKB = static_cast<uint64_t>(
PERCENTAGE(availableKB, _500MB, .05) +
PERCENTAGE(_500MB, 0, gSmartLimitRatio)
);
}
else {
resultKB = static_cast<uint64_t>(
PERCENTAGE(availableKB, 0, gSmartLimitRatio)
);
}
#undef PERCENTAGE
*aLimit = 1024 * mozilla::clamped<uint64_t>(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<uint64_t>(mTemporaryStorageLimit * .20, 2 GB);
// In low-storage situations, make an exception (while not exceeding the total
// storage limit).
return std::min<uint64_t>(mTemporaryStorageLimit,
std::max<uint64_t>(x, 10 MB));
}
// static
uint32_t
QuotaManager::GetStorageQuotaMB()

View File

@ -279,10 +279,7 @@ public:
}
uint64_t
GetGroupLimit() const
{
return mTemporaryStorageLimit / 5;
}
GetGroupLimit() const;
static uint32_t
GetStorageQuotaMB();