blob: 5680b493f938195641af3929b4d8cd8fa301aa30 [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 <fidl/fuchsia.io/cpp/wire.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(std::string_view 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(fxbug.dev/105904): Implement directory navigation over flat filesystem.
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_FILE;
}
zx_status_t Directory::Write(const void* data, size_t len, size_t offset, size_t* out_actual) {
return ZX_ERR_NOT_FILE;
}
zx_status_t Directory::Append(const void* data, size_t len, size_t* out_end, size_t* out_actual) {
return ZX_ERR_NOT_FILE;
}
zx_status_t Directory::Truncate(size_t len) { return ZX_ERR_NOT_FILE; }
zx_status_t Directory::GetVmo(fuchsia_io::wire::VmoFlags flags, zx::vmo* out_vmo) {
return ZX_ERR_NOT_FILE;
}
void Directory::Sync(SyncCallback closure) { closure(ZX_ERR_NOT_SUPPORTED); }
zx_status_t Directory::Lookup(std::string_view 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;
}
#ifdef __Fuchsia__
zx::result<std::string> Directory::GetDevicePath() const {
return factoryfs_.Device().GetDevicePath();
}
#endif
zx_status_t Directory::Unlink(std::string_view 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 = fuchsia_io::wire::kInoUnknown;
attributes->content_size =
static_cast<uint64_t>(Info().directory_ent_blocks) * kFactoryfsBlockSize;
attributes->storage_size =
static_cast<uint64_t>(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, std::string_view currname,
std::string_view newname, bool srcdir, bool dstdir) {
return ZX_ERR_NOT_SUPPORTED;
}
} // namespace factoryfs