// 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 <inttypes.h>
#include <limits>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <bitmap/raw-bitmap.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/unique_ptr.h>
#include <fs/block-txn.h>
#include <fs/trace.h>
#include <safemath/checked_math.h>

#ifdef __Fuchsia__
#include <fbl/auto_lock.h>
#include <fuchsia/minfs/c/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/zx/event.h>
#endif

#include <minfs/fsck.h>
#include <minfs/minfs.h>

#include <utility>

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

namespace minfs {
namespace {

// Deletes all known slices from an MinFS Partition.
void minfs_free_slices(Bcache* bc, const Superblock* info) {
    if ((info->flags & kMinfsFlagFVM) == 0) {
        return;
    }
#ifdef __Fuchsia__
    extend_request_t request;
    const size_t kBlocksPerSlice = info->slice_size / kMinfsBlockSize;
    if (info->ibm_slices) {
        request.length = info->ibm_slices;
        request.offset = kFVMBlockInodeBmStart / kBlocksPerSlice;
        bc->FVMShrink(&request);
    }
    if (info->abm_slices) {
        request.length = info->abm_slices;
        request.offset = kFVMBlockDataBmStart / kBlocksPerSlice;
        bc->FVMShrink(&request);
    }
    if (info->ino_slices) {
        request.length = info->ino_slices;
        request.offset = kFVMBlockInodeStart / kBlocksPerSlice;
        bc->FVMShrink(&request);
    }
    if (info->dat_slices) {
        request.length = info->dat_slices;
        request.offset = kFVMBlockDataStart / kBlocksPerSlice;
        bc->FVMShrink(&request);
    }
#endif
}

} // namespace

zx_time_t GetTimeUTC() {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    zx_time_t time = zx_time_add_duration(ZX_SEC(ts.tv_sec), ts.tv_nsec);
    return time;
}

void DumpInfo(const Superblock* info) {
    FS_TRACE_DEBUG("minfs: data blocks:  %10u (size %u)\n", info->block_count, info->block_size);
    FS_TRACE_DEBUG("minfs: inodes:  %10u (size %u)\n", info->inode_count, info->inode_size);
    FS_TRACE_DEBUG("minfs: allocated blocks  @ %10u\n", info->alloc_block_count);
    FS_TRACE_DEBUG("minfs: allocated inodes  @ %10u\n", info->alloc_inode_count);
    FS_TRACE_DEBUG("minfs: inode bitmap @ %10u\n", info->ibm_block);
    FS_TRACE_DEBUG("minfs: alloc bitmap @ %10u\n", info->abm_block);
    FS_TRACE_DEBUG("minfs: inode table  @ %10u\n", info->ino_block);
    FS_TRACE_DEBUG("minfs: data blocks  @ %10u\n", info->dat_block);
    FS_TRACE_DEBUG("minfs: FVM-aware: %s\n", (info->flags & kMinfsFlagFVM) ? "YES" : "NO");
}

void DumpInode(const Inode* inode, ino_t ino) {
    FS_TRACE_DEBUG("inode[%u]: magic:  %10u\n", ino, inode->magic);
    FS_TRACE_DEBUG("inode[%u]: size:   %10u\n", ino, inode->size);
    FS_TRACE_DEBUG("inode[%u]: blocks: %10u\n", ino, inode->block_count);
    FS_TRACE_DEBUG("inode[%u]: links:  %10u\n", ino, inode->link_count);
}

zx_status_t CheckSuperblock(const Superblock* info, Bcache* bc) {
    uint32_t max = bc->Maxblk();
    DumpInfo(info);

    if ((info->magic0 != kMinfsMagic0) || (info->magic1 != kMinfsMagic1)) {
        FS_TRACE_ERROR("minfs: bad magic\n");
        return ZX_ERR_INVALID_ARGS;
    }
    if (info->version != kMinfsVersion) {
        FS_TRACE_ERROR("minfs: FS Version: %08x. Driver version: %08x\n", info->version,
                       kMinfsVersion);
        return ZX_ERR_INVALID_ARGS;
    }
    if ((info->block_size != kMinfsBlockSize) || (info->inode_size != kMinfsInodeSize)) {
        FS_TRACE_ERROR("minfs: bsz/isz %u/%u unsupported\n", info->block_size, info->inode_size);
        return ZX_ERR_INVALID_ARGS;
    }

#ifdef __Fuchsia__
    if ((info->flags & kMinfsFlagClean) == 0) {
        FS_TRACE_ERROR("minfs: filesystem in dirty state. Was not unmounted cleanly.\n");
    } else {
        FS_TRACE_INFO("minfs: filesystem in clean state.\n");
    }
#endif

    TransactionLimits limits(*info);
    if ((info->flags & kMinfsFlagFVM) == 0) {
        if (info->dat_block + info->block_count != max) {
            FS_TRACE_ERROR("minfs: too large for device\n");
            return ZX_ERR_INVALID_ARGS;
        }

        if (info->dat_block - info->journal_start_block < limits.GetMinimumJournalBlocks()) {
            FS_TRACE_ERROR("minfs: journal too small\n");
            return ZX_ERR_BAD_STATE;
        }
    } else {
        const size_t kBlocksPerSlice = info->slice_size / kMinfsBlockSize;
#ifdef __Fuchsia__
        fuchsia_hardware_block_volume_VolumeInfo fvm_info;
        if (bc->FVMQuery(&fvm_info) != ZX_OK) {
            FS_TRACE_ERROR("minfs: Unable to query FVM\n");
            return ZX_ERR_UNAVAILABLE;
        }

        if (info->slice_size != fvm_info.slice_size) {
            FS_TRACE_ERROR("minfs: Slice size did not match expected\n");
            return ZX_ERR_BAD_STATE;
        }

        size_t expected_count[4];
        expected_count[0] = info->ibm_slices;
        expected_count[1] = info->abm_slices;
        expected_count[2] = info->ino_slices;
        expected_count[3] = info->dat_slices;

        query_request_t request;
        request.count = 4;
        request.vslice_start[0] = kFVMBlockInodeBmStart / kBlocksPerSlice;
        request.vslice_start[1] = kFVMBlockDataBmStart / kBlocksPerSlice;
        request.vslice_start[2] = kFVMBlockInodeStart / kBlocksPerSlice;
        request.vslice_start[3] = kFVMBlockDataStart / kBlocksPerSlice;

        fuchsia_hardware_block_volume_VsliceRange
                ranges[fuchsia_hardware_block_volume_MAX_SLICE_REQUESTS];
        size_t ranges_count;

        if (bc->FVMVsliceQuery(&request, ranges, &ranges_count) != ZX_OK) {
            FS_TRACE_ERROR("minfs: Unable to query FVM\n");
            return ZX_ERR_UNAVAILABLE;
        }

        if (ranges_count != request.count) {
            FS_TRACE_ERROR("minfs: Unable to query FVM\n");
            return ZX_ERR_BAD_STATE;
        }

        for (unsigned i = 0; i < request.count; i++) {
            size_t minfs_count = expected_count[i];
            size_t fvm_count = ranges[i].count;

            if (!ranges[i].allocated || fvm_count < minfs_count) {
                // Currently, since Minfs can only grow new slices, it should not be possible for
                // the FVM to report a slice size smaller than what is reported by Minfs. In this
                // case, automatically fail without trying to resolve the situation, as it is
                // possible that Minfs structures are allocated in the slices that have been lost.
                FS_TRACE_ERROR("minfs: Mismatched slice count\n");
                return ZX_ERR_IO_DATA_INTEGRITY;
            }

            if (fvm_count > minfs_count) {
                // If FVM reports more slices than we expect, try to free remainder.
                extend_request_t shrink;
                shrink.length = fvm_count - minfs_count;
                shrink.offset = request.vslice_start[i] + minfs_count;
                zx_status_t status;
                if ((status = bc->FVMShrink(&shrink)) != ZX_OK) {
                    FS_TRACE_ERROR("minfs: Unable to shrink to expected size, status: %d\n",
                                   status);
                    return ZX_ERR_IO_DATA_INTEGRITY;
                }
            }
        }
#endif
        // Verify that the allocated slices are sufficient to hold
        // the allocated data structures of the filesystem.
        size_t ibm_blocks_needed = (info->inode_count + kMinfsBlockBits - 1) / kMinfsBlockBits;
        size_t ibm_blocks_allocated = info->ibm_slices * kBlocksPerSlice;
        if (ibm_blocks_needed > ibm_blocks_allocated) {
            FS_TRACE_ERROR("minfs: Not enough slices for inode bitmap\n");
            return ZX_ERR_INVALID_ARGS;
        } else if (ibm_blocks_allocated + info->ibm_block >= info->abm_block) {
            FS_TRACE_ERROR("minfs: Inode bitmap collides into block bitmap\n");
            return ZX_ERR_INVALID_ARGS;
        }

        size_t abm_blocks_needed = (info->block_count + kMinfsBlockBits - 1) / kMinfsBlockBits;
        size_t abm_blocks_allocated = info->abm_slices * kBlocksPerSlice;
        if (abm_blocks_needed > abm_blocks_allocated) {
            FS_TRACE_ERROR("minfs: Not enough slices for block bitmap\n");
            return ZX_ERR_INVALID_ARGS;
        } else if (abm_blocks_allocated + info->abm_block >= info->ino_block) {
            FS_TRACE_ERROR("minfs: Block bitmap collides with inode table\n");
            return ZX_ERR_INVALID_ARGS;
        }

        size_t ino_blocks_needed =
            (info->inode_count + kMinfsInodesPerBlock - 1) / kMinfsInodesPerBlock;
        size_t ino_blocks_allocated = info->ino_slices * kBlocksPerSlice;
        if (ino_blocks_needed > ino_blocks_allocated) {
            FS_TRACE_ERROR("minfs: Not enough slices for inode table\n");
            return ZX_ERR_INVALID_ARGS;
        } else if (ino_blocks_allocated + info->ino_block >= info->journal_start_block) {
            FS_TRACE_ERROR("minfs: Inode table collides with data blocks\n");
            return ZX_ERR_INVALID_ARGS;
        }

        size_t journal_blocks_needed = limits.GetMinimumJournalBlocks();
        size_t journal_blocks_allocated = info->journal_slices * kBlocksPerSlice;
        if (journal_blocks_needed > journal_blocks_allocated) {
            FS_TRACE_ERROR("minfs: Not enough slices for journal\n");
            return ZX_ERR_INVALID_ARGS;
        }
        if (journal_blocks_allocated + info->journal_start_block > info->dat_block) {
            FS_TRACE_ERROR("minfs: Journal collides with data blocks\n");
            return ZX_ERR_INVALID_ARGS;
        }

        size_t dat_blocks_needed = info->block_count;
        size_t dat_blocks_allocated = info->dat_slices * kBlocksPerSlice;
        if (dat_blocks_needed > dat_blocks_allocated) {
            FS_TRACE_ERROR("minfs: Not enough slices for data blocks\n");
            return ZX_ERR_INVALID_ARGS;
        } else if (dat_blocks_allocated + info->dat_block > std::numeric_limits<blk_t>::max()) {
            FS_TRACE_ERROR("minfs: Data blocks overflow blk_t\n");
            return ZX_ERR_INVALID_ARGS;
        } else if (dat_blocks_needed <= 1) {
            FS_TRACE_ERROR("minfs: Not enough data blocks\n");
            return ZX_ERR_INVALID_ARGS;
        }
    }
    // TODO: validate layout
    return 0;
}

#ifndef __Fuchsia__
BlockOffsets::BlockOffsets(const Bcache& bc, const SuperblockManager& sb) {
    if (bc.extent_lengths_.size() > 0) {
        ZX_ASSERT(bc.extent_lengths_.size() == kExtentCount);
        ibm_block_count_ = static_cast<blk_t>(bc.extent_lengths_[1] / kMinfsBlockSize);
        abm_block_count_ = static_cast<blk_t>(bc.extent_lengths_[2] / kMinfsBlockSize);
        ino_block_count_ = static_cast<blk_t>(bc.extent_lengths_[3] / kMinfsBlockSize);
        journal_block_count_ = static_cast<blk_t>(bc.extent_lengths_[4] / kMinfsBlockSize);
        dat_block_count_ = static_cast<blk_t>(bc.extent_lengths_[5] / kMinfsBlockSize);

        ibm_start_block_ = static_cast<blk_t>(bc.extent_lengths_[0] / kMinfsBlockSize);
        abm_start_block_ = ibm_start_block_ + ibm_block_count_;
        ino_start_block_ = abm_start_block_ + abm_block_count_;
        journal_start_block_ = ino_start_block_ + ino_block_count_;
        dat_start_block_ = journal_start_block_ + journal_block_count_;
    } else {
        ibm_start_block_ = sb.Info().ibm_block;
        abm_start_block_ = sb.Info().abm_block;
        ino_start_block_ = sb.Info().ino_block;
        journal_start_block_ = sb.Info().journal_start_block;
        dat_start_block_ = sb.Info().dat_block;

        ibm_block_count_ = abm_start_block_ - ibm_start_block_;
        abm_block_count_ = ino_start_block_ - abm_start_block_;
        ino_block_count_ = dat_start_block_ - ino_start_block_;
        journal_block_count_ = dat_start_block_ - journal_start_block_;
        dat_block_count_ = sb.Info().block_count;
    }
}
#endif

zx_status_t Minfs::BeginTransaction(size_t reserve_inodes, size_t reserve_blocks,
                                    fbl::unique_ptr<Transaction>* out) {
    ZX_DEBUG_ASSERT(reserve_inodes <= TransactionLimits::kMaxInodeBitmapBlocks);
#ifdef __Fuchsia__
    if (writeback_ == nullptr) {
        return ZX_ERR_BAD_STATE;
    }

    // TODO(planders): Once we are splitting up write transactions, assert this on host as well.
    ZX_DEBUG_ASSERT(reserve_blocks <= limits_.GetMaximumDataBlocks());
#endif
    // Reserve blocks from allocators before returning WritebackWork to client.
    return Transaction::Create(this, reserve_inodes, reserve_blocks, inodes_.get(),
                               block_allocator_.get(), out);
}

zx_status_t Minfs::EnqueueWork(fbl::unique_ptr<WritebackWork> work) {
#ifdef __Fuchsia__
    return writeback_->Enqueue(std::move(work));
#else
    return work->Complete();
#endif
}

zx_status_t Minfs::CommitTransaction(fbl::unique_ptr<Transaction> transaction) {
#ifdef __Fuchsia__
    ZX_DEBUG_ASSERT(writeback_ != nullptr);
    // TODO(planders): Move this check to Journal enqueue.
    ZX_DEBUG_ASSERT(transaction->GetWork()->BlockCount() <= limits_.GetMaximumEntryDataBlocks());
#endif
    // Take the transaction's metadata updates, and pass them back to the writeback buffer.
    // This begins the pipeline of "actually writing these updates out to persistent storage".
    return EnqueueWork(transaction->RemoveWork());
}

#ifdef __Fuchsia__
void Minfs::Sync(SyncCallback closure) {
    if (assigner_ != nullptr) {
        // This callback will be processed after all "delayed data" operations have completed:
        // this is why we "enqueue a callback" that will later "enqueue a callback" somewhere
        // else.
        auto cb = [closure = std::move(closure)](TransactionalFs* minfs) mutable {
            minfs->EnqueueCallback(std::move(closure));
        };
        assigner_->EnqueueCallback(std::move(cb));
    } else {
        // If Minfs is read-only (data block assigner has not been initialized), immediately
        // resolve the callback.
        closure(ZX_OK);
    }
}
#endif

#ifdef __Fuchsia__
Minfs::Minfs(fbl::unique_ptr<Bcache> bc, fbl::unique_ptr<SuperblockManager> sb,
             fbl::unique_ptr<Allocator> block_allocator, fbl::unique_ptr<InodeManager> inodes,
             uint64_t fs_id)
    : bc_(std::move(bc)), sb_(std::move(sb)), block_allocator_(std::move(block_allocator)),
      inodes_(std::move(inodes)), fs_id_(fs_id), limits_(sb_->Info()) {}
#else
Minfs::Minfs(fbl::unique_ptr<Bcache> bc, fbl::unique_ptr<SuperblockManager> sb,
             fbl::unique_ptr<Allocator> block_allocator, fbl::unique_ptr<InodeManager> inodes,
             BlockOffsets offsets)
    : bc_(std::move(bc)), sb_(std::move(sb)), block_allocator_(std::move(block_allocator)),
      inodes_(std::move(inodes)), offsets_(std::move(offsets)), limits_(sb_->Info()) {}
#endif

Minfs::~Minfs() {
    vnode_hash_.clear();
}

#ifdef __Fuchsia__
zx_status_t Minfs::FVMQuery(fuchsia_hardware_block_volume_VolumeInfo* info) const {
    if (!(Info().flags & kMinfsFlagFVM)) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    return bc_->FVMQuery(info);
}
#endif

zx_status_t Minfs::InoFree(Transaction* transaction, VnodeMinfs* vn) {
    TRACE_DURATION("minfs", "Minfs::InoFree", "ino", vn->GetIno());

#ifdef __Fuchsia__
    vn->CancelPendingWriteback();
#endif

    inodes_->Free(transaction->GetWork(), vn->GetIno());
    uint32_t block_count = vn->GetInode()->block_count;

    // release all direct blocks
    for (unsigned n = 0; n < kMinfsDirect; n++) {
        if (vn->GetInode()->dnum[n] == 0) {
            continue;
        }
        ValidateBno(vn->GetInode()->dnum[n]);
        block_count--;
        block_allocator_->Free(transaction->GetWork(), vn->GetInode()->dnum[n]);
    }

    // release all indirect blocks
    for (unsigned n = 0; n < kMinfsIndirect; n++) {
        if (vn->GetInode()->inum[n] == 0) {
            continue;
        }

#ifdef __Fuchsia__
        zx_status_t status;
        if ((status = vn->InitIndirectVmo()) != ZX_OK) {
            return status;
        }

        uint32_t* entry;
        vn->ReadIndirectVmoBlock(n, &entry);
#else
        uint32_t entry[kMinfsBlockSize];
        vn->ReadIndirectBlock(vn->GetInode()->inum[n], entry);
#endif

        // release the direct blocks pointed at by the entries in the indirect block
        for (unsigned m = 0; m < kMinfsDirectPerIndirect; m++) {
            if (entry[m] == 0) {
                continue;
            }
            block_count--;
            block_allocator_->Free(transaction->GetWork(), entry[m]);
        }
        // release the direct block itself
        block_count--;
        block_allocator_->Free(transaction->GetWork(), vn->GetInode()->inum[n]);
    }

    // release doubly indirect blocks
    for (unsigned n = 0; n < kMinfsDoublyIndirect; n++) {
        if (vn->GetInode()->dinum[n] == 0) {
            continue;
        }
#ifdef __Fuchsia__
        zx_status_t status;
        if ((status = vn->InitIndirectVmo()) != ZX_OK) {
            return status;
        }

        uint32_t* dentry;
        vn->ReadIndirectVmoBlock(GetVmoOffsetForDoublyIndirect(n), &dentry);
#else
        uint32_t dentry[kMinfsBlockSize];
        vn->ReadIndirectBlock(vn->GetInode()->dinum[n], dentry);
#endif
        // release indirect blocks
        for (unsigned m = 0; m < kMinfsDirectPerIndirect; m++) {
            if (dentry[m] == 0) {
                continue;
            }

#ifdef __Fuchsia__
            if ((status = vn->LoadIndirectWithinDoublyIndirect(n)) != ZX_OK) {
                return status;
            }

            uint32_t* entry;
            vn->ReadIndirectVmoBlock(GetVmoOffsetForIndirect(n) + m, &entry);

#else
            uint32_t entry[kMinfsBlockSize];
            vn->ReadIndirectBlock(dentry[m], entry);
#endif

            // release direct blocks
            for (unsigned k = 0; k < kMinfsDirectPerIndirect; k++) {
                if (entry[k] == 0) {
                    continue;
                }

                block_count--;
                block_allocator_->Free(transaction->GetWork(), entry[k]);
            }

            block_count--;
            block_allocator_->Free(transaction->GetWork(), dentry[m]);
        }

        // release the doubly indirect block itself
        block_count--;
        block_allocator_->Free(transaction->GetWork(), vn->GetInode()->dinum[n]);
    }

    ZX_DEBUG_ASSERT(block_count == 0);
    ZX_DEBUG_ASSERT(vn->IsUnlinked());
    return ZX_OK;
}

void Minfs::AddUnlinked(Transaction* transaction, VnodeMinfs* vn) {
    ZX_DEBUG_ASSERT(vn->GetInode()->link_count == 0);

    Superblock* info = sb_->MutableInfo();

    if (info->unlinked_tail == 0) {
        // If no other vnodes are unlinked, |vn| is now both the head and the tail.
        ZX_DEBUG_ASSERT(info->unlinked_head == 0);
        info->unlinked_head = vn->GetIno();
        info->unlinked_tail = vn->GetIno();
    } else {
        // Since all vnodes in the unlinked list are necessarily open, the last vnode
        // must currently exist in the vnode lookup.
        fbl::RefPtr<VnodeMinfs> last_vn = VnodeLookupInternal(info->unlinked_tail);
        ZX_DEBUG_ASSERT(last_vn != nullptr);

        // Add |vn| to the end of the unlinked list.
        last_vn->SetNextInode(vn->GetIno());
        vn->SetLastInode(last_vn->GetIno());
        info->unlinked_tail = vn->GetIno();

        last_vn->InodeSync(transaction->GetWork(), kMxFsSyncDefault);
        vn->InodeSync(transaction->GetWork(), kMxFsSyncDefault);
    }

    sb_->Write(transaction->GetWork());
}

void Minfs::RemoveUnlinked(Transaction* transaction, VnodeMinfs* vn) {
    if (vn->GetInode()->last_inode == 0) {
        // If |vn| is the first unlinked inode, we just need to update the list head
        // to the next inode (which may not exist).
        ZX_DEBUG_ASSERT_MSG(Info().unlinked_head == vn->GetIno(),
            "Vnode %u has no previous link, but is not listed as unlinked list head", vn->GetIno());
        sb_->MutableInfo()->unlinked_head = vn->GetInode()->next_inode;
    } else {
        // Set the previous vnode's next to |vn|'s next.
        fbl::RefPtr<VnodeMinfs> last_vn = VnodeLookupInternal(vn->GetInode()->last_inode);
        ZX_DEBUG_ASSERT(last_vn != nullptr);
        last_vn->SetNextInode(vn->GetInode()->next_inode);
        last_vn->InodeSync(transaction->GetWork(), kMxFsSyncDefault);
    }

    if (vn->GetInode()->next_inode == 0) {
        // If |vn| is the last unlinked inode, we just need to update the list tail
        // to the previous inode (which may not exist).
        ZX_DEBUG_ASSERT_MSG(Info().unlinked_tail == vn->GetIno(),
            "Vnode %u has no next link, but is not listed as unlinked list tail", vn->GetIno());
        sb_->MutableInfo()->unlinked_tail = vn->GetInode()->last_inode;
    } else {
        // Set the next vnode's previous to |vn|'s previous.
        fbl::RefPtr<VnodeMinfs> next_vn = VnodeLookupInternal(vn->GetInode()->next_inode);
        ZX_DEBUG_ASSERT(next_vn != nullptr);
        next_vn->SetLastInode(vn->GetInode()->last_inode);
        next_vn->InodeSync(transaction->GetWork(), kMxFsSyncDefault);
    }
}

zx_status_t Minfs::PurgeUnlinked() {
    ino_t last_ino = 0;
    ino_t next_ino = Info().unlinked_head;
    ino_t unlinked_count = 0;

    // Loop through the unlinked list and free all allocated resources.
    while (next_ino != 0) {
        zx_status_t status;
        fbl::RefPtr<VnodeMinfs> vn;
        fbl::unique_ptr<Transaction> transaction;
        if ((status = BeginTransaction(0, 0, &transaction)) != ZX_OK) {
            return status;
        }
        if ((status = VnodeMinfs::Recreate(this, next_ino, &vn)) != ZX_OK) {
            return ZX_ERR_NO_MEMORY;
        }

        ZX_DEBUG_ASSERT(vn->GetInode()->last_inode == last_ino);
        ZX_DEBUG_ASSERT(vn->GetInode()->link_count == 0);

        if ((status = InoFree(transaction.get(), vn.get())) != ZX_OK) {
            return status;
        }

        last_ino = next_ino;
        next_ino = vn->GetInode()->next_inode;

        sb_->MutableInfo()->unlinked_head = next_ino;

        if (next_ino == 0) {
            ZX_DEBUG_ASSERT(Info().unlinked_tail == last_ino);
            sb_->MutableInfo()->unlinked_tail = 0;
        }

        sb_->Write(transaction->GetWork());
        status = CommitTransaction(std::move(transaction));
        if (status != ZX_OK) {
            return status;
        }

        unlinked_count++;
    }

    ZX_DEBUG_ASSERT(Info().unlinked_head == 0);
    ZX_DEBUG_ASSERT(Info().unlinked_tail == 0);

    if (unlinked_count > 0) {
        FS_TRACE_WARN("minfs: Found and purged %u unlinked vnode(s) on mount\n", unlinked_count);
    }

    return ZX_OK;
}

#ifdef __Fuchsia__
zx_status_t Minfs::CreateFsId(uint64_t* out) {
    zx::event event;
    zx_status_t status = zx::event::create(0, &event);
    if (status != ZX_OK) {
        return status;
    }
    zx_info_handle_basic_t info;
    status = event.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
    if (status != ZX_OK) {
        return status;
    }

    *out = info.koid;
    return ZX_OK;
}
#endif

fbl::RefPtr<VnodeMinfs> Minfs::VnodeLookupInternal(uint32_t ino) {
#ifdef __Fuchsia__
    fbl::RefPtr<VnodeMinfs> vn;
    {
        // Avoid releasing a reference to |vn| while holding |hash_lock_|.
        fbl::AutoLock lock(&hash_lock_);
        auto rawVn = vnode_hash_.find(ino);
        if (!rawVn.IsValid()) {
            // Nothing exists in the lookup table
            return nullptr;
        }
        vn = fbl::MakeRefPtrUpgradeFromRaw(rawVn.CopyPointer(), hash_lock_);
        if (vn == nullptr) {
            // The vn 'exists' in the map, but it is being deleted.
            // Remove it (by key) so the next person doesn't trip on it,
            // and so we can insert another node with the same key into the hash
            // map.
            // Notably, VnodeRelease erases the vnode by object, not key,
            // so it will not attempt to replace any distinct Vnodes that happen
            // to be re-using the same inode.
            vnode_hash_.erase(ino);
        }
    }
    return vn;
#else
    return fbl::WrapRefPtr(vnode_hash_.find(ino).CopyPointer());
#endif
}

void Minfs::InoNew(Transaction* transaction, const Inode* inode, ino_t* out_ino) {
    size_t allocated_ino = transaction->AllocateInode();
    *out_ino = static_cast<ino_t>(allocated_ino);
    // Write the inode back to storage.
    InodeUpdate(transaction->GetWork(), *out_ino, inode);
}

zx_status_t Minfs::VnodeNew(Transaction* transaction, fbl::RefPtr<VnodeMinfs>* out, uint32_t type) {
    TRACE_DURATION("minfs", "Minfs::VnodeNew");
    if ((type != kMinfsTypeFile) && (type != kMinfsTypeDir)) {
        return ZX_ERR_INVALID_ARGS;
    }

    fbl::RefPtr<VnodeMinfs> vn;

    // Allocate the in-memory vnode
    VnodeMinfs::Allocate(this, type, &vn);

    // Allocate the on-disk inode
    ino_t ino;
    InoNew(transaction, vn->GetInode(), &ino);
    vn->SetIno(ino);
    VnodeInsert(vn.get());
    *out = std::move(vn);
    return ZX_OK;
}

void Minfs::VnodeInsert(VnodeMinfs* vn) {
#ifdef __Fuchsia__
    fbl::AutoLock lock(&hash_lock_);
#endif

    ZX_DEBUG_ASSERT_MSG(!vnode_hash_.find(vn->GetKey()).IsValid(), "ino %u already in map\n",
                        vn->GetKey());
    vnode_hash_.insert(vn);
}

fbl::RefPtr<VnodeMinfs> Minfs::VnodeLookup(uint32_t ino) {
    fbl::RefPtr<VnodeMinfs> vn = VnodeLookupInternal(ino);
#ifdef __Fuchsia__
    if (vn != nullptr && vn->IsUnlinked()) {
        vn = nullptr;
    }
#endif
    return vn;
}

void Minfs::VnodeRelease(VnodeMinfs* vn) {
#ifdef __Fuchsia__
    fbl::AutoLock lock(&hash_lock_);
#endif
    vnode_hash_.erase(*vn);
}

zx_status_t Minfs::VnodeGet(fbl::RefPtr<VnodeMinfs>* out, ino_t ino) {
    TRACE_DURATION("minfs", "Minfs::VnodeGet", "ino", ino);
    if ((ino < 1) || (ino >= Info().inode_count)) {
        return ZX_ERR_OUT_OF_RANGE;
    }

    fs::Ticker ticker(StartTicker());

    fbl::RefPtr<VnodeMinfs> vn = VnodeLookup(ino);
    if (vn != nullptr) {
        *out = std::move(vn);
        UpdateOpenMetrics(/* cache_hit= */ true, ticker.End());
        return ZX_OK;
    }

    zx_status_t status;
    if ((status = VnodeMinfs::Recreate(this, ino, &vn)) != ZX_OK) {
        return ZX_ERR_NO_MEMORY;
    }

    if (vn->IsUnlinked()) {
        // If a vnode we have recreated from disk is unlinked, something has gone wrong during the
        // unlink process and our filesystem is now in an inconsistent state. In order to avoid
        // further inconsistencies, prohibit access to this vnode.
        FS_TRACE_WARN("minfs: Attempted to load unlinked vnode %u\n", ino);
        return ZX_ERR_BAD_STATE;
    }

    VnodeInsert(vn.get());
    *out = std::move(vn);
    UpdateOpenMetrics(/* cache_hit= */ false, ticker.End());
    return ZX_OK;
}

// Allocate a new data block from the block bitmap.
void Minfs::BlockNew(Transaction* transaction, blk_t* out_bno) {
    size_t allocated_bno = transaction->AllocateBlock();
    *out_bno = static_cast<blk_t>(allocated_bno);
    ValidateBno(*out_bno);
}

bool Minfs::IsReadonly() {
 #ifdef __Fuchsia__
    fbl::AutoLock lock(&vfs_lock_);
 #endif
    return ReadonlyLocked();
}

void Minfs::UpdateFlags(Transaction* transaction, uint32_t flags, bool set) {
     if (set) {
        sb_->MutableInfo()->flags |= flags;
     } else {
        sb_->MutableInfo()->flags &= (~flags);
     }
     sb_->Write(transaction->GetWork());
}

#ifdef __Fuchsia__
void Minfs::BlockSwap(Transaction* transaction, blk_t in_bno, blk_t* out_bno) {
    if (in_bno > 0) {
        ValidateBno(in_bno);
    }

    size_t allocated_bno = transaction->SwapBlock(in_bno);
    *out_bno = static_cast<blk_t>(allocated_bno);
    ValidateBno(*out_bno);
}
#endif

void Minfs::BlockFree(Transaction* transaction, blk_t bno) {
    ValidateBno(bno);
    block_allocator_->Free(transaction->GetWork(), bno);
}

void InitializeDirectory(void* bdata, ino_t ino_self, ino_t ino_parent) {
#define DE0_SIZE DirentSize(1)

    // directory entry for self
    Dirent* de = (Dirent*)bdata;
    de->ino = ino_self;
    de->reclen = DE0_SIZE;
    de->namelen = 1;
    de->type = kMinfsTypeDir;
    de->name[0] = '.';

    // directory entry for parent
    de = (Dirent*)((uintptr_t)bdata + DE0_SIZE);
    de->ino = ino_parent;
    de->reclen = DirentSize(2) | kMinfsReclenLast;
    de->namelen = 2;
    de->type = kMinfsTypeDir;
    de->name[0] = '.';
    de->name[1] = '.';
}

zx_status_t Minfs::Create(fbl::unique_ptr<Bcache> bc, const Superblock* info,
                          fbl::unique_ptr<Minfs>* out, IntegrityCheck checks) {
#ifndef __Fuchsia__
    if (bc->extent_lengths_.size() != 0 && bc->extent_lengths_.size() != kExtentCount) {
        FS_TRACE_ERROR("minfs: invalid number of extents\n");
        return ZX_ERR_INVALID_ARGS;
    }
#endif

    fbl::unique_ptr<SuperblockManager> sb;
    zx_status_t status;

    if ((status = SuperblockManager::Create(bc.get(), info, &sb, checks)) != ZX_OK) {
        FS_TRACE_ERROR("Minfs::Create failed to initialize superblock: %d\n", status);
        return status;
    }

#ifdef __Fuchsia__
    const blk_t abm_start_block = sb->Info().abm_block;
    const blk_t ibm_start_block = sb->Info().ibm_block;
    const blk_t ino_start_block = sb->Info().ino_block;
#else
    BlockOffsets offsets(*bc, *sb);
    const blk_t abm_start_block = offsets.AbmStartBlock();
    const blk_t ibm_start_block = offsets.IbmStartBlock();
    const blk_t ino_start_block = offsets.InoStartBlock();
#endif

    fs::ReadTxn transaction(bc.get());

    // Block Bitmap allocator initialization.
    AllocatorFvmMetadata block_allocator_fvm = AllocatorFvmMetadata(
        &sb->MutableInfo()->dat_slices, &sb->MutableInfo()->abm_slices, info->slice_size);
    AllocatorMetadata block_allocator_meta =
        AllocatorMetadata(info->dat_block, abm_start_block, (info->flags & kMinfsFlagFVM) != 0,
                          std::move(block_allocator_fvm), &sb->MutableInfo()->alloc_block_count,
                          &sb->MutableInfo()->block_count);

    fbl::unique_ptr<PersistentStorage> storage(
        new PersistentStorage(bc.get(), sb.get(), kMinfsBlockSize, nullptr,
                              std::move(block_allocator_meta)));

    fbl::unique_ptr<Allocator> block_allocator;
    if ((status = Allocator::Create(&transaction, std::move(storage), &block_allocator)) != ZX_OK) {
        FS_TRACE_ERROR("Minfs::Create failed to initialize block allocator: %d\n", status);
        return status;
    }

    // Inode Bitmap allocator initialization.
    AllocatorFvmMetadata inode_allocator_fvm = AllocatorFvmMetadata(
        &sb->MutableInfo()->ino_slices, &sb->MutableInfo()->ibm_slices, info->slice_size);
    AllocatorMetadata inode_allocator_meta =
        AllocatorMetadata(ino_start_block, ibm_start_block, (info->flags & kMinfsFlagFVM) != 0,
                          std::move(inode_allocator_fvm), &sb->MutableInfo()->alloc_inode_count,
                          &sb->MutableInfo()->inode_count);

    fbl::unique_ptr<InodeManager> inodes;
    if ((status = InodeManager::Create(bc.get(), sb.get(), &transaction,
                                       std::move(inode_allocator_meta),
                                       ino_start_block, info->inode_count, &inodes)) != ZX_OK) {
        FS_TRACE_ERROR("Minfs::Create failed to initialize inodes: %d\n", status);
        return status;
    }

    if ((status = transaction.Transact()) != ZX_OK) {
        FS_TRACE_ERROR("Minfs::Create failed to read initial blocks: %d\n", status);
        return status;
    }

#ifdef __Fuchsia__
    uint64_t id;
    status = Minfs::CreateFsId(&id);
    if (status != ZX_OK) {
        FS_TRACE_ERROR("minfs: failed to create fs_id:%d\n", status);
        return status;
    }

    *out =
        fbl::unique_ptr<Minfs>(new Minfs(std::move(bc), std::move(sb), std::move(block_allocator),
                                         std::move(inodes), id));
#else
    *out =
        fbl::unique_ptr<Minfs>(new Minfs(std::move(bc), std::move(sb), std::move(block_allocator),
                                         std::move(inodes), std::move(offsets)));
#endif

    return ZX_OK;
}

#ifdef __Fuchsia__
zx_status_t Minfs::InitializeWriteback() {
    // Use a heuristics-based approach based on physical RAM size to
    // determine the size of the writeback buffer.
    //
    // Currently, we set the writeback buffer size to 2% of physical
    // memory.
    static const size_t kWriteBufferSize =
        fbl::round_up((zx_system_get_physmem() * 2) / 100, kMinfsBlockSize);
    static const blk_t kWriteBufferBlocks = static_cast<blk_t>(kWriteBufferSize / kMinfsBlockSize);

    zx_status_t status;
    if ((status = WritebackQueue::Create(bc_.get(), kWriteBufferBlocks, &writeback_)) != ZX_OK) {
        return status;
    }

    if ((status = PurgeUnlinked()) != ZX_OK) {
        return status;
    }

    if ((status = WorkQueue::Create(this, &assigner_)) != ZX_OK) {
        return status;
    }

    return ZX_OK;
}
#endif

zx_status_t Mount(fbl::unique_ptr<minfs::Bcache> bc, const MountOptions& options,
                  fbl::RefPtr<VnodeMinfs>* root_out) {
    TRACE_DURATION("minfs", "minfs_mount");
    zx_status_t status;

    char blk[kMinfsBlockSize];
    if ((status = bc->Readblk(0, &blk)) != ZX_OK) {
        FS_TRACE_ERROR("minfs: could not read info block\n");
        return status;
    }
    const Superblock* info = reinterpret_cast<Superblock*>(blk);
#ifdef __Fuchsia__
    if ((info->flags & kMinfsFlagClean) == 0) {
        FS_TRACE_WARN("minfs: filesystem not unmounted cleanly. Integrity check required\n");
    }
#endif
    fbl::unique_ptr<Minfs> fs;
    if ((status = Minfs::Create(std::move(bc), info, &fs, IntegrityCheck::kAll)) != ZX_OK) {
        FS_TRACE_ERROR("minfs: mount failed\n");
        return status;
    }

#ifdef __Fuchsia__
    if (!options.readonly && (status = fs->InitializeWriteback()) != ZX_OK) {
        return status;
    }
#endif

    fbl::RefPtr<VnodeMinfs> vn;
    if ((status = fs->VnodeGet(&vn, kMinfsRootIno)) != ZX_OK) {
        FS_TRACE_ERROR("minfs: cannot find root inode\n");
        return status;
    }

    ZX_DEBUG_ASSERT(vn->IsDirectory());

#ifdef __Fuchsia__
    // Filesystem is safely mounted at this point. On a read-write filesystem, since we can now
    // serve writes on the filesystem, we need to unset the kMinfsFlagClean flag to indicate
    // that the filesystem may not be in a "clean" state anymore. This helps to make sure we are
    // unmounted cleanly i.e the kMinfsFlagClean flag is set back on clean unmount.
    if (options.readonly == false) {
        fbl::unique_ptr<Transaction> transaction;
        if ((status = fs->BeginTransaction(0, 0, &transaction)) == ZX_OK) {
            fs->UpdateFlags(transaction.get(), kMinfsFlagClean, false);
            status = fs->CommitTransaction(std::move(transaction));
        }
        if (status != ZX_OK) {
            FS_TRACE_WARN("minfs: failed to unset clean flag\n");
        }
     }
#endif
    __UNUSED auto r = fs.release();
    *root_out = std::move(vn);
    return ZX_OK;
}

#ifdef __Fuchsia__
zx_status_t MountAndServe(const MountOptions& options, async_dispatcher_t* dispatcher,
                          fbl::unique_ptr<Bcache> bc, zx::channel mount_channel,
                          fbl::Closure on_unmount) {
    TRACE_DURATION("minfs", "MountAndServe");

    fbl::RefPtr<VnodeMinfs> vn;
    zx_status_t status = Mount(std::move(bc), options, &vn);
    if (status != ZX_OK) {
        return status;
    }

    Minfs* vfs = vn->Vfs();
    vfs->SetReadonly(options.readonly);
    vfs->SetMetrics(options.metrics);
    vfs->SetUnmountCallback(std::move(on_unmount));
    vfs->SetDispatcher(dispatcher);
    return vfs->ServeDirectory(std::move(vn), std::move(mount_channel));
}

void Minfs::Shutdown(fs::Vfs::ShutdownCallback cb) {
    // On a read-write filesystem, set the kMinfsFlagClean on a clean unmount.
    if (IsReadonly() == false) {
        fbl::unique_ptr<Transaction> transaction;
        zx_status_t status;
        if ((status = BeginTransaction(0, 0, &transaction)) == ZX_OK) {
            UpdateFlags(transaction.get(), kMinfsFlagClean, true);
            status = CommitTransaction(std::move(transaction));
        }
        if (status != ZX_OK) {
            FS_TRACE_WARN("minfs: Failed to set clean flag on unmount.\n");
        }
    }
    ManagedVfs::Shutdown([this, cb = std::move(cb)](zx_status_t status) mutable {
        Sync([this, cb = std::move(cb)](zx_status_t) mutable {
            async::PostTask(dispatcher(), [this, cb = std::move(cb)]() mutable {
                // Ensure writeback buffer completes before auxilliary structures
                // are deleted.
                // The data block assigner must be resolved first, so it can enqueue any pending
                // transactions to the writeback buffer.
                assigner_ = nullptr;
                writeback_ = nullptr;
                bc_->Sync();

                auto on_unmount = std::move(on_unmount_);

                // Explicitly delete this (rather than just letting the memory release when
                // the process exits) to ensure that the block device's fifo has been
                // closed.
                delete this;

                // Identify to the unmounting channel that teardown is complete.
                cb(ZX_OK);

                // Identify to the unmounting thread that teardown is complete.
                if (on_unmount) {
                    on_unmount();
                }
            });
        });
    });
}
#endif

uint32_t BlocksRequiredForInode(uint64_t inode_count) {
    return safemath::checked_cast<uint32_t>((inode_count + kMinfsInodesPerBlock - 1) /
                                            kMinfsInodesPerBlock);
}

uint32_t BlocksRequiredForBits(uint64_t bit_count) {
    return safemath::checked_cast<uint32_t>((bit_count + kMinfsBlockBits - 1) / kMinfsBlockBits);
}

zx_status_t Mkfs(const MountOptions& options, fbl::unique_ptr<Bcache> bc) {
    Superblock info;
    memset(&info, 0x00, sizeof(info));
    info.magic0 = kMinfsMagic0;
    info.magic1 = kMinfsMagic1;
    info.version = kMinfsVersion;
    info.flags = kMinfsFlagClean;
    info.block_size = kMinfsBlockSize;
    info.inode_size = kMinfsInodeSize;

    uint32_t blocks = 0;
    uint32_t inodes = 0;

    zx_status_t status;
    auto fvm_cleanup =
        fbl::MakeAutoCall([bc = bc.get(), &info]() { minfs_free_slices(bc, &info); });
#ifdef __Fuchsia__
    fuchsia_hardware_block_volume_VolumeInfo fvm_info;
    if (bc->FVMQuery(&fvm_info) == ZX_OK) {
        info.slice_size = fvm_info.slice_size;
        SetMinfsFlagFvm(info);

        if (info.slice_size % kMinfsBlockSize) {
            FS_TRACE_ERROR("minfs mkfs: Slice size not multiple of minfs block\n");
            return -1;
        }

        const size_t kBlocksPerSlice = info.slice_size / kMinfsBlockSize;
        extend_request_t request;
        request.length = 1;
        request.offset = kFVMBlockInodeBmStart / kBlocksPerSlice;
        if ((status = bc->FVMReset()) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to reset FVM slices: %d\n", status);
            return status;
        }
        if ((status = bc->FVMExtend(&request)) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to allocate inode bitmap: %d\n", status);
            return status;
        }
        info.ibm_slices = 1;
        request.offset = kFVMBlockDataBmStart / kBlocksPerSlice;
        if ((status = bc->FVMExtend(&request)) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to allocate data bitmap: %d\n", status);
            return status;
        }
        info.abm_slices = 1;
        request.offset = kFVMBlockInodeStart / kBlocksPerSlice;
        if ((status = bc->FVMExtend(&request)) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to allocate inode table: %d\n", status);
            return status;
        }
        info.ino_slices = 1;

        TransactionLimits limits(info);
        blk_t journal_blocks = limits.GetRecommendedJournalBlocks();
        request.length = fbl::round_up(journal_blocks, kBlocksPerSlice) / kBlocksPerSlice;
        request.offset = kFVMBlockJournalStart / kBlocksPerSlice;
        if ((status = bc->FVMExtend(&request)) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to allocate journal blocks\n");
            return status;
        }
        info.journal_slices = static_cast<blk_t>(request.length);

        ZX_ASSERT(options.fvm_data_slices > 0);
        request.length = options.fvm_data_slices;
        request.offset = kFVMBlockDataStart / kBlocksPerSlice;
        if ((status = bc->FVMExtend(&request)) != ZX_OK) {
            FS_TRACE_ERROR("minfs mkfs: Failed to allocate data blocks\n");
            return status;
        }
        info.dat_slices = options.fvm_data_slices;

        inodes = static_cast<uint32_t>(info.ino_slices * info.slice_size / kMinfsInodeSize);
        blocks = static_cast<uint32_t>(info.dat_slices * info.slice_size / kMinfsBlockSize);
    }
#endif
    if ((info.flags & kMinfsFlagFVM) == 0) {
        inodes = kMinfsDefaultInodeCount;
        blocks = bc->Maxblk();
    }

    // determine how many blocks of inodes, allocation bitmaps,
    // and inode bitmaps there are
    uint32_t inoblks = (inodes + kMinfsInodesPerBlock - 1) / kMinfsInodesPerBlock;
    uint32_t ibmblks = (inodes + kMinfsBlockBits - 1) / kMinfsBlockBits;
    uint32_t abmblks = 0;

    info.inode_count = inodes;
    info.alloc_block_count = 0;
    info.alloc_inode_count = 0;

    if ((info.flags & kMinfsFlagFVM) == 0) {
        blk_t non_dat_blocks;
        blk_t journal_blocks = 0;

        info.ibm_block = 8;
        info.abm_block = info.ibm_block + fbl::round_up(ibmblks, 8u);

        for (uint32_t alloc_bitmap_rounded = 8; alloc_bitmap_rounded < blocks;
             alloc_bitmap_rounded += 8) {
            // Increment bitmap blocks by 8, since we will always round this value up to 8.
            ZX_ASSERT(alloc_bitmap_rounded % 8 == 0);

            info.ino_block = info.abm_block + alloc_bitmap_rounded;

            // Calculate the journal size based on other metadata structures.
            TransactionLimits limits(info);
            journal_blocks = limits.GetRecommendedJournalBlocks();

            non_dat_blocks = 8 + fbl::round_up(ibmblks, 8u) + alloc_bitmap_rounded + inoblks;

            // If the recommended journal count is too high, try using the minimum instead.
            if (non_dat_blocks + journal_blocks >= blocks) {
                journal_blocks = limits.GetMinimumJournalBlocks();
            }

            non_dat_blocks += journal_blocks;
            if (non_dat_blocks >= blocks) {
                FS_TRACE_ERROR("mkfs: Partition size (%" PRIu64 " bytes) is too small\n",
                        static_cast<uint64_t>(blocks) * kMinfsBlockSize);
                return ZX_ERR_INVALID_ARGS;
            }

            info.block_count = blocks - non_dat_blocks;
            // Calculate the exact number of bitmap blocks needed to track this many data blocks.
            abmblks = (info.block_count + kMinfsBlockBits - 1) / kMinfsBlockBits;

            if (alloc_bitmap_rounded >= abmblks) {
                // It is possible that the abmblks value will actually bring us back to the next
                // lowest tier of 8-rounded values. This means we may have 8 blocks allocated for
                // the block bitmap which will never actually be used. This is not ideal, but is
                // expected, and should only happen for very particular block counts.
                break;
            }
        }

        info.journal_start_block = info.ino_block + inoblks;
        info.dat_block = info.journal_start_block + journal_blocks;
    } else {
        info.block_count = blocks;
        abmblks = (info.block_count + kMinfsBlockBits - 1) / kMinfsBlockBits;
        info.ibm_block = kFVMBlockInodeBmStart;
        info.abm_block = kFVMBlockDataBmStart;
        info.ino_block = kFVMBlockInodeStart;
        info.journal_start_block = kFVMBlockJournalStart;
        info.dat_block = kFVMBlockDataStart;
    }

    DumpInfo(&info);

    RawBitmap abm;
    RawBitmap ibm;

    // By allocating the bitmap and then shrinking it, we keep the underlying
    // storage a block multiple but ensure we can't allocate beyond the last
    // real block or inode.
    if ((status = abm.Reset(fbl::round_up(info.block_count, kMinfsBlockBits))) != ZX_OK) {
        FS_TRACE_ERROR("mkfs: Failed to allocate block bitmap\n");
        return status;
    }
    if ((status = ibm.Reset(fbl::round_up(info.inode_count, kMinfsBlockBits))) != ZX_OK) {
        FS_TRACE_ERROR("mkfs: Failed to allocate inode bitmap\n");
        return status;
    }
    if ((status = abm.Shrink(info.block_count)) != ZX_OK) {
        FS_TRACE_ERROR("mkfs: Failed to shrink block bitmap\n");
        return status;
    }
    if ((status = ibm.Shrink(info.inode_count)) != ZX_OK) {
        FS_TRACE_ERROR("mkfs: Failed to shrink inode bitmap\n");
        return status;
    }

    // write rootdir
    uint8_t blk[kMinfsBlockSize];
    memset(blk, 0, sizeof(blk));
    InitializeDirectory(blk, kMinfsRootIno, kMinfsRootIno);
    if ((status = bc->Writeblk(info.dat_block + 1, blk)) != ZX_OK) {
        FS_TRACE_ERROR("mkfs: Failed to write root directory\n");
        return status;
    }

    // update inode bitmap
    ibm.Set(0, 1);
    ibm.Set(kMinfsRootIno, kMinfsRootIno + 1);
    info.alloc_inode_count += 2;

    // update block bitmap:
    // Reserve the 0th data block (as a 'null' value)
    // Reserve the 1st data block (for root directory)
    abm.Set(0, 2);
    info.alloc_block_count += 2;

    // write allocation bitmap
    for (uint32_t n = 0; n < abmblks; n++) {
        void* bmdata = fs::GetBlock(kMinfsBlockSize, abm.StorageUnsafe()->GetData(), n);
        memcpy(blk, bmdata, kMinfsBlockSize);
        if ((status = bc->Writeblk(info.abm_block + n, blk)) != ZX_OK) {
            return status;
        }
    }

    // write inode bitmap
    for (uint32_t n = 0; n < ibmblks; n++) {
        void* bmdata = fs::GetBlock(kMinfsBlockSize, ibm.StorageUnsafe()->GetData(), n);
        memcpy(blk, bmdata, kMinfsBlockSize);
        if ((status = bc->Writeblk(info.ibm_block + n, blk)) != ZX_OK) {
            return status;
        }
    }

    // write inodes
    memset(blk, 0, sizeof(blk));
    for (uint32_t n = 0; n < inoblks; n++) {
        if ((status = bc->Writeblk(info.ino_block + n, blk)) != ZX_OK) {
            return status;
        }
    }

    // setup root inode
    Inode* ino = reinterpret_cast<Inode*>(&blk[0]);
    ino[kMinfsRootIno].magic = kMinfsMagicDir;
    ino[kMinfsRootIno].size = kMinfsBlockSize;
    ino[kMinfsRootIno].block_count = 1;
    ino[kMinfsRootIno].link_count = 2;
    ino[kMinfsRootIno].dirent_count = 2;
    ino[kMinfsRootIno].dnum[0] = 1;
    ino[kMinfsRootIno].create_time = GetTimeUTC();
    bc->Writeblk(info.ino_block, blk);

    memset(blk, 0, sizeof(blk));
    memcpy(blk, &info, sizeof(info));
    bc->Writeblk(0, blk);

    // Write the journal info block to disk.
    memset(blk, 0, sizeof(blk));
    JournalInfo* journal_info = reinterpret_cast<JournalInfo*>(blk);
    journal_info->magic = kJournalMagic;
    bc->Writeblk(info.journal_start_block, blk);

    fvm_cleanup.cancel();
    return ZX_OK;
}

zx_status_t Minfs::ReadDat(blk_t bno, void* data) {
#ifdef __Fuchsia__
    return bc_->Readblk(Info().dat_block + bno, data);
#else
    return ReadBlk(bno, offsets_.DatStartBlock(), offsets_.DatBlockCount(), Info().block_count,
                   data);
#endif
}


zx_status_t Minfs::ReadBlock(blk_t start_block_num,  void* out_data) const {
    return bc_->Readblk(start_block_num, out_data);
}

#ifndef __Fuchsia__
zx_status_t Minfs::ReadBlk(blk_t bno, blk_t start, blk_t soft_max, blk_t hard_max, void* data) {
    if (bno >= hard_max) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    if (bno >= soft_max) {
        memset(data, 0, kMinfsBlockSize);
        return ZX_OK;
    }

    return bc_->Readblk(start + bno, data);
}

zx_status_t CreateBcacheFromFd(fbl::unique_fd fd, off_t start, off_t end,
                               const fbl::Vector<size_t>& extent_lengths,
                               fbl::unique_ptr<minfs::Bcache>* out) {
    if (start >= end) {
        fprintf(stderr, "error: Insufficient space allocated\n");
        return ZX_ERR_INVALID_ARGS;
    }

    if (extent_lengths.size() != kExtentCount) {
        FS_TRACE_ERROR("error: invalid number of extents\n");
        return ZX_ERR_INVALID_ARGS;
    }

    struct stat s;
    if (fstat(fd.get(), &s) < 0) {
        FS_TRACE_ERROR("error: minfs could not find end of file/device\n");
        return ZX_ERR_IO;
    }

    if (s.st_size < end) {
        FS_TRACE_ERROR("error: invalid file size\n");
        return ZX_ERR_INVALID_ARGS;
    }

    size_t size = (end - start) / minfs::kMinfsBlockSize;

    zx_status_t status;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = minfs::Bcache::Create(&bc, std::move(fd), static_cast<uint32_t>(size))) !=
        ZX_OK) {
        FS_TRACE_ERROR("error: cannot create block cache\n");
        return status;
    }

    if ((status = bc->SetSparse(start, extent_lengths)) != ZX_OK) {
        FS_TRACE_ERROR("Bcache is already sparse\n");
        return status;
    }

    *out = std::move(bc);
    return ZX_OK;
}

