// 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 <fs/block-txn.h>
#include <fbl/algorithm.h>
#include <zircon/device/vfs.h>

#ifdef __Fuchsia__
#include <zircon/syscalls.h>
#include <fdio/vfs.h>
#include <fbl/auto_lock.h>
#endif

#include "minfs-private.h"

// #define DEBUG_PRINTF
#ifdef DEBUG_PRINTF
#define xprintf(args...) fprintf(stderr, args)
#else
#define xprintf(args...)
#endif

namespace {

zx_time_t minfs_gettime_utc() {
    // linux/zircon compatible
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    zx_time_t time = ZX_SEC(ts.tv_sec)+ts.tv_nsec;
    return time;
}

} // namespace anonymous

namespace minfs {

#ifdef __Fuchsia__
zx_status_t VnodeMinfs::VmoReadExact(void* data, uint64_t offset, size_t len) const {
    size_t actual;
    zx_status_t status = vmo_.read(data, offset, len, &actual);
    if (status != ZX_OK) {
        return status;
    } else if (actual != len) {
        return ZX_ERR_IO;
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::VmoWriteExact(const void* data, uint64_t offset, size_t len) {
    size_t actual;
    zx_status_t status = vmo_.write(data, offset, len, &actual);
    if (status != ZX_OK) {
        return status;
    } else if (actual != len) {
        return ZX_ERR_IO;
    }
    return ZX_OK;
}
#endif

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

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

    fs_->InodeSync(txn, 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(WriteTxn *txn, blk_t start) {
    ZX_DEBUG_ASSERT(txn != nullptr);
    bop_params_t boparams(start, static_cast<blk_t>(kMinfsMaxFileBlock - start), nullptr);
    zx_status_t status;
    if ((status = BlockOp(txn, DELETE, &boparams)) != 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_->GetSize() > 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_->GetSize() < size) {
        zx_status_t status;
        if ((status = vmo_indirect_->Grow(size)) != ZX_OK) {
            return status;
        }
    }

    ReadTxn txn(fs_->bc_.get());

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

    return txn.Flush();
}

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

    size_t size = GetVmoSizeForIndirect(dindex);
    if (vmo_indirect_->GetSize() >= 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;
    }

    zx_status_t status;
    if ((status = MappedVmo::Create(kMinfsBlockSize * (kMinfsIndirect + kMinfsDoublyIndirect),
                                    "minfs-indirect", &vmo_indirect_)) != ZX_OK) {
        return status;
    }
    if ((status = fs_->bc_->AttachVmo(vmo_indirect_->GetVmo(), &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() {
    if (vmo_.is_valid()) {
        return ZX_OK;
    }

    zx_status_t status;
    const size_t vmo_size = fbl::round_up(inode_.size, 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;
    }

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

    if ((status = fs_->bc_->AttachVmo(vmo_.get(), &vmoid_)) != ZX_OK) {
        vmo_.reset();
        return status;
    }
    ReadTxn txn(fs_->bc_.get());

    // Initialize all direct blocks
    blk_t bno;
    for (uint32_t d = 0; d < kMinfsDirect; d++) {
        if ((bno = inode_.dnum[d]) != 0) {
            fs_->ValidateBno(bno);
            txn.Enqueue(vmoid_, 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);

            // 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;
                    txn.Enqueue(vmoid_, 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);

            // 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;
                            txn.Enqueue(vmoid_, n, bno + fs_->info_.dat_block, 1);
                        }
                    }
                }
            }
        }
    }

    status = txn.Flush();
    ValidateVmoTail();
    return status;
}
#endif

zx_status_t VnodeMinfs::AllocateIndirect(WriteTxn* txn, blk_t index, IndirectArgs* args) {
    ZX_DEBUG_ASSERT(txn != nullptr);

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

    // allocate new indirect block
    zx_status_t status;
    blk_t bno;
    if ((status = fs_->BlockNew(txn, 0, &bno)) != ZX_OK) {
        return status;
    }

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

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

zx_status_t VnodeMinfs::BlockOpDirect(WriteTxn *txn, DirectArgs* params) {
    for (unsigned i = 0; i < params->GetCount(); i++) {
        blk_t bno = params->GetBno(i);
        switch (params->GetOp()) {
            case DELETE: {
                // If we found a valid block, delete it.
                if (bno) {
                    fs_->ValidateBno(bno);
                    fs_->BlockFree(txn, bno);
                    params->SetBno(i, 0);
                    inode_.block_count--;
                }
                break;
            }
            case WRITE: {
                ZX_DEBUG_ASSERT(txn != nullptr);
                if (bno == 0) {
                    zx_status_t status;
                    if ((status = fs_->BlockNew(txn, 0, &bno)) != ZX_OK) {
                        return status;
                    }
                    inode_.block_count++;
                }

                fs_->ValidateBno(bno);
            }
            // fall through
            case READ: {
                params->SetBno(i, bno);
                break;
            }
            default: {
                return ZX_ERR_NOT_SUPPORTED;
            }
        }
    }

    return ZX_OK;
}

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

#ifdef __Fuchsia__
    if (params->GetOp() == READ || params->GetOp() == WRITE) {
        validate_vmo_size(vmo_indirect_->GetVmo(), params->GetOffset() + params->GetCount());
    }
#endif

    for (unsigned i = 0; i < params->GetCount(); i++) {
        bool dirty = false;
        if (params->GetBno(i) == 0) {
            switch (params->GetOp()) {
            case DELETE:
                continue;
            case READ:
                return ZX_OK;
            case WRITE:
                if ((status = AllocateIndirect(txn, i, params)) != ZX_OK) {
                    return status;
                }
                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(txn, &direct_params)) != ZX_OK) {
            return status;
        }

        // only update the indirect block if an entry was deleted
        if (dirty || direct_params.IsDirty()) {
#ifdef __Fuchsia__
            txn->Enqueue(vmo_indirect_->GetVmo(), 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();
        }

        // We can delete the current indirect block if all direct blocks within it are deleted
        if (params->GetOp() == DELETE && direct_params.GetCount() == kMinfsDirectPerIndirect) {
            // release the direct block itself
            fs_->BlockFree(txn, params->GetBno(i));
            params->SetBno(i, 0);
            inode_.block_count--;
        }
    }

    return ZX_OK;

}

zx_status_t VnodeMinfs::BlockOpDindirect(WriteTxn* txn, DindirectArgs* params) {
    zx_status_t status;

#ifdef __Fuchsia__
    if (params->GetOp() == READ || params->GetOp() == WRITE) {
        validate_vmo_size(vmo_indirect_->GetVmo(), params->GetOffset() + params->GetCount());
    }
#endif

    // operate on doubly indirect blocks
    for (unsigned i = 0; i < params->GetCount(); i++) {
        bool dirty = false;
        if (params->GetBno(i) == 0) {
            switch (params->GetOp()) {
            case DELETE:
                continue;
            case READ:
                return ZX_OK;
            case WRITE:
                if ((status = AllocateIndirect(txn, i, params)) != ZX_OK) {
                    return status;
                }
                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(txn, &indirect_params)) != ZX_OK) {
            return status;
        }

        // only update the indirect block if an entry was deleted
        if (dirty || indirect_params.IsDirty()) {
#ifdef __Fuchsia__
            txn->Enqueue(vmo_indirect_->GetVmo(), 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();
        }

        // We can delete the current doubly indirect block if all indirect blocks within it
        // (and direct blocks within those) are deleted
        if (params->GetOp() == DELETE && indirect_params.GetCount() == kMinfsDirectPerDindirect) {
            // release the doubly indirect block itself
            fs_->BlockFree(txn, params->GetBno(i));
            params->SetBno(i, 0);
            inode_.block_count--;
        }
    }

    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_->GetData());
    validate_vmo_size(vmo_indirect_->GetVmo(), 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_->GetData());
    validate_vmo_size(vmo_indirect_->GetVmo(), 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::BlockOp(WriteTxn* txn, blk_op_t op, bop_params_t* boparams) {
    blk_t start = boparams->start;
    blk_t found = 0;
    bool dirty = false;
    if (found < boparams->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(boparams->count - found, kMinfsDirect - start);
        // if bnos exist, adjust past found (should be 0)
        blk_t* bnos = boparams->bnos == nullptr ? nullptr : &boparams->bnos[found];

        DirectArgs direct_params(op, array, count, bnos);
        zx_status_t status;
        if ((status = BlockOpDirect(txn, &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 < boparams->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(boparams->count - found,
                                         kMinfsIndirect * kMinfsDirectPerIndirect - start);
        // if bnos exist, adjust past found
        blk_t* bnos = boparams->bnos == nullptr ? nullptr : &boparams->bnos[found];

        IndirectArgs indirect_params(op, array, count, bnos, bindex, ibindex);
        zx_status_t status;
        if ((status = BlockOpIndirect(txn, &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 < boparams->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(boparams->count - found,
                kMinfsDoublyIndirect * kMinfsDirectPerIndirect * kMinfsDirectPerIndirect - start);
        // if bnos exist, adjust past found
        blk_t* bnos = boparams->bnos == nullptr ? nullptr : &boparams->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, array, count, bnos, bindex, ib_vmo_offset, ibindex,
                                       dib_vmo_offset);
        zx_status_t status;
        if ((status = BlockOpDindirect(txn, &dindirect_params)) != ZX_OK) {
            return status;
        }

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

    if (dirty) {
        ZX_DEBUG_ASSERT(txn != nullptr);
        InodeSync(txn, kMxFsSyncDefault);
    }

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

zx_status_t VnodeMinfs::BlockGet(WriteTxn* txn, blk_t n, blk_t* bno) {
#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_->GetSize() < vmo_size) {
                if ((status = vmo_indirect_->Grow(vmo_size)) != ZX_OK) {
                    return status;
                }
            }
        }
    }
#endif

    bop_params_t boparams(n, 1, bno);
    return BlockOp(txn, txn ? WRITE : READ, &boparams);
}

// Immediately stop iterating over the directory.
#define DIR_CB_DONE 0
// Access the next direntry in the directory. Offsets updated.
#define DIR_CB_NEXT 1
// Identify that the direntry record was modified. Stop iterating.
#define DIR_CB_SAVE_SYNC 2

zx_status_t VnodeMinfs::ReadExactInternal(void* data, size_t len, size_t off) {
    size_t actual;
    zx_status_t status = ReadInternal(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(WriteTxn* txn, const void* data,
                                           size_t len, size_t off) {
    size_t actual;
    zx_status_t status = WriteInternal(txn, data, len, off, &actual);
    if (status != ZX_OK) {
        return status;
    } else if (actual != len) {
        return ZX_ERR_IO;
    }
    InodeSync(txn, kMxFsSyncMtime);
    return ZX_OK;
}

static zx_status_t validate_dirent(minfs_dirent_t* de, size_t bytes_read, size_t off) {
    uint32_t reclen = static_cast<uint32_t>(MinfsReclen(de, off));
    if ((bytes_read < MINFS_DIRENT_SIZE) || (reclen < MINFS_DIRENT_SIZE)) {
        FS_TRACE_ERROR("vn_dir: Could not read dirent at offset: %zd\n", off);
        return ZX_ERR_IO;
    } else if ((off + reclen > kMinfsMaxDirectorySize) || (reclen & 3)) {
        FS_TRACE_ERROR("vn_dir: bad reclen %u > %u\n", reclen, kMinfsMaxDirectorySize);
        return ZX_ERR_IO;
    } else if (de->ino != 0) {
        if ((de->namelen == 0) ||
            (de->namelen > (reclen - MINFS_DIRENT_SIZE))) {
            FS_TRACE_ERROR("vn_dir: bad namelen %u / %u\n", de->namelen, reclen);
            return ZX_ERR_IO;
        }
    }
    return ZX_OK;
}

// Updates offset information to move to the next direntry in the directory.
static zx_status_t do_next_dirent(minfs_dirent_t* de, DirectoryOffset* offs) {
    offs->off_prev = offs->off;
    offs->off += MinfsReclen(de, offs->off);
    return DIR_CB_NEXT;
}

zx_status_t VnodeMinfs::DirentCallbackFind(fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de,
                                           DirArgs* args, DirectoryOffset* offs) {
    if ((de->ino != 0) && fbl::StringPiece(de->name, de->namelen) == args->name) {
        args->ino = de->ino;
        args->type = de->type;
        return DIR_CB_DONE;
    } else {
        return do_next_dirent(de, offs);
    }
}

zx_status_t VnodeMinfs::CanUnlink() const {
    // directories must be empty (dirent_count == 2)
    if (IsDirectory()) {
        if (inode_.dirent_count != 2) {
            // if we have more than "." and "..", not empty, cannot unlink
            return ZX_ERR_NOT_EMPTY;
#ifdef __Fuchsia__
        } else if (IsRemote()) {
            // we cannot unlink mount points
            return ZX_ERR_UNAVAILABLE;
#endif
        }
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::UnlinkChild(WritebackWork* wb,
                                    fbl::RefPtr<VnodeMinfs> childvn,
                                    minfs_dirent_t* de, DirectoryOffset* offs) {
    // Coalesce the current dirent with the previous/next dirent, if they
    // (1) exist and (2) are free.
    size_t off_prev = offs->off_prev;
    size_t off = offs->off;
    size_t off_next = off + MinfsReclen(de, off);
    minfs_dirent_t de_prev, de_next;
    zx_status_t status;

    // Read the direntries we're considering merging with.
    // Verify they are free and small enough to merge.
    size_t coalesced_size = MinfsReclen(de, off);
    // Coalesce with "next" first, so the kMinfsReclenLast bit can easily flow
    // back to "de" and "de_prev".
    if (!(de->reclen & kMinfsReclenLast)) {
        size_t len = MINFS_DIRENT_SIZE;
        if ((status = ReadExactInternal(&de_next, len, off_next)) != ZX_OK) {
            FS_TRACE_ERROR("unlink: Failed to read next dirent\n");
            return status;
        } else if ((status = validate_dirent(&de_next, len, off_next)) != ZX_OK) {
            FS_TRACE_ERROR("unlink: Read invalid dirent\n");
            return status;
        }
        if (de_next.ino == 0) {
            coalesced_size += MinfsReclen(&de_next, off_next);
            // If the next entry *was* last, then 'de' is now last.
            de->reclen |= (de_next.reclen & kMinfsReclenLast);
        }
    }
    if (off_prev != off) {
        size_t len = MINFS_DIRENT_SIZE;
        if ((status = ReadExactInternal(&de_prev, len, off_prev)) != ZX_OK) {
            FS_TRACE_ERROR("unlink: Failed to read previous dirent\n");
            return status;
        } else if ((status = validate_dirent(&de_prev, len, off_prev)) != ZX_OK) {
            FS_TRACE_ERROR("unlink: Read invalid dirent\n");
            return status;
        }
        if (de_prev.ino == 0) {
            coalesced_size += MinfsReclen(&de_prev, off_prev);
            off = off_prev;
        }
    }

    if (!(de->reclen & kMinfsReclenLast) && (coalesced_size >= kMinfsReclenMask)) {
        // Should only be possible if the on-disk record format is corrupted
        return ZX_ERR_IO;
    }
    de->ino = 0;
    de->reclen = static_cast<uint32_t>(coalesced_size & kMinfsReclenMask) |
        (de->reclen & kMinfsReclenLast);
    // Erase dirent (replace with 'empty' dirent)
    if ((status = WriteExactInternal(wb->txn(), de, MINFS_DIRENT_SIZE, off)) != ZX_OK) {
        return status;
    }

    if (de->reclen & kMinfsReclenLast) {
        // Truncating the directory merely removed unused space; if it fails,
        // the directory contents are still valid.
        TruncateInternal(wb->txn(), off + MINFS_DIRENT_SIZE);
    }

    inode_.dirent_count--;

    if (MinfsMagicType(childvn->inode_.magic) == kMinfsTypeDir) {
        // Child directory had '..' which pointed to parent directory
        inode_.link_count--;
    }
    childvn->RemoveInodeLink(wb->txn());
    wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
    wb->PinVnode(childvn);
    return DIR_CB_SAVE_SYNC;
}

void VnodeMinfs::RemoveInodeLink(WriteTxn* txn) {
    // This effectively 'unlinks' the target node without deleting the direntry
    inode_.link_count--;
    if (MinfsMagicType(inode_.magic) == kMinfsTypeDir) {
        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 (fd_count_ == 0 && IsUnlinked()) {
        Purge(txn);
    }

    InodeSync(txn, kMxFsSyncMtime);
}

// caller is expected to prevent unlink of "." or ".."
zx_status_t VnodeMinfs::DirentCallbackUnlink(fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de,
                                             DirArgs* args, DirectoryOffset* offs) {
    if ((de->ino == 0) || fbl::StringPiece(de->name, de->namelen) != args->name) {
        return do_next_dirent(de, offs);
    }

    fbl::RefPtr<VnodeMinfs> vn;
    zx_status_t status;
    if ((status = vndir->fs_->VnodeGet(&vn, de->ino)) < 0) {
        return status;
    }

    // If a directory was requested, then only try unlinking a directory
    if ((args->type == kMinfsTypeDir) && !vn->IsDirectory()) {
        return ZX_ERR_NOT_DIR;
    }
    if ((status = vn->CanUnlink()) != ZX_OK) {
        return status;
    }
    return vndir->UnlinkChild(args->wb, fbl::move(vn), de, offs);
}

// same as unlink, but do not validate vnode
zx_status_t VnodeMinfs::DirentCallbackForceUnlink(fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de,
                                                  DirArgs* args, DirectoryOffset* offs) {
    if ((de->ino == 0) || fbl::StringPiece(de->name, de->namelen) != args->name) {
        return do_next_dirent(de, offs);
    }

    fbl::RefPtr<VnodeMinfs> vn;
    zx_status_t status;
    if ((status = vndir->fs_->VnodeGet(&vn, de->ino)) < 0) {
        return status;
    }
    return vndir->UnlinkChild(args->wb, fbl::move(vn), de, offs);
}

// Given a (name, inode, type) combination:
//   - If no corresponding 'name' is found, ZX_ERR_NOT_FOUND is returned
//   - If the 'name' corresponds to a vnode, check that the target vnode:
//      - Does not have the same inode as the argument inode
//      - Is the same type as the argument 'type'
//      - Is unlinkable
//   - If the previous checks pass, then:
//      - Remove the old vnode (decrement link count by one)
//      - Replace the old vnode's position in the directory with the new inode
zx_status_t VnodeMinfs::DirentCallbackAttemptRename(fbl::RefPtr<VnodeMinfs> vndir,
                                                    minfs_dirent_t* de, DirArgs* args,
                                                    DirectoryOffset* offs) {
    if ((de->ino == 0) || fbl::StringPiece(de->name, de->namelen) != args->name) {
        return do_next_dirent(de, offs);
    }

    fbl::RefPtr<VnodeMinfs> vn;
    zx_status_t status;
    if ((status = vndir->fs_->VnodeGet(&vn, de->ino)) < 0) {
        return status;
    } else if (args->ino == vn->ino_) {
        // cannot rename node to itself
        return ZX_ERR_BAD_STATE;
    } else if (args->type != de->type) {
        // cannot rename directory to file (or vice versa)
        return ZX_ERR_BAD_STATE;
    } else if ((status = vn->CanUnlink()) != ZX_OK) {
        // if we cannot unlink the target, we cannot rename the target
        return status;
    }

    // If we are renaming ON TOP of a directory, then we can skip
    // updating the parent link count -- the old directory had a ".." entry to
    // the parent (link count of 1), but the new directory will ALSO have a ".."
    // entry, making the rename operation idempotent w.r.t. the parent link
    // count.
    vn->RemoveInodeLink(args->wb->txn());

    de->ino = args->ino;
    status = vndir->WriteExactInternal(args->wb->txn(), de, DirentSize(de->namelen), offs->off);
    if (status != ZX_OK) {
        return status;
    }

    args->wb->PinVnode(vn);
    args->wb->PinVnode(vndir);
    return DIR_CB_SAVE_SYNC;
}

zx_status_t VnodeMinfs::DirentCallbackUpdateInode(fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de,
                                                  DirArgs* args, DirectoryOffset* offs) {
    if ((de->ino == 0) || fbl::StringPiece(de->name, de->namelen) != args->name) {
        return do_next_dirent(de, offs);
    }

    de->ino = args->ino;
    zx_status_t status = vndir->WriteExactInternal(args->wb->txn(), de,
                                                   DirentSize(de->namelen),
                                                   offs->off);
    if (status != ZX_OK) {
        return status;
    }
    args->wb->PinVnode(vndir);
    return DIR_CB_SAVE_SYNC;
}

zx_status_t VnodeMinfs::DirentCallbackAppend(fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de,
                                             DirArgs* args, DirectoryOffset* offs) {
    auto add_dirent = [](fbl::RefPtr<VnodeMinfs> vndir, minfs_dirent_t* de, DirArgs* args,
                         size_t off) {
        de->ino = args->ino;
        de->type = static_cast<uint8_t>(args->type);
        de->namelen = static_cast<uint8_t>(args->name.length());
        memcpy(de->name, args->name.data(), de->namelen);
        zx_status_t status = vndir->WriteExactInternal(args->wb->txn(), de, DirentSize(de->namelen),
                                                       off);
        if (status != ZX_OK) {
            return status;
        }
        vndir->inode_.dirent_count++;
        if (args->type == kMinfsTypeDir) {
            // Child directory has '..' which will point to parent directory
            vndir->inode_.link_count++;
        }
        args->wb->PinVnode(fbl::move(vndir));
        return DIR_CB_SAVE_SYNC;
    };

    uint32_t reclen = static_cast<uint32_t>(MinfsReclen(de, offs->off));
    if (de->ino == 0) {
        // empty entry, do we fit?
        if (args->reclen > reclen) {
            return do_next_dirent(de, offs);
        }
        return add_dirent(fbl::move(vndir), de, args, offs->off);
    } else {
        // filled entry, can we sub-divide?
        uint32_t size = static_cast<uint32_t>(DirentSize(de->namelen));
        if (size > reclen) {
            FS_TRACE_ERROR("bad reclen (smaller than dirent) %u < %u\n", reclen, size);
            return ZX_ERR_IO;
        }
        uint32_t extra = reclen - size;
        if (extra < args->reclen) {
            return do_next_dirent(de, offs);
        }
        // shrink existing entry
        bool was_last_record = de->reclen & kMinfsReclenLast;
        de->reclen = size;
        zx_status_t status = vndir->WriteExactInternal(args->wb->txn(), de,
                                                       DirentSize(de->namelen),
                                                       offs->off);
        if (status != ZX_OK) {
            return status;
        }
        offs->off += size;
        // create new entry in the remaining space
        char data[kMinfsMaxDirentSize];
        de = (minfs_dirent_t*) data;
        de->reclen = extra | (was_last_record ? kMinfsReclenLast : 0);
        return add_dirent(fbl::move(vndir), de, args, offs->off);
    }
}

// Calls a callback 'func' on all direntries in a directory 'vn' with the
// provided arguments, reacting to the return code of the callback.
//
// When 'func' is called, it receives a few arguments:
//  'vndir': The directory on which the callback is operating
//  'de': A pointer the start of a single dirent.
//        Only DirentSize(de->namelen) bytes are guaranteed to exist in
//        memory from this starting pointer.
//  'args': Additional arguments plumbed through ForEachDirent
//  'offs': Offset info about where in the directory this direntry is located.
//          Since 'func' may create / remove surrounding dirents, it is responsible for
//          updating the offset information to access the next dirent.
zx_status_t VnodeMinfs::ForEachDirent(DirArgs* args, const DirentCallback func) {
    char data[kMinfsMaxDirentSize];
    minfs_dirent_t* de = (minfs_dirent_t*) data;
    DirectoryOffset offs = {
        .off = 0,
        .off_prev = 0,
    };
    while (offs.off + MINFS_DIRENT_SIZE < kMinfsMaxDirectorySize) {
        xprintf("Reading dirent at offset %zd\n", offs.off);
        size_t r;
        zx_status_t status = ReadInternal(data, kMinfsMaxDirentSize, offs.off, &r);
        if (status != ZX_OK) {
            return status;
        } else if ((status = validate_dirent(de, r, offs.off)) != ZX_OK) {
            return status;
        }

        switch ((status = func(fbl::RefPtr<VnodeMinfs>(this), de, args, &offs))) {
        case DIR_CB_NEXT:
            break;
        case DIR_CB_SAVE_SYNC:
            inode_.seq_num++;
            InodeSync(args->wb->txn(), kMxFsSyncMtime);
            args->wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
            return ZX_OK;
        case DIR_CB_DONE:
        default:
            return status;
        }
    }
    return ZX_ERR_NOT_FOUND;
}

void VnodeMinfs::fbl_recycle() {
    if (fd_count_ != 0 || !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).
#ifdef __Fuchsia__
        fbl::AutoLock lock(&fs_->hash_lock_);
#endif
        fs_->VnodeReleaseLocked(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].txnid = fs_->bc_->TxnId();
        request[request_count].vmoid = vmoid_;
        request[request_count].opcode = BLOCKIO_CLOSE_VMO;
        request_count++;
    }
    if (vmo_indirect_ != nullptr) {
        request[request_count].txnid = fs_->bc_->TxnId();
        request[request_count].vmoid = vmoid_indirect_;
        request[request_count].opcode = BLOCKIO_CLOSE_VMO;
        request_count++;
    }
    if (request_count) {
        fs_->bc_->Txn(&request[0], request_count);
    }
#endif
}

zx_status_t VnodeMinfs::ValidateFlags(uint32_t flags) {
    xprintf("VnodeMinfs::ValidateFlags(0x%x) vn=%p(#%u)\n", flags, this, ino_);
    if ((flags & ZX_FS_FLAG_DIRECTORY) && !IsDirectory()) {
        return ZX_ERR_NOT_DIR;
    }

    if ((flags & ZX_FS_RIGHT_WRITABLE) && IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }
    return ZX_OK;
}

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

void VnodeMinfs::Purge(WriteTxn* txn) {
    ZX_DEBUG_ASSERT(fd_count_ == 0);
    ZX_DEBUG_ASSERT(IsUnlinked());
#ifdef __Fuchsia__
    {
        fbl::AutoLock lock(&fs_->hash_lock_);
        fs_->VnodeReleaseLocked(this);
    }
    // TODO(smklein): Only init indirect vmo if it's needed
    if (InitIndirectVmo() == ZX_OK) {
        fs_->InoFree(this, txn);
    } else {
        fprintf(stderr, "minfs: Failed to Init Indirect VMO while purging %u\n", ino_);
    }
#else
    fs_->VnodeReleaseLocked(this);
    fs_->InoFree(this, txn);
#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()) {
        fbl::unique_ptr<WritebackWork> wb(new WritebackWork(fs_->bc_.get()));
        Purge(wb->txn());
        fs_->EnqueueWork(fbl::move(wb));
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::Read(void* data, size_t len, size_t off, size_t* out_actual) {
    TRACE_DURATION("minfs", "VnodeMinfs::Read", "ino", ino_, "len", len, "off", off);
    ZX_DEBUG_ASSERT_MSG(fd_count_ > 0, "Reading from ino with no fds open");
    xprintf("minfs_read() vn=%p(#%u) len=%zd off=%zd\n", this, ino_, len, off);
    if (IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }
    zx_status_t status = ReadInternal(data, len, off, out_actual);
    if (status != ZX_OK) {
        return status;
    }
    return ZX_OK;
}

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

    zx_status_t status;
#ifdef __Fuchsia__
    if ((status = InitVmo()) != ZX_OK) {
        return status;
    } else if ((status = vmo_.read(data, off, len, actual)) != ZX_OK) {
        return status;
    }
#else
    void* start = data;
    uint32_t n = 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 = BlockGet(nullptr, n, &bno)) != ZX_OK) {
            return status;
        }
        if (bno != 0) {
            char bdata[kMinfsBlockSize];
            if (fs_->ReadDat(bno, bdata)) {
                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;
}

zx_status_t VnodeMinfs::Write(const void* data, size_t len, size_t offset,
                              size_t* out_actual) {
    TRACE_DURATION("minfs", "VnodeMinfs::Write", "ino", ino_, "len", len, "off", offset);
    ZX_DEBUG_ASSERT_MSG(fd_count_ > 0, "Writing to ino with no fds open");
    xprintf("minfs_write() vn=%p(#%u) len=%zd off=%zd\n", this, ino_, len, offset);
    if (IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }

    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    zx_status_t status = WriteInternal(wb->txn(), data, len, offset, out_actual);
    if (status != ZX_OK) {
        return status;
    }
    if (*out_actual != 0) {
        InodeSync(wb->txn(), kMxFsSyncMtime);  // Successful writes updates mtime
        wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
        fs_->EnqueueWork(fbl::move(wb));
    }
    return ZX_OK;
}

zx_status_t VnodeMinfs::Append(const void* data, size_t len, size_t* out_end,
                               size_t* out_actual) {
    zx_status_t status = Write(data, len, inode_.size, out_actual);
    *out_end = inode_.size;
    return status;
}

// Internal write. Usable on directories.
zx_status_t VnodeMinfs::WriteInternal(WriteTxn* txn, 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__
    if ((status = InitVmo()) != 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) > inode_.size) {
            size_t new_size = fbl::round_up(xfer_off + xfer, kMinfsBlockSize);
            ZX_DEBUG_ASSERT(new_size >= inode_.size); // Overflow.
            if ((status = vmo_.set_size(new_size)) != ZX_OK) {
                goto done;
            }
        }

        // Update this block of the in-memory VMO
        if ((status = VmoWriteExact(data, xfer_off, xfer)) != ZX_OK) {
            goto done;
        }

        // Update this block on-disk
        blk_t bno;
        if ((status = BlockGet(txn, n, &bno))) {
            goto done;
        }
        ZX_DEBUG_ASSERT(bno != 0);
        txn->Enqueue(vmo_.get(), n, bno + fs_->info_.dat_block, 1);
#else
        blk_t bno;
        if ((status = BlockGet(txn, n, &bno))) {
            goto done;
        }
        ZX_DEBUG_ASSERT(bno != 0);
        char wdata[kMinfsBlockSize];
        if (fs_->bc_->Readblk(bno + fs_->info_.dat_block, wdata)) {
            goto done;
        }
        memcpy(wdata + adjust, data, xfer);
        if (len < kMinfsBlockSize && max_size >= inode_.size) {
            memset(wdata + adjust + xfer, 0, kMinfsBlockSize - (adjust + xfer));
        }
        if (fs_->bc_->Writeblk(bno + fs_->info_.dat_block, wdata)) {
            goto done;
        }
#endif

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

done:
    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) > inode_.size) {
        inode_.size = static_cast<uint32_t>(off + len);
    }

    *actual = len;
    ValidateVmoTail();
    return ZX_OK;
}

zx_status_t VnodeMinfs::Lookup(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) {
    TRACE_DURATION("minfs", "VnodeMinfs::Lookup", "name", name);
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(name));

    if (!IsDirectory()) {
        FS_TRACE_ERROR("not directory\n");
        return ZX_ERR_NOT_SUPPORTED;
    }

    return LookupInternal(out, name);
}

zx_status_t VnodeMinfs::LookupInternal(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) {
    DirArgs args = DirArgs();
    args.name = name;
    zx_status_t status;
    if ((status = ForEachDirent(&args, DirentCallbackFind)) < 0) {
        return status;
    }
    fbl::RefPtr<VnodeMinfs> vn;
    if ((status = fs_->VnodeGet(&vn, args.ino)) < 0) {
        return status;
    }
    *out = fbl::move(vn);
    return ZX_OK;
}

zx_status_t VnodeMinfs::Getattr(vnattr_t* a) {
    xprintf("minfs_getattr() vn=%p(#%u)\n", this, ino_);
    a->mode = DTYPE_TO_VTYPE(MinfsMagicType(inode_.magic)) |
            V_IRUSR | V_IWUSR | V_IRGRP | V_IROTH;
    a->inode = ino_;
    a->size = inode_.size;
    a->blksize = kMinfsBlockSize;
    a->blkcount = inode_.block_count * (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;
    xprintf("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
        fbl::AllocChecker ac;
        fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
        if (!ac.check()) {
            return ZX_ERR_NO_MEMORY;
        }
        InodeSync(wb->txn(), kMxFsSyncDefault);
        wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
        fs_->EnqueueWork(fbl::move(wb));
    }
    return ZX_OK;
}

typedef struct dircookie {
    size_t off;        // Offset into directory
    uint32_t reserved; // Unused
    uint32_t seqno;    // inode seq no
} dircookie_t;

static_assert(sizeof(dircookie_t) <= sizeof(fs::vdircookie_t),
              "MinFS dircookie too large to fit in IO state");

zx_status_t VnodeMinfs::Readdir(fs::vdircookie_t* cookie, void* dirents, size_t len,
                                size_t* out_actual) {
    TRACE_DURATION("minfs", "VnodeMinfs::Readdir");
    xprintf("minfs_readdir() vn=%p(#%u) cookie=%p len=%zd\n", this, ino_, cookie, len);
    dircookie_t* dc = reinterpret_cast<dircookie_t*>(cookie);
    fs::DirentFiller df(dirents, len);

    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    size_t off = dc->off;
    size_t r;
    char data[kMinfsMaxDirentSize];
    minfs_dirent_t* de = (minfs_dirent_t*) data;

    if (off != 0 && dc->seqno != inode_.seq_num) {
        // The offset *might* be invalid, if we called Readdir after a directory
        // has been modified. In this case, we need to re-read the directory
        // until we get to the direntry at or after the previously identified offset.

        size_t off_recovered = 0;
        while (off_recovered < off) {
            if (off_recovered + MINFS_DIRENT_SIZE >= kMinfsMaxDirectorySize) {
                goto fail;
            }
            zx_status_t status = ReadInternal(de, kMinfsMaxDirentSize, off_recovered, &r);
            if ((status != ZX_OK) || (validate_dirent(de, r, off_recovered) != ZX_OK)) {
                goto fail;
            }
            off_recovered += MinfsReclen(de, off_recovered);
        }
        off = off_recovered;
    }

    while (off + MINFS_DIRENT_SIZE < kMinfsMaxDirectorySize) {
        zx_status_t status = ReadInternal(de, kMinfsMaxDirentSize, off, &r);
        if (status != ZX_OK) {
            goto fail;
        } else if (validate_dirent(de, r, off) != ZX_OK) {
            goto fail;
        }

        fbl::StringPiece name(de->name, de->namelen);

        if (de->ino && name != "..") {
            zx_status_t status;
            if ((status = df.Next(name, de->type)) != ZX_OK) {
                // no more space
                goto done;
            }
        }

        off += MinfsReclen(de, off);
    }

done:
    // save our place in the dircookie
    dc->off = off;
    dc->seqno = inode_.seq_num;
    *out_actual = df.BytesFilled();
    ZX_DEBUG_ASSERT(*out_actual <= len); // Otherwise, we're overflowing the input buffer.
    return ZX_OK;

fail:
    dc->off = 0;
    return ZX_ERR_IO;
}

#ifdef __Fuchsia__
VnodeMinfs::VnodeMinfs(Minfs* fs) :
    fs_(fs), vmo_(ZX_HANDLE_INVALID), vmo_indirect_(nullptr) {}

void VnodeMinfs::Notify(fbl::StringPiece name, unsigned event) { watcher_.Notify(name, event); }
zx_status_t VnodeMinfs::WatchDir(fs::Vfs* vfs, const vfs_watch_dir_t* cmd) {
    return watcher_.WatchDir(vfs, this, cmd);
}

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(fbl::move(remote)); }

#else
VnodeMinfs::VnodeMinfs(Minfs* fs) : fs_(fs) {}
#endif

zx_status_t VnodeMinfs::Allocate(Minfs* fs, uint32_t type, fbl::RefPtr<VnodeMinfs>* out) {
    fbl::AllocChecker ac;
    *out = fbl::AdoptRef(new (&ac) VnodeMinfs(fs));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    memset(&(*out)->inode_, 0, sizeof((*out)->inode_));
    (*out)->inode_.magic = MinfsMagic(type);
    (*out)->inode_.create_time = (*out)->inode_.modify_time = minfs_gettime_utc();
    (*out)->inode_.link_count = (type == kMinfsTypeDir ? 2 : 1);
    return ZX_OK;
}

zx_status_t VnodeMinfs::Recreate(Minfs* fs, ino_t ino, const minfs_inode_t* inode,
                                 fbl::RefPtr<VnodeMinfs>* out) {
    fbl::AllocChecker ac;
    *out = fbl::AdoptRef(new (&ac) VnodeMinfs(fs));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    memcpy(&(*out)->inode_, inode, kMinfsInodeSize);
    (*out)->ino_ = ino;
    return ZX_OK;
}

zx_status_t VnodeMinfs::Create(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name, uint32_t mode) {
    TRACE_DURATION("minfs", "VnodeMinfs::Create", "name", name);
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(name));

    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    if (IsUnlinked()) {
        return ZX_ERR_BAD_STATE;
    }

    DirArgs args = DirArgs();
    args.name = name;
    // ensure file does not exist
    zx_status_t status;
    if ((status = ForEachDirent(&args, DirentCallbackFind)) != ZX_ERR_NOT_FOUND) {
        return ZX_ERR_ALREADY_EXISTS;
    }

    // creating a directory?
    uint32_t type = S_ISDIR(mode) ? kMinfsTypeDir : kMinfsTypeFile;

    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    // mint a new inode and vnode for it
    fbl::RefPtr<VnodeMinfs> vn;
    if ((status = fs_->VnodeNew(wb->txn(), &vn, type)) < 0) {
        return status;
    }

    // If the new node is a directory, fill it with '.' and '..'.
    if (type == kMinfsTypeDir) {
        char bdata[DirentSize(1) + DirentSize(2)];
        minfs_dir_init(bdata, vn->ino_, ino_);
        size_t expected = DirentSize(1) + DirentSize(2);
        if (vn->WriteExactInternal(wb->txn(), bdata, expected, 0) != ZX_OK) {
            return ZX_ERR_IO;
        }
        vn->inode_.dirent_count = 2;
        vn->InodeSync(wb->txn(), kMxFsSyncDefault);
    }

    // add directory entry for the new child node
    args.ino = vn->ino_;
    args.type = type;
    args.reclen = static_cast<uint32_t>(DirentSize(static_cast<uint8_t>(name.length())));
    args.wb = wb.get();
    if ((status = ForEachDirent(&args, DirentCallbackAppend)) < 0) {
        return status;
    }

    wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
    wb->PinVnode(vn);
    fs_->EnqueueWork(fbl::move(wb));

    vn->fd_count_ = 1;
    *out = fbl::move(vn);
    return ZX_OK;
}

constexpr const char kFsName[] = "minfs";

zx_status_t VnodeMinfs::Ioctl(uint32_t op, const void* in_buf, size_t in_len, void* out_buf,
                              size_t out_len, size_t* out_actual) {
    switch (op) {
        case IOCTL_VFS_QUERY_FS: {
            if (out_len < (sizeof(vfs_query_info_t) + strlen(kFsName))) {
                return ZX_ERR_INVALID_ARGS;
            }

            vfs_query_info_t* info = static_cast<vfs_query_info_t*>(out_buf);
            memset(info, 0, sizeof(*info));
            info->block_size = kMinfsBlockSize;
            info->max_filename_size = kMinfsMaxNameSize;
            info->fs_type = VFS_TYPE_MINFS;
#ifdef __Fuchsia__
            info->fs_id = fs_->GetFsId();
#endif
            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;
            memcpy(info->name, kFsName, strlen(kFsName));
            *out_actual = sizeof(vfs_query_info_t) + strlen(kFsName);
            return ZX_OK;
        }
#ifdef __Fuchsia__
        case IOCTL_VFS_UNMOUNT_FS: {
            // TODO(ZX-1577): Avoid calling completion_wait here.
            // Prefer to use dispatcher's async_t to be notified
            // whenever Sync completes.
            completion_t completion;
            SyncCallback closure([&completion](zx_status_t status) {
                if (status != ZX_OK) {
                    FS_TRACE_ERROR("minfs unmount failed to sync; unmounting "
                                   "anyway: %d\n", status);
                }
                completion_signal(&completion);
            });

            Sync(fbl::move(closure));
            completion_wait(&completion, ZX_TIME_INFINITE);

            // 'fs_' is deleted after Unmount is called.
            *out_actual = 0;
            return fs_->Unmount();
        }
        case IOCTL_VFS_GET_DEVICE_PATH: {
            ssize_t len = fs_->bc_->GetDevicePath(static_cast<char*>(out_buf), out_len);

            if ((ssize_t)out_len < len) {
                return ZX_ERR_INVALID_ARGS;
            }
            if (len >= 0) {
                *out_actual = len;
            }
            return len > 0 ? ZX_OK : static_cast<zx_status_t>(len);
        }
#endif
        default: {
            return ZX_ERR_NOT_SUPPORTED;
        }
    }
}

zx_status_t VnodeMinfs::Unlink(fbl::StringPiece name, bool must_be_dir) {
    TRACE_DURATION("minfs", "VnodeMinfs::Unlink", "name", name);
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(name));

    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    DirArgs args = DirArgs();
    args.name = name;
    args.type = must_be_dir ? kMinfsTypeDir : 0;
    args.wb = wb.get();
    zx_status_t status = ForEachDirent(&args, DirentCallbackUnlink);
    if (status == ZX_OK) {
        wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
        fs_->EnqueueWork(fbl::move(wb));
    }
    return status;
}

zx_status_t VnodeMinfs::Truncate(size_t len) {
    TRACE_DURATION("minfs", "VnodeMinfs::Truncate");
    if (IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }

    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    zx_status_t status = TruncateInternal(wb->txn(), len);
    if (status == ZX_OK) {
        // Successful truncates update inode
        InodeSync(wb->txn(), kMxFsSyncMtime);
    }
    wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
    fs_->EnqueueWork(fbl::move(wb));
    return status;
}

zx_status_t VnodeMinfs::TruncateInternal(WriteTxn* txn, size_t len) {
    zx_status_t r = 0;
#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 (InitVmo() != ZX_OK) {
        return ZX_ERR_IO;
    }
#endif

    if (len < inode_.size) {
        // Truncate should make the file shorter
        blk_t bno = inode_.size / kMinfsBlockSize;
        blk_t trunc_bno = static_cast<blk_t>(len / kMinfsBlockSize);

        // Truncate to the nearest block
        if (trunc_bno <= bno) {
            blk_t start_bno = static_cast<blk_t>((len % kMinfsBlockSize == 0) ?
                                                 trunc_bno : trunc_bno + 1);
            if ((r = BlocksShrink(txn, start_bno)) < 0) {
                return r;
            }

            if (start_bno * kMinfsBlockSize < inode_.size) {
                inode_.size = start_bno * kMinfsBlockSize;
            }
        }

        // Write zeroes to the rest of the remaining block, if it exists
        if (len < inode_.size) {
            char bdata[kMinfsBlockSize];
            blk_t rel_bno = static_cast<blk_t>(len / kMinfsBlockSize);
            if (BlockGet(nullptr, rel_bno, &bno) != ZX_OK) {
                return ZX_ERR_IO;
            }
            if (bno != 0) {
                size_t adjust = len % kMinfsBlockSize;
#ifdef __Fuchsia__
                if ((r = VmoReadExact(bdata, len - adjust, adjust)) != ZX_OK) {
                    return ZX_ERR_IO;
                }
                memset(bdata + adjust, 0, kMinfsBlockSize - adjust);

                if ((r = VmoWriteExact(bdata, len - adjust, kMinfsBlockSize)) != ZX_OK) {
                    return ZX_ERR_IO;
                }
                txn->Enqueue(vmo_.get(), rel_bno, bno + fs_->info_.dat_block, 1);
#else
                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
            }
        }
    } else if (len > inode_.size) {
        // Truncate should make the file longer, filled with zeroes.
        if (kMinfsMaxFileSize < len) {
            return ZX_ERR_INVALID_ARGS;
        }
    } else {
        return ZX_OK;
    }

    inode_.size = static_cast<uint32_t>(len);
#ifdef __Fuchsia__
    if ((r = vmo_.set_size(fbl::round_up(len, kMinfsBlockSize))) != ZX_OK) {
        return r;
    }
#endif

    ValidateVmoTail();
    return ZX_OK;
}

// Verify that the 'newdir' inode is not a subdirectory of the source.
zx_status_t VnodeMinfs::CheckNotSubdirectory(fbl::RefPtr<VnodeMinfs> newdir) {
    fbl::RefPtr<VnodeMinfs> vn = newdir;
    zx_status_t status = ZX_OK;
    while (vn->ino_ != kMinfsRootIno) {
        if (vn->ino_ == ino_) {
            status = ZX_ERR_INVALID_ARGS;
            break;
        }

        fbl::RefPtr<fs::Vnode> out = nullptr;
        if ((status = vn->LookupInternal(&out, "..")) < 0) {
            break;
        }
        vn = fbl::RefPtr<VnodeMinfs>::Downcast(out);
    }
    return status;
}

zx_status_t VnodeMinfs::Rename(fbl::RefPtr<fs::Vnode> _newdir, fbl::StringPiece oldname,
                               fbl::StringPiece newname, bool src_must_be_dir,
                               bool dst_must_be_dir) {
    TRACE_DURATION("minfs", "VnodeMinfs::Rename", "src", oldname, "dst", newname);
    auto newdir = fbl::RefPtr<VnodeMinfs>::Downcast(_newdir);
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(oldname));
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(newname));

    // ensure that the vnodes containing oldname and newname are directories
    if (!(IsDirectory() && newdir->IsDirectory()))
        return ZX_ERR_NOT_SUPPORTED;

    zx_status_t status;
    fbl::RefPtr<VnodeMinfs> oldvn = nullptr;
    // acquire the 'oldname' node (it must exist)
    DirArgs args = DirArgs();
    args.name = oldname;
    if ((status = ForEachDirent(&args, DirentCallbackFind)) < 0) {
        return status;
    } else if ((status = fs_->VnodeGet(&oldvn, args.ino)) < 0) {
        return status;
    } else if ((status = oldvn->CheckNotSubdirectory(newdir)) < 0) {
        return status;
    }

    // If either the 'src' or 'dst' must be directories, BOTH of them must be directories.
    if (!oldvn->IsDirectory() && (src_must_be_dir || dst_must_be_dir)) {
        return ZX_ERR_NOT_DIR;
    } else if ((newdir->ino_ == ino_) && (oldname == newname)) {
        // Renaming a file or directory to itself?
        // Shortcut success case.
        return ZX_OK;
    }

    // if the entry for 'newname' exists, make sure it can be replaced by
    // the vnode behind 'oldname'.
    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    args.wb = wb.get();
    args.name = newname;
    args.ino = oldvn->ino_;
    args.type = oldvn->IsDirectory() ? kMinfsTypeDir : kMinfsTypeFile;
    status = newdir->ForEachDirent(&args, DirentCallbackAttemptRename);
    if (status == ZX_ERR_NOT_FOUND) {
        // if 'newname' does not exist, create it
        args.reclen = static_cast<uint32_t>(DirentSize(static_cast<uint8_t>(newname.length())));
        if ((status = newdir->ForEachDirent(&args, DirentCallbackAppend)) < 0) {
            return status;
        }
    } else if (status != ZX_OK) {
        return status;
    }

    // update the oldvn's entry for '..' if (1) it was a directory, and (2) it
    // moved to a new directory
    if ((args.type == kMinfsTypeDir) && (ino_ != newdir->ino_)) {
        fbl::RefPtr<fs::Vnode> vn_fs;
        if ((status = newdir->Lookup(&vn_fs, newname)) < 0) {
            return status;
        }
        auto vn = fbl::RefPtr<VnodeMinfs>::Downcast(vn_fs);
        args.name = "..";
        args.ino = newdir->ino_;
        if ((status = vn->ForEachDirent(&args, DirentCallbackUpdateInode)) < 0) {
            return status;
        }
    }

    // at this point, the oldvn exists with multiple names (or the same name in
    // different directories)
    oldvn->inode_.link_count++;

    // finally, remove oldname from its original position
    args.name = oldname;
    status = ForEachDirent(&args, DirentCallbackForceUnlink);
    wb->PinVnode(oldvn);
    wb->PinVnode(newdir);
    fs_->EnqueueWork(fbl::move(wb));
    return status;
}

zx_status_t VnodeMinfs::Link(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> _target) {
    TRACE_DURATION("minfs", "VnodeMinfs::Link", "name", name);
    ZX_DEBUG_ASSERT(fs::vfs_valid_name(name));

    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    } else if (IsUnlinked()) {
        return ZX_ERR_BAD_STATE;
    }

    auto target = fbl::RefPtr<VnodeMinfs>::Downcast(_target);
    if (target->IsDirectory()) {
        // The target must not be a directory
        return ZX_ERR_NOT_FILE;
    }

    // The destination should not exist
    DirArgs args = DirArgs();
    args.name = name;
    zx_status_t status;
    if ((status = ForEachDirent(&args, DirentCallbackFind)) != ZX_ERR_NOT_FOUND) {
        return (status == ZX_OK) ? ZX_ERR_ALREADY_EXISTS : status;
    }

    fbl::AllocChecker ac;
    fbl::unique_ptr<WritebackWork> wb(new (&ac) WritebackWork(fs_->bc_.get()));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }
    args.ino = target->ino_;
    args.type = kMinfsTypeFile; // We can't hard link directories
    args.reclen = static_cast<uint32_t>(DirentSize(static_cast<uint8_t>(name.length())));
    args.wb = wb.get();
    if ((status = ForEachDirent(&args, DirentCallbackAppend)) < 0) {
        return status;
    }

    // We have successfully added the vn to a new location. Increment the link count.
    target->inode_.link_count++;
    target->InodeSync(wb->txn(), kMxFsSyncDefault);
    wb->PinVnode(fbl::move(fbl::WrapRefPtr(this)));
    wb->PinVnode(target);
    fs_->EnqueueWork(fbl::move(wb));
    return ZX_OK;
}

#ifdef __Fuchsia__
void VnodeMinfs::Sync(SyncCallback closure) {
    TRACE_DURATION("minfs", "VnodeMinfs::Sync");
    fs_->Sync([this, cb = fbl::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(fbl::move(h.TakeChannel()));
    return ZX_OK;
}
#endif

VnodeMinfs::DirectArgs VnodeMinfs::IndirectArgs::GetDirect(blk_t* barray, unsigned 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 found = 0;

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

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

VnodeMinfs::IndirectArgs VnodeMinfs::DindirectArgs::GetIndirect(blk_t* iarray,
                                                                unsigned 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 found = 0;
    if (dibindex) {
        found = kMinfsDirectPerIndirect * kMinfsDirectPerIndirect * dibindex -
                (ibindex_ * kMinfsDirectPerIndirect) + bindex_;
    }

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

} // namespace minfs
