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

#ifndef SRC_STORAGE_MINFS_VNODE_H_
#define SRC_STORAGE_MINFS_VNODE_H_

#include <inttypes.h>

#include <cstdint>
#include <memory>
#include <utility>

#ifdef __Fuchsia__
#include <fuchsia/io/llcpp/fidl.h>
#include <fuchsia/minfs/llcpp/fidl.h>
#include <lib/fzl/resizeable-vmo-mapper.h>
#include <lib/zx/vmo.h>

#include <fbl/auto_lock.h>
#include <fs/remote_container.h>
#include <fs/watcher.h>

#include "src/storage/minfs/vnode_allocation.h"
#endif

#include <lib/zircon-internal/fnv1hash.h>

#include <fbl/algorithm.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include <fs/locking.h>
#include <fs/ticker.h>
#include <fs/vfs.h>
#include <fs/vnode.h>

#include "src/storage/minfs/format.h"
#include "src/storage/minfs/lazy_buffer.h"
#include "src/storage/minfs/minfs.h"
#include "src/storage/minfs/transaction_limits.h"
#include "src/storage/minfs/vnode_mapper.h"
#include "src/storage/minfs/writeback.h"

namespace minfs {

// Used by fsck
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.
#ifdef __Fuchsia__
class VnodeMinfs : public fs::Vnode,
                   public fbl::SinglyLinkedListable<VnodeMinfs*>,
                   public fbl::Recyclable<VnodeMinfs>,
                   llcpp::fuchsia::minfs::Minfs::Interface {
#else
class VnodeMinfs : public fs::Vnode,
                   public fbl::SinglyLinkedListable<VnodeMinfs*>,
                   public fbl::Recyclable<VnodeMinfs> {
#endif
 public:
  explicit VnodeMinfs(Minfs* fs);
  ~VnodeMinfs() override;

  // 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 void Recreate(Minfs* fs, ino_t ino, fbl::RefPtr<VnodeMinfs>* out);

  bool IsUnlinked() const { return inode_.link_count == 0; }

  const Inode* GetInode() const { return &inode_; }
  Inode* GetMutableInode() { 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();

  void MarkPurged() { inode_.magic = kMinfsMagicPurged; }

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

  // fs::Vnode interface (invoked publicly).
#ifdef __Fuchsia__
  void HandleFsSpecificMessage(fidl_incoming_msg_t* msg, fidl::Transaction* txn) final;
#endif
  using fs::Vnode::Open;
  zx_status_t Open(ValidatedOptions options, 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;

  // Removes from disk an unlinked and closed vnode. Asserts that inode IsUnlinked().
  zx_status_t RemoveUnlinked();

  // Issues a write on all dirty bytes within a vnode.
  virtual zx::status<> FlushCachedWrites() = 0;

  // Discards all the dirty bytes within a vnode.
  // This also drops any inode or block reservation a vnode might have.
  virtual void DropCachedWrites() = 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;

  // Returns if the node is a directory.
  // TODO(fxbug.dev/39864): This function is used only within minfs to implement unlinking and
  // renaming. Consider replacing this with the more general |Vnode::GetProtocols|.
  virtual bool IsDirectory() 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(unknown): 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). |indirect| specifies whether the block is a direct or
  // indirect block.
  virtual void DeleteBlock(PendingWork* transaction, blk_t vmo_offset, blk_t dev_offset,
                           bool indirect) = 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.
  void GetMetrics(GetMetricsCompleter::Sync& completer) final;
  void ToggleMetrics(bool enabled, ToggleMetricsCompleter::Sync& completer) final;
  void GetAllocatedRegions(GetAllocatedRegionsCompleter::Sync& completer) final;
  void GetMountState(GetMountStateCompleter::Sync& completer) final;

  // Returns a copy of unowned vmo.
  zx::unowned_vmo vmo() const { return zx::unowned_vmo(vmo_.get()); }

#endif
  // Returns true if dirty pages can be cached.
  virtual bool DirtyCacheEnabled() const = 0;

  // Returns true if the vnode needs to be flushed.
  virtual bool IsDirty() const = 0;

  Minfs* Vfs() const { return fs_; }

  // Local implementations of read, write, and truncate functions which
  // may operate on either files or directories.
  zx_status_t ReadInternal(PendingWork* transaction, void* data, size_t len, size_t off,
                           size_t* actual);
  zx_status_t ReadExactInternal(PendingWork* transaction, void* data, size_t len, size_t off);
  zx_status_t WriteInternal(Transaction* transaction, const uint8_t* 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);

  // Update the vnode's inode and write it to disk.
  void InodeSync(PendingWork* transaction, 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.
  [[nodiscard]] zx_status_t RemoveInodeLink(Transaction* transaction);

  // Allocates an indirect block.
  void AllocateIndirect(PendingWork* transaction, blk_t* block);

  // Initializes (if necessary) and returns the indirect file.
  [[nodiscard]] zx::status<LazyBuffer*> GetIndirectFile();

  // 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(PendingWork* transaction, blk_t start);

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

 private:
  // fs::Vnode interface.
  zx_status_t GetAttributes(fs::VnodeAttributes* a) final;
  zx_status_t SetAttributes(fs::VnodeAttributesUpdate a) final;
#ifdef __Fuchsia__
  zx_status_t QueryFilesystem(llcpp::fuchsia::io::FilesystemInfo* out) final;
  zx_status_t GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) final;
#endif

  // 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(unknown): 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 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)
  [[nodiscard]] zx_status_t Purge(Transaction* transaction);

#ifdef __Fuchsia__
  zx_status_t GetNodeInfoForProtocol(fs::VnodeProtocol protocol, fs::Rights rights,
                                     fs::VnodeRepresentation* info) final;

  void Sync(SyncCallback closure) final;
  zx_status_t AttachRemote(fs::MountChannel h) final;

  // Initializes vmo that contains file's data by reading data from the disk.
  // Since we cannot yet register the filesystem as a paging service (and
  // cleanly fault on pages when they are actually needed), we currently read an
  // entire file to a VMO when a file's data block are accessed.
  zx_status_t InitVmo();

  // 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;
#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;
  storage::Vmoid vmoid_;
  fs::WatcherContainer watcher_{};
#endif

  // vnode_mapper.cc explains what this is and the code there is responsible for manipulating it.
  // It is created on-demand.
  std::unique_ptr<LazyBuffer> indirect_file_;

  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

#endif  // SRC_STORAGE_MINFS_VNODE_H_
