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

#pragma once

#include <utility>

#include <inttypes.h>

#ifdef __Fuchsia__
#include <fbl/auto_lock.h>
#include <fs/remote.h>
#include <fs/watcher.h>
#include <fuchsia/io/c/fidl.h>
#include <fuchsia/minfs/c/fidl.h>
#include <lib/fzl/resizeable-vmo-mapper.h>
#include <lib/zx/vmo.h>
#include <minfs/writeback-async.h>

#include "vnode-allocation.h"
#endif

#include <fbl/algorithm.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>
#include <fs/block-txn.h>
#include <fs/locking.h>
#include <fs/ticker.h>
#include <fs/trace.h>
#include <fs/vfs.h>
#include <fs/vnode.h>
#include <lib/zircon-internal/fnv1hash.h>
#include <minfs/format.h>
#include <minfs/minfs.h>
#include <minfs/transaction-limits.h>
#include <minfs/writeback.h>

namespace minfs {

// Used by fsck
class MinfsChecker;
class Minfs;

// An abstract Vnode class contains the following:
//
// - A VMO, holding the in-memory representation of data stored persistently.
// - An inode, holding the root of this node's metadata.
//
// This class is capable of writing, reading, and truncating the node's data
// in a linear block-address space.
class VnodeMinfs : public fs::Vnode,
                   public fbl::SinglyLinkedListable<VnodeMinfs*>,
                   public fbl::Recyclable<VnodeMinfs> {
public:
    virtual ~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 void 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 IsUnlinked() const { return inode_.link_count == 0; }

    const Inode* GetInode() const { return &inode_; }
    ino_t GetIno() const { return ino_; }

    ino_t GetKey() const { return ino_; }
    // Should only be called once for the VnodeMinfs lifecycle.
    void SetIno(ino_t ino);

    void SetNextInode(ino_t ino) {
        inode_.next_inode = ino;
    }
    void SetLastInode(ino_t ino) {
        inode_.last_inode = ino;
    }

    void AddLink() {
        inode_.link_count++;
    }

    static size_t GetHash(ino_t key) { return fnv1a_tiny(key, kMinfsHashBits); }

    // fs::Vnode interface (invoked publicly).
#ifdef __Fuchsia__
    zx_status_t Serve(fs::Vfs* vfs, zx::channel channel, uint32_t flags) final;
#endif
    zx_status_t Open(uint32_t flags, fbl::RefPtr<Vnode>* out_redirect) final;
    zx_status_t Close() final;

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

    // Queries the underlying vnode to ask if it may be unlinked.
    //
    // If the response is not ZX_OK, operations to unlink (or rename on top of) this
    // vnode will fail.
    virtual zx_status_t CanUnlink() const = 0;

    // Returns the current block count of the vnode.
    virtual blk_t GetBlockCount() const = 0;

    // Returns the total size of the vnode.
    virtual uint64_t GetSize() const = 0;

    // Sets the new size of the vnode.
    // Should update the in-memory representation of the Vnode, but not necessarily
    // write it out to persistent storage.
    //
    // TODO: Upgrade internal size to 64-bit integer.
    virtual void SetSize(uint32_t new_size) = 0;

    // Accesses a block in the vnode at |vmo_offset| relative to the start of the file,
    // which was previously at the device offset |dev_offset|.
    //
    // If the block was not previously allocated, |dev_offset| is zero.
    // |*out_dev_offset| must contain the new value of the device offset to use when writing
    // to this part of the Vnode. By default, it is set to |dev_offset|.
    //
    // |*out_dev_offset| may be passed to |IssueWriteback| as |dev_offset|.
    virtual void AcquireWritableBlock(Transaction* transaction, blk_t vmo_offset,
                                      blk_t dev_offset, blk_t* out_dev_offset) = 0;

    // Deletes the block at |vmo_offset| within the file, corresponding to on-disk
    // block |dev_offset| (zero if unallocated).
    virtual void DeleteBlock(Transaction* transaction, blk_t vmo_offset, blk_t dev_offset) = 0;

#ifdef __Fuchsia__
    // Instructs the Vnode to write out |count| blocks of the vnode, starting at local
    // offset |vmo_offset|, corresponding to on-disk offset |dev_offset|.
    virtual void IssueWriteback(Transaction* transaction, blk_t vmo_offset, blk_t dev_offset,
                                blk_t count) = 0;

    // Queries the node, returning |true| if the node has an in-flight operation on |vmo_offset|
    // that has not yet been enqueued to the writeback pipeline.
    virtual bool HasPendingAllocation(blk_t vmo_offset) = 0;

    // Instructs the node to cancel all pending writeback operations that have not yet been
    // enqueued to the writeback pipeline.
    //
    // This method is used exclusively when deleting nodes.
    virtual void CancelPendingWriteback() = 0;

    // Minfs FIDL interface.
    zx_status_t GetMetrics(fidl_txn_t* transaction);
    zx_status_t ToggleMetrics(bool enabled, fidl_txn_t* transaction);
    zx_status_t GetAllocatedRegions(fidl_txn_t* transaction) const;

#endif
    Minfs* Vfs() { return fs_; }

    // Local implementations of read, write, and truncate functions which
    // may operate on either files or directories.
    zx_status_t ReadInternal(Transaction* transaction, void* data, size_t len, size_t off,
                             size_t* actual);
    zx_status_t ReadExactInternal(Transaction* transaction, void* data, size_t len, size_t off);
    zx_status_t WriteInternal(Transaction* transaction, const void* data, size_t len,
                              size_t off, size_t* actual);
    zx_status_t WriteExactInternal(Transaction* transaction, const void* data, size_t len,
                                   size_t off);
    zx_status_t TruncateInternal(Transaction* transaction, size_t len);

    // TODO: The following methods should be made private:
#ifdef __Fuchsia__
    zx_status_t InitIndirectVmo();
    // Reads the block at |offset| in memory.
    // Assumes that vmo_indirect_ has already been initialized
    void ReadIndirectVmoBlock(uint32_t offset, uint32_t** entry);
    // Loads indirect blocks up to and including the doubly indirect block at |index|.
    zx_status_t LoadIndirectWithinDoublyIndirect(uint32_t index);
#else
    // Reads the block at |bno| on disk.
    void ReadIndirectBlock(blk_t bno, uint32_t* entry);
#endif

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

    // Decrements the inode link count to a vnode.
    // Writes the inode back to |transaction|.
    //
    // If the link count becomes zero, the node either:
    // 1) Calls |Purge()| (if no open fds exist), or
    // 2) Adds itself to the "unlinked list", to be purged later.
    void RemoveInodeLink(Transaction* transaction);

    // TODO(smklein): These operations and members are protected as a historical artifact
    // of "File + Directory + Vnode" being a single class. They should be transitioned to
    // private.
protected:
    VnodeMinfs(Minfs* fs);

    // fs::Vnode interface.
    zx_status_t Getattr(vnattr_t* a) final;
    zx_status_t Setattr(const vnattr_t* a) final;
#ifdef __Fuchsia__
    zx_status_t QueryFilesystem(fuchsia_io_FilesystemInfo* out) final;
    zx_status_t GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) final;
#endif

