Commit 9a36fa99 authored by Ben Kelly's avatar Ben Kelly Committed by Commit Bot

CacheStorage: Report disk full error correctly when creating a cache.

Past metrics show that the main cause of failure for
base::CreateDirectory in IndexedDB is the device being out of space.
This CL plumbs the error code through so we can properly report this
as a QuotaExceeded exception.

An alternative would be to retry the operation, but if the disk is
truly full then its likely any further operations will run into disk
exhaustion anyway.  For now lets just report the problem as accurately
as we can.

Bug: 1113829
Change-Id: Idc66d2f43b474e1a97229e0057031ba12c96d677
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2343305Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Commit-Queue: Ben Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795979}
parent b8fa712a
......@@ -86,8 +86,9 @@ struct LegacyCacheStorage::CacheMatchResponse {
// Handles the loading and clean up of CacheStorageCache objects.
class LegacyCacheStorage::CacheLoader {
public:
using CacheCallback =
base::OnceCallback<void(std::unique_ptr<LegacyCacheStorageCache>)>;
using CacheAndErrorCallback =
base::OnceCallback<void(std::unique_ptr<LegacyCacheStorageCache>,
CacheStorageError status)>;
using BoolCallback = base::OnceCallback<void(bool)>;
using CacheStorageIndexLoadCallback =
base::OnceCallback<void(std::unique_ptr<CacheStorageIndex>)>;
......@@ -121,7 +122,7 @@ class LegacyCacheStorage::CacheLoader {
// Deletes any pre-existing cache of the same name and then loads it.
virtual void PrepareNewCacheDestination(const std::string& cache_name,
CacheCallback callback) = 0;
CacheAndErrorCallback callback) = 0;
// After the backend has been deleted, do any extra house keeping such as
// removing the cache's directory.
......@@ -194,11 +195,11 @@ class LegacyCacheStorage::MemoryLoader
}
void PrepareNewCacheDestination(const std::string& cache_name,
CacheCallback callback) override {
CacheAndErrorCallback callback) override {
std::unique_ptr<LegacyCacheStorageCache> cache =
CreateCache(cache_name, 0 /*cache_size*/, 0 /* cache_padding */,
storage::CopyDefaultPaddingKey());
std::move(callback).Run(std::move(cache));
std::move(callback).Run(std::move(cache), CacheStorageError::kSuccess);
}
void CleanUpDeletedCache(CacheStorageCache* cache) override {}
......@@ -272,7 +273,7 @@ class LegacyCacheStorage::SimpleCacheLoader
}
void PrepareNewCacheDestination(const std::string& cache_name,
CacheCallback callback) override {
CacheAndErrorCallback callback) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
PostTaskAndReplyWithResult(
......@@ -285,8 +286,8 @@ class LegacyCacheStorage::SimpleCacheLoader
}
// Runs on the cache_task_runner_.
static std::string PrepareNewCacheDirectoryInPool(
const base::FilePath& origin_path) {
static std::tuple<CacheStorageError, std::string>
PrepareNewCacheDirectoryInPool(const base::FilePath& origin_path) {
std::string cache_dir;
base::FilePath cache_path;
do {
......@@ -294,21 +295,38 @@ class LegacyCacheStorage::SimpleCacheLoader
cache_path = origin_path.AppendASCII(cache_dir);
} while (base::PathExists(cache_path));
return base::CreateDirectory(cache_path) ? cache_dir : "";
base::File::Error error = base::File::FILE_OK;
if (base::CreateDirectoryAndGetError(cache_path, &error)) {
return std::make_tuple(CacheStorageError::kSuccess, cache_dir);
} else {
CacheStorageError status =
error == base::File::FILE_ERROR_NO_SPACE
? CacheStorageError::kErrorQuotaExceeded
: MakeErrorStorage(ErrorStorageType::kDidCreateNullCache);
return std::make_tuple(status, cache_dir);
}
}
void PrepareNewCacheCreateCache(const std::string& cache_name,
CacheCallback callback,
const std::string& cache_dir) {
if (cache_dir.empty()) {
std::move(callback).Run(nullptr);
void PrepareNewCacheCreateCache(
const std::string& cache_name,
CacheAndErrorCallback callback,
const std::tuple<CacheStorageError, std::string>& result) {
CacheStorageError status;
std::string cache_dir;
std::tie(status, cache_dir) = result;
if (status != CacheStorageError::kSuccess) {
std::move(callback).Run(nullptr, status);
return;
}
DCHECK(!cache_dir.empty());
cache_name_to_cache_dir_[cache_name] = cache_dir;
std::move(callback).Run(CreateCache(
cache_name, LegacyCacheStorage::kSizeUnknown,
LegacyCacheStorage::kSizeUnknown, storage::CopyDefaultPaddingKey()));
std::move(callback).Run(
CreateCache(cache_name, LegacyCacheStorage::kSizeUnknown,
LegacyCacheStorage::kSizeUnknown,
storage::CopyDefaultPaddingKey()),
CacheStorageError::kSuccess);
}
void CleanUpDeletedCache(CacheStorageCache* cache) override {
......@@ -1019,7 +1037,8 @@ void LegacyCacheStorage::CreateCacheDidCreateCache(
const std::string& cache_name,
int64_t trace_id,
CacheAndErrorCallback callback,
std::unique_ptr<LegacyCacheStorageCache> cache) {
std::unique_ptr<LegacyCacheStorageCache> cache,
CacheStorageError status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
TRACE_EVENT_WITH_FLOW0("CacheStorage",
......@@ -1030,10 +1049,8 @@ void LegacyCacheStorage::CreateCacheDidCreateCache(
UMA_HISTOGRAM_BOOLEAN("ServiceWorkerCache.CreateCacheStorageResult",
static_cast<bool>(cache));
if (!cache) {
std::move(callback).Run(
CacheStorageCacheHandle(),
MakeErrorStorage(ErrorStorageType::kDidCreateNullCache));
if (status != CacheStorageError::kSuccess) {
std::move(callback).Run(CacheStorageCacheHandle(), status);
return;
}
......
......@@ -187,11 +187,11 @@ class CONTENT_EXPORT LegacyCacheStorage : public CacheStorage,
void OpenCacheImpl(const std::string& cache_name,
int64_t trace_id,
CacheAndErrorCallback callback);
void CreateCacheDidCreateCache(
const std::string& cache_name,
int64_t trace_id,
CacheAndErrorCallback callback,
std::unique_ptr<LegacyCacheStorageCache> cache);
void CreateCacheDidCreateCache(const std::string& cache_name,
int64_t trace_id,
CacheAndErrorCallback callback,
std::unique_ptr<LegacyCacheStorageCache> cache,
blink::mojom::CacheStorageError status);
void CreateCacheDidWriteIndex(CacheAndErrorCallback callback,
CacheStorageCacheHandle cache_handle,
int64_t trace_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment