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

namespace f2fs {

/* start node id of a node block dedicated to the given node id */
inline uint32_t StartNid(uint32_t nid) {
  return (nid / kNatEntryPerBlock) * kNatEntryPerBlock;
}

/* node block offset on the NAT area dedicated to the given start node id */
//#define NAT_BLOCK_OFFSET(start_nid) (start_nid / kNatEntryPerBlock)
inline uint64_t NatBlockOffset(uint32_t start_nid) {
  return start_nid / kNatEntryPerBlock;
}

/* # of pages to perform readahead before building free nids */
constexpr int kFreeNidPages = 4;

/* maximum # of free node ids to produce during build_free_nids */
constexpr int kMaxFreeNids = kNatEntryPerBlock * kFreeNidPages;

/* maximum readahead size for node during getting data blocks */
constexpr int kMaxRaNode = 128;

/* maximum cached nat entries to manage memory footprint */
constexpr uint32_t kNmWoutThreshold = 64 * kNatEntryPerBlock;

/* vector size for gang look-up from nat cache that consists of radix tree */
constexpr uint32_t kNatvecSize = 64;

/*
 * For node information
 */
struct NodeInfo {
  nid_t nid = 0;             /* node id */
  nid_t ino = 0;             /* inode number of the node's owner */
  block_t blk_addr = 0;      /* block address of the node */
  uint8_t version = 0; /* version of the node */
};

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

inline uint32_t NatGetNid(NatEntry *nat) { return nat->ni.nid; }
inline void NatSetNid(NatEntry *nat, nid_t n) { nat->ni.nid = n; }
inline block_t NatGetBlkaddr(NatEntry *nat) { return nat->ni.blk_addr; }
inline void NatSetBlkaddr(NatEntry *nat, block_t b) { nat->ni.blk_addr = b; }
inline uint32_t NatGetIno(NatEntry *nat) { return nat->ni.ino; }
inline void NatSetIno(NatEntry *nat, uint32_t i) { nat->ni.ino = i; }
inline uint8_t NatGetVersion(NatEntry *nat) { return nat->ni.version; }
inline void NatSetVersion(NatEntry *nat, uint8_t v) { nat->ni.version = v; }

inline uint8_t IncNodeVersion(uint8_t version) { return ++version; }

/*
 * For free nid mangement
 */
enum class NidState {
  kNidNew = 0,  /* newly added to free nid list */
  kNidAlloc, /* it is allocated */
};

struct FreeNid {
  list_node_t list; /* for free node id list */
  nid_t nid = 0;        /* node id */
  int state = 0;        /* in use or not: kNidNew or kNidAlloc */
};

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(NodeInfo *ni, RawNatEntry *raw_ne);
  static zx_status_t RestoreNodeSummary(F2fs *fs, uint32_t segno, SummaryBlock *sum);
  zx_status_t BuildNodeManager();
  void DestroyNodeManager();
  zx_status_t ReadNodePage(Page *page, nid_t nid, int type);
  zx_status_t GetNodePage(pgoff_t nid, Page **out);

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

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

  uint32_t OfsOfNode(Page *node_page);

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

  uint8_t IsDentDnode(Page *page);
  uint8_t IsFsyncDnode(Page *page);

  uint64_t 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, NodeInfo *ni);
  int SyncNodePages(nid_t ino, WritebackControl *wbc);
  void SyncInodePage(DnodeOfData *dn);

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

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

  void ClearColdData(Page *page);

  void DecValidNodeCount(SbInfo *sbis, VnodeF2fs *vnode, uint32_t count);
  void GetNatBitmap(void *addr);
  bool FlushNatsInJournal();
  void FlushNatEntries();

  int F2fsWriteNodePage(Page *page, WritebackControl *wbc);
  int F2fsWriteNodePages(struct address_space *mapping, WritebackControl *wbc);
  zx_status_t RecoverInodePage(Page *page);
  void RecoverNodePage(Page *page, Summary *sum, NodeInfo *ni,
                       block_t new_blkaddr);

 private:
  F2fs *fs_;

  // Inline functions
  bool inc_ValidNodeCount(SbInfo *sbi, VnodeF2fs *vnode, uint32_t count);

  pgoff_t CurrentNatAddr(nid_t start);
  bool IsUpdatedNatPage(nid_t start);
  pgoff_t NextNatAddr(pgoff_t block_addr);
  void SetToNextNat(NmInfo *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);
  NatEntry *LookupNatCache(NmInfo *nm_i, nid_t n);
  uint32_t GangLookupNatCache(NmInfo *nm_i, nid_t start, uint32_t nr,
                                    NatEntry **ep);
  void DelFromNatCache(NmInfo *nm_i, NatEntry *e);

  NatEntry *GrabNatEntry(NmInfo *nm_i, nid_t nid);
  void CacheNatEntry(NmInfo *nm_i, nid_t nid, RawNatEntry *ne);
  void SetNodeAddr(NodeInfo *ni, block_t new_blkaddr);
  int TryToFreeNats(int nr_shrink);

  int GetNodePath(long block, int offset[4], uint32_t noffset[4]);
  void TruncateNode(DnodeOfData *dn);
  zx_status_t TruncateDnode(DnodeOfData *dn);
  zx_status_t TruncateNodes(DnodeOfData *dn, uint32_t nofs, int ofs, int depth);
  zx_status_t TruncatePartialNodes(DnodeOfData *dn, Inode *ri, int *offset, int depth);

  zx_status_t NewNodePage(DnodeOfData *dn, uint32_t 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(address_space *mapping,
            WritebackControl *wbc);
  int F2fsSetNodePageDirty(Page *page);
  void F2fsInvalidateNodePage(Page *page, uint64_t offset);
  int F2fsReleaseNodePage(Page *page, gfp_t wait);
  #endif

  FreeNid *LookupFreeNidList(nid_t n, list_node_t *head);
  void DelFromFreeNidList(FreeNid *i);
  int AddFreeNid(NmInfo *nm_i, nid_t nid);
  void RemoveFreeNid(NmInfo *nm_i, nid_t nid);
  int ScanNatPage(NmInfo *nm_i, Page *nat_page, nid_t start_nid);
  void BuildFreeNids();

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

}  // namespace f2fs

#endif  // F2FS_NODE_H_
