blob: 3f1965933c965de28045c17fc20f70b76126d709 [file] [log] [blame]
// 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/factory/factoryfs/directory.h"
#include <fuchsia/device/c/fidl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <sys/stat.h>
#include <zircon/assert.h>
#include <string_view>
#include "src/storage/factory/factoryfs/superblock.h"
namespace factoryfs {
Directory::Directory(factoryfs::Factoryfs& fs, std::string_view path)
: factoryfs_(fs), path_(path) {
factoryfs_.DidOpen(path_, *this);
}
Directory::~Directory() { factoryfs_.DidClose(path_); }
zx_status_t Directory::Create(fbl::StringPiece name_view, uint32_t mode,
fbl::RefPtr<fs::Vnode>* out) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t Directory::Readdir(fs::VdirCookie* cookie, void* dirents, size_t len,
size_t* out_actual) {
// TODO(manalib)
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t Directory::Read(void* data, size_t len, size_t off, size_t* out_actual) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t Directory::Write(const void* data, size_t len, size_t offset, size_t* out_actual) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t Directory::Append(const void* data, size_t len, size_t* out_end, size_t* out_actual) {
return ZX_ERR_NOT_SUPPORTED;
}
void Directory::Sync(SyncCallback closure) {}
zx_status_t Directory::Lookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode>* out) {
ZX_ASSERT(name.find('/') == std::string::npos);
if (name == ".") {
*out = fbl::RefPtr<Directory>(this);
return ZX_OK;
}
std::string full_path;
if (!path_.empty()) {
full_path.reserve(path_.size() + 1 + name.size());
full_path = path_;
full_path.push_back('/');
full_path.append(name);
name = full_path;
}
auto result = factoryfs_.Lookup(name);
if (result.is_error()) {
return result.status_value();
}
*out = std::move(result).value();
return ZX_OK;
}
zx_status_t Directory::Close() { return ZX_OK; }
#ifdef __Fuchsia__
constexpr const char kFsName[] = "factoryfs";
zx_status_t Directory::QueryFilesystem(::llcpp::fuchsia::io::FilesystemInfo* info) {
static_assert(fbl::constexpr_strlen(kFsName) + 1 < ::llcpp::fuchsia::io::MAX_FS_NAME_BUFFER,
"Factoryfs name too long");
*info = {};
info->block_size = kFactoryfsBlockSize;
info->max_filename_size = kFactoryfsMaxNameSize;
info->fs_type = VFS_TYPE_FACTORYFS;
info->fs_id = factoryfs_.GetFsIdLegacy();
info->total_bytes = Info().data_blocks * kFactoryfsBlockSize;
info->used_bytes = Info().data_blocks * kFactoryfsBlockSize;
info->total_nodes = Info().directory_entries;
info->used_nodes = Info().directory_entries;
strlcpy(reinterpret_cast<char*>(info->name.data()), kFsName,
::llcpp::fuchsia::io::MAX_FS_NAME_BUFFER);
return ZX_OK;
}
zx_status_t Directory::GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) {
return factoryfs_.Device().GetDevicePath(buffer_len, out_name, out_len);
}
#endif
zx_status_t Directory::Unlink(fbl::StringPiece path, bool is_dir) { return ZX_ERR_NOT_SUPPORTED; }
const factoryfs::Superblock& Directory::Info() const { return factoryfs_.Info(); }
zx_status_t Directory::GetAttributes(fs::VnodeAttributes* attributes) {
*attributes = fs::VnodeAttributes();
attributes->mode = (V_TYPE_DIR | V_IRUSR);
attributes->inode = ::llcpp::fuchsia::io::INO_UNKNOWN;
attributes->content_size = Info().directory_ent_blocks * kFactoryfsBlockSize;
attributes->storage_size = Info().directory_ent_blocks * kFactoryfsBlockSize;
attributes->link_count = 1;
attributes->creation_time = 0;
attributes->modification_time = 0;
return ZX_OK;
}
zx_status_t Directory::Rename(fbl::RefPtr<fs::Vnode> newdirectory, fbl::StringPiece currname,
fbl::StringPiece newname, bool srcdir, bool dstdir) {
return ZX_ERR_NOT_SUPPORTED;
}
} // namespace factoryfs