// 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 THIRD_PARTY_F2FS_F2FS_INTERNAL_H_
#define THIRD_PARTY_F2FS_F2FS_INTERNAL_H_

namespace f2fs {

class VnodeF2fs;

// For checkpoint manager
enum class MetaBitmap { kNatBitmap, kSitBitmap };

// for the list of orphan inodes
struct OrphanInodeEntry {
  list_node_t list;  // list head
  nid_t ino = 0;     // inode number
};

// for the list of directory inodes
struct DirInodeEntry {
  list_node_t list;            // list head
  VnodeF2fs *vnode = nullptr;  // vfs inode pointer
};

// for the list of fsync inodes, used only during recovery
struct FsyncInodeEntry {
  list_node_t list;                        // list head
  fbl::RefPtr<VnodeF2fs> vnode = nullptr;  // vfs inode pointer
  block_t blkaddr = 0;                     // block address locating the last inode
};

inline int NatsInCursum(SummaryBlock *sum) { return LeToCpu(sum->n_nats); }
inline int SitsInCursum(SummaryBlock *sum) { return LeToCpu(sum->n_sits); }

inline RawNatEntry NatInJournal(SummaryBlock *sum, int i) { return sum->nat_j.entries[i].ne; }
inline void SetNatInJournal(SummaryBlock *sum, int i, RawNatEntry raw_ne) {
  sum->nat_j.entries[i].ne = raw_ne;
}
inline nid_t NidInJournal(SummaryBlock *sum, int i) { return sum->nat_j.entries[i].nid; }
inline void SetNidInJournal(SummaryBlock *sum, int i, nid_t nid) {
  sum->nat_j.entries[i].nid = nid;
}

inline SitEntry *SitInJournal(SummaryBlock *sum, int i) { return &sum->sit_j.entries[i].se; }
inline uint32_t SegnoInJournal(SummaryBlock *sum, int i) { return sum->sit_j.entries[i].segno; }
inline void SetSegnoInJournal(SummaryBlock *sum, int i, uint32_t segno) {
  sum->sit_j.entries[i].segno = segno;
}

static inline int UpdateNatsInCursum(SummaryBlock *rs, int i) {
  int before = NatsInCursum(rs);
  rs->n_nats = CpuToLe(static_cast<uint32_t>(before + i));
  return before;
}

static inline int UpdateSitsInCursum(SummaryBlock *rs, int i) {
  int before = SitsInCursum(rs);
  rs->n_sits = CpuToLe(static_cast<uint32_t>(before + i));
  return before;
}

// For INODE and NODE manager
constexpr int kXattrNodeOffset = -1;
// store xattrs to one node block per
// file keeping -1 as its node offset to
// distinguish from index node blocks.
constexpr int kRdOnlyNode = 1;
// specify a read-only mode when getting
// a node block. 0 is read-write mode.
// used by GetDnodeOfData().
constexpr int kLinkMax = 32000;  // maximum link count per file

// for in-memory extent cache entry
struct ExtentInfo {
  fs::SharedMutex ext_lock;  // rwlock for consistency
  uint64_t fofs = 0;         // start offset in a file
  uint32_t blk_addr = 0;     // start block address of the extent
  uint64_t len = 0;          // lenth of the extent
};

// i_advise uses Fadvise:xxx bit. We can add additional hints later.
enum class FAdvise {
  kCold = 1,
};

struct InodeInfo {
  uint32_t i_flags = 0;          // keep an inode flags for ioctl
  uint8_t i_advise = 0;          // use to give file attribute hints
  uint64_t i_current_depth = 0;  // use only in directory structure
  umode_t i_acl_mode = 0;        // keep file acl mode temporarily

  uint32_t flags = 0;         // use to pass per-file flags
  uint64_t data_version = 0;  // lastest version of data for fsync
  atomic_t dirty_dents;       // # of dirty dentry pages
  f2fs_hash_t chash;          // hash value of given file name
  uint64_t clevel = 0;        // maximum level of given file name
  nid_t i_xattr_nid = 0;      // node id that contains xattrs
  ExtentInfo ext;             // in-memory extent cache entry
};

struct NmInfo {
  block_t nat_blkaddr = 0;  // base disk address of NAT
  nid_t max_nid = 0;        // maximum possible node ids
  nid_t init_scan_nid = 0;  // the first nid to be scanned
  nid_t next_scan_nid = 0;  // the next nid to be scanned

  // NAT cache management
  RadixTreeRoot nat_root;         // root of the nat entry cache
  fs::SharedMutex nat_tree_lock;  // protect nat_tree_lock
  uint32_t nat_cnt = 0;           // the # of cached nat entries
  list_node_t nat_entries;        // cached nat entry list (clean)
  list_node_t dirty_nat_entries;  // cached nat entry list (dirty)

  // free node ids management
  list_node_t free_nid_list;           // a list for free nids
  fs::SharedMutex free_nid_list_lock;  // protect free nid list
  uint64_t fcnt = 0;                   // the number of free node id
  fbl::Mutex build_lock;               // lock for build free nids

  // for checkpoint
  char *nat_bitmap = nullptr;       // NAT bitmap pointer
  char *nat_prev_bitmap = nullptr;  // JY: NAT previous checkpoint bitmap pointer
  int bitmap_size = 0;              // bitmap size
};

// this structure is used as one of function parameters.
// all the information are dedicated to a given direct node block determined
// by the data offset in a file.
struct DnodeOfData {
  // inode *inode;		// vfs inode pointer
  VnodeF2fs *vnode = nullptr;
  Page *inode_page = nullptr;      // its inode page, NULL is possible
  Page *node_page = nullptr;       // cached direct node page
  nid_t nid = 0;                   // node id of the direct node block
  uint64_t ofs_in_node = 0;        // data offset in the node page
  bool inode_page_locked = false;  // inode page is locked or not
  block_t data_blkaddr = 0;        // block address of the node block
};

static inline void SetNewDnode(DnodeOfData *dn, VnodeF2fs *vnode, Page *ipage, Page *npage,
                               nid_t nid) {
  dn->vnode = vnode;
  dn->inode_page = ipage;
  dn->node_page = npage;
  dn->nid = nid;
  dn->inode_page_locked = 0;
}

// For SIT manager
//
// By default, there are 6 active log areas across the whole main area.
// When considering hot and cold data separation to reduce cleaning overhead,
// we split 3 for data logs and 3 for node logs as hot, warm, and cold types,
// respectively.
// In the current design, you should not change the numbers intentionally.
// Instead, as a mount option such as active_logs=x, you can use 2, 4, and 6
// logs individually according to the underlying devices. (default: 6)
// Just in case, on-disk layout covers maximum 16 logs that consist of 8 for
// data and 8 for node logs.
constexpr int kNrCursegDataType = 3;
constexpr int kNrCursegNodeType = 3;
constexpr int kNrCursegType = kNrCursegDataType + kNrCursegNodeType;

enum class CursegType {
  kCursegHotData = 0,  // directory entry blocks
  kCursegWarmData,     // data blocks
  kCursegColdData,     // multimedia or GCed data blocks
  kCursegHotNode,      // direct node blocks of directory files
  kCursegWarmNode,     // direct node blocks of normal files
  kCursegColdNode,     // indirect node blocks
  kNoCheckType
};

struct SmInfo {
  struct SitInfo *SitInfo = nullptr;              // whole segment information
  struct FreeSegmapInfo *free_info = nullptr;     // free segment information
  struct DirtySeglistInfo *dirty_info = nullptr;  // dirty segment information
  struct CursegInfo *curseg_array = nullptr;      // active segment information

  block_t seg0_blkaddr = 0;  // block address of 0'th segment
  block_t main_blkaddr = 0;  // start block address of main area
  block_t ssa_blkaddr = 0;   // start block address of SSA area

