1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/file_system/quota/quota_reservation_buffer.h"
#include <stdint.h>
#include <memory>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "storage/browser/file_system/quota/open_file_handle.h"
#include "storage/browser/file_system/quota/open_file_handle_context.h"
#include "storage/browser/file_system/quota/quota_reservation.h"
namespace storage {
QuotaReservationBuffer::QuotaReservationBuffer(
base::WeakPtr<QuotaReservationManager> reservation_manager,
const url::Origin& origin,
FileSystemType type)
: reservation_manager_(reservation_manager),
origin_(origin),
type_(type),
reserved_quota_(0) {
DCHECK(!origin.opaque());
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
reservation_manager_->IncrementDirtyCount(origin, type);
}
scoped_refptr<QuotaReservation> QuotaReservationBuffer::CreateReservation() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return base::WrapRefCounted(new QuotaReservation(this));
}
std::unique_ptr<OpenFileHandle> QuotaReservationBuffer::GetOpenFileHandle(
QuotaReservation* reservation,
const base::FilePath& platform_path) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto& open_file = open_files_[platform_path];
if (!open_file) {
open_file = new OpenFileHandleContext(platform_path, this);
}
return base::WrapUnique(new OpenFileHandle(reservation, open_file));
}
void QuotaReservationBuffer::CommitFileGrowth(
int64_t reserved_quota_consumption,
int64_t usage_delta) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!reservation_manager_)
return;
reservation_manager_->CommitQuotaUsage(origin_, type_, usage_delta);
if (reserved_quota_consumption > 0) {
if (reserved_quota_consumption > reserved_quota_) {
LOG(ERROR) << "Detected over consumption of the storage quota beyond its"
<< " reservation";
reserved_quota_consumption = reserved_quota_;
}
reserved_quota_ -= reserved_quota_consumption;
reservation_manager_->ReleaseReservedQuota(origin_, type_,
reserved_quota_consumption);
}
}
void QuotaReservationBuffer::DetachOpenFileHandleContext(
OpenFileHandleContext* open_file) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(open_file, open_files_[open_file->platform_path()]);
open_files_.erase(open_file->platform_path());
}
void QuotaReservationBuffer::PutReservationToBuffer(int64_t reservation) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_LE(0, reservation);
reserved_quota_ += reservation;
}
QuotaReservationBuffer::~QuotaReservationBuffer() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!reservation_manager_)
return;
DCHECK_LE(0, reserved_quota_);
if (reserved_quota_ && reservation_manager_) {
reservation_manager_->ReserveQuota(
origin_, type_, -reserved_quota_,
base::BindOnce(&QuotaReservationBuffer::DecrementDirtyCount,
reservation_manager_, origin_, type_));
}
reservation_manager_->ReleaseReservationBuffer(this);
}
// static
bool QuotaReservationBuffer::DecrementDirtyCount(
base::WeakPtr<QuotaReservationManager> reservation_manager,
const url::Origin& origin,
FileSystemType type,
base::File::Error error,
int64_t delta_unused) {
DCHECK(!origin.opaque());
if (error == base::File::FILE_OK && reservation_manager) {
reservation_manager->DecrementDirtyCount(origin, type);
return true;
}
return false;
}
} // namespace storage
|