// 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.

// This file describes the in-memory structures which construct
// a MinFS filesystem.

#pragma once

#include <inttypes.h>

#ifdef __Fuchsia__
#include <fbl/auto_lock.h>
#include <fs/managed-vfs.h>
#include <fs/remote.h>
#include <fs/watcher.h>
#include <sync/completion.h>
#include <lib/zx/vmo.h>
#endif

#include <fbl/algorithm.h>
#include <fbl/function.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>

#include <fs/block-txn.h>
#include <fs/mapped-vmo.h>
#include <fs/ticker.h>
#include <fs/trace.h>
#include <fs/vfs.h>
#include <fs/vnode.h>

#include <zircon/misc/fnv1hash.h>

#include <minfs/format.h>
#include <minfs/writeback.h>

#include "allocator.h"
#include "inode-manager.h"
#include "superblock.h"

#ifdef __Fuchsia__
#include "metrics.h"
#endif

#define EXTENT_COUNT 5

// A compile-time debug check, which, if enabled, causes
// inline functions to be expanded to error checking code.
// Since this may be expensive, it is typically turned
// off, except for debugging.
// #define MINFS_PARANOID_MODE

namespace minfs {

#ifdef __Fuchsia__
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::VmoStorage>;
#else
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::DefaultStorage>;
#endif

#ifdef __Fuchsia__
// Validate that |vmo| is large enough to access block |blk|,
// relative to the start of the vmo.
inline void validate_vmo_size(zx_handle_t vmo, blk_t blk) {
#ifdef MINFS_PARANOID_MODE
    uint64_t size;
    size_t min = (blk + 1) * kMinfsBlockSize;
    ZX_ASSERT(zx_vmo_get_size(vmo, &size) == ZX_OK);
    ZX_ASSERT_MSG(size >= min, "VMO size %" PRIu64 " too small for access at block %u\n",
                  size, blk);
#endif // MINFS_PARANOID_MODE
}
#endif // __Fuchsia__

// minfs_sync_vnode flags
constexpr uint32_t kMxFsSyncDefault = 0; // default: no implicit time update
constexpr uint32_t kMxFsSyncMtime = (1 << 0);
constexpr uint32_t kMxFsSyncCtime = (1 << 1);

constexpr uint32_t kMinfsBlockCacheSize = 64;

// Used by fsck
class MinfsChecker;
class VnodeMinfs;

using SyncCallback = fs::Vnode::SyncCallback;

#ifndef __Fuchsia__
// Store start block + length for all extents. These may differ from info block for
// sparse files.
class BlockOffsets {
public:
    BlockOffsets(const Bcache* bc, const Superblock* sb);

    blk_t IbmStartBlock() const { return ibm_start_block_; }
    blk_t IbmBlockCount() const { return ibm_block_count_; }

    blk_t AbmStartBlock() const { return abm_start_block_; }
    blk_t AbmBlockCount() const { return abm_block_count_; }

    blk_t InoStartBlock() const { return ino_start_block_; }
    blk_t InoBlockCount() const { return ino_block_count_; }

    blk_t DatStartBlock() const { return dat_start_block_; }
    blk_t DatBlockCount() const { return dat_block_count_; }

private:
    blk_t ibm_start_block_;
    blk_t ibm_block_count_;

    blk_t abm_start_block_;
    blk_t abm_block_count_;

    blk_t ino_start_block_;
    blk_t ino_block_count_;

    blk_t dat_start_block_;
    blk_t dat_block_count_;
};
#endif

class Minfs :
#ifdef __Fuchsia__
    public fs::ManagedVfs,
#else
    public fs::Vfs,
#endif
    public fbl::RefCounted<Minfs> {
public:
    DISALLOW_COPY_ASSIGN_AND_MOVE(Minfs);

    ~Minfs();

    static zx_status_t Create(fbl::unique_ptr<Bcache> bc, const minfs_info_t* info,
                              fbl::unique_ptr<Minfs>* out);

    // instantiate a vnode from an inode
    // the inode must exist in the file system
    zx_status_t VnodeGet(fbl::RefPtr<VnodeMinfs>* out, ino_t ino);

    // instantiate a vnode with a new inode
    zx_status_t VnodeNew(WritebackWork* wb, fbl::RefPtr<VnodeMinfs>* out, uint32_t type);

    // Insert, lookup, and remove vnode from hash map.
    void VnodeInsert(VnodeMinfs* vn) __TA_EXCLUDES(hash_lock_);
    fbl::RefPtr<VnodeMinfs> VnodeLookup(uint32_t ino) __TA_EXCLUDES(hash_lock_);
    void VnodeRelease(VnodeMinfs* vn) __TA_EXCLUDES(hash_lock_);

    // Allocate a new data block.
    zx_status_t BlockNew(WriteTxn* txn, blk_t* out_bno);

    // Free a data block.
    void BlockFree(WriteTxn* txn, blk_t bno);

    // Free ino in inode bitmap, release all blocks held by inode.
    zx_status_t InoFree(VnodeMinfs* vn, WritebackWork* wb);

    // Writes back an inode into the inode table on persistent storage.
    // Does not modify inode bitmap.
    void InodeUpdate(WriteTxn* txn, ino_t ino, const minfs_inode_t* inode) {
        inodes_->Update(txn, ino, inode);
    }

    // Reads an inode from the inode table into memory.
    void InodeLoad(ino_t ino, minfs_inode_t* out) const {
        inodes_->Load(ino, out);
    }

    void ValidateBno(blk_t bno) const {
        ZX_DEBUG_ASSERT(bno != 0);
        ZX_DEBUG_ASSERT(bno < Info().block_count);
    }

    zx_status_t CreateWork(fbl::unique_ptr<WritebackWork>* out);

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

#ifdef __Fuchsia__
    void SetUnmountCallback(fbl::Closure closure) { on_unmount_ = fbl::move(closure); }
    void Shutdown(fs::Vfs::ShutdownCallback cb) final;

    // Returns a unique identifier for this instance.
    uint64_t GetFsId() const { return fs_id_; }

    // Signals the completion object as soon as...
    // (1) A sync probe has entered and exited the writeback queue, and
    // (2) The block cache has sync'd with the underlying block device.
    void Sync(SyncCallback closure);
#endif

    // The following methods are used to read one block from the specified extent,
    // from relative block |bno|.
    // |data| is an out parameter that must be a block in size, provided by the caller
    // These functions are single-block and synchronous. On Fuchsia, using the batched read
    // functions is preferred.
    zx_status_t ReadDat(blk_t bno, void* data);

    void SetMetrics(bool enable) { collecting_metrics_ = enable; }
    fs::Ticker StartTicker() { return fs::Ticker(collecting_metrics_); }

    // Update aggregate information about VMO initialization.
    void UpdateInitMetrics(uint32_t dnum_count, uint32_t inum_count,
                           uint32_t dinum_count, uint64_t user_data_size,
                           const fs::Duration& duration);
    // Update aggregate information about looking up vnodes by name.
    void UpdateLookupMetrics(bool success, const fs::Duration& duration);
    // Update aggregate information about looking up vnodes by inode.
    void UpdateOpenMetrics(bool cache_hit, const fs::Duration& duration);
    // Update aggregate information about inode creation.
    void UpdateCreateMetrics(bool success, const fs::Duration& duration);
    // Update aggregate information about reading from Vnodes.
    void UpdateReadMetrics(uint64_t size, const fs::Duration& duration);
    // Update aggregate information about writing to Vnodes.
    void UpdateWriteMetrics(uint64_t size, const fs::Duration& duration);
    // Update aggregate information about truncating Vnodes.
    void UpdateTruncateMetrics(const fs::Duration& duration);
    // Update aggregate information about unlinking Vnodes.
    void UpdateUnlinkMetrics(bool success, const fs::Duration& duration);
    // Update aggregate information about renaming Vnodes.
    void UpdateRenameMetrics(bool success, const fs::Duration& duration);
    // Print information about filesystem metrics.
    void DumpMetrics() const;

    // Return an immutable reference to a copy of the internal info.
    const minfs_info_t& Info() const {
        return sb_->Info();
    }

    // TODO(rvargas): Make private.
    fbl::unique_ptr<Bcache> bc_;

private:
    // Fsck can introspect Minfs
    friend class MinfsChecker;
    using HashTable = fbl::HashTable<ino_t, VnodeMinfs*>;

#ifdef __Fuchsia__
    Minfs(fbl::unique_ptr<Bcache> bc, fbl::unique_ptr<Superblock> sb,
          fbl::unique_ptr<Allocator> block_allocator,
          fbl::unique_ptr<InodeManager> inodes,
          fbl::unique_ptr<WritebackBuffer> writeback,
          uint64_t fs_id);
#else
    Minfs(fbl::unique_ptr<Bcache> bc, fbl::unique_ptr<Superblock> sb,
          fbl::unique_ptr<Allocator> block_allocator,
          fbl::unique_ptr<InodeManager> inodes, BlockOffsets offsets);
#endif

    // Find a free inode, allocate it in the inode bitmap, and write it back to disk
    zx_status_t InoNew(WriteTxn* txn, const minfs_inode_t* inode, ino_t* out_ino);

    // Enqueues an update to the super block.
    void WriteInfo(WriteTxn* txn);

    // Creates an unique identifier for this instance. This is to be called only during
    // "construction".
    static zx_status_t CreateFsId(uint64_t* out);

#ifndef __Fuchsia__
    zx_status_t ReadBlk(blk_t bno, blk_t start, blk_t soft_max, blk_t hard_max, void* data);
#endif

    // Global information about the filesystem.
    fbl::unique_ptr<Superblock> sb_;
    fbl::unique_ptr<Allocator> block_allocator_;
    fbl::unique_ptr<InodeManager> inodes_;

    // Vnodes exist in the hash table as long as one or more reference exists;
    // when the Vnode is deleted, it is immediately removed from the map.
#ifdef __Fuchsia__
    fbl::Mutex hash_lock_;
#endif
    HashTable vnode_hash_ __TA_GUARDED(hash_lock_){};

    bool collecting_metrics_ = false;
#ifdef __Fuchsia__
    fbl::Closure on_unmount_{};
    MinfsMetrics metrics_ = {};
    fbl::unique_ptr<WritebackBuffer> writeback_;
    uint64_t fs_id_{};
#else
    // Store start block + length for all extents. These may differ from info block for
    // sparse files.
    BlockOffsets offsets_;
#endif
};

struct DirArgs {
    fbl::StringPiece name;
    ino_t ino;
    uint32_t type;
    uint32_t reclen;
    WritebackWork* wb;
};

struct DirectoryOffset {
    size_t off;      // Offset in directory of current record
    size_t off_prev; // Offset in directory of previous record
};

class VnodeMinfs final : public fs::Vnode,
                         public fbl::SinglyLinkedListable<VnodeMinfs*>,
                         public fbl::Recyclable<VnodeMinfs> {
public:
    ~VnodeMinfs();

    // Allocates a new Vnode and initializes the in-memory inode structure given the type, where
    // type is one of:
    // - kMinfsTypeFile
    // - kMinfsTypeDir
    //
    // Sets create / modify times of the new node.
    // Does not allocate an inode number for the Vnode.
    static zx_status_t Allocate(Minfs* fs, uint32_t type, fbl::RefPtr<VnodeMinfs>* out);

    // Allocates a Vnode, loading |ino| from storage.
    //
    // Doesn't update create / modify times of the node.
    static zx_status_t Recreate(Minfs* fs, ino_t ino, fbl::RefPtr<VnodeMinfs>* out);

    bool IsDirectory() const { return inode_.magic == kMinfsMagicDir; }
    bool IsUnlinked() const { return inode_.link_count == 0; }
    zx_status_t CanUnlink() const;

    const minfs_inode_t* GetInode() const { return &inode_; }

    ino_t GetKey() const { return ino_; }
    // Should only be called once for the VnodeMinfs lifecycle.
    void SetIno(ino_t ino);
    static size_t GetHash(ino_t key) { return fnv1a_tiny(key, kMinfsHashBits); }

    // fs::Vnode interface (invoked publicly).
    zx_status_t Open(uint32_t flags, fbl::RefPtr<Vnode>* out_redirect) final;
    zx_status_t Close() final;

    // fbl::Recyclable interface.
    void fbl_recycle() final;

    // TODO(rvargas): Make private.
    Minfs* const fs_;

private:
    // Fsck can introspect Minfs
    friend class MinfsChecker;
    friend zx_status_t Minfs::InoFree(VnodeMinfs* vn, WritebackWork* wb);

    VnodeMinfs(Minfs* fs);

    // fs::Vnode interface.
    zx_status_t ValidateFlags(uint32_t flags) final;
    zx_status_t Lookup(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) final;
    zx_status_t Read(void* data, size_t len, size_t off, size_t* out_actual) final;
    zx_status_t Write(const void* data, size_t len, size_t offset,
                      size_t* out_actual) final;
    zx_status_t Append(const void* data, size_t len, size_t* out_end,
                       size_t* out_actual) final;
    zx_status_t Getattr(vnattr_t* a) final;
    zx_status_t Setattr(const vnattr_t* a) final;
    zx_status_t Readdir(fs::vdircookie_t* cookie, void* dirents, size_t len,
                        size_t* out_actual) final;
    zx_status_t Create(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name,
                       uint32_t mode) final;
    zx_status_t Unlink(fbl::StringPiece name, bool must_be_dir) final;
    zx_status_t Rename(fbl::RefPtr<fs::Vnode> newdir,
                       fbl::StringPiece oldname, fbl::StringPiece newname,
                       bool src_must_be_dir, bool dst_must_be_dir) final;
    zx_status_t Link(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> target) final;
    zx_status_t Truncate(size_t len) final;
    zx_status_t Ioctl(uint32_t op, const void* in_buf, size_t in_len, void* out_buf,
                      size_t out_len, size_t* out_actual) final;

    // Internal functions
    zx_status_t ReadInternal(void* data, size_t len, size_t off, size_t* actual);
    zx_status_t ReadExactInternal(void* data, size_t len, size_t off);
    zx_status_t WriteInternal(WritebackWork* wb, const void* data, size_t len,
                              size_t off, size_t* actual);
    zx_status_t WriteExactInternal(WritebackWork* wb, const void* data, size_t len,
                                   size_t off);
    zx_status_t TruncateInternal(WritebackWork* wb, size_t len);
    // Lookup which can traverse '..'
    zx_status_t LookupInternal(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name);

    // Verify that the 'newdir' inode is not a subdirectory of this Vnode.
    // Traces the path from newdir back to the root inode.
    zx_status_t CheckNotSubdirectory(fbl::RefPtr<VnodeMinfs> newdir);

    using DirentCallback = zx_status_t (*)(fbl::RefPtr<VnodeMinfs>,
                                           minfs_dirent_t*, DirArgs*,
                                           DirectoryOffset*);

    // Enumerates directories.
    zx_status_t ForEachDirent(DirArgs* args, const DirentCallback func);

    // Directory callback functions.
    //
    // The following functions are passable to |ForEachDirent|, which reads the parent directory,
    // one dirent at a time, and passes each entry to the callback function, along with the DirArgs
    // information passed to the initial call of |ForEachDirent|.
    static zx_status_t DirentCallbackFind(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*, DirArgs*,
                                          DirectoryOffset*);
    static zx_status_t DirentCallbackUnlink(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*, DirArgs*,
                                            DirectoryOffset*);
    static zx_status_t DirentCallbackForceUnlink(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*, DirArgs*,
                                                 DirectoryOffset*);
    static zx_status_t DirentCallbackAttemptRename(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*,
                                                   DirArgs*, DirectoryOffset*);
    static zx_status_t DirentCallbackUpdateInode(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*, DirArgs*,
                                                 DirectoryOffset*);
    static zx_status_t DirentCallbackAppend(fbl::RefPtr<VnodeMinfs>, minfs_dirent_t*, DirArgs*,
                                            DirectoryOffset*);

    zx_status_t UnlinkChild(WritebackWork* wb, fbl::RefPtr<VnodeMinfs> child,
                            minfs_dirent_t* de, DirectoryOffset* offs);
    // Remove the link to a vnode (referring to inodes exclusively).
    // Has no impact on direntries (or parent inode).
    void RemoveInodeLink(WritebackWork* wb);

    // Although file sizes don't need to be block-aligned, the underlying VMO is
    // always kept at a size which is a multiple of |kMinfsBlockSize|.
    //
    // When a Vnode is truncated to a size larger than |inode_.size|, it is
    // assumed that any space between |inode_.size| and the nearest block is
    // filled with zeroes in the internal VMO. This function validates that
    // assumption.
    inline void ValidateVmoTail() const {
#if defined(MINFS_PARANOID_MODE) && defined(__Fuchsia__)
        if (!vmo_.is_valid()) {
            return;
        }

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

    typedef enum {
        READ,
        WRITE,
        DELETE,
    } blk_op_t;

    typedef struct bop_params {
        bop_params(blk_t start, blk_t count, blk_t* bnos)
            : start(start), count(count), bnos(bnos) {
                // Initialize output array to 0 in case the indirect block(s) containing these bnos
                // do not exist
                if (bnos) {
                    memset(bnos, 0, sizeof(blk_t) * count);
                }
            }

        blk_t start;
        blk_t count;
        blk_t* bnos;
    } bop_params_t;

    class DirectArgs {
    public:
        DirectArgs(blk_op_t op, blk_t* array, blk_t count, blk_t* bnos)
            : op_(op), array_(array), count_(count), bnos_(bnos), dirty_(false) {}

        blk_op_t GetOp() const { return op_; }
        blk_t GetBno(blk_t index) const { return array_[index]; }
        void SetBno(blk_t index, blk_t value) {
            ZX_DEBUG_ASSERT(index < GetCount());

            if (bnos_ != nullptr) {
                bnos_[index] = value ? value : array_[index];
            }

            if (array_[index] != value) {
                array_[index] = value;
                dirty_ = true;
            }
        }

        blk_t GetCount() const { return count_; }

        bool IsDirty() const { return dirty_; }
    protected:
        const blk_op_t op_; // determines what operation to perform on blocks
        blk_t* const array_; // array containing blocks to be operated on
        const blk_t count_; // number of direct blocks to operate on
        blk_t* const bnos_; // array of |count| bnos returned to the user
        bool dirty_; // true if blocks have successfully been op'd
    };

    class IndirectArgs : public DirectArgs {
    public:
        IndirectArgs(blk_op_t op, blk_t* array, blk_t count, blk_t* bnos, blk_t bindex,
                     blk_t ib_vmo_offset)
            : DirectArgs(op, array, count, bnos), bindex_(bindex), ib_vmo_offset_(ib_vmo_offset) {}

        void SetDirty() { dirty_ = true; }

        void SetBno(blk_t index, blk_t value) {
            ZX_DEBUG_ASSERT(index < GetCount());
            array_[index] = value;
            SetDirty();
        }

        // Number of indirect blocks we need to iterate through to touch all |count| direct blocks.
        blk_t GetCount() const {
            return (bindex_ + count_ + kMinfsDirectPerIndirect - 1) / kMinfsDirectPerIndirect;
        }

        blk_t GetOffset() const { return ib_vmo_offset_; }

        // Generate parameters for direct blocks in indirect block |ibindex|, which are contained
        // in |barray|
        DirectArgs GetDirect(blk_t* barray, unsigned ibindex) const;

    protected:
        const blk_t bindex_; // relative index of the first direct block within the first indirect
                            // block
        const blk_t ib_vmo_offset_; // index of the first indirect block
    };

    class DindirectArgs : public IndirectArgs {
    public:
        DindirectArgs(blk_op_t op, blk_t* array, blk_t count, blk_t* bnos, blk_t bindex,
                      blk_t ib_vmo_offset, blk_t ibindex, blk_t dib_vmo_offset)
            : IndirectArgs(op, array, count, bnos, bindex, ib_vmo_offset),
              ibindex_(ibindex), dib_vmo_offset_(dib_vmo_offset) {}

        // Number of doubly indirect blocks we need to iterate through to touch all |count| direct
        // blocks.
        blk_t GetCount() const {
            return (ibindex_ + count_ + kMinfsDirectPerDindirect - 1) / kMinfsDirectPerDindirect;
        }

        blk_t GetOffset() const { return dib_vmo_offset_; }

        // Generate parameters for indirect blocks in doubly indirect block |dibindex|, which are
        // contained in |iarray|
        IndirectArgs GetIndirect(blk_t* iarray, unsigned dibindex) const;

    protected:
        const blk_t ibindex_; // relative index of the first indirect block within the first
                             // doubly indirect block
        const blk_t dib_vmo_offset_; // index of the first doubly indirect block
    };

    // Allocate an indirect or doubly indirect block at |offset| within the indirect vmo and clear
    // the in-memory block array
    // Assumes that vmo_indirect_ has already been initialized
    zx_status_t AllocateIndirect(WritebackWork* wb, blk_t index, IndirectArgs* args);

    // Perform operation |op| on blocks as specified by |params|
    // The BlockOp methods should not be called directly
    // All BlockOp methods assume that vmo_indirect_ has been grown to the required size
    zx_status_t BlockOp(WritebackWork* wb, blk_op_t op, bop_params_t* params);
    zx_status_t BlockOpDirect(WritebackWork* wb, DirectArgs* params);
    zx_status_t BlockOpIndirect(WritebackWork* wb, IndirectArgs* params);
    zx_status_t BlockOpDindirect(WritebackWork* wb, DindirectArgs* params);

    // Get the disk block 'bno' corresponding to the 'n' block
    // If 'txn' is non-null, new blocks are allocated for all un-allocated bnos.
    // This can be extended to retrieve multiple contiguous blocks in one call
    zx_status_t BlockGet(WritebackWork* wb, blk_t n, blk_t* bno);
    // Deletes all blocks (relative to a file) from "start" (inclusive) to the end
    // of the file. Does not update mtime/atime.
    // This can be extended to return indices of deleted bnos, or to delete a specific number of
    // bnos
    zx_status_t BlocksShrink(WritebackWork* wb, blk_t start);

    // Update the vnode's inode and write it to disk.
    void InodeSync(WritebackWork* wb, uint32_t flags);

    // Deletes this Vnode from disk, freeing the inode and blocks.
    //
    // Must only be called on Vnodes which
    // - Have no open fds
    // - Are fully unlinked (link count == 0)
    void Purge(WritebackWork* wb);

#ifdef __Fuchsia__
    zx_status_t GetHandles(uint32_t flags, zx_handle_t* hnd, uint32_t* type,
                           zxrio_object_info_t* extra) final;
    void Sync(SyncCallback closure) final;
    zx_status_t AttachRemote(fs::MountChannel h) final;
    zx_status_t InitVmo();
    zx_status_t InitIndirectVmo();

    // Loads indirect blocks up to and including the doubly indirect block at |index|.
    zx_status_t LoadIndirectWithinDoublyIndirect(uint32_t index);

    // Initializes the indirect VMO, grows it to |size| bytes, and reads |count| indirect
    // blocks from |iarray| into the indirect VMO, starting at block offset |offset|.
    zx_status_t LoadIndirectBlocks(blk_t* iarray, uint32_t count, uint32_t offset,
                                   uint64_t size);

    // Reads the block at |offset| in memory.
    // Assumes that vmo_indirect_ has already been initialized
    void ReadIndirectVmoBlock(uint32_t offset, uint32_t** entry);

    // Clears the block at |offset| in memory.
    // Assumes that vmo_indirect_ has already been initialized
    void ClearIndirectVmoBlock(uint32_t offset);

    // Use the watcher container to implement a directory watcher
    void Notify(fbl::StringPiece name, unsigned event) final;
    zx_status_t WatchDir(fs::Vfs* vfs, const vfs_watch_dir_t* cmd) final;

    // The vnode is acting as a mount point for a remote filesystem or device.
    bool IsRemote() const final;
    zx::channel DetachRemote() final;
    zx_handle_t GetRemote() const final;
    void SetRemote(zx::channel remote) final;
#else  // !__Fuchsia__
    // Reads the block at |bno| on disk.
    void ReadIndirectBlock(blk_t bno, uint32_t* entry);

    // Clears the block at |bno| on disk.
    void ClearIndirectBlock(blk_t bno);
#endif

#ifdef __Fuchsia__
    // TODO(smklein): When we have can register MinFS as a pager service, and
    // it can properly handle pages faults on a vnode's contents, then we can
    // avoid reading the entire file up-front. Until then, read the contents of
    // a VMO into memory when it is read/written.
    zx::vmo vmo_{};

    // vmo_indirect_ contains all indirect and doubly indirect blocks in the following order:
    // First kMinfsIndirect blocks                                - initial set of indirect blocks
    // Next kMinfsDoublyIndirect blocks                           - doubly indirect blocks
    // Next kMinfsDoublyIndirect * kMinfsDirectPerIndirect blocks - indirect blocks pointed to
    //                                                              by doubly indirect blocks
    fbl::unique_ptr<fs::MappedVmo> vmo_indirect_{};

    vmoid_t vmoid_{};
    vmoid_t vmoid_indirect_{};

    fs::RemoteContainer remoter_{};
    fs::WatcherContainer watcher_{};
#endif

    ino_t ino_{};
    minfs_inode_t inode_{};

    // This field tracks the current number of file descriptors with
    // an open reference to this Vnode. Notably, this is distinct from the
    // VnodeMinfs's own refcount, since there may still be filesystem
    // work to do after the last file descriptor has been closed.
    uint32_t fd_count_{};
};

// Return the block offset in vmo_indirect_ of indirect blocks pointed to by the doubly indirect
// block at dindex
constexpr uint32_t GetVmoOffsetForIndirect(uint32_t dibindex) {
    return kMinfsIndirect + kMinfsDoublyIndirect + (dibindex * kMinfsDirectPerIndirect);
}

// Return the required vmo size (in bytes) to store indirect blocks pointed to by doubly indirect
// block dibindex
constexpr size_t GetVmoSizeForIndirect(uint32_t dibindex) {
    return GetVmoOffsetForIndirect(dibindex + 1) * kMinfsBlockSize;
}

// Return the block offset of doubly indirect blocks in vmo_indirect_
constexpr uint32_t GetVmoOffsetForDoublyIndirect(uint32_t dibindex) {
    ZX_DEBUG_ASSERT(dibindex < kMinfsDoublyIndirect);
    return kMinfsIndirect + dibindex;
}

// Return the required vmo size (in bytes) to store doubly indirect blocks in vmo_indirect_
constexpr size_t GetVmoSizeForDoublyIndirect() {
    return (kMinfsIndirect + kMinfsDoublyIndirect) * kMinfsBlockSize;
}

// write the inode data of this vnode to disk (default does not update time values)
void minfs_sync_vnode(fbl::RefPtr<VnodeMinfs> vn, uint32_t flags);
void minfs_dump_info(const minfs_info_t* info);
void minfs_dump_inode(const minfs_inode_t* inode, ino_t ino);
void minfs_dir_init(void* bdata, ino_t ino_self, ino_t ino_parent);

// Given an input bcache, initialize the filesystem and return a reference to the
// root node.
zx_status_t minfs_mount(fbl::unique_ptr<minfs::Bcache> bc, fbl::RefPtr<VnodeMinfs>* root_out);

} // namespace minfs