  uint64_t segment_count = 0;      // total # of segments
  uint64_t main_segments = 0;      // # of segments in main area
  uint64_t reserved_segments = 0;  // # of reserved segments
  uint64_t ovp_segments = 0;       // # of overprovision segments
};

// For directory operation
constexpr size_t kNodeDir1Block = kAddrsPerInode + 1;
constexpr size_t kNodeDir2Block = kAddrsPerInode + 2;
constexpr size_t kNodeInd1Block = kAddrsPerInode + 3;
constexpr size_t kNodeInd2Block = kAddrsPerInode + 4;
constexpr size_t kNodeDIndBlock = kAddrsPerInode + 5;

// For superblock

// CountType for monitoring
//
// f2fs monitors the number of several block types such as on-writeback,
// dirty dentry blocks, dirty node blocks, and dirty meta blocks.
enum class CountType {
  kWriteback = 0,
  kDirtyDents,
  kDirtyNodes,
  kDirtyMeta,
  kNrCountType,
};

// FS_LOCK nesting subclasses for the lock validator:
//
// The locking order between these classes is
// LockType::kRename -> LockType::kDentryOps -> LockType::kDataWrtie -> LockType::kDataNew
//    -> LockType::kDataTrunc -> LockType::kNodeWrite -> LockType::kNodeNew -> LockType::kNodeTrunc
enum class LockType {
  kRename = 0,  // for renaming operations
  kDentryOps,   // for directory operations
  kDataWrtie,   // for data write
  kDataNew,     // for data allocation
  kDataTrunc,   // for data truncate
  kNodeNew,     // for node allocation
  kNodeTrunc,   // for node truncate
  kNodeWrite,   // for node write
  kNrLockType,
};

// The below are the page types.
// The available types are:
// kData         User data pages. It operates as async mode.
// kNode         Node pages. It operates as async mode.
// kMeta         FS metadata pages such as SIT, NAT, CP.
// kNrPageType   The number of page types.
// kMetaFlush    Make sure the previous pages are written
//               with waiting the bio's completion
// ...           Only can be used with META.
enum class PageType {
  kData = 0,
  kNode,
  kMeta,
  kNrPageType,
  kMetaFlush,
};

struct SbInfo {
  // super_block *sb;			// pointer to VFS super block
  // buffer_head *raw_super_buf;	// buffer head of raw sb
  const SuperBlock *raw_super;  // raw super block pointer
  int s_dirty = 0;              // dirty flag for checkpoint

  // for node-related operations
  NmInfo *nm_info = nullptr;  // node manager
  // inode *node_inode;		// cache node blocks
  fbl::RefPtr<VnodeF2fs> node_vnode;

  // for segment-related operations
  SmInfo *sm_info = nullptr;                                            // segment manager
  struct bio *bio[static_cast<int>(PageType::kNrPageType)];             // bios to merge
  sector_t last_block_in_bio[static_cast<int>(PageType::kNrPageType)];  // last block number
  // rw_semaphore bio_sem;		// IO semaphore

  // for checkpoint
  Checkpoint *ckpt = nullptr;  // raw checkpoint pointer
  // inode *meta_inode;		// cache meta blocks
  fbl::RefPtr<VnodeF2fs> meta_vnode;
  fbl::Mutex cp_mutex;                                               // for checkpoint procedure
  fs::SharedMutex fs_lock[static_cast<int>(LockType::kNrLockType)];  // for blocking FS operations
  fbl::Mutex write_inode;                                            // mutex for write inode
  fbl::Mutex writepages;                                             // mutex for writepages()
  int por_doing = 0;                                                 // recovery is doing or not

  // for orphan inode management
  list_node_t orphan_inode_list;       // orphan inode list
  fs::SharedMutex orphan_inode_mutex;  // for orphan inode list
  uint64_t n_orphans = 0;              // # of orphan inodes

  // for directory inode management
  list_node_t dir_inode_list;  // dir inode list
  fbl::Mutex dir_inode_lock;   // for dir inode list lock
  uint64_t n_dirty_dirs = 0;   // # of dir inodes

  // basic file system units
  uint64_t log_sectors_per_block = 0;    // log2 sectors per block
  uint64_t log_blocksize = 0;            // log2 block size
  uint64_t blocksize = 0;                // block size
  uint64_t root_ino_num = 0;             // root inode numbe
  uint64_t node_ino_num = 0;             // node inode numbe
  uint64_t meta_ino_num = 0;             // meta inode numbe
  uint64_t log_blocks_per_seg = 0;       // log2 blocks per segment
  uint64_t blocks_per_seg = 0;           // blocks per segment
  uint64_t segs_per_sec = 0;             // segments per section
  uint64_t secs_per_zone = 0;            // sections per zone
  uint64_t total_sections = 0;           // total section count
  uint64_t total_node_count = 0;         // total node block count
  uint64_t total_valid_node_count = 0;   // valid node block count
  uint64_t total_valid_inode_count = 0;  // valid inode count
  int active_logs = 0;                   // # of active logs

  block_t user_block_count = 0;                                  // # of user blocks
  block_t total_valid_block_count = 0;                           // # of valid blocks
  block_t alloc_valid_block_count = 0;                           // # of allocated blocks
  block_t last_valid_block_count = 0;                            // for recovery
  uint32_t s_next_generation = 0;                                // for NFS support
  atomic_t nr_pages[static_cast<int>(CountType::kNrCountType)];  // # of pages, see count_type

