blob: 4f1fbb8d5dccbd66aba62508e7e626990ccd5ea0 [file] [log] [blame] [edit]
// Copyright 2020 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/blobfs/query.h"
#include <lib/fidl-async/cpp/bind.h>
#include "src/storage/blobfs/blobfs.h"
#include "src/storage/blobfs/format.h"
#include "src/storage/blobfs/runner.h"
namespace fuchsia_fs = ::llcpp::fuchsia::fs;
namespace blobfs {
constexpr const char kFsName[] = "blobfs";
QueryService::QueryService(async_dispatcher_t* dispatcher, Blobfs* blobfs, Runner* runner)
: fs::Service([dispatcher, this](zx::channel server_end) {
return fidl::BindSingleInFlightOnly(dispatcher, std::move(server_end), this);
}),
blobfs_(blobfs),
runner_(runner) {}
void QueryService::GetInfo(fuchsia_fs::FilesystemInfoQuery query,
GetInfoCompleter::Sync& completer) {
static_assert(fbl::constexpr_strlen(kFsName) < fuchsia_fs::MAX_FS_NAME_LENGTH,
"Blobfs name too long");
fuchsia_fs::FilesystemInfo::UnownedBuilder builder;
uint64_t total_bytes;
if (query & fuchsia_fs::FilesystemInfoQuery::TOTAL_BYTES) {
total_bytes = blobfs_->Info().data_block_count * blobfs_->Info().block_size;
builder.set_total_bytes(fidl::unowned_ptr(&total_bytes));
}
uint64_t used_bytes;
if (query & fuchsia_fs::FilesystemInfoQuery::USED_BYTES) {
used_bytes = blobfs_->Info().alloc_block_count * blobfs_->Info().block_size;
builder.set_used_bytes(fidl::unowned_ptr(&used_bytes));
}
uint64_t total_nodes;
if (query & fuchsia_fs::FilesystemInfoQuery::TOTAL_NODES) {
total_nodes = blobfs_->Info().inode_count;
builder.set_total_nodes(fidl::unowned_ptr(&total_nodes));
}
uint64_t used_nodes;
if (query & fuchsia_fs::FilesystemInfoQuery::USED_NODES) {
used_nodes = blobfs_->Info().alloc_inode_count;
builder.set_used_nodes(fidl::unowned_ptr(&used_nodes));
}
zx::event fs_id;
if (query & fuchsia_fs::FilesystemInfoQuery::FS_ID) {
zx_status_t status = blobfs_->GetFsId(&fs_id);
if (status != ZX_OK) {
completer.ReplyError(status);
return;
}
builder.set_fs_id(fidl::unowned_ptr(&fs_id));
}
uint32_t block_size;
if (query & fuchsia_fs::FilesystemInfoQuery::BLOCK_SIZE) {
block_size = kBlobfsBlockSize;
builder.set_block_size(fidl::unowned_ptr(&block_size));
}
uint32_t max_node_name_size;
if (query & fuchsia_fs::FilesystemInfoQuery::MAX_NODE_NAME_SIZE) {
max_node_name_size = digest::kSha256HexLength;
builder.set_max_node_name_size(fidl::unowned_ptr(&max_node_name_size));
}
fuchsia_fs::FsType fs_type;
if (query & fuchsia_fs::FilesystemInfoQuery::FS_TYPE) {
fs_type = fuchsia_fs::FsType::BLOBFS;
builder.set_fs_type(fidl::unowned_ptr(&fs_type));
}
fidl::StringView name;
if (query & fuchsia_fs::FilesystemInfoQuery::NAME) {
name = fidl::StringView(kFsName);
builder.set_name(fidl::unowned_ptr(&name));
}
fidl::StringView device_path;
char name_buf[llcpp::fuchsia::io2::MAX_PATH_LENGTH];
size_t name_len;
if (query & fuchsia_fs::FilesystemInfoQuery::DEVICE_PATH) {
zx_status_t status =
blobfs_->Device()->GetDevicePath(llcpp::fuchsia::io2::MAX_PATH_LENGTH, name_buf, &name_len);
if (status != ZX_OK) {
completer.ReplyError(status);
return;
}
// It appears that the |name_len| returned by |GetDevicePath| includes a trailing NUL.
ZX_ASSERT(name_buf[name_len - 1] == '\0');
device_path = fidl::StringView(name_buf, name_len - 1);
builder.set_device_path(fidl::unowned_ptr(&device_path));
}
completer.ReplySuccess(builder.build());
}
void QueryService::IsNodeInFilesystem(zx::event token,
IsNodeInFilesystemCompleter::Sync& completer) {
completer.Reply(runner_->IsTokenAssociatedWithVnode(std::move(token)));
}
} // namespace blobfs