// Copyright 2021 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 F2FS_NODE_H_
#define F2FS_NODE_H_

#include "zircon/types.h"
namespace f2fs {

/* start node id of a node block dedicated to the given node id */
#define START_NID(nid) ((nid / NAT_ENTRY_PER_BLOCK) * NAT_ENTRY_PER_BLOCK)

/* node block offset on the NAT area dedicated to the given start node id */
#define NAT_BLOCK_OFFSET(start_nid) (start_nid / NAT_ENTRY_PER_BLOCK)

/* # of pages to perform readahead before building free nids */
#define FREE_NID_PAGES 4

/* maximum # of free node ids to produce during build_free_nids */
#define MAX_FREE_NIDS (NAT_ENTRY_PER_BLOCK * FREE_NID_PAGES)

/* maximum readahead size for node during getting data blocks */
#define MAX_RA_NODE 128

/* maximum cached nat entries to manage memory footprint */
#define NM_WOUT_THRESHOLD (64 * NAT_ENTRY_PER_BLOCK)

/* vector size for gang look-up from nat cache that consists of radix tree */
#define NATVEC_SIZE 64

/*
 * For node information
 */
struct node_info {
  nid_t nid;             /* node id */
  nid_t ino;             /* inode number of the node's owner */
  block_t blk_addr;      /* block address of the node */
  unsigned char version; /* version of the node */
};

struct nat_entry {
  list_node_t list;    /* for clean or dirty nat list */
  bool checkpointed;   /* whether it is checkpointed or not */
  struct node_info ni; /* in-memory node information */
};

#define nat_get_nid(nat) (nat->ni.nid)
#define nat_set_nid(nat, n) (nat->ni.nid = n)
#define nat_get_blkaddr(nat) (nat->ni.blk_addr)
#define nat_set_blkaddr(nat, b) (nat->ni.blk_addr = b)
#define nat_get_ino(nat) (nat->ni.ino)
#define nat_set_ino(nat, i) (nat->ni.ino = i)
#define nat_get_version(nat) (nat->ni.version)
#define nat_set_version(nat, v) (nat->ni.version = v)

#define inc_node_version(version) (++version)

/*
 * For free nid mangement
 */
enum nid_state {
  NID_NEW,  /* newly added to free nid list */
  NID_ALLOC /* it is allocated */
};

struct free_nid {
  list_node_t list; /* for free node id list */
  nid_t nid;        /* node id */
  int state;        /* in use or not: NID_NEW or NID_ALLOC */
};

class NodeMgr {
 public:
  // Not copyable or moveable
  NodeMgr(const NodeMgr &) = delete;
  NodeMgr &operator=(const NodeMgr &) = delete;
  NodeMgr(NodeMgr &&) = delete;
  NodeMgr &operator=(NodeMgr &&) = delete;

  // TODO: Implement constructor
  NodeMgr(F2fs *fs);

  // TODO: Implement destructor
  ~NodeMgr() = default;

  // Public functions
  void SetFsyncMark(Page *page, int mark);
  void SetDentryMark(Page *page, int mark);

  zx_status_t NextFreeNid(nid_t *nid);
  void NodeInfoFromRawNat(node_info *ni, f2fs_nat_entry *raw_ne);
  static int RestoreNodeSummary(F2fs *fs, unsigned int segno, struct f2fs_summary_block *sum);
  zx_status_t BuildNodeManager();
  void DestroyNodeManager();
  zx_status_t ReadNodePage(Page *page, unsigned long nid, int type);
  zx_status_t GetNodePage(pgoff_t nid, Page **out);

  zx_status_t GetDnodeOfData(struct dnode_of_data *dn, pgoff_t index, int ro);

  void FillNodeFooter(Page *page, nid_t nid, nid_t ino, unsigned int ofs, bool reset);
  void CopyNodeFooter(Page *dst, Page *src);

  unsigned int OfsOfNode(Page *node_page);

  static int IsColdNode(Page *page);
  static int IsColdFile(VnodeF2fs *vnode);
  static int IsColdData(Page *page);

  unsigned char IsDentDnode(Page *page);
  unsigned char IsFsyncDnode(Page *page);

  unsigned long long CpverOfNode(Page *node_page);

  void FillNodeFooterBlkaddr(Page *page, block_t blkaddr);
  static block_t NextBlkaddrOfNode(Page *node_page);

  nid_t InoOfNode(Page *node_page);
  nid_t NidOfNode(Page *node_page);