  uint64_t mount_opt = 0;  // set with kMountOptxxxx bits according to F2fs::mount_options_

  // for cleaning operations
  fs::SharedMutex gc_mutex;                    // mutex for GC
  struct F2fsGc_kthread *gc_thread = nullptr;  // GC thread

  // for stat information.
  // one is for the LFS mode, and the other is for the SSR mode.
  struct f2fs_stat_info *stat_info = nullptr;  // FS status information
  uint64_t segment_count[2];                   // # of allocated segments
  uint64_t block_count[2];                     // # of allocated blocks
  uint64_t last_victim[2];                     // last victim segment #
  int total_hit_ext = 0, read_hit_ext = 0;     // extent cache hit ratio
  int bg_gc = 0;                               // background gc calls
  fbl::Mutex stat_lock;                        // lock for stat operations
};

static inline const SuperBlock *RawSuper(SbInfo *sbi) {
  return static_cast<const SuperBlock *>(sbi->raw_super);
}

static inline Checkpoint *GetCheckpoint(SbInfo *sbi) {
  return static_cast<Checkpoint *>(sbi->ckpt);
}

static inline NmInfo *GetNmInfo(SbInfo *sbi) { return static_cast<NmInfo *>(sbi->nm_info); }

static inline SmInfo *GetSmInfo(SbInfo *sbi) { return static_cast<SmInfo *>(sbi->sm_info); }

static inline SitInfo *GetSitInfo(SbInfo *sbi) {
  return static_cast<SitInfo *>((GetSmInfo(sbi)->SitInfo));
}

static inline FreeSegmapInfo *GetFreeInfo(SbInfo *sbi) {
  return static_cast<FreeSegmapInfo *>(GetSmInfo(sbi)->free_info);
}

static inline DirtySeglistInfo *GetDirtyInfo(SbInfo *sbi) {
  return static_cast<DirtySeglistInfo *>(GetSmInfo(sbi)->dirty_info);
}

static inline void SetSbDirt(SbInfo *sbi) { sbi->s_dirty = 1; }

static inline void ResetSbDirt(SbInfo *sbi) { sbi->s_dirty = 0; }

static inline void mutex_lock_op(SbInfo *sbi, LockType t)
    TA_ACQ(&sbi->fs_lock[static_cast<int>(t)]) {
  // TODO: Too many locks.
  // It seems that two locks (node/io) are enough to sync between cp and io path.
  sbi->fs_lock[static_cast<int>(t)].lock();
}

static inline void mutex_unlock_op(SbInfo *sbi, LockType t)
    TA_REL(&sbi->fs_lock[static_cast<int>(t)]) {
  sbi->fs_lock[static_cast<int>(t)].unlock();
}

constexpr uint32_t kDefaultAllocatedBlocks = 1;

[[maybe_unused]] static inline void IncPageCount(SbInfo *sbi, int count_type) {
  // TODO: IMPL
  // AtomicInc(&sbi->nr_pages[count_type]);
  SetSbDirt(sbi);
}

static inline void InodeIncDirtyDents(VnodeF2fs *vnode) {
  //   //TODO: IMPL
  // 	//AtomicInc(&F2FS_I(inode)->dirty_dents);
}

static inline void DecPageCount(SbInfo *sbi, CountType count_type) {
  // TODO: IMPL
  // AtomicDec(&sbi->nr_pages[count_type]);
}

static inline void InodeDecDirtyDents(void *vnode) {
  //   //TODO: IMPL
  // 	//AtomicDec(&F2FS_I(inode)->dirty_dents);
}

static inline int GetPages(SbInfo *sbi, CountType count_type) {
  // TODO: IMPL
  // return AtomicRead(&sbi->nr_pages[count_type]);
  return 0;
}

static inline uint32_t BitmapSize(SbInfo *sbi, MetaBitmap flag) {
  Checkpoint *ckpt = GetCheckpoint(sbi);

  // return NAT or SIT bitmap
  if (flag == MetaBitmap::kNatBitmap)
    return LeToCpu(ckpt->nat_ver_bitmap_bytesize);
  else if (flag == MetaBitmap::kSitBitmap)
    return LeToCpu(ckpt->sit_ver_bitmap_bytesize);

  return 0;
}

static inline void *BitmapPrt(SbInfo *sbi, MetaBitmap flag) {
  Checkpoint *ckpt = GetCheckpoint(sbi);
  int offset = (flag == MetaBitmap::kNatBitmap) ? ckpt->sit_ver_bitmap_bytesize : 0;
  return &ckpt->sit_nat_version_bitmap + offset;
}

static inline bool IsSetCkptFlags(Checkpoint *cp, uint32_t f) {
  uint32_t ckpt_flags = LeToCpu(cp->ckpt_flags);
  return ckpt_flags & f;
}

static inline block_t StartCpAddr(SbInfo *sbi) {
  block_t start_addr;
  Checkpoint *ckpt = GetCheckpoint(sbi);
  uint64_t ckpt_version = LeToCpu(ckpt->checkpoint_ver);

  start_addr = LeToCpu(RawSuper(sbi)->cp_blkaddr);

  // odd numbered checkpoint should at cp segment 0
  // and even segent must be at cp segment 1
  if (!(ckpt_version & 1))
    start_addr += sbi->blocks_per_seg;

  return start_addr;
}

[[maybe_unused]] static inline block_t StartSumAddr(SbInfo *sbi) {
  return LeToCpu(GetCheckpoint(sbi)->cp_pack_start_sum);
}

inline void F2fsPutPage(Page *page, int unlock) {
  if (page != nullptr)
    delete page;
}

static inline void F2fsPutDnode(DnodeOfData *dn) {
  // TODO: IMPL
  if (dn->node_page)
    F2fsPutPage(dn->node_page, 1);
  if (dn->inode_page && dn->node_page != dn->inode_page)
    F2fsPutPage(dn->inode_page, 0);
  dn->node_page = NULL;
  dn->inode_page = NULL;
}

[[maybe_unused]] static inline struct kmem_cache *KmemCacheCreate(const char *name, size_t size,
                                                                  void (*ctor)(void *)) {
  return nullptr;
}

inline bool RawIsInode(Node *p) { return p->footer.nid == p->footer.ino; }

static inline bool IsInode(Page *page) {
  Node *p = static_cast<Node *>(PageAddress(page));
  return RawIsInode(p);
}

static inline uint32_t *BlkaddrInNode(Node *node) {
  return RawIsInode(node) ? node->i.i_addr : node->dn.addr;
}

static inline block_t DatablockAddr(Page *node_page, uint64_t offset) {
  Node *raw_node;
  uint32_t *addr_array;
  raw_node = static_cast<Node *>(PageAddress(node_page));
  addr_array = BlkaddrInNode(raw_node);
  return LeToCpu(addr_array[offset]);
}

static inline int TestValidBitmap(uint64_t nr, char *addr) {
  int mask;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  return mask & *addr;
}

static inline int SetValidBitmap(uint64_t nr, char *addr) {
  int mask;
  int ret;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  ret = mask & *addr;
  *addr |= mask;
  return ret;
}

static inline int ClearValidBitmap(uint64_t nr, char *addr) {
  int mask;
  int ret;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  ret = mask & *addr;
  *addr &= ~mask;
  return ret;
}

// InodeInfo->flags keeping only in memory
enum class InodeInfoFlag {
  kInit = 0,      // indicate inode is being initialized
  kActive,        // indicate open_count > 0
  kDirty,         // indicate dirty vnode
  kNewInode,      // indicate newly allocated vnode
  kNeedCp,        // need to do checkpoint during fsync
  kIncLink,       // need to increment i_nlink
  kAclMode,       // indicate acl mode
  kNoAlloc,       // should not allocate any blocks
  kUpdateDir,     // should update inode block for consistency
  kInlineXattr,   // used for inline xattr
  kInlineData,    // used for inline data
  kInlineDentry,  // used for inline dentry
  kBad,           // should drop this inode without purging
};

#if 0  // porting needed
[[maybe_unused]] static inline void SetAclInode(InodeInfo *fi, umode_t mode) {
  fi->i_acl_mode = mode;
  SetInodeFlag(fi, InodeInfoFlag::kAclMode);
}

[[maybe_unused]] static inline int CondClearInodeFlag(InodeInfo *fi, InodeInfoFlag flag) {
  if (IsInodeFlagSet(fi, InodeInfoFlag::kAclMode)) {
    ClearInodeFlag(fi, InodeInfoFlag::kAclMode);
    return 1;
  }
  return 0;
}
#endif

inline uint32_t RootIno(SbInfo *sbi) { return sbi->root_ino_num; }
inline uint32_t NodeIno(SbInfo *sbi) { return sbi->node_ino_num; }
inline uint32_t MetaIno(SbInfo *sbi) { return sbi->meta_ino_num; }

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_F2FS_INTERNAL_H_
