#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "storage/browser/blob/blob_memory_controller.h"
#include <algorithm>
#include <memory>
#include <numeric>
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/small_map.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_number_conversions.h"
#include "base/system/sys_info.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_item.h"
#include "storage/browser/blob/shareable_blob_data_item.h"
#include "storage/browser/blob/shareable_file_reference.h"
File;
FilePath;
namespace storage {
namespace {
constexpr int64_t kUnknownDiskAvailability = …;
const int64_t kMinSecondsForPressureEvictions = …;
FileCreationInfo;
MemoryAllocation;
QuotaAllocationTask;
DiskSpaceFuncPtr;
File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { … }
BlobStorageLimits CalculateBlobStorageLimitsImpl(
const FilePath& storage_dir,
bool disk_enabled,
std::optional<uint64_t> optional_memory_size_for_testing) { … }
void DestructFile(File infos_without_references) { … }
void DeleteFiles(std::vector<FileCreationInfo> files) { … }
struct EmptyFilesResult { … };
EmptyFilesResult CreateEmptyFiles(
const FilePath& blob_storage_dir,
DiskSpaceFuncPtr disk_space_function,
scoped_refptr<base::TaskRunner> file_task_runner,
std::vector<base::FilePath> file_paths) { … }
std::pair<FileCreationInfo, int64_t> CreateFileAndWriteItems(
const FilePath& blob_storage_dir,
DiskSpaceFuncPtr disk_space_function,
const FilePath& file_path,
scoped_refptr<base::TaskRunner> file_task_runner,
std::vector<base::span<const uint8_t>> data,
size_t total_size_bytes) { … }
uint64_t GetTotalSizeAndFileSizes(
const std::vector<scoped_refptr<ShareableBlobDataItem>>&
unreserved_file_items,
std::vector<uint64_t>* file_sizes_output) { … }
}
FileCreationInfo::FileCreationInfo() = default;
FileCreationInfo::~FileCreationInfo() { … }
FileCreationInfo::FileCreationInfo(FileCreationInfo&&) = default;
FileCreationInfo& FileCreationInfo::operator=(FileCreationInfo&&) = default;
MemoryAllocation::MemoryAllocation(
base::WeakPtr<BlobMemoryController> controller,
uint64_t item_id,
size_t length)
: … { … }
MemoryAllocation::~MemoryAllocation() { … }
BlobMemoryController::QuotaAllocationTask::~QuotaAllocationTask() = default;
class BlobMemoryController::MemoryQuotaAllocationTask
: public BlobMemoryController::QuotaAllocationTask { … };
class BlobMemoryController::FileQuotaAllocationTask
: public BlobMemoryController::QuotaAllocationTask { … };
BlobMemoryController::BlobMemoryController(
const base::FilePath& storage_directory,
scoped_refptr<base::TaskRunner> file_runner)
: … { … }
BlobMemoryController::~BlobMemoryController() = default;
void BlobMemoryController::DisableFilePaging(base::File::Error reason) { … }
BlobMemoryController::Strategy BlobMemoryController::DetermineStrategy(
size_t preemptive_transported_bytes,
uint64_t total_transportation_bytes) const { … }
bool BlobMemoryController::CanReserveQuota(uint64_t size) const { … }
base::WeakPtr<QuotaAllocationTask> BlobMemoryController::ReserveMemoryQuota(
std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_memory_items,
MemoryQuotaRequestCallback done_callback) { … }
base::WeakPtr<QuotaAllocationTask> BlobMemoryController::ReserveFileQuota(
std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_file_items,
FileQuotaRequestCallback done_callback) { … }
void BlobMemoryController::ShrinkMemoryAllocation(ShareableBlobDataItem* item) { … }
void BlobMemoryController::ShrinkFileAllocation(
ShareableFileReference* file_reference,
uint64_t old_length,
uint64_t new_length) { … }
void BlobMemoryController::GrowFileAllocation(
ShareableFileReference* file_reference,
uint64_t delta) { … }
void BlobMemoryController::NotifyMemoryItemsUsed(
const std::vector<scoped_refptr<ShareableBlobDataItem>>& items) { … }
void BlobMemoryController::CallWhenStorageLimitsAreKnown(
base::OnceClosure callback) { … }
void BlobMemoryController::CalculateBlobStorageLimits() { … }
base::WeakPtr<BlobMemoryController> BlobMemoryController::GetWeakPtr() { … }
void BlobMemoryController::OnStorageLimitsCalculated(BlobStorageLimits limits) { … }
void BlobMemoryController::AdjustDiskUsage(uint64_t avail_disk) { … }
base::WeakPtr<QuotaAllocationTask> BlobMemoryController::AppendMemoryTask(
uint64_t total_bytes_needed,
std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_memory_items,
MemoryQuotaRequestCallback done_callback) { … }
void BlobMemoryController::MaybeGrantPendingMemoryRequests() { … }
size_t BlobMemoryController::CollectItemsForEviction(
std::vector<scoped_refptr<ShareableBlobDataItem>>* output,
uint64_t min_page_file_size) { … }
void BlobMemoryController::MaybeScheduleEvictionUntilSystemHealthy(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { … }
void BlobMemoryController::OnEvictionComplete(
scoped_refptr<ShareableFileReference> file_reference,
std::vector<scoped_refptr<ShareableBlobDataItem>> items,
size_t total_items_size,
std::pair<FileCreationInfo, int64_t > result) { … }
void BlobMemoryController::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { … }
FilePath BlobMemoryController::GenerateNextPageFileName() { … }
void BlobMemoryController::RecordTracingCounters() const { … }
size_t BlobMemoryController::GetAvailableMemoryForBlobs() const { … }
uint64_t BlobMemoryController::GetAvailableFileSpaceForBlobs() const { … }
void BlobMemoryController::GrantMemoryAllocations(
std::vector<scoped_refptr<ShareableBlobDataItem>>* items,
size_t total_bytes) { … }
void BlobMemoryController::RevokeMemoryAllocation(uint64_t item_id,
size_t length) { … }
void BlobMemoryController::OnBlobFileDelete(uint64_t size,
const FilePath& path) { … }
void BlobMemoryController::OnShrunkenBlobFileDelete(uint64_t shrink_delta,
const FilePath& path) { … }
}