// Copyright 2016 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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>

#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <fbl/string_piece.h>
#include <fs/block-txn.h>
#include <safemath/checked_math.h>
#include <zircon/device/vfs.h>
#include <zircon/time.h>

#ifdef __Fuchsia__
#include <lib/fdio/vfs.h>
#include <lib/fidl-utils/bind.h>
#include <fbl/auto_lock.h>
#include <zircon/syscalls.h>

#include <utility>
#endif

#include "directory.h"
#include "file.h"
#include "minfs-private.h"
#include "vnode.h"

namespace minfs {
namespace {

#ifdef __Fuchsia__

// MinfsConnection overrides the base Connection class to allow Minfs to
// dispatch its own ordinals.
class MinfsConnection : public fs::Connection {
public:
    using MinfsConnectionBinder = fidl::Binder<MinfsConnection>;

    MinfsConnection(fs::Vfs* vfs, fbl::RefPtr<fs::Vnode> vnode, zx::channel channel, uint32_t flags)
            : Connection(vfs, std::move(vnode), std::move(channel), flags) {}

private:
    VnodeMinfs& GetVnodeMinfs() const {
        return reinterpret_cast<VnodeMinfs&>(GetVnode());
    }

    zx_status_t GetMetrics(fidl_txn_t* transaction) {
        return GetVnodeMinfs().GetMetrics(transaction);
    }

    zx_status_t ToggleMetrics(bool enable, fidl_txn_t* transaction) {
        return GetVnodeMinfs().ToggleMetrics(enable, transaction);
    }

    zx_status_t GetAllocatedRegions(fidl_txn_t* transaction) {
        return GetVnodeMinfs().GetAllocatedRegions(transaction);
    }

    static const fuchsia_minfs_Minfs_ops* Ops() {
        static const fuchsia_minfs_Minfs_ops kMinfsOps = {
            .GetMetrics = MinfsConnectionBinder::BindMember<&MinfsConnection::GetMetrics>,
            .ToggleMetrics = MinfsConnectionBinder::BindMember<&MinfsConnection::ToggleMetrics>,
            .GetAllocatedRegions =
                MinfsConnectionBinder::BindMember<&MinfsConnection::GetAllocatedRegions>,
        };
        return &kMinfsOps;
    }