    // 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.
    void ValidateVmoTail(uint64_t inode_size) const;

    enum class BlockOp {
        // Read skips unallocated indirect blocks, setting all output |bno| values to zero.
        kRead,
        // Delete avoids accessing indirect blocks, but additionally releases indirect blocks
        // (and doubly indirect blocks) if all contained blocks have been freed.
        //
        // |out_dev_offset| must be zero for all callbacks invoked via this operation.
        kDelete,
        // Write ensures all indirect blocks are allocated before accessing the underlying |bno|.
        // Acquiring a block via "kWrite" may cause additional writeback traffic to update
        // the metadata itself.
        kWrite,
        // Swap is identical to write: It ensures all indirect blocks are allocated
        // before being accessed.
        kSwap,
    };

    // Callback for block operations. Called exclusively on "leaf node" blocks: indirect blocks
    // are considered metadata, and handled internally by the "BlockOp" functions.
    //
    // |vmo_offset|: Block address relative to start of Vnode.
    // |dev_offset|: Previous absolute block address at this node. Zero if unallocated.
    // |out_dev_offset|: A new, optional output value. Set to |dev_offset| by default.
    //            Will alter the results of |bno| returned via |ApplyOperation|.
    using BlockOpCallback = fbl::Function<void(blk_t vmo_offset,
                                               blk_t dev_offset,
                                               blk_t* out_dev_offset)>;