  bool IS_DNODE(Page *node_page);
  void GetNodeInfo(nid_t nid, struct node_info *ni);
  int SyncNodePages(nid_t ino, struct writeback_control *wbc);
  void SyncInodePage(struct dnode_of_data *dn);

  bool AllocNid(nid_t *nid);
  void AllocNidFailed(nid_t nid);
  void AllocNidDone(nid_t nid);
  int TruncateInodeBlocks(VnodeF2fs *vnode, pgoff_t from);

  int RemoveInodePage(VnodeF2fs *vnode);
  zx_status_t NewInodePage(Dir *parent, VnodeF2fs *child);
  int IsCheckpointedNode(nid_t nid);

  void ClearColdData(Page *page);

  void DecValidNodeCount(struct f2fs_sb_info *sbi, VnodeF2fs *vnode, unsigned int count);
  void GetNatBitmap(void *addr);
  bool FlushNatsInJournal();
  void FlushNatEntries();

  int F2fsWriteNodePage(Page *page, struct writeback_control *wbc);
  int F2fsWriteNodePages(struct address_space *mapping, struct writeback_control *wbc);
  zx_status_t RecoverInodePage(Page *page);
  void RecoverNodePage(Page *page, struct f2fs_summary *sum, struct node_info *ni,
                       block_t new_blkaddr);

 private:
  F2fs *fs_;

  // Inline functions
  bool inc_valid_node_count(struct f2fs_sb_info *sbi, VnodeF2fs *vnode, unsigned int count);

  pgoff_t CurrentNatAddr(nid_t start);
  bool IsUpdatedNatPage(nid_t start);
  pgoff_t NextNatAddr(pgoff_t block_addr);
  void SetToNextNat(struct f2fs_nm_info *nm_i, nid_t start_nid);

  void SetNid(Page *p, int off, nid_t nid, bool i);
  nid_t GetNid(Page *p, int off, bool i);

#if 0 // porting needed
  void SetColdData(Page *page);
#endif

  void SetColdNode(VnodeF2fs *vnode, Page *page);

  // Functions
  void ClearNodePageDirty(Page *page);
  Page *GetCurrentNatPage(nid_t nid);
  Page *GetNextNatPage(nid_t nid);
  void RaNatPages(nid_t nid);
  struct nat_entry *__LookupNatCache(struct f2fs_nm_info *nm_i, nid_t n);
  unsigned int __GangLookupNatCache(struct f2fs_nm_info *nm_i, nid_t start, unsigned int nr,
                                    struct nat_entry **ep);
  void __DelFromNatCache(struct f2fs_nm_info *nm_i, struct nat_entry *e);

  struct nat_entry *GrabNatEntry(struct f2fs_nm_info *nm_i, nid_t nid);
  void CacheNatEntry(struct f2fs_nm_info *nm_i, nid_t nid, struct f2fs_nat_entry *ne);
  void SetNodeAddr(struct node_info *ni, block_t new_blkaddr);
  int TryToFreeNats(int nr_shrink);

  int GetNodePath(long block, int offset[4], unsigned int noffset[4]);
  void TruncateNode(struct dnode_of_data *dn);
  int TruncateDnode(struct dnode_of_data *dn);
  int TruncateNodes(struct dnode_of_data *dn, unsigned int nofs, int ofs, int depth);
  int TruncatePartialNodes(struct dnode_of_data *dn, struct f2fs_inode *ri, int *offset, int depth);

  zx_status_t NewNodePage(struct dnode_of_data *dn, unsigned int ofs, Page **out);
#if 0 // porting needed
  void RaNodePage(nid_t nid);
 #endif
  Page *GetNodePageRa(Page *parent, int start);

#if 0 // porting needed
  int F2fsWriteNodePages(struct address_space *mapping,
           struct writeback_control *wbc);
  int F2fsSetNodePageDirty(Page *page);
  void F2fsInvalidateNodePage(Page *page, unsigned long offset);
  int F2fsReleaseNodePage(Page *page, gfp_t wait);
  #endif

  struct free_nid *__LookupFreeNidList(nid_t n, list_node_t *head);
  void __DelFromFreeNidList(struct free_nid *i);
  int AddFreeNid(struct f2fs_nm_info *nm_i, nid_t nid);
  void RemoveFreeNid(struct f2fs_nm_info *nm_i, nid_t nid);
  int ScanNatPage(struct f2fs_nm_info *nm_i, Page *nat_page, nid_t start_nid);
  void BuildFreeNids();

  zx_status_t InitNodeManager();
  int CreateNodeManagerCaches();
  void DestroyNodeManagerCaches();
};

}  // namespace f2fs

#endif  // F2FS_NODE_H_
