// 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 WritebackControl *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 WritebackControl *wbc);
  int F2fsWriteNodePages(struct address_space *mapping, struct WritebackControl *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 WritebackControl *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_