zx_status_t SparseFsck(fbl::unique_fd fd, off_t start, off_t end,
                       const fbl::Vector<size_t>& extent_lengths) {

    fbl::unique_ptr<minfs::Bcache> bc;
    zx_status_t status;
    if ((status = CreateBcacheFromFd(std::move(fd), start, end, extent_lengths, &bc)) != ZX_OK) {
        return status;
    }

    return Fsck(std::move(bc));
}

zx_status_t SparseUsedDataSize(fbl::unique_fd fd, off_t start, off_t end,
                               const fbl::Vector<size_t>& extent_lengths, uint64_t* out_size) {
    fbl::unique_ptr<minfs::Bcache> bc;
    zx_status_t status;

    if ((status = CreateBcacheFromFd(std::move(fd), start, end, extent_lengths, &bc)) != ZX_OK) {
        return status;
    }
    return UsedDataSize(bc, out_size);
}

zx_status_t SparseUsedInodes(fbl::unique_fd fd, off_t start, off_t end,
                             const fbl::Vector<size_t>& extent_lengths, uint64_t* out_inodes) {
    fbl::unique_ptr<minfs::Bcache> bc;
    zx_status_t status;
    if ((status = CreateBcacheFromFd(std::move(fd), start, end, extent_lengths, &bc)) != ZX_OK) {
        return status;
    }
    return UsedInodes(bc, out_inodes);
}

zx_status_t SparseUsedSize(fbl::unique_fd fd, off_t start, off_t end,
                           const fbl::Vector<size_t>& extent_lengths, uint64_t* out_size) {
    fbl::unique_ptr<minfs::Bcache> bc;
    zx_status_t status;

    if ((status = CreateBcacheFromFd(std::move(fd), start, end, extent_lengths, &bc)) != ZX_OK) {
        return status;
    }
    return UsedSize(bc, out_size);
}

#endif


#ifdef __Fuchsia__
fbl::Vector<BlockRegion> Minfs::GetAllocatedRegions() const {
    return block_allocator_->GetAllocatedRegions();
}
#endif

} // namespace minfs
