blob: 7cf3eb529bc33a6e5563a00e1bafa03502c54bc0 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/f2fs/f2fs.h"
namespace f2fs {
InspectTree::InspectTree(F2fs* fs) : fs_(fs) { ZX_ASSERT(fs_ != nullptr); }
void InspectTree::Initialize() {
zx::status<fs::FilesystemInfo> fs_info = fs_->GetFilesystemInfo();
if (fs_info.is_error()) {
FX_LOGS(ERROR) << "Failed to initialize F2fs inspect tree: GetFilesystemInfo returned "
<< fs_info.status_string();
return;
}
{
std::lock_guard guard(info_mutex_);
info_ = {
.id = fs_info.value().fs_id,
.type = fs_info.value().fs_type,
.name = fs_info.value().name,
.version_major = fs_->GetSuperblockInfo().GetRawSuperblock().major_ver,
.version_minor = fs_->GetSuperblockInfo().GetRawSuperblock().minor_ver,
.block_size = fs_info.value().block_size,
.max_filename_length = fs_info.value().max_filename_size,
};
}
{
std::lock_guard guard(usage_mutex_);
UpdateUsage();
}
{
std::lock_guard guard(volume_mutex_);
UpdateVolumeSizeInfo();
}
tree_root_ = inspector_.GetRoot().CreateChild("f2fs");
fs_inspect_nodes_ = fs_inspect::CreateTree(tree_root_, CreateCallbacks());
inspector_.CreateStatsNode();
}
void InspectTree::UpdateUsage() {
zx::status<fs::FilesystemInfo> fs_info = fs_->GetFilesystemInfo();
if (fs_info.is_error()) {
FX_LOGS(ERROR) << "Failed to initialize F2fs inspect tree: GetFilesystemInfo returned "
<< fs_info.status_string();
return;
}
usage_.total_bytes = fs_info.value().total_bytes;
usage_.used_bytes = fs_info.value().used_bytes;
usage_.total_nodes = fs_info.value().total_nodes;
usage_.used_nodes = fs_info.value().used_nodes;
}
void InspectTree::UpdateVolumeSizeInfo() {
zx::status<fs_inspect::VolumeData::SizeInfo> size_info = zx::error(ZX_ERR_BAD_HANDLE);
{
size_info = fs_inspect::VolumeData::GetSizeInfoFromDevice(*fs_->GetBc().GetDevice());
if (size_info.is_error()) {
FX_LOGS(WARNING) << "Failed to obtain size information from block device: "
<< size_info.status_string();
}
}
if (size_info.is_ok()) {
volume_.size_info = size_info.value();
}
}
void InspectTree::OnOutOfSpace() {
zx::time curr_time = zx::clock::get_monotonic();
std::lock_guard guard(volume_mutex_);
if ((curr_time - last_out_of_space_time_) > kOutOfSpaceDuration) {
++volume_.out_of_space_events;
last_out_of_space_time_ = curr_time;
}
}
fs_inspect::NodeCallbacks InspectTree::CreateCallbacks() {
return {
.info_callback =
[this] {
std::lock_guard guard(info_mutex_);
return info_;
},
.usage_callback =
[this] {
std::lock_guard guard(usage_mutex_);
UpdateUsage();
return usage_;
},
.volume_callback =
[this] {
std::lock_guard guard(volume_mutex_);
UpdateVolumeSizeInfo();
return volume_;
},
};
}
} // namespace f2fs