    zx_status_t HandleFsSpecificMessage(fidl_msg_t* msg, fidl_txn_t* transaction) final {
        return fuchsia_minfs_Minfs_dispatch(this, transaction, msg, Ops());
    }
};

#endif

} // namespace anonymous

void VnodeMinfs::SetIno(ino_t ino) {
    ZX_DEBUG_ASSERT(ino_ == 0);
    ino_ = ino;
}

void VnodeMinfs::InodeSync(WritebackWork* wb, uint32_t flags) {
    // by default, c/mtimes are not updated to current time
    if (flags != kMxFsSyncDefault) {
        zx_time_t cur_time = GetTimeUTC();
        // update times before syncing
        if ((flags & kMxFsSyncMtime) != 0) {
            inode_.modify_time = cur_time;
        }
        if ((flags & kMxFsSyncCtime) != 0) {
            inode_.create_time = cur_time;
        }
    }

    fs_->InodeUpdate(wb, ino_, &inode_);
}

// Delete all blocks (relative to a file) from "start" (inclusive) to the end of
// the file. Does not update mtime/atime.
zx_status_t VnodeMinfs::BlocksShrink(Transaction* transaction, blk_t start) {
    ZX_DEBUG_ASSERT(transaction != nullptr);

    auto block_callback = [this, transaction](blk_t local_bno, blk_t old_bno, blk_t* out_bno) {
        DeleteBlock(transaction, local_bno, old_bno);
        *out_bno = 0;
    };

    BlockOpArgs op_args(transaction, BlockOp::kDelete, std::move(block_callback), start,
                        static_cast<blk_t>(kMinfsMaxFileBlock - start), nullptr);
    zx_status_t status;
    if ((status = ApplyOperation(&op_args)) != ZX_OK) {
        return status;
    }

#ifdef __Fuchsia__
    // Arbitrary minimum size for indirect vmo
    size_t size = (kMinfsIndirect + kMinfsDoublyIndirect) * kMinfsBlockSize;
    // Number of blocks before dindirect blocks start
    blk_t pre_dindirect = kMinfsDirect + kMinfsDirectPerIndirect * kMinfsIndirect;
    if (start > pre_dindirect) {
        blk_t distart = start - pre_dindirect; //first bno relative to dindirect blocks
        blk_t last_dindirect = distart / (kMinfsDirectPerDindirect); // index of last dindirect

        // Calculate new size for indirect vmo
        if (distart % kMinfsDirectPerDindirect) {
            size = GetVmoSizeForIndirect(last_dindirect);
        } else if (last_dindirect) {
            size = GetVmoSizeForIndirect(last_dindirect - 1);
        }
    }

    // Shrink the indirect vmo if necessary
    if (vmo_indirect_ != nullptr && vmo_indirect_->size() > size) {
        if ((status = vmo_indirect_->Shrink(size)) != ZX_OK) {
            return status;
        }
    }
#endif
    return ZX_OK;
}

#ifdef __Fuchsia__

zx_status_t VnodeMinfs::LoadIndirectBlocks(blk_t* iarray, uint32_t count, uint32_t offset,
                                           uint64_t size) {
    zx_status_t status;
    if ((status = InitIndirectVmo()) != ZX_OK) {
        return status;
    }

    if (vmo_indirect_->size() < size) {
        zx_status_t status;
        if ((status = vmo_indirect_->Grow(size)) != ZX_OK) {
            return status;
        }
    }

    fs::ReadTxn read_transaction(fs_->bc_.get());

    for (uint32_t i = 0; i < count; i++) {
        blk_t ibno;
        if ((ibno = iarray[i]) != 0) {
            fs_->ValidateBno(ibno);
            read_transaction.Enqueue(vmoid_indirect_.id, offset + i,
                                     ibno + fs_->Info().dat_block, 1);
        }
    }

    return read_transaction.Transact();
}

zx_status_t VnodeMinfs::LoadIndirectWithinDoublyIndirect(uint32_t dindex) {
    uint32_t* dientry;

    size_t size = GetVmoSizeForIndirect(dindex);
    if (vmo_indirect_->size() >= size) {
        // We've already loaded this indirect (within dind) block.
        return ZX_OK;
    }

    ReadIndirectVmoBlock(GetVmoOffsetForDoublyIndirect(dindex), &dientry);
    return LoadIndirectBlocks(dientry, kMinfsDirectPerIndirect,
                              GetVmoOffsetForIndirect(dindex), size);
}

zx_status_t VnodeMinfs::InitIndirectVmo() {
    if (vmo_indirect_ != nullptr) {
        return ZX_OK;
    }

    vmo_indirect_ = fzl::ResizeableVmoMapper::Create(
            kMinfsBlockSize * (kMinfsIndirect + kMinfsDoublyIndirect), "minfs-indirect");

    zx_status_t status;
    if ((status = fs_->bc_->AttachVmo(vmo_indirect_->vmo(), &vmoid_indirect_)) != ZX_OK) {
        vmo_indirect_ = nullptr;
        return status;
    }

    // Load initial set of indirect blocks
    if ((status = LoadIndirectBlocks(inode_.inum, kMinfsIndirect, 0, 0)) != ZX_OK) {
        vmo_indirect_ = nullptr;
        return status;
    }

    // Load doubly indirect blocks
    if ((status = LoadIndirectBlocks(inode_.dinum, kMinfsDoublyIndirect,
                                     GetVmoOffsetForDoublyIndirect(0),
                                     GetVmoSizeForDoublyIndirect()) != ZX_OK)) {
        vmo_indirect_ = nullptr;
        return status;
    }

    return ZX_OK;
}

// Since we cannot yet register the filesystem as a paging service (and cleanly
// fault on pages when they are actually needed), we currently read an entire
// file to a VMO when a file's data block are accessed.
//
// TODO(smklein): Even this hack can be optimized; a bitmap could be used to
// track all 'empty/read/dirty' blocks for each vnode, rather than reading
// the entire file.
zx_status_t VnodeMinfs::InitVmo(Transaction* transaction) {
    if (vmo_.is_valid()) {
        return ZX_OK;
    }

    zx_status_t status;
    const size_t vmo_size = fbl::round_up(GetSize(), kMinfsBlockSize);
    if ((status = zx::vmo::create(vmo_size, 0, &vmo_)) != ZX_OK) {
        FS_TRACE_ERROR("Failed to initialize vmo; error: %d\n", status);
        return status;
    }
    vmo_size_ = vmo_size;

    zx_object_set_property(vmo_.get(), ZX_PROP_NAME, "minfs-inode", 11);

    if ((status = fs_->bc_->AttachVmo(vmo_, &vmoid_)) != ZX_OK) {
        vmo_.reset();
        return status;
    }
    fs::ReadTxn read_transaction(fs_->bc_.get());
    uint32_t dnum_count = 0;
    uint32_t inum_count = 0;
    uint32_t dinum_count = 0;
    fs::Ticker ticker(fs_->StartTicker());
    auto get_metrics = fbl::MakeAutoCall([&]() {
        fs_->UpdateInitMetrics(dnum_count, inum_count, dinum_count, vmo_size,
                               ticker.End());
    });

    // Initialize all direct blocks
    blk_t bno;
    for (uint32_t d = 0; d < kMinfsDirect; d++) {
        if ((bno = inode_.dnum[d]) != 0) {
            fs_->ValidateBno(bno);
            dnum_count++;
            read_transaction.Enqueue(vmoid_.id, d, bno + fs_->Info().dat_block, 1);
        }
    }

    // Initialize all indirect blocks
    for (uint32_t i = 0; i < kMinfsIndirect; i++) {
        blk_t ibno;
        if ((ibno = inode_.inum[i]) != 0) {
            fs_->ValidateBno(ibno);
            inum_count++;

            // Only initialize the indirect vmo if it is being used.
            if ((status = InitIndirectVmo()) != ZX_OK) {
                vmo_.reset();
                return status;
            }

            uint32_t* ientry;
            ReadIndirectVmoBlock(i, &ientry);

            for (uint32_t j = 0; j < kMinfsDirectPerIndirect; j++) {
                if ((bno = ientry[j]) != 0) {
                    fs_->ValidateBno(bno);
                    uint32_t n = kMinfsDirect + i * kMinfsDirectPerIndirect + j;
                    read_transaction.Enqueue(vmoid_.id, n, bno + fs_->Info().dat_block, 1);
                }
            }
        }
    }

    // Initialize all doubly indirect blocks
    for (uint32_t i = 0; i < kMinfsDoublyIndirect; i++) {
        blk_t dibno;

        if ((dibno = inode_.dinum[i]) != 0) {
            fs_->ValidateBno(dibno);
            dinum_count++;

            // Only initialize the doubly indirect vmo if it is being used.
            if ((status = InitIndirectVmo()) != ZX_OK) {
                vmo_.reset();
                return status;
            }

            uint32_t* dientry;
            ReadIndirectVmoBlock(GetVmoOffsetForDoublyIndirect(i), &dientry);

            for (uint32_t j = 0; j < kMinfsDirectPerIndirect; j++) {
                blk_t ibno;
                if ((ibno = dientry[j]) != 0) {
                    fs_->ValidateBno(ibno);

                    // Only initialize the indirect vmo if it is being used.
                    if ((status = LoadIndirectWithinDoublyIndirect(i)) != ZX_OK) {
                        vmo_.reset();
                        return status;
                    }

                    uint32_t* ientry;
                    ReadIndirectVmoBlock(GetVmoOffsetForIndirect(i) + j, &ientry);

                    for (uint32_t k = 0; k < kMinfsDirectPerIndirect; k++) {
                        if ((bno = ientry[k]) != 0) {
                            fs_->ValidateBno(bno);
                            uint32_t n = kMinfsDirect + kMinfsIndirect * kMinfsDirectPerIndirect
                                         + j * kMinfsDirectPerIndirect + k;
                            read_transaction.Enqueue(vmoid_.id, n, bno + fs_->Info().dat_block, 1);
                        }
                    }
                }
            }
        }
    }

    status = read_transaction.Transact();
    ValidateVmoTail(GetSize());
    return status;
}
#endif

void VnodeMinfs::AllocateIndirect(Transaction* transaction, blk_t index, IndirectArgs* args) {
    ZX_DEBUG_ASSERT(transaction != nullptr);

    // *bno must not be already allocated
    ZX_DEBUG_ASSERT(args->GetBno(index) == 0);

    // allocate new indirect block
    blk_t bno;
    fs_->BlockNew(transaction, &bno);

#ifdef __Fuchsia__
    ClearIndirectVmoBlock(args->GetOffset() + index);
#else
    ClearIndirectBlock(bno);
#endif

    args->SetBno(index, bno);
    inode_.block_count++;
}

zx_status_t VnodeMinfs::BlockOpDirect(BlockOpArgs* op_args, DirectArgs* params) {
    for (unsigned i = 0; i < params->GetCount(); i++) {
        blk_t bno = params->GetBno(i);
        op_args->callback(params->GetRelativeBlock() + i, bno, &bno);
        params->SetBno(i, bno);
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::BlockOpIndirect(BlockOpArgs* op_args, IndirectArgs* params) {
    // we should have initialized vmo before calling this method
    zx_status_t status;

#ifdef __Fuchsia__
    if (params->GetOp() != BlockOp::kDelete) {
        ValidateVmoSize(vmo_indirect_->vmo().get(), params->GetOffset() + params->GetCount());
    }
#endif

    for (unsigned i = 0; i < params->GetCount(); i++) {
        // If the indirect block is newly allocated, we must write an empty block out to disk.
        bool allocated = false;
        if (params->GetBno(i) == 0) {
            switch (params->GetOp()) {
            case BlockOp::kDelete:
                continue;
            case BlockOp::kRead:
                continue;
            case BlockOp::kSwap:
                __FALLTHROUGH;
            case BlockOp::kWrite:
                AllocateIndirect(op_args->transaction, i, params);
                allocated = true;
                break;
            default:
                return ZX_ERR_NOT_SUPPORTED;
            }

        }

#ifdef __Fuchsia__
        blk_t* entry;
        ReadIndirectVmoBlock(params->GetOffset() + i, &entry);
#else
        blk_t entry[kMinfsBlockSize];
        ReadIndirectBlock(params->GetBno(i), entry);
#endif

        DirectArgs direct_params = params->GetDirect(entry, i);
        if ((status = BlockOpDirect(op_args, &direct_params)) != ZX_OK) {
            return status;
        }

        // We can delete the current indirect block if all direct blocks within it are deleted
        if (params->GetOp() == BlockOp::kDelete
            && direct_params.GetCount() == kMinfsDirectPerIndirect) {
            // release the indirect block itself
            fs_->BlockFree(op_args->transaction, params->GetBno(i));
            params->SetBno(i, 0);
            inode_.block_count--;
        } else if (allocated || direct_params.IsDirty()) {
            // Only update the indirect block if an entry was deleted, and the indirect block
            // itself was not deleted.
#ifdef __Fuchsia__
            op_args->transaction->GetWork()->Enqueue(vmo_indirect_->vmo().get(),
                                                     params->GetOffset() + i,
                                                     params->GetBno(i) + fs_->Info().dat_block,
                                                     1);
#else
            fs_->bc_->Writeblk(params->GetBno(i) + fs_->Info().dat_block, entry);
#endif
            params->SetDirty();
        }
    }

    return ZX_OK;

}

zx_status_t VnodeMinfs::BlockOpDindirect(BlockOpArgs* op_args, DindirectArgs* params) {
    zx_status_t status;

#ifdef __Fuchsia__
    if (params->GetOp() != BlockOp::kDelete) {
        ValidateVmoSize(vmo_indirect_->vmo().get(), params->GetOffset() + params->GetCount());
    }
#endif

    // operate on doubly indirect blocks
    for (unsigned i = 0; i < params->GetCount(); i++) {
        // If the indirect block is newly allocated, we must write an empty block out to disk.
        bool allocated = false;
        if (params->GetBno(i) == 0) {
            switch (params->GetOp()) {
            case BlockOp::kDelete:
                continue;
            case BlockOp::kRead:
                continue;
            case BlockOp::kSwap:
                __FALLTHROUGH;
            case BlockOp::kWrite:
                AllocateIndirect(op_args->transaction, i, params);
                allocated = true;
                break;
            default:
                return ZX_ERR_NOT_SUPPORTED;
            }
        }

#ifdef __Fuchsia__
        uint32_t* dientry;
        ReadIndirectVmoBlock(GetVmoOffsetForDoublyIndirect(i), &dientry);
#else
        uint32_t dientry[kMinfsBlockSize];
        ReadIndirectBlock(params->GetBno(i), dientry);
#endif

        // operate on blocks pointed at by the entries in the indirect block
        IndirectArgs indirect_params = params->GetIndirect(dientry, i);
        if ((status = BlockOpIndirect(op_args, &indirect_params)) != ZX_OK) {
            return status;
        }

        // We can delete the current doubly indirect block if all indirect blocks within it
        // (and direct blocks within those) are deleted
        if (params->GetOp() == BlockOp::kDelete &&
            indirect_params.GetCount() == kMinfsDirectPerDindirect) {
            // release the doubly indirect block itself
            fs_->BlockFree(op_args->transaction, params->GetBno(i));
            params->SetBno(i, 0);
            inode_.block_count--;
        } else if (allocated || indirect_params.IsDirty()) {
            // Only update the indirect block if an entry was deleted, and the indirect block
            // itself was not deleted.
#ifdef __Fuchsia__
            op_args->transaction->GetWork()->Enqueue(vmo_indirect_->vmo().get(),
                                                     params->GetOffset() + i,
                                                     params->GetBno(i) + fs_->Info().dat_block, 1);
#else
            fs_->bc_->Writeblk(params->GetBno(i) + fs_->Info().dat_block, dientry);
#endif
            params->SetDirty();
        }
    }

    return ZX_OK;
}

#ifdef __Fuchsia__
void VnodeMinfs::ReadIndirectVmoBlock(uint32_t offset, uint32_t** entry) {
    ZX_DEBUG_ASSERT(vmo_indirect_ != nullptr);
    uintptr_t addr = reinterpret_cast<uintptr_t>(vmo_indirect_->start());
    ValidateVmoSize(vmo_indirect_->vmo().get(), offset);
    *entry = reinterpret_cast<uint32_t*>(addr + kMinfsBlockSize * offset);
}

void VnodeMinfs::ClearIndirectVmoBlock(uint32_t offset) {
    ZX_DEBUG_ASSERT(vmo_indirect_ != nullptr);
    uintptr_t addr = reinterpret_cast<uintptr_t>(vmo_indirect_->start());
    ValidateVmoSize(vmo_indirect_->vmo().get(), offset);
    memset(reinterpret_cast<void*>(addr + kMinfsBlockSize * offset), 0, kMinfsBlockSize);
}
#else
void VnodeMinfs::ReadIndirectBlock(blk_t bno, uint32_t* entry) {
    fs_->bc_->Readblk(bno + fs_->Info().dat_block, entry);
}

void VnodeMinfs::ClearIndirectBlock(blk_t bno) {
    uint32_t data[kMinfsBlockSize];
    memset(data, 0, kMinfsBlockSize);
    fs_->bc_->Writeblk(bno + fs_->Info().dat_block, data);
}
#endif

zx_status_t VnodeMinfs::ApplyOperation(BlockOpArgs* op_args) {
    blk_t start = op_args->start;
    blk_t found = 0;
    bool dirty = false;
    if (found < op_args->count && start < kMinfsDirect) {
        // array starting with first direct block
        blk_t* array = &inode_.dnum[start];
        // number of direct blocks to process
        blk_t count = fbl::min(op_args->count - found, kMinfsDirect - start);
        // if bnos exist, adjust past found (should be 0)
        blk_t* bnos = op_args->bnos == nullptr ? nullptr : &op_args->bnos[found];

        DirectArgs direct_params(op_args->op, array, count, op_args->start, bnos);
        zx_status_t status;
        if ((status = BlockOpDirect(op_args, &direct_params)) != ZX_OK) {
            return status;
        }

        found += count;
        dirty |= direct_params.IsDirty();
    }

    // for indirect blocks, adjust past the direct blocks
    if (start < kMinfsDirect) {
        start = 0;
    } else {
        start -= kMinfsDirect;
    }

    if (found < op_args->count && start < kMinfsIndirect * kMinfsDirectPerIndirect) {
        // index of indirect block, and offset of that block within indirect vmo
        blk_t ibindex = start / kMinfsDirectPerIndirect;
        // index of direct block within indirect block
        blk_t bindex = start % kMinfsDirectPerIndirect;

        // array starting with first indirect block
        blk_t* array = &inode_.inum[ibindex];
        // number of direct blocks to process within indirect blocks
        blk_t count = fbl::min(op_args->count - found,
                               kMinfsIndirect * kMinfsDirectPerIndirect - start);
        // if bnos exist, adjust past found
        blk_t* bnos = op_args->bnos == nullptr ? nullptr : &op_args->bnos[found];

        IndirectArgs indirect_params(op_args->op, array, count, op_args->start + found,
                                     bnos, bindex, ibindex);
        zx_status_t status;
        if ((status = BlockOpIndirect(op_args, &indirect_params)) != ZX_OK) {
            return status;
        }

        found += count;
        dirty |= indirect_params.IsDirty();
    }

    // for doubly indirect blocks, adjust past the indirect blocks
    if (start < kMinfsIndirect * kMinfsDirectPerIndirect) {
        start = 0;
    } else {
        start -= kMinfsIndirect * kMinfsDirectPerIndirect;
    }

    if (found < op_args->count &&
        start < kMinfsDoublyIndirect * kMinfsDirectPerIndirect * kMinfsDirectPerIndirect) {
        // index of doubly indirect block
        uint32_t dibindex = start / (kMinfsDirectPerIndirect * kMinfsDirectPerIndirect);
        ZX_DEBUG_ASSERT(dibindex < kMinfsDoublyIndirect);
        start -= (dibindex * kMinfsDirectPerIndirect * kMinfsDirectPerIndirect);

        // array starting with first doubly indirect block
        blk_t* array = &inode_.dinum[dibindex];
        // number of direct blocks to process within doubly indirect blocks
        blk_t count = fbl::min(op_args->count - found,
                kMinfsDoublyIndirect * kMinfsDirectPerIndirect * kMinfsDirectPerIndirect - start);
        // if bnos exist, adjust past found
        blk_t* bnos = op_args->bnos == nullptr ? nullptr : &op_args->bnos[found];
        // index of direct block within indirect block
        blk_t bindex = start % kMinfsDirectPerIndirect;
        // offset of indirect block within indirect vmo
        blk_t ib_vmo_offset = GetVmoOffsetForIndirect(dibindex);
        // index of indirect block within doubly indirect block
        blk_t ibindex = start / kMinfsDirectPerIndirect;
        // offset of doubly indirect block within indirect vmo
        blk_t dib_vmo_offset = GetVmoOffsetForDoublyIndirect(dibindex);

        DindirectArgs dindirect_params(op_args->op, array, count, op_args->start + found, bnos,
                                       bindex, ib_vmo_offset, ibindex, dib_vmo_offset);
        zx_status_t status;
        if ((status = BlockOpDindirect(op_args, &dindirect_params)) != ZX_OK) {
            return status;
        }

        found += count;
        dirty |= dindirect_params.IsDirty();
    }

    if (dirty) {
        ZX_DEBUG_ASSERT(op_args->transaction != nullptr);
        InodeSync(op_args->transaction->GetWork(), kMxFsSyncDefault);
    }

    // Return out of range if we were not able to process all blocks
    return found == op_args->count ? ZX_OK : ZX_ERR_OUT_OF_RANGE;
}

zx_status_t VnodeMinfs::EnsureIndirectVmoSize(blk_t n) {
#ifdef __Fuchsia__
    if (n >= kMinfsDirect) {
        zx_status_t status;
        // If the vmo_indirect_ vmo has not been created, make it now.
        if ((status = InitIndirectVmo()) != ZX_OK) {
            return status;
        }

        // Number of blocks prior to dindirect blocks
        blk_t pre_dindirect = kMinfsDirect + kMinfsDirectPerIndirect * kMinfsIndirect;
        if (n >= pre_dindirect) {
            // Index of last doubly indirect block
            blk_t dibindex = (n - pre_dindirect) / kMinfsDirectPerDindirect;
            ZX_DEBUG_ASSERT(dibindex < kMinfsDoublyIndirect);
            uint64_t vmo_size = GetVmoSizeForIndirect(dibindex);
            // Grow VMO if we need more space to fit doubly indirect blocks
            if (vmo_indirect_->size() < vmo_size) {
                if ((status = vmo_indirect_->Grow(vmo_size)) != ZX_OK) {
                    return status;
                }
            }
        }
    }
#endif
    return ZX_OK;
}

zx_status_t VnodeMinfs::BlockGetWritable(Transaction* transaction, blk_t n, blk_t* bno) {
    zx_status_t status = EnsureIndirectVmoSize(n);
    if (status != ZX_OK) {
        return ZX_OK;
    }

    auto block_callback = [this, transaction](blk_t local_bno, blk_t old_bno, blk_t* out_bno) {
        AcquireWritableBlock(transaction, local_bno, old_bno, out_bno);
    };
    BlockOpArgs op_args(transaction, BlockOp::kWrite, std::move(block_callback), n, 1, bno);
    return ApplyOperation(&op_args);
}

zx_status_t VnodeMinfs::BlockGetReadable(blk_t n, blk_t* bno) {
    zx_status_t status = EnsureIndirectVmoSize(n);
    if (status != ZX_OK) {
        return ZX_OK;
    }

    // Just acquire the old values.
    auto block_callback = [](blk_t local_bno, blk_t old_bno, blk_t* out_bno) {};

    BlockOpArgs op_args(nullptr, BlockOp::kRead, std::move(block_callback), n, 1, bno);
    return ApplyOperation(&op_args);
}

zx_status_t VnodeMinfs::ReadExactInternal(Transaction* transaction, void* data, size_t len,
                                          size_t off) {
    size_t actual;
    zx_status_t status = ReadInternal(transaction, data, len, off, &actual);
    if (status != ZX_OK) {
        return status;
    } else if (actual != len) {
        return ZX_ERR_IO;
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::WriteExactInternal(Transaction* transaction, const void* data,
                                           size_t len, size_t off) {
    size_t actual;
    zx_status_t status = WriteInternal(transaction, data, len, off, &actual);
    if (status != ZX_OK) {
        return status;
    } else if (actual != len) {
        return ZX_ERR_IO;
    }
    InodeSync(transaction->GetWork(), kMxFsSyncMtime);
    return ZX_OK;
}

void VnodeMinfs::RemoveInodeLink(Transaction* transaction) {
    ZX_ASSERT(inode_.link_count > 0);

    // This effectively 'unlinks' the target node without deleting the direntry
    inode_.link_count--;
    if (IsDirectory()) {
        if (inode_.link_count == 1) {
            // Directories are initialized with two links, since they point
            // to themselves via ".". Thus, when they reach "one link", they
            // are only pointed to by themselves, and should be deleted.
            inode_.link_count--;
        }
    }

    if (IsUnlinked()) {
        if (fd_count_ == 0) {
            Purge(transaction);
        } else {
            fs_->AddUnlinked(transaction, this);
        }
    }

    InodeSync(transaction->GetWork(), kMxFsSyncMtime);
}

void VnodeMinfs::ValidateVmoTail(uint64_t inode_size) const {
#if defined(MINFS_PARANOID_MODE) && defined(__Fuchsia__)
    if (!vmo_.is_valid()) {
        return;
    }

    // Verify that everything not allocated to "inode_size" in the
    // last block is filled with zeroes.
    char buf[kMinfsBlockSize];
    const size_t vmo_size = fbl::round_up(inode_size, kMinfsBlockSize);
    ZX_ASSERT(vmo_.read(buf, inode_size, vmo_size - inode_size) == ZX_OK);
    for (size_t i = 0; i < vmo_size - inode_size; i++) {
        ZX_ASSERT_MSG(buf[i] == 0, "vmo[%" PRIu64 "] != 0 (inode size = %u)\n",
                      inode_size + i, inode_size);
    }
#endif  // MINFS_PARANOID_MODE && __Fuchsia__
}

void VnodeMinfs::fbl_recycle() {
    ZX_DEBUG_ASSERT(fd_count_ == 0);
    if (!IsUnlinked()) {
        // If this node has not been purged already, remove it from the
        // hash map. If it has been purged; it will already be absent
        // from the map (and may have already been replaced with a new
        // node, if the inode has been re-used).
        fs_->VnodeRelease(this);
    }
    delete this;
}

VnodeMinfs::~VnodeMinfs() {
#ifdef __Fuchsia__
    // Detach the vmoids from the underlying block device,
    // so the underlying VMO may be released.
    size_t request_count = 0;
    block_fifo_request_t request[2];
    if (vmo_.is_valid()) {
        request[request_count].group = fs_->bc_->BlockGroupID();
        request[request_count].vmoid = vmoid_.id;
        request[request_count].opcode = BLOCKIO_CLOSE_VMO;
        request_count++;
    }
    if (vmo_indirect_ != nullptr) {
        request[request_count].group = fs_->bc_->BlockGroupID();
        request[request_count].vmoid = vmoid_indirect_.id;
        request[request_count].opcode = BLOCKIO_CLOSE_VMO;
        request_count++;
    }
    if (request_count) {
        fs_->bc_->Transaction(&request[0], request_count);
    }
#endif
}

#ifdef __Fuchsia__
zx_status_t VnodeMinfs::Serve(fs::Vfs* vfs, zx::channel channel, uint32_t flags) {
    return vfs->ServeConnection(std::make_unique<MinfsConnection>(
        vfs, fbl::WrapRefPtr(this), std::move(channel), flags));
}
#endif

zx_status_t VnodeMinfs::Open(uint32_t flags, fbl::RefPtr<Vnode>* out_redirect) {
    fd_count_++;
    return ZX_OK;
}

void VnodeMinfs::Purge(Transaction* transaction) {
    ZX_DEBUG_ASSERT(fd_count_ == 0);
    ZX_DEBUG_ASSERT(IsUnlinked());
    fs_->VnodeRelease(this);
#ifdef __Fuchsia__
    // TODO(smklein): Only init indirect vmo if it's needed
    if (InitIndirectVmo() == ZX_OK) {
        fs_->InoFree(transaction, this);
    } else {
        FS_TRACE_ERROR("minfs: Failed to Init Indirect VMO while purging %u\n", ino_);
    }
#else
    fs_->InoFree(transaction, this);
#endif
}

zx_status_t VnodeMinfs::Close() {
    ZX_DEBUG_ASSERT_MSG(fd_count_ > 0, "Closing ino with no fds open");
    fd_count_--;

    if (fd_count_ == 0 && IsUnlinked()) {
        zx_status_t status;
        fbl::unique_ptr<Transaction> transaction;
        if ((status = fs_->BeginTransaction(0, 0, &transaction)) != ZX_OK) {
            return status;
        }
        fs_->RemoveUnlinked(transaction.get(), this);
        Purge(transaction.get());
        return fs_->CommitTransaction(std::move(transaction));
    }
    return ZX_OK;
}

// Internal read. Usable on directories.
zx_status_t VnodeMinfs::ReadInternal(Transaction* transaction, void* data, size_t len, size_t off,
                                     size_t* actual) {
    // clip to EOF
    if (off >= GetSize()) {
        *actual = 0;
        return ZX_OK;
    }
    if (len > (GetSize() - off)) {
        len = GetSize() - off;
    }

    zx_status_t status;
#ifdef __Fuchsia__
    if ((status = InitVmo(transaction)) != ZX_OK) {
        return status;
    } else if ((status = vmo_.read(data, off, len)) != ZX_OK) {
        return status;
    } else {
        *actual = len;
    }
#else
    void* start = data;
    uint32_t n = static_cast<uint32_t>(off / kMinfsBlockSize);
    size_t adjust = off % kMinfsBlockSize;

    while ((len > 0) && (n < kMinfsMaxFileBlock)) {
        size_t xfer;
        if (len > (kMinfsBlockSize - adjust)) {
            xfer = kMinfsBlockSize - adjust;
        } else {
            xfer = len;
        }

        blk_t bno;
        if ((status = BlockGetReadable(n, &bno)) != ZX_OK) {
            return status;
        }
        if (bno != 0) {
            char bdata[kMinfsBlockSize];
            if (fs_->ReadDat(bno, bdata)) {
                FS_TRACE_ERROR("minfs: Failed to read data block %u\n", bno);
                return ZX_ERR_IO;
            }
            memcpy(data, bdata + adjust, xfer);
        } else {
            // If the block is not allocated, just read zeros
            memset(data, 0, xfer);
        }

        adjust = 0;
        len -= xfer;
        data = (void*)((uintptr_t)data + xfer);
        n++;
    }
    *actual = (uintptr_t)data - (uintptr_t)start;
#endif
    return ZX_OK;
}

// Internal write. Usable on directories.
zx_status_t VnodeMinfs::WriteInternal(Transaction* transaction, const void* data,
                                      size_t len, size_t off, size_t* actual) {
    if (len == 0) {
        *actual = 0;
        return ZX_OK;
    }
    zx_status_t status;
#ifdef __Fuchsia__
    // TODO(planders): Once we are splitting up write transactions, assert this on host as well.
    ZX_DEBUG_ASSERT(len < TransactionLimits::kMaxWriteBytes);
    if ((status = InitVmo(transaction)) != ZX_OK) {
        return status;
    }

#else
    size_t max_size = off + len;
#endif

    const void* const start = data;
    uint32_t n = static_cast<uint32_t>(off / kMinfsBlockSize);
    size_t adjust = off % kMinfsBlockSize;

    while ((len > 0) && (n < kMinfsMaxFileBlock)) {
        size_t xfer;
        if (len > (kMinfsBlockSize - adjust)) {
            xfer = kMinfsBlockSize - adjust;
        } else {
            xfer = len;
        }

#ifdef __Fuchsia__
        size_t xfer_off = n * kMinfsBlockSize + adjust;
        if ((xfer_off + xfer) > vmo_size_) {
            size_t new_size = fbl::round_up(xfer_off + xfer, kMinfsBlockSize);
            ZX_DEBUG_ASSERT(new_size >= GetSize()); // Overflow.
            if ((status = vmo_.set_size(new_size)) != ZX_OK) {
                break;
            }
            vmo_size_ = new_size;
        }

        // Update this block of the in-memory VMO
        if ((status = vmo_.write(data, xfer_off, xfer)) != ZX_OK) {
            break;
        }

        // Update this block on-disk
        blk_t bno;
        if ((status = BlockGetWritable(transaction, n, &bno))) {
            break;
        }

        IssueWriteback(transaction, n, bno + fs_->Info().dat_block, 1);
#else // __Fuchsia__
        blk_t bno;
        if ((status = BlockGetWritable(transaction, n, &bno))) {
            break;
        }
        ZX_DEBUG_ASSERT(bno != 0);
        char wdata[kMinfsBlockSize];
        if (fs_->bc_->Readblk(bno + fs_->Info().dat_block, wdata)) {
            break;
        }
        memcpy(wdata + adjust, data, xfer);
        if (len < kMinfsBlockSize && max_size >= GetSize()) {
            memset(wdata + adjust + xfer, 0, kMinfsBlockSize - (adjust + xfer));
        }
        if (fs_->bc_->Writeblk(bno + fs_->Info().dat_block, wdata)) {
            break;
        }
#endif // __Fuchsia__

        adjust = 0;
        len -= xfer;
        data = (void*)((uintptr_t)(data) + xfer);
        n++;
    }

    len = (uintptr_t)data - (uintptr_t)start;
    if (len == 0) {
        // If more than zero bytes were requested, but zero bytes were written,
        // return an error explicitly (rather than zero).
        if (off >= kMinfsMaxFileSize) {
            return ZX_ERR_FILE_BIG;
        }

        return ZX_ERR_NO_SPACE;
    }

    if ((off + len) > GetSize()) {
        SetSize(static_cast<uint32_t>(off + len));
    }

    *actual = len;

    ValidateVmoTail(GetSize());
    return ZX_OK;
}

zx_status_t VnodeMinfs::Getattr(vnattr_t* a) {
    FS_TRACE_DEBUG("minfs_getattr() vn=%p(#%u)\n", this, ino_);
    // This transaction exists because acquiring the block size and block
    // count may be unsafe without locking.
    //
    // TODO: Improve locking semantics of pending data allocation to make this less confusing.
    Transaction transaction(fs_);
    a->mode = DTYPE_TO_VTYPE(MinfsMagicType(inode_.magic)) |
            V_IRUSR | V_IWUSR | V_IRGRP | V_IROTH;
    a->inode = ino_;
    a->size = GetSize();
    a->blksize = kMinfsBlockSize;
    a->blkcount = GetBlockCount() * (kMinfsBlockSize / VNATTR_BLKSIZE);
    a->nlink = inode_.link_count;
    a->create_time = inode_.create_time;
    a->modify_time = inode_.modify_time;
    return ZX_OK;
}

zx_status_t VnodeMinfs::Setattr(const vnattr_t* a) {
    int dirty = 0;
    FS_TRACE_DEBUG("minfs_setattr() vn=%p(#%u)\n", this, ino_);
    if ((a->valid & ~(ATTR_CTIME|ATTR_MTIME)) != 0) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    if ((a->valid & ATTR_CTIME) != 0) {
        inode_.create_time = a->create_time;
        dirty = 1;
    }
    if ((a->valid & ATTR_MTIME) != 0) {
        inode_.modify_time = a->modify_time;
        dirty = 1;
    }
    if (dirty) {
        // write to disk, but don't overwrite the time
        zx_status_t status;
        fbl::unique_ptr<Transaction> transaction;
        if ((status = fs_->BeginTransaction(0, 0, &transaction)) != ZX_OK) {
            return status;
        }
        InodeSync(transaction->GetWork(), kMxFsSyncDefault);
        transaction->GetWork()->PinVnode(fbl::WrapRefPtr(this));
        return fs_->CommitTransaction(std::move(transaction));
    }
    return ZX_OK;
}

VnodeMinfs::VnodeMinfs(Minfs* fs) : fs_(fs) {}

#ifdef __Fuchsia__
void VnodeMinfs::Notify(fbl::StringPiece name, unsigned event) { watcher_.Notify(name, event); }
zx_status_t VnodeMinfs::WatchDir(fs::Vfs* vfs, uint32_t mask, uint32_t options,
                                 zx::channel watcher) {
    return watcher_.WatchDir(vfs, this, mask, options, std::move(watcher));
}

bool VnodeMinfs::IsRemote() const { return remoter_.IsRemote(); }
zx::channel VnodeMinfs::DetachRemote() { return remoter_.DetachRemote(); }
zx_handle_t VnodeMinfs::GetRemote() const { return remoter_.GetRemote(); }
void VnodeMinfs::SetRemote(zx::channel remote) { return remoter_.SetRemote(std::move(remote)); }

#endif

void VnodeMinfs::Allocate(Minfs* fs, uint32_t type, fbl::RefPtr<VnodeMinfs>* out) {
    if (type == kMinfsTypeDir) {
        *out = fbl::AdoptRef(new Directory(fs));
    } else {
        *out = fbl::AdoptRef(new File(fs));
    }
    memset(&(*out)->inode_, 0, sizeof((*out)->inode_));
    (*out)->inode_.magic = MinfsMagic(type);
    (*out)->inode_.create_time = (*out)->inode_.modify_time = GetTimeUTC();
    if (type == kMinfsTypeDir) {
        (*out)->inode_.link_count = 2;
        // "." and "..".
        (*out)->inode_.dirent_count = 2;
    } else {
        (*out)->inode_.link_count = 1;
    }
}

zx_status_t VnodeMinfs::Recreate(Minfs* fs, ino_t ino, fbl::RefPtr<VnodeMinfs>* out) {
    Inode inode;
    fs->InodeLoad(ino, &inode);
    if (inode.magic == kMinfsMagicDir) {
        *out = fbl::AdoptRef(new Directory(fs));
    } else {
        *out = fbl::AdoptRef(new File(fs));
    }
    memcpy(&(*out)->inode_, &inode, sizeof(inode));

    // TODO: Loading the inode should be part of the private constructor of a Vnode.
    fs->InodeLoad(ino, &(*out)->inode_);
    (*out)->ino_ = ino;
    (*out)->SetSize((*out)->inode_.size);
    return ZX_OK;
}

#ifdef __Fuchsia__

constexpr const char kFsName[] = "minfs";

zx_status_t VnodeMinfs::QueryFilesystem(fuchsia_io_FilesystemInfo* info) {
    static_assert(fbl::constexpr_strlen(kFsName) + 1 < fuchsia_io_MAX_FS_NAME_BUFFER,
                  "Minfs name too long");
    Transaction transaction(fs_);
    memset(info, 0, sizeof(*info));
    info->block_size = kMinfsBlockSize;
    info->max_filename_size = kMinfsMaxNameSize;
    info->fs_type = VFS_TYPE_MINFS;
    info->fs_id = fs_->GetFsId();
    info->total_bytes = fs_->Info().block_count * fs_->Info().block_size;
    info->used_bytes = fs_->Info().alloc_block_count * fs_->Info().block_size;
    info->total_nodes = fs_->Info().inode_count;
    info->used_nodes = fs_->Info().alloc_inode_count;

    fuchsia_hardware_block_volume_VolumeInfo fvm_info;
    if (fs_->FVMQuery(&fvm_info) == ZX_OK) {
        uint64_t free_slices = fvm_info.pslice_total_count - fvm_info.pslice_allocated_count;
        info->free_shared_pool_bytes = fvm_info.slice_size * free_slices;
    }

    strlcpy(reinterpret_cast<char*>(info->name), kFsName, fuchsia_io_MAX_FS_NAME_BUFFER);
    return ZX_OK;
}

zx_status_t VnodeMinfs::GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) {
    return fs_->bc_->GetDevicePath(buffer_len, out_name, out_len);
}

zx_status_t VnodeMinfs::GetMetrics(fidl_txn_t* transaction) {
    fuchsia_minfs_Metrics metrics;
    zx_status_t status = fs_->GetMetrics(&metrics);
    return fuchsia_minfs_MinfsGetMetrics_reply(transaction, status,
                                               status == ZX_OK ? &metrics : nullptr);
}

zx_status_t VnodeMinfs::ToggleMetrics(bool enable, fidl_txn_t* transaction) {
    fs_->SetMetrics(enable);
    return fuchsia_minfs_MinfsToggleMetrics_reply(transaction, ZX_OK);
}

zx_status_t VnodeMinfs::GetAllocatedRegions(fidl_txn_t* transaction) const {
    zx::vmo vmo;
    zx_status_t status = ZX_OK;
    fbl::Vector<BlockRegion> buffer = fs_->GetAllocatedRegions();
    uint64_t allocations = buffer.size();
    if (allocations != 0) {
        status = zx::vmo::create(sizeof(BlockRegion) * allocations, 0, &vmo);
        if (status == ZX_OK) {
            status = vmo.write(buffer.get(), 0, sizeof(BlockRegion) * allocations);
        }
    }
    return fuchsia_minfs_MinfsGetAllocatedRegions_reply(transaction, status,
                                                        status == ZX_OK ? vmo.get() :
                                                        ZX_HANDLE_INVALID,
                                                        status == ZX_OK ? allocations : 0);
}

#endif

zx_status_t VnodeMinfs::TruncateInternal(Transaction* transaction, size_t len) {
    zx_status_t status = ZX_OK;
#ifdef __Fuchsia__
    // TODO(smklein): We should only init up to 'len'; no need
    // to read in the portion of a large file we plan on deleting.
    if ((status = InitVmo(transaction)) != ZX_OK) {
        FS_TRACE_ERROR("minfs: Truncate failed to initialize VMO: %d\n", status);
        return ZX_ERR_IO;
    }
#endif

    uint64_t inode_size = GetSize();
    if (len < inode_size) {
        // Truncate should make the file shorter.
        blk_t bno = safemath::checked_cast<blk_t>(inode_size / kMinfsBlockSize);

        // Truncate to the nearest block.
        blk_t trunc_bno = static_cast<blk_t>(len / kMinfsBlockSize);
        // [start_bno, EOF) blocks should be deleted entirely.
        blk_t start_bno = static_cast<blk_t>((len % kMinfsBlockSize == 0) ?
                                             trunc_bno : trunc_bno + 1);

        if ((status = BlocksShrink(transaction, start_bno)) != ZX_OK) {
            return status;
        }

#ifdef __Fuchsia__
        uint64_t decommit_offset = fbl::round_up(len, kMinfsBlockSize);
        uint64_t decommit_length = fbl::round_up(inode_size, kMinfsBlockSize) - decommit_offset;
        if (decommit_length > 0) {
            ZX_ASSERT(vmo_.op_range(ZX_VMO_OP_DECOMMIT, decommit_offset,
                                    decommit_length, nullptr, 0) == ZX_OK);
        }
#endif
        // Shrink the size to be block-aligned if we are removing blocks from
        // the end of the vnode.
        if (start_bno * kMinfsBlockSize < inode_size) {
            SetSize(start_bno * kMinfsBlockSize);
        }

        // Write zeroes to the rest of the remaining block, if it exists
        if (len < GetSize()) {
            char bdata[kMinfsBlockSize];
            blk_t rel_bno = static_cast<blk_t>(len / kMinfsBlockSize);
            bno = 0;
            if ((status = BlockGetReadable(rel_bno, &bno)) != ZX_OK) {
                FS_TRACE_ERROR("minfs: Truncate failed to get block %u of file: %d\n", rel_bno,
                               status);
                return ZX_ERR_IO;
            }

            size_t adjust = len % kMinfsBlockSize;
#ifdef __Fuchsia__
            bool allocated = (bno != 0);
            if (allocated || HasPendingAllocation(rel_bno)) {
                if ((status = vmo_.read(bdata, len - adjust, adjust)) != ZX_OK) {
                    FS_TRACE_ERROR("minfs: Truncate failed to read last block: %d\n", status);
                    return ZX_ERR_IO;
                }
                memset(bdata + adjust, 0, kMinfsBlockSize - adjust);

                if ((status = vmo_.write(bdata, len - adjust, kMinfsBlockSize)) != ZX_OK) {
                    FS_TRACE_ERROR("minfs: Truncate failed to write last block: %d\n", status);
                    return ZX_ERR_IO;
                }

                if ((status = BlockGetWritable(transaction, rel_bno, &bno)) != ZX_OK) {
                    FS_TRACE_ERROR("minfs: Truncate failed to get block %u of file: %d\n", rel_bno,
                                   status);
                    return ZX_ERR_IO;
                }
                IssueWriteback(transaction, rel_bno, bno + fs_->Info().dat_block, 1);
            }
#else // __Fuchsia__
            if (bno != 0) {
                if (fs_->bc_->Readblk(bno + fs_->Info().dat_block, bdata)) {
                    return ZX_ERR_IO;
                }
                memset(bdata + adjust, 0, kMinfsBlockSize - adjust);
                if (fs_->bc_->Writeblk(bno + fs_->Info().dat_block, bdata)) {
                    return ZX_ERR_IO;
                }
            }
#endif // __Fuchsia__
        }
    } else if (len > inode_size) {
        // Truncate should make the file longer, filled with zeroes.
        if (kMinfsMaxFileSize < len) {
            return ZX_ERR_INVALID_ARGS;
        }
#ifdef __Fuchsia__
        uint64_t new_size = fbl::round_up(len, kMinfsBlockSize);
        if ((status = vmo_.set_size(new_size)) != ZX_OK) {
            return status;
        }
        vmo_size_ = new_size;
#endif
    } else {
        return ZX_OK;
    }

    // Setting the size does not ensure the on-disk inode is updated. Ensuring
    // writeback occurs is the responsibility of the caller.
    SetSize(static_cast<uint32_t>(len));
    ValidateVmoTail(GetSize());
    return ZX_OK;
}

#ifdef __Fuchsia__
zx_status_t VnodeMinfs::GetNodeInfo(uint32_t flags, fuchsia_io_NodeInfo* info) {
    if (IsDirectory()) {
        info->tag = fuchsia_io_NodeInfoTag_directory;
    } else {
        info->tag = fuchsia_io_NodeInfoTag_file;
    }
    return ZX_OK;
}

void VnodeMinfs::Sync(SyncCallback closure) {
    TRACE_DURATION("minfs", "VnodeMinfs::Sync");
    fs_->Sync([this, cb = std::move(closure)](zx_status_t status) {
        if (status != ZX_OK) {
            cb(status);
            return;
        }
        status = fs_->bc_->Sync();
        cb(status);
    });
    return;
}

zx_status_t VnodeMinfs::AttachRemote(fs::MountChannel h) {
    if (kMinfsRootIno == ino_) {
        return ZX_ERR_ACCESS_DENIED;
    } else if (!IsDirectory() || IsUnlinked()) {
        return ZX_ERR_NOT_DIR;
    } else if (IsRemote()) {
        return ZX_ERR_ALREADY_BOUND;
    }
    SetRemote(h.TakeChannel());
    return ZX_OK;
}
#endif

VnodeMinfs::DirectArgs VnodeMinfs::IndirectArgs::GetDirect(blk_t* barray, blk_t ibindex) const {
    // Determine the starting index for direct blocks within this indirect block
    blk_t direct_start = ibindex == 0 ? bindex_ : 0;

    // Determine how many direct blocks have already been op'd in indirect block context
    blk_t offset = 0;

    if (ibindex) {
        offset = kMinfsDirectPerIndirect * ibindex - bindex_;
    }

    DirectArgs params(op_, // op
                      &barray[direct_start], // array
                      fbl::min(count_ - offset, kMinfsDirectPerIndirect - direct_start), // count
                      rel_bno_ + offset, // rel_bno
                      bnos_ == nullptr ? nullptr : &bnos_[offset]); // bnos
    return params;
}

VnodeMinfs::IndirectArgs VnodeMinfs::DindirectArgs::GetIndirect(blk_t* iarray,
                                                                blk_t dibindex) const {
    // Determine relative starting indices for indirect and direct blocks
    uint32_t indirect_start = dibindex == 0 ? ibindex_ : 0;
    uint32_t direct_start = (dibindex == 0 && indirect_start == ibindex_) ? bindex_ : 0;

    // Determine how many direct blocks we have already op'd within doubly indirect
    // context
    blk_t offset = 0;
    if (dibindex) {
        offset = kMinfsDirectPerIndirect * kMinfsDirectPerIndirect * dibindex -
                (ibindex_ * kMinfsDirectPerIndirect) + bindex_;
    }

    IndirectArgs params(op_, // op
                        &iarray[indirect_start], // array
                        fbl::min(count_ - offset, kMinfsDirectPerDindirect - direct_start), // count
                        rel_bno_ + offset, // rel_bno
                        bnos_ == nullptr ? nullptr : &bnos_[offset], // bnos
                        direct_start, // bindex
                        ib_vmo_offset_ + dibindex + ibindex_ // ib_vmo_offset
                        );
    return params;
}

} // namespace minfs