    // Arguments to invoke |callback| on all local nodes of the file in [start, start + count).
    //
    // Collects result blocks in |bnos|.
    struct BlockOpArgs {
        BlockOpArgs(Transaction* transaction, BlockOp op, BlockOpCallback callback, blk_t start,
                    blk_t count, blk_t* bnos)
            : transaction(transaction), op(op), callback(std::move(callback)), 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);
            }
        }

        Transaction* transaction;
        BlockOp op;
        BlockOpCallback callback;
        blk_t start;
        blk_t count;
        blk_t* bnos;
    };

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

        BlockOp 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_; }
        blk_t GetRelativeBlock() const { return rel_bno_; }

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

    class IndirectArgs : public DirectArgs {
    public:
        IndirectArgs(BlockOp op, blk_t* array, blk_t count, blk_t rel_bno,
                     blk_t* bnos, blk_t bindex, blk_t ib_vmo_offset)
            : DirectArgs(op, array, count, rel_bno, 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(BlockOp op, blk_t* array, blk_t count, blk_t rel_bno, blk_t* bnos,
                      blk_t bindex, blk_t ib_vmo_offset, blk_t ibindex, blk_t dib_vmo_offset)
            : IndirectArgs(op, array, count, rel_bno, 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
    void AllocateIndirect(Transaction* transaction, 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 ApplyOperation(BlockOpArgs* params);
    zx_status_t BlockOpDirect(BlockOpArgs* op_args, DirectArgs* params);
    zx_status_t BlockOpIndirect(BlockOpArgs* op_args, IndirectArgs* params);
    zx_status_t BlockOpDindirect(BlockOpArgs* op_args, DindirectArgs* params);

    // Ensures that the indirect vmo is large enough to reference a block at
    // relative block address |n| within the file.
    zx_status_t EnsureIndirectVmoSize(blk_t n);

    // Get the disk block 'bno' corresponding to the 'n' block
    //
    // May or may not allocate |bno|; certain Vnodes (like File) delay allocation
    // until writeback, and will return a sentinel value of zero.
    //
    // TODO: Use types to represent that |bno|, as an output, is optional.
    zx_status_t BlockGetWritable(Transaction* transaction, blk_t n, blk_t* bno);

    // Get the disk block 'bno' corresponding to relative block address |n| within the file.
    // Does not allocate any blocks, direct or indirect, to acquire this block.
    zx_status_t BlockGetReadable(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(Transaction* transaction, blk_t start);

    // 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(Transaction* transaction);

#ifdef __Fuchsia__
    zx_status_t GetNodeInfo(uint32_t flags, fuchsia_io_NodeInfo* info) final;

    void Sync(SyncCallback closure) final;
    zx_status_t AttachRemote(fs::MountChannel h) final;
    zx_status_t InitVmo(Transaction* transaction);

    // 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);

    // 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, uint32_t mask, uint32_t options, zx::channel watcher) 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__
    // Clears the block at |bno| on disk.
    void ClearIndirectBlock(blk_t bno);
#endif
    uint32_t FdCount() const { return fd_count_; }

    Minfs* const fs_;
#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_{};
    uint64_t vmo_size_ = 0;

    // 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
    // DataBlockAssigner may modify this field asynchronously, so a valid Transaction object must
    // be held before accessing it.
    fbl::unique_ptr<fzl::ResizeableVmoMapper> vmo_indirect_;

    fuchsia_hardware_block_VmoID vmoid_{};
    fuchsia_hardware_block_VmoID vmoid_indirect_{};

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

    ino_t ino_{};

    // DataBlockAssigner may modify this field asynchronously, so a valid Transaction object must
    // be held before accessing it.
    Inode 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_{};
};

} // namespace minfs
