summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authortzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 09:59:48 +0000
committertzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 09:59:48 +0000
commitbce0aaf723befbf7c69d3492964c71bd8dbbd87e (patch)
treeb409ef8fb862765366b04602a9381fa14c1a7f69 /webkit
parenteb7ef5f39f4041a06a2eef6e2916b0ab3039238f (diff)
downloadchromium_src-bce0aaf723befbf7c69d3492964c71bd8dbbd87e.zip
chromium_src-bce0aaf723befbf7c69d3492964c71bd8dbbd87e.tar.gz
chromium_src-bce0aaf723befbf7c69d3492964c71bd8dbbd87e.tar.bz2
[FileAPI] Don't fail on ReserveQuota() even on insufficient space
Return maximum available quota when there isn't sufficient available space to satisfy the requested amount of quota reservation. BUG=340703 Review URL: https://codereview.chromium.org/155603002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249323 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/browser/fileapi/quota/quota_backend_impl.cc25
-rw-r--r--webkit/browser/fileapi/quota/quota_backend_impl_unittest.cc32
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation.cc16
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation.h14
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation_buffer.cc3
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation_buffer.h3
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation_manager.h2
-rw-r--r--webkit/browser/fileapi/quota/quota_reservation_manager_unittest.cc2
8 files changed, 64 insertions, 33 deletions
diff --git a/webkit/browser/fileapi/quota/quota_backend_impl.cc b/webkit/browser/fileapi/quota/quota_backend_impl.cc
index 62cd5a86..de0b3ac 100644
--- a/webkit/browser/fileapi/quota/quota_backend_impl.cc
+++ b/webkit/browser/fileapi/quota/quota_backend_impl.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "base/sequenced_task_runner.h"
#include "webkit/browser/fileapi/file_system_usage_cache.h"
#include "webkit/browser/quota/quota_client.h"
@@ -39,7 +40,7 @@ void QuotaBackendImpl::ReserveQuota(const GURL& origin,
DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
DCHECK(origin.is_valid());
if (!delta) {
- callback.Run(base::File::FILE_OK);
+ callback.Run(base::File::FILE_OK, 0);
return;
}
DCHECK(quota_manager_proxy_);
@@ -104,22 +105,30 @@ void QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota(
quota::QuotaStatusCode status, int64 usage, int64 quota) {
DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
DCHECK(info.origin.is_valid());
+ DCHECK_LE(0, usage);
+ DCHECK_LE(0, quota);
if (status != quota::kQuotaStatusOk) {
- callback.Run(base::File::FILE_ERROR_FAILED);
+ callback.Run(base::File::FILE_ERROR_FAILED, 0);
return;
}
- if (quota < usage + info.delta) {
- callback.Run(base::File::FILE_ERROR_NO_SPACE);
- return;
+ QuotaReservationInfo normalized_info = info;
+ if (info.delta > 0) {
+ int64 new_usage =
+ base::saturated_cast<int64>(usage + static_cast<uint64>(info.delta));
+ if (quota < new_usage)
+ new_usage = quota;
+ normalized_info.delta = std::max(static_cast<int64>(0), new_usage - usage);
}
- ReserveQuotaInternal(info);
- if (callback.Run(base::File::FILE_OK))
+ ReserveQuotaInternal(normalized_info);
+ if (callback.Run(base::File::FILE_OK, normalized_info.delta))
return;
// The requester could not accept the reserved quota. Revert it.
ReserveQuotaInternal(
- QuotaReservationInfo(info.origin, info.type, -info.delta));
+ QuotaReservationInfo(normalized_info.origin,
+ normalized_info.type,
+ -normalized_info.delta));
}
void QuotaBackendImpl::ReserveQuotaInternal(const QuotaReservationInfo& info) {
diff --git a/webkit/browser/fileapi/quota/quota_backend_impl_unittest.cc b/webkit/browser/fileapi/quota/quota_backend_impl_unittest.cc
index 6e7b94b..9f665e4 100644
--- a/webkit/browser/fileapi/quota/quota_backend_impl_unittest.cc
+++ b/webkit/browser/fileapi/quota/quota_backend_impl_unittest.cc
@@ -23,9 +23,13 @@ const char kOrigin[] = "http://example.com";
bool DidReserveQuota(bool accepted,
base::File::Error* error_out,
- base::File::Error error) {
+ int64* delta_out,
+ base::File::Error error,
+ int64 delta) {
DCHECK(error_out);
+ DCHECK(delta_out);
*error_out = error;
+ *delta_out = delta;
return accepted;
}
@@ -51,7 +55,7 @@ class MockQuotaManagerProxy : public quota::QuotaManagerProxy {
int64 delta) OVERRIDE {
++storage_modified_count_;
usage_ += delta;
- ASSERT_LT(usage_, quota_);
+ ASSERT_LE(usage_, quota_);
}
virtual void GetUsageAndQuota(
@@ -150,18 +154,22 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Basic) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(10000);
+ int64 delta = 0;
+
const int64 kDelta1 = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta1,
- base::Bind(&DidReserveQuota, true, &error));
+ base::Bind(&DidReserveQuota, true, &error, &delta));
EXPECT_EQ(base::File::FILE_OK, error);
+ EXPECT_EQ(kDelta1, delta);
EXPECT_EQ(kDelta1, quota_manager_proxy_->usage());
const int64 kDelta2 = -300;
error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta2,
- base::Bind(&DidReserveQuota, true, &error));
+ base::Bind(&DidReserveQuota, true, &error, &delta));
EXPECT_EQ(base::File::FILE_OK, error);
+ EXPECT_EQ(kDelta2, delta);
EXPECT_EQ(kDelta1 + kDelta2, quota_manager_proxy_->usage());
EXPECT_EQ(2, quota_manager_proxy_->storage_modified_count());
@@ -172,14 +180,17 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_NoSpace) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(100);
+ int64 delta = 0;
+
const int64 kDelta = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
- base::Bind(&DidReserveQuota, true, &error));
- EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, error);
- EXPECT_EQ(0, quota_manager_proxy_->usage());
+ base::Bind(&DidReserveQuota, true, &error, &delta));
+ EXPECT_EQ(base::File::FILE_OK, error);
+ EXPECT_EQ(100, delta);
+ EXPECT_EQ(100, quota_manager_proxy_->usage());
- EXPECT_EQ(0, quota_manager_proxy_->storage_modified_count());
+ EXPECT_EQ(1, quota_manager_proxy_->storage_modified_count());
}
TEST_F(QuotaBackendImplTest, ReserveQuota_Revert) {
@@ -187,11 +198,14 @@ TEST_F(QuotaBackendImplTest, ReserveQuota_Revert) {
InitializeForOriginAndType(GURL(kOrigin), type);
quota_manager_proxy_->set_quota(10000);
+ int64 delta = 0;
+
const int64 kDelta = 1000;
base::File::Error error = base::File::FILE_ERROR_FAILED;
backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
- base::Bind(&DidReserveQuota, false, &error));
+ base::Bind(&DidReserveQuota, false, &error, &delta));
EXPECT_EQ(base::File::FILE_OK, error);
+ EXPECT_EQ(kDelta, delta);
EXPECT_EQ(0, quota_manager_proxy_->usage());
EXPECT_EQ(2, quota_manager_proxy_->storage_modified_count());
diff --git a/webkit/browser/fileapi/quota/quota_reservation.cc b/webkit/browser/fileapi/quota/quota_reservation.cc
index af74174..f199b35 100644
--- a/webkit/browser/fileapi/quota/quota_reservation.cc
+++ b/webkit/browser/fileapi/quota/quota_reservation.cc
@@ -25,7 +25,7 @@ void QuotaReservation::RefreshReservation(
origin(), type(), size - remaining_quota_,
base::Bind(&QuotaReservation::AdaptDidUpdateReservedQuota,
weak_ptr_factory_.GetWeakPtr(),
- size, callback));
+ remaining_quota_, callback));
if (running_refresh_request_)
remaining_quota_ = 0;
@@ -93,20 +93,22 @@ QuotaReservation::~QuotaReservation() {
// static
bool QuotaReservation::AdaptDidUpdateReservedQuota(
const base::WeakPtr<QuotaReservation>& reservation,
- int64 new_reserved_size,
+ int64 previous_size,
const StatusCallback& callback,
- base::File::Error error) {
+ base::File::Error error,
+ int64 delta) {
if (!reservation)
return false;
return reservation->DidUpdateReservedQuota(
- new_reserved_size, callback, error);
+ previous_size, callback, error, delta);
}
bool QuotaReservation::DidUpdateReservedQuota(
- int64 new_reserved_size,
+ int64 previous_size,
const StatusCallback& callback,
- base::File::Error error) {
+ base::File::Error error,
+ int64 delta) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK(running_refresh_request_);
running_refresh_request_ = false;
@@ -117,7 +119,7 @@ bool QuotaReservation::DidUpdateReservedQuota(
}
if (error == base::File::FILE_OK)
- remaining_quota_ = new_reserved_size;
+ remaining_quota_ = previous_size + delta;
callback.Run(error);
return true;
}
diff --git a/webkit/browser/fileapi/quota/quota_reservation.h b/webkit/browser/fileapi/quota/quota_reservation.h
index dad3b30..9233a24 100644
--- a/webkit/browser/fileapi/quota/quota_reservation.h
+++ b/webkit/browser/fileapi/quota/quota_reservation.h
@@ -28,7 +28,9 @@ class WEBKIT_STORAGE_BROWSER_EXPORT QuotaReservation
typedef base::Callback<void(base::File::Error error)> StatusCallback;
// Reclaims unused quota and reserves another |size| of quota. So that the
- // resulting new |remaining_quota| will be same as |size|.
+ // resulting new |remaining_quota_| will be same as |size| as far as available
+ // space is enough. |remaining_quota_| may be less than |size| if there is
+ // not enough space available.
// Invokes |callback| upon completion.
void RefreshReservation(int64 size, const StatusCallback& callback);
@@ -67,12 +69,14 @@ class WEBKIT_STORAGE_BROWSER_EXPORT QuotaReservation
static bool AdaptDidUpdateReservedQuota(
const base::WeakPtr<QuotaReservation>& reservation,
- int64 new_reserved_size,
+ int64 previous_size,
const StatusCallback& callback,
- base::File::Error error);
- bool DidUpdateReservedQuota(int64 new_reserved_size,
+ base::File::Error error,
+ int64 delta);
+ bool DidUpdateReservedQuota(int64 previous_size,
const StatusCallback& callback,
- base::File::Error error);
+ base::File::Error error,
+ int64 delta);
bool client_crashed_;
bool running_refresh_request_;
diff --git a/webkit/browser/fileapi/quota/quota_reservation_buffer.cc b/webkit/browser/fileapi/quota/quota_reservation_buffer.cc
index 662c415..9e44319 100644
--- a/webkit/browser/fileapi/quota/quota_reservation_buffer.cc
+++ b/webkit/browser/fileapi/quota/quota_reservation_buffer.cc
@@ -92,7 +92,8 @@ bool QuotaReservationBuffer::DecrementDirtyCount(
base::WeakPtr<QuotaReservationManager> reservation_manager,
const GURL& origin,
FileSystemType type,
- base::File::Error error) {
+ base::File::Error error,
+ int64 delta_unused) {
DCHECK(origin.is_valid());
if (error == base::File::FILE_OK && reservation_manager) {
reservation_manager->DecrementDirtyCount(origin, type);
diff --git a/webkit/browser/fileapi/quota/quota_reservation_buffer.h b/webkit/browser/fileapi/quota/quota_reservation_buffer.h
index cc6a435..0d87a99 100644
--- a/webkit/browser/fileapi/quota/quota_reservation_buffer.h
+++ b/webkit/browser/fileapi/quota/quota_reservation_buffer.h
@@ -60,7 +60,8 @@ class QuotaReservationBuffer : public base::RefCounted<QuotaReservationBuffer> {
base::WeakPtr<QuotaReservationManager> reservation_manager,
const GURL& origin,
FileSystemType type,
- base::File::Error error);
+ base::File::Error error,
+ int64 delta);
typedef std::map<base::FilePath, OpenFileHandleContext*>
OpenFileHandleContextByPath;
diff --git a/webkit/browser/fileapi/quota/quota_reservation_manager.h b/webkit/browser/fileapi/quota/quota_reservation_manager.h
index 9b64a15..2fea930 100644
--- a/webkit/browser/fileapi/quota/quota_reservation_manager.h
+++ b/webkit/browser/fileapi/quota/quota_reservation_manager.h
@@ -28,7 +28,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT QuotaReservationManager {
public:
// Callback for ReserveQuota. When this callback returns false, ReserveQuota
// operation should be reverted.
- typedef base::Callback<bool(base::File::Error error)>
+ typedef base::Callback<bool(base::File::Error error, int64 delta)>
ReserveQuotaCallback;
// An abstraction of backing quota system.
diff --git a/webkit/browser/fileapi/quota/quota_reservation_manager_unittest.cc b/webkit/browser/fileapi/quota/quota_reservation_manager_unittest.cc
index 1ec2fb7..7b2b738 100644
--- a/webkit/browser/fileapi/quota/quota_reservation_manager_unittest.cc
+++ b/webkit/browser/fileapi/quota/quota_reservation_manager_unittest.cc
@@ -53,7 +53,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
on_memory_usage_ += delta;
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
- base::Bind(base::IgnoreResult(callback), base::File::FILE_OK));
+ base::Bind(base::IgnoreResult(callback), base::File::FILE_OK, delta));
}
virtual void ReleaseReservedQuota(const GURL& origin,