blob: 95ba5eef95bb00f697134ab15a91b5defb5c23ae [file] [log] [blame]
// Copyright 2018 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 <stdlib.h>
#include <memory>
#include "src/storage/minfs/allocator/inode_manager.h"
#include "src/storage/minfs/format.h"
namespace minfs {
InodeManager::InodeManager(Bcache* bc, blk_t start_block, uint32_t block_size)
: start_block_(start_block), block_size_(block_size), bc_(bc) {}
zx_status_t InodeManager::Create(Bcache* bc, SuperblockManager* sb,
fs::BufferedOperationsBuilder* builder, AllocatorMetadata metadata,
blk_t start_block, size_t inodes,
std::unique_ptr<InodeManager>* out) {
auto mgr = std::unique_ptr<InodeManager>(new InodeManager(bc, start_block, sb->BlockSize()));
InodeManager* mgr_raw = mgr.get();
auto grow_cb = [mgr_raw](uint32_t pool_size) { return mgr_raw->Grow(pool_size); };
zx_status_t status;
std::unique_ptr<PersistentStorage> storage(new PersistentStorage(
sb, kMinfsInodeSize, std::move(grow_cb), std::move(metadata), sb->BlockSize()));
if ((status = Allocator::Create(builder, std::move(storage), &mgr->inode_allocator_)) != ZX_OK) {
return status;
}
*out = std::move(mgr);
return ZX_OK;
}
void InodeManager::Update(PendingWork* transaction, ino_t ino, const Inode* inode) {
// Obtain the offset of the inode within its containing block
const uint32_t off_of_ino = (ino % kMinfsInodesPerBlock) * kMinfsInodeSize;
const blk_t inoblock_rel = ino / kMinfsInodesPerBlock;
const blk_t inoblock_abs = inoblock_rel + start_block_;
ZX_DEBUG_ASSERT(inoblock_abs < kFVMBlockDataStart);
// Since host-side tools don't have "mapped vmos", just read / update /
// write the single absolute inode block.
uint8_t inodata[BlockSize()];
bc_->Readblk(inoblock_abs, inodata);
memcpy(inodata + off_of_ino, inode, kMinfsInodeSize);
bc_->Writeblk(inoblock_abs, inodata);
}
const Allocator* InodeManager::GetInodeAllocator() const { return inode_allocator_.get(); }
void InodeManager::Load(ino_t ino, Inode* out) const {
// obtain the block of the inode table we need
uint32_t off_of_ino = (ino % kMinfsInodesPerBlock) * kMinfsInodeSize;
uint8_t inodata[BlockSize()];
bc_->Readblk(start_block_ + (ino / kMinfsInodesPerBlock), inodata);
const Inode* inode =
reinterpret_cast<const Inode*>(reinterpret_cast<uintptr_t>(inodata) + off_of_ino);
memcpy(out, inode, kMinfsInodeSize);
}
zx_status_t InodeManager::Grow(size_t inodes) { return ZX_ERR_NO_SPACE; }
} // namespace minfs