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

#include <string.h>
#include <sys/stat.h>

#include "f2fs.h"
#include "zircon/errors.h"
#include "zircon/types.h"

namespace f2fs {

/*
 * inline functions
 */
inline struct seg_entry *SegMgr::GetSegEntry(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  return &sit_i->sentries[segno];
}

inline struct sec_entry *SegMgr::GetSecEntry(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  return &sit_i->sec_entries[GET_SECNO(&sbi, segno)];
}

inline unsigned int SegMgr::GetValidBlocks(unsigned int segno, int section) {
  /*
   * In order to get # of valid blocks in a section instantly from many
   * segments, f2fs manages two counting structures separately.
   */
  if (section > 1)
    return GetSecEntry(segno)->valid_blocks;
  else
    return GetSegEntry(segno)->valid_blocks;
}

inline void SegMgr::SegInfoFromRawSit(struct seg_entry *se, struct f2fs_sit_entry *rs) {
  se->valid_blocks = GET_SIT_VBLOCKS(rs);
  se->ckpt_valid_blocks = GET_SIT_VBLOCKS(rs);
  memcpy(se->cur_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
  memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
  se->type = GET_SIT_TYPE(rs);
  se->mtime = LeToCpu(uint64_t{rs->mtime});
}

inline void SegMgr::SegInfoToRawSit(struct seg_entry *se, struct f2fs_sit_entry *rs) {
  unsigned short raw_vblocks = (se->type << SIT_VBLOCKS_SHIFT) | se->valid_blocks;
  rs->vblocks = CpuToLe(raw_vblocks);
  memcpy(rs->valid_map, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
  memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
  se->ckpt_valid_blocks = se->valid_blocks;
  rs->mtime = CpuToLe(static_cast<uint64_t>(se->mtime));
}

inline unsigned int SegMgr::FindNextInuse(struct free_segmap_info *free_i, unsigned int max,
                                          unsigned int segno) {
  unsigned int ret;
  ReadLock(&free_i->segmap_lock);
  ret = find_next_bit_le(free_i->free_segmap, max, segno);
  ReadUnlock(&free_i->segmap_lock);
  return ret;
}

inline void SegMgr::__SetFree(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int secno = segno / sbi.segs_per_sec;
  unsigned int start_segno = secno * sbi.segs_per_sec;
  unsigned int next;

  WriteLock(&free_i->segmap_lock);
  clear_bit(segno, free_i->free_segmap);
  free_i->free_segments++;

  next = find_next_bit_le(free_i->free_segmap, TOTAL_SEGS(&sbi), start_segno);
  if (next >= start_segno + sbi.segs_per_sec) {
    clear_bit(secno, free_i->free_secmap);
    free_i->free_sections++;
  }
  WriteUnlock(&free_i->segmap_lock);
}

inline void SegMgr::__SetInuse(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int secno = segno / sbi.segs_per_sec;
  set_bit(segno, free_i->free_segmap);
  free_i->free_segments--;
  if (!test_and_set_bit(secno, free_i->free_secmap))
    free_i->free_sections--;
}

inline void SegMgr::__SetTestAndFree(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int secno = segno / sbi.segs_per_sec;
  unsigned int start_segno = secno * sbi.segs_per_sec;
  unsigned int next;

  WriteLock(&free_i->segmap_lock);
  if (test_and_clear_bit(segno, free_i->free_segmap)) {
    free_i->free_segments++;

    next = find_next_bit_le(free_i->free_segmap, TOTAL_SEGS(&sbi), start_segno);
    if (next >= start_segno + sbi.segs_per_sec) {
      if (test_and_clear_bit(secno, free_i->free_secmap))
        free_i->free_sections++;
    }
  }
  WriteUnlock(&free_i->segmap_lock);
}

inline void SegMgr::__SetTestAndInuse(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int secno = segno / sbi.segs_per_sec;
  WriteLock(&free_i->segmap_lock);
  if (!test_and_set_bit(segno, free_i->free_segmap)) {
    free_i->free_segments--;
    if (!test_and_set_bit(secno, free_i->free_secmap))
      free_i->free_sections--;
  }
  WriteUnlock(&free_i->segmap_lock);
}

void SegMgr::GetSitBitmap(void *dst_addr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  memcpy(dst_addr, sit_i->sit_bitmap, sit_i->bitmap_size);
}

#if 0  // porting needed
inline block_t SegMgr::WrittenBlockCount() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  block_t vblocks;

  mtx_lock(&sit_i->sentry_lock);
  vblocks = sit_i->written_valid_blocks;
  mtx_unlock(&sit_i->sentry_lock);

  return vblocks;
}
#endif

unsigned int SegMgr::FreeSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int free_segs;

  ReadLock(&free_i->segmap_lock);
  free_segs = free_i->free_segments;
  ReadUnlock(&free_i->segmap_lock);

  return free_segs;
}

inline int SegMgr::ReservedSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return SM_I(&sbi)->reserved_segments;
}

inline unsigned int SegMgr::FreeSections() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int free_secs;

  ReadLock(&free_i->segmap_lock);
  free_secs = free_i->free_sections;
  ReadUnlock(&free_i->segmap_lock);

  return free_secs;
}

inline unsigned int SegMgr::PrefreeSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return DIRTY_I(&sbi)->nr_dirty[PRE];
}

inline unsigned int SegMgr::DirtySegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return DIRTY_I(&sbi)->nr_dirty[DIRTY_HOT_DATA] + DIRTY_I(&sbi)->nr_dirty[DIRTY_WARM_DATA] +
         DIRTY_I(&sbi)->nr_dirty[DIRTY_COLD_DATA] + DIRTY_I(&sbi)->nr_dirty[DIRTY_HOT_NODE] +
         DIRTY_I(&sbi)->nr_dirty[DIRTY_WARM_NODE] + DIRTY_I(&sbi)->nr_dirty[DIRTY_COLD_NODE];
}

inline int SegMgr::OverprovisionSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return SM_I(&sbi)->ovp_segments;
}

inline int SegMgr::OverprovisionSections() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return ((unsigned int)OverprovisionSegments()) / sbi.segs_per_sec;
}

inline int SegMgr::ReservedSections() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return ((unsigned int)ReservedSegments()) / sbi.segs_per_sec;
}

inline bool SegMgr::NeedSSR() { return (FreeSections() < (unsigned int)OverprovisionSections()); }

inline int SegMgr::GetSsrSegment(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  return DIRTY_I(&sbi)->v_ops->get_victim(&sbi, &(curseg)->next_segno, BG_GC, type, SSR);
}

inline bool SegMgr::HasNotEnoughFreeSecs() {
  return FreeSections() <= (unsigned int)ReservedSections();
}

inline int SegMgr::Utilization() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return (long int)valid_user_blocks(&sbi) * 100 / (long int)sbi.user_block_count;
}

/*
 * Sometimes f2fs may be better to drop out-of-place update policy.
 * So, if fs utilization is over MIN_IPU_UTIL, then f2fs tries to write
 * data in the original place likewise other traditional file systems.
 * But, currently set 100 in percentage, which means it is disabled.
 * See below need_inplace_update().
 */
#define MIN_IPU_UTIL 50
bool SegMgr::NeedInplaceUpdate(VnodeF2fs *vnode) {
  if (S_ISDIR(vnode->i_mode_))
    return false;
  if (/*NeedSSR() &&*/ Utilization() > MIN_IPU_UTIL)
    return true;
  return false;
}

unsigned int SegMgr::CursegSegno(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  return curseg->segno;
}

unsigned char SegMgr::CursegAllocType(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  return curseg->alloc_type;
}

inline unsigned short SegMgr::CursegBlkoff(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  return curseg->next_blkoff;
}

inline void SegMgr::CheckSegRange(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  [[maybe_unused]] unsigned int end_segno = SM_I(&sbi)->segment_count - 1;
  ZX_ASSERT(!(segno > end_segno));
}

  #if 0  // porting needed
/*
 * This function is used for only debugging.
 * NOTE: In future, we have to remove this function.
 */
inline void SegMgr::VerifyBlockAddr(block_t blk_addr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_sm_info *sm_info = SM_I(&sbi);
  block_t total_blks = sm_info->segment_count << sbi.log_blocks_per_seg;
  [[maybe_unused]] block_t start_addr = sm_info->seg0_blkaddr;
  [[maybe_unused]] block_t end_addr = start_addr + total_blks - 1;
  ZX_ASSERT(!(blk_addr < start_addr));
  ZX_ASSERT(!(blk_addr > end_addr));
}
#endif

/*
 * Summary block is always treated as invalid block
 */
inline void SegMgr::CheckBlockCount(int segno, struct f2fs_sit_entry *raw_sit) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_sm_info *sm_info = SM_I(&sbi);
  unsigned int end_segno = sm_info->segment_count - 1;
  int valid_blocks = 0;
  unsigned int i;

  /* check segment usage */
  ZX_ASSERT(!(GET_SIT_VBLOCKS(raw_sit) > sbi.blocks_per_seg));

  /* check boundary of a given segment number */
  ZX_ASSERT(!(segno > (int)end_segno));

  /* check bitmap with valid block count */
  for (i = 0; i < sbi.blocks_per_seg; i++)
    if (f2fs_test_bit(i, (char *)raw_sit->valid_map))
      valid_blocks++;
  ZX_ASSERT(GET_SIT_VBLOCKS(raw_sit) == valid_blocks);
}

inline pgoff_t SegMgr::CurrentSitAddr(unsigned int start) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  unsigned int offset = SIT_BLOCK_OFFSET(sit_i, start);
  block_t blk_addr = sit_i->sit_base_addr + offset;

  CheckSegRange(start);

  /* calculate sit block address */
  if (f2fs_test_bit(offset, (char *)sit_i->sit_bitmap))
    blk_addr += sit_i->sit_blocks;

  return blk_addr;
}

inline pgoff_t SegMgr::NextSitAddr(pgoff_t block_addr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  block_addr -= sit_i->sit_base_addr;
  if (block_addr < sit_i->sit_blocks)
    block_addr += sit_i->sit_blocks;
  else
    block_addr -= sit_i->sit_blocks;

  return block_addr + sit_i->sit_base_addr;
}

inline void SegMgr::SetToNextSit(struct sit_info *sit_i, unsigned int start) {
  unsigned int block_off = SIT_BLOCK_OFFSET(sit_i, start);

  if (f2fs_test_bit(block_off, sit_i->sit_bitmap))
    f2fs_clear_bit(block_off, sit_i->sit_bitmap);
  else
    f2fs_set_bit(block_off, sit_i->sit_bitmap);
}

inline unsigned long long SegMgr::GetMtime() {
  auto cur_time = time(nullptr);
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);

  return sit_i->elapsed_time + cur_time - sit_i->mounted_time;
  return 0;
}

inline void SegMgr::SetSummary(struct f2fs_summary *sum, nid_t nid, unsigned int ofs_in_node,
                               unsigned char version) {
  sum->nid = CpuToLe(nid);
  sum->ofs_in_node = CpuToLe(ofs_in_node);
  sum->version = version;
}

inline block_t SegMgr::StartSumBlock() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return __start_cp_addr(&sbi) + LeToCpu(F2FS_CKPT(&sbi)->cp_pack_start_sum);
}

inline block_t SegMgr::SumBlkAddr(int base, int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return __start_cp_addr(&sbi) + LeToCpu(F2FS_CKPT(&sbi)->cp_pack_total_block_count) -
         (base + 1) + type;
}

/*
 * functions
 */
SegMgr::SegMgr(F2fs *fs) : fs_(fs){};

int SegMgr::NeedToFlush() {
  f2fs_sb_info &sbi = fs_->SbInfo();

  unsigned int pages_per_sec = (1 << sbi.log_blocks_per_seg) * sbi.segs_per_sec;
  int node_secs =
      ((get_pages(&sbi, F2FS_DIRTY_NODES) + pages_per_sec - 1) >> sbi.log_blocks_per_seg) /
      sbi.segs_per_sec;
  int dent_secs =
      ((get_pages(&sbi, F2FS_DIRTY_DENTS) + pages_per_sec - 1) >> sbi.log_blocks_per_seg) /
      sbi.segs_per_sec;

  if (sbi.por_doing)
    return 0;

  if (FreeSections() <= (unsigned int)(node_secs + 2 * dent_secs + ReservedSections()))
    return 1;
  return 0;
}

/**
 * This function balances dirty node and dentry pages.
 * In addition, it controls garbage collection.
 */
void SegMgr::F2fsBalanceFs() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct WritebackControl wbc = {
#if 0  // porting needed
      // .nr_to_write = LONG_MAX,
      // .sync_mode = WB_SYNC_ALL,
      // .for_reclaim = 0,
#endif
  };

  if (sbi.por_doing)
    return;

  /*
   * We should do checkpoint when there are so many dirty node pages
   * with enough free segments. After then, we should do GC.
   */
  if (NeedToFlush()) {
    fs_->SyncDirtyDirInodes();
    fs_->Nodemgr().SyncNodePages(0, &wbc);
  }

  // TODO: IMPL GC
  if (HasNotEnoughFreeSecs() && PrefreeSegments()) {
#if 0  // porting needed
    // mtx_lock(&sbi.gc_mutex);
    // f2fs_gc(&sbi, 1);
#endif
    fs_->WriteCheckpoint(false, false);
  }
}

void SegMgr::__LocateDirtySegment(unsigned int segno, enum dirty_type dirty_type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);

  /* need not be added */
  if (IS_CURSEG(&sbi, segno))
    return;

  if (!test_and_set_bit(segno, dirty_i->dirty_segmap[dirty_type]))
    dirty_i->nr_dirty[dirty_type]++;

  if (dirty_type == DIRTY) {
    struct seg_entry *sentry = GetSegEntry(segno);
    dirty_type = static_cast<enum dirty_type>(sentry->type);
    if (!test_and_set_bit(segno, dirty_i->dirty_segmap[dirty_type]))
      dirty_i->nr_dirty[dirty_type]++;
  }
}

void SegMgr::__RemoveDirtySegment(unsigned int segno, enum dirty_type dirty_type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);

  if (test_and_clear_bit(segno, dirty_i->dirty_segmap[dirty_type]))
    dirty_i->nr_dirty[dirty_type]--;

  if (dirty_type == DIRTY) {
    struct seg_entry *sentry = GetSegEntry(segno);
    dirty_type = static_cast<enum dirty_type>(sentry->type);
    if (test_and_clear_bit(segno, dirty_i->dirty_segmap[dirty_type]))
      dirty_i->nr_dirty[dirty_type]--;
    clear_bit(segno, dirty_i->victim_segmap[FG_GC]);
    clear_bit(segno, dirty_i->victim_segmap[BG_GC]);
  }
}

/**
 * Should not occur error such as -ENOMEM.
 * Adding dirty entry into seglist is not critical operation.
 * If a given segment is one of current working segments, it won't be added.
 */
void SegMgr::LocateDirtySegment(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  unsigned short valid_blocks;

  if (segno == NULL_SEGNO || IS_CURSEG(&sbi, segno))
    return;

  mtx_lock(&dirty_i->seglist_lock);

  valid_blocks = GetValidBlocks(segno, 0);

  if (valid_blocks == 0) {
    __LocateDirtySegment(segno, PRE);
    __RemoveDirtySegment(segno, DIRTY);
  } else if (valid_blocks < sbi.blocks_per_seg) {
    __LocateDirtySegment(segno, DIRTY);
  } else {
    /* Recovery routine with SSR needs this */
    __RemoveDirtySegment(segno, DIRTY);
  }

  mtx_unlock(&dirty_i->seglist_lock);
  return;
}

/**
 * Should call clear_prefree_segments after checkpoint is done.
 */
void SegMgr::SetPrefreeAsFreeSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  unsigned int segno, offset = 0;
  unsigned int total_segs = TOTAL_SEGS(&sbi);

  mtx_lock(&dirty_i->seglist_lock);
  while (true) {
    segno = find_next_bit_le(dirty_i->dirty_segmap[PRE], total_segs, offset);
    if (segno >= total_segs)
      break;
    __SetTestAndFree(segno);
    offset = segno + 1;
  }
  mtx_unlock(&dirty_i->seglist_lock);
}

void SegMgr::ClearPrefreeSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  unsigned int segno, offset = 0;
  unsigned int total_segs = TOTAL_SEGS(&sbi);

  mtx_lock(&dirty_i->seglist_lock);
  while (true) {
    segno = find_next_bit_le(dirty_i->dirty_segmap[PRE], total_segs, offset);
    if (segno >= total_segs)
      break;

    offset = segno + 1;
    if (test_and_clear_bit(segno, dirty_i->dirty_segmap[PRE]))
      dirty_i->nr_dirty[PRE]--;

#if 0  // porting needed (Trim)
    /* Let's use trim */
    // if (test_opt(sbi, DISCARD))
    //	blkdev_issue_discard(sbi->sb->s_bdev,
    //			START_BLOCK(sbi, segno) <<
    //			sbi->log_sectors_per_block,
    //			1 << (sbi->log_sectors_per_block +
    //				sbi->log_blocks_per_seg),
    //			GFP_NOFS, 0);
#endif
  }
  mtx_unlock(&dirty_i->seglist_lock);
}

void SegMgr::__MarkSitEntryDirty(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  if (!test_and_set_bit_le(segno, sit_i->dirty_sentries_bitmap))
    sit_i->dirty_sentries++;
}

void SegMgr::__SetSitEntryType(int type, unsigned int segno, int modified) {
  struct seg_entry *se = GetSegEntry(segno);
  se->type = type;
  if (modified)
    __MarkSitEntryDirty(segno);
}

void SegMgr::UpdateSitEntry(block_t blkaddr, int del) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct seg_entry *se;
  unsigned int segno, offset;
  long int new_vblocks;

  segno = GET_SEGNO(&sbi, blkaddr);

  se = GetSegEntry(segno);
  new_vblocks = se->valid_blocks + del;
  offset = GET_SEGOFF_FROM_SEG0(&sbi, blkaddr) & (sbi.blocks_per_seg - 1);

  ZX_ASSERT(!((new_vblocks >> (sizeof(unsigned short) << 3) || (new_vblocks > sbi.blocks_per_seg))));

  se->valid_blocks = new_vblocks;
  se->mtime = GetMtime();
  SIT_I(&sbi)->max_mtime = se->mtime;

  /* Update valid block bitmap */
  if (del > 0) {
    if (f2fs_set_bit(offset, reinterpret_cast<char *>(se->cur_valid_map)))
      ZX_ASSERT(0);
  } else {
    if (!f2fs_clear_bit(offset, reinterpret_cast<char *>(se->cur_valid_map)))
      ZX_ASSERT(0);
  }
  if (!f2fs_test_bit(offset, reinterpret_cast<char *>(se->ckpt_valid_map)))
    se->ckpt_valid_blocks += del;

  __MarkSitEntryDirty(segno);

  /* update total number of valid blocks to be written in ckpt area */
  SIT_I(&sbi)->written_valid_blocks += del;

  if (sbi.segs_per_sec > 1)
    GetSecEntry(segno)->valid_blocks += del;
}

void SegMgr::RefreshSitEntry(block_t old_blkaddr, block_t new_blkaddr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  UpdateSitEntry(new_blkaddr, 1);
  if (GET_SEGNO(&sbi, old_blkaddr) != NULL_SEGNO)
    UpdateSitEntry(old_blkaddr, -1);
}

void SegMgr::InvalidateBlocks(block_t addr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  unsigned int segno = GET_SEGNO(&sbi, addr);
  struct sit_info *sit_i = SIT_I(&sbi);

  ZX_ASSERT(addr != NULL_ADDR);
  if (addr == NEW_ADDR)
    return;

  /* add it into sit main buffer */
  mtx_lock(&sit_i->sentry_lock);

  UpdateSitEntry(addr, -1);

  /* add it into dirty seglist */
  LocateDirtySegment(segno);

  mtx_unlock(&sit_i->sentry_lock);
}

/**
 * This function should be resided under the curseg_mutex lock
 */
void SegMgr::__AddSumEntry(int type, struct f2fs_summary *sum, unsigned short offset) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  char *addr = (char *)curseg->sum_blk;
  (addr) += offset * sizeof(struct f2fs_summary);
  memcpy(addr, sum, sizeof(struct f2fs_summary));
}

/**
 * Calculate the number of current summary pages for writing
 */
int SegMgr::NpagesForSummaryFlush() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  int total_size_bytes = 0;
  int valid_sum_count = 0;
  int i, sum_space;

  for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
    if (sbi.ckpt->alloc_type[i] == SSR)
      valid_sum_count += sbi.blocks_per_seg;
    else
      valid_sum_count += CursegBlkoff(i);
  }

  total_size_bytes = valid_sum_count * (SUMMARY_SIZE + 1) + sizeof(struct nat_journal) + 2 +
                     sizeof(struct sit_journal) + 2;
  sum_space = kPageCacheSize - SUM_FOOTER_SIZE;
  if (total_size_bytes < sum_space)
    return 1;
  else if (total_size_bytes < 2 * sum_space)
    return 2;
  return 3;
}

/**
 * Caller should put this summary page
 */
Page *SegMgr::GetSumPage(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  return fs_->GetMetaPage(GET_SUM_BLOCK(&sbi, segno));
}

void SegMgr::WriteSumPage(struct f2fs_summary_block *sum_blk, block_t blk_addr) {
  Page *page = fs_->GrabMetaPage(blk_addr);
  void *kaddr = PageAddress(page);
  memcpy(kaddr, sum_blk, kPageCacheSize);
#if 0  // porting needed
  // set_page_dirty(page);
#endif
  FlushDirtyMetaPage(fs_, page);
  F2fsPutPage(page, 1);
}

unsigned int SegMgr::CheckPrefreeSegments(int ofs_unit, int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  unsigned long *prefree_segmap = dirty_i->dirty_segmap[PRE];
  unsigned int segno, next_segno, i;
  int ofs = 0;

  /*
   * If there is not enough reserved sections,
   * we should not reuse prefree segments.
   */
  if (HasNotEnoughFreeSecs())
    return NULL_SEGNO;

  /*
   * NODE page should not reuse prefree segment,
   * since those information is used for SPOR.
   */
  if (IS_NODESEG(type))
    return NULL_SEGNO;
next:
  segno = find_next_bit_le(prefree_segmap, TOTAL_SEGS(&sbi), ofs++);
  ofs = ((segno / ofs_unit) * ofs_unit) + ofs_unit;
  if (segno < TOTAL_SEGS(&sbi)) {
    /* skip intermediate segments in a section */
    if (segno % ofs_unit)
      goto next;

    /* skip if whole section is not prefree */
    next_segno = find_next_zero_bit(prefree_segmap, TOTAL_SEGS(&sbi), segno + 1);
    if (next_segno - segno < static_cast<unsigned int>(ofs_unit))
      goto next;

    /* skip if whole section was not free at the last checkpoint */
    for (i = 0; i < static_cast<unsigned int>(ofs_unit); i++)
      if (GetSegEntry(segno)->ckpt_valid_blocks)
        goto next;
    return segno;
  }
  return NULL_SEGNO;
}

/**
 * Find a new segment from the free segments bitmap to right order
 * This function should be returned with success, otherwise BUG
 */
void SegMgr::GetNewSegment(unsigned int *newseg, bool new_sec, int dir) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int total_secs = sbi.total_sections;
  unsigned int segno, secno, zoneno;
  unsigned int total_zones = sbi.total_sections / sbi.secs_per_zone;
  unsigned int hint = *newseg / sbi.segs_per_sec;
  unsigned int old_zoneno = GET_ZONENO_FROM_SEGNO(&sbi, *newseg);
  unsigned int left_start = hint;
  bool init = true;
  int go_left = 0;
  int i;

  WriteLock(&free_i->segmap_lock);

  if (!new_sec && ((*newseg + 1) % sbi.segs_per_sec)) {
    segno = find_next_zero_bit(free_i->free_segmap, TOTAL_SEGS(&sbi), *newseg + 1);
    if (segno < TOTAL_SEGS(&sbi))
      goto got_it;
  }
find_other_zone:
  secno = find_next_zero_bit(free_i->free_secmap, total_secs, hint);
  if (secno >= total_secs) {
    if (dir == ALLOC_RIGHT) {
      secno = find_next_zero_bit(free_i->free_secmap, total_secs, 0);
      ZX_ASSERT(!(secno >= total_secs));
    } else {
      go_left = 1;
      left_start = hint - 1;
    }
  }
  if (go_left == 0)
    goto skip_left;

  while (test_bit(left_start, free_i->free_secmap)) {
    if (left_start > 0) {
      left_start--;
      continue;
    }
    left_start = find_next_zero_bit(free_i->free_secmap, total_secs, 0);
    ZX_ASSERT(!(left_start >= total_secs));
    break;
  }
  secno = left_start;
skip_left:
  hint = secno;
  segno = secno * sbi.segs_per_sec;
  zoneno = secno / sbi.secs_per_zone;

  /* give up on finding another zone */
  if (!init)
    goto got_it;
  if (sbi.secs_per_zone == 1)
    goto got_it;
  if (zoneno == old_zoneno)
    goto got_it;
  if (dir == ALLOC_LEFT) {
    if (!go_left && zoneno + 1 >= total_zones)
      goto got_it;
    if (go_left && zoneno == 0)
      goto got_it;
  }
  for (i = 0; i < NR_CURSEG_TYPE; i++)
    if (CURSEG_I(&sbi, i)->zone == zoneno)
      break;

  if (i < NR_CURSEG_TYPE) {
    /* zone is in user, try another */
    if (go_left)
      hint = zoneno * sbi.secs_per_zone - 1;
    else if (zoneno + 1 >= total_zones)
      hint = 0;
    else
      hint = (zoneno + 1) * sbi.secs_per_zone;
    init = false;
    goto find_other_zone;
  }
got_it:
  /* set it as dirty segment in free segmap */
  ZX_ASSERT(!test_bit(segno, free_i->free_segmap));
  __SetInuse(segno);
  *newseg = segno;
  WriteUnlock(&free_i->segmap_lock);
}

void SegMgr::ResetCurseg(int type, int modified) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  struct summary_footer *sum_footer;

  curseg->segno = curseg->next_segno;
  curseg->zone = GET_ZONENO_FROM_SEGNO(&sbi, curseg->segno);
  curseg->next_blkoff = 0;
  curseg->next_segno = NULL_SEGNO;

  sum_footer = &(curseg->sum_blk->footer);
  memset(sum_footer, 0, sizeof(struct summary_footer));
  if (IS_DATASEG(type))
    SET_SUM_TYPE(sum_footer, SUM_TYPE_DATA);
  if (IS_NODESEG(type))
    SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
  __SetSitEntryType(type, curseg->segno, modified);
}

/**
 * Allocate a current working segment.
 * This function always allocates a free segment in LFS manner.
 */
void SegMgr::NewCurseg(int type, bool new_sec) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  unsigned int segno = curseg->segno;
  int dir = ALLOC_LEFT;

  WriteSumPage(curseg->sum_blk, GET_SUM_BLOCK(&sbi, curseg->segno));
  if (type == CURSEG_WARM_DATA || type == CURSEG_COLD_DATA)
    dir = ALLOC_RIGHT;

  if (test_opt(&sbi, NOHEAP))
    dir = ALLOC_RIGHT;

  GetNewSegment(&segno, new_sec, dir);
  curseg->next_segno = segno;
  ResetCurseg(type, 1);
  curseg->alloc_type = LFS;
}

void SegMgr::__NextFreeBlkoff(struct curseg_info *seg, block_t start) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct seg_entry *se = GetSegEntry(seg->segno);
  block_t ofs;
  for (ofs = start; ofs < sbi.blocks_per_seg; ofs++) {
    if (!f2fs_test_bit(ofs, (char *)se->ckpt_valid_map) &&
        !f2fs_test_bit(ofs, (char *)se->cur_valid_map))
      break;
  }
  seg->next_blkoff = ofs;
}

/**
 * If a segment is written by LFS manner, next block offset is just obtained
 * by increasing the current block offset. However, if a segment is written by
 * SSR manner, next block offset obtained by calling __next_free_blkoff
 */
void SegMgr::__RefreshNextBlkoff(struct curseg_info *seg) {
  if (seg->alloc_type == SSR) {
    __NextFreeBlkoff(seg, seg->next_blkoff + 1);
  } else {
    seg->next_blkoff++;
  }
}

/**
 * This function always allocates a used segment (from dirty seglist) by SSR
 * manner, so it should recover the existing segment information of valid blocks
 */
void SegMgr::ChangeCurseg(int type, bool reuse) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  unsigned int new_segno = curseg->next_segno;
  struct f2fs_summary_block *sum_node;
  struct Page *sum_page;

  WriteSumPage(curseg->sum_blk, GET_SUM_BLOCK(&sbi, curseg->segno));
  __SetTestAndInuse(new_segno);

  mtx_lock(&dirty_i->seglist_lock);
  __RemoveDirtySegment(new_segno, PRE);
  __RemoveDirtySegment(new_segno, DIRTY);
  mtx_unlock(&dirty_i->seglist_lock);

  ResetCurseg(type, 1);
  curseg->alloc_type = SSR;
  __NextFreeBlkoff(curseg, 0);

  if (reuse) {
    sum_page = GetSumPage(new_segno);
    sum_node = (struct f2fs_summary_block *)PageAddress(sum_page);
    memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
    F2fsPutPage(sum_page, 1);
  }
}

/*
 * flush out current segment and replace it with new segment
 * This function should be returned with success, otherwise BUG
 */
void SegMgr::AllocateSegmentByDefault(int type, bool force) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  // unsigned int ofs_unit;

  if (force) {
    NewCurseg(type, true);
    goto out;
  }

  // TODO: BUG (we can get next_segno from prefree_segment only after checkpoint)
  // ofs_unit = NeedSSR() ? 1 : sbi.segs_per_sec;
  // curseg->next_segno = CheckPrefreeSegments(ofs_unit, type);

  // if (curseg->next_segno != NULL_SEGNO)
  // 	ChangeCurseg(type, false);
  // else

  if (type == CURSEG_WARM_NODE) {
    NewCurseg(type, false);
  } else if (false) {
#if 0  // porting needed
    // TODO: IMPL (SSR)
    //} else if (NeedSSR() && GetSsrSegment(type)) {
#endif
    ChangeCurseg(type, true);
  } else {
    NewCurseg(type, false);
  }
out:
  sbi.segment_count[curseg->alloc_type]++;

#ifdef F2FS_BU_DEBUG
  std::cout << "SegMgr::AllocateSegmentByDefault, type=" << type
            << ", curseg->segno =" << curseg->segno
            << ", FreeSections()=" << FreeSections()
            << ", PrefreeSegments()=" << PrefreeSegments()
            << ", DirtySegments()=" << DirtySegments()
            << ", TOTAL_SEGS=" << TOTAL_SEGS(&sbi)
            << ", Utilization()=" << Utilization()
            << std::endl;
#endif
}

void SegMgr::AllocateNewSegments() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg;
  unsigned int old_curseg;
  int i;

  for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
    curseg = CURSEG_I(&sbi, i);
    old_curseg = curseg->segno;
    SIT_I(&sbi)->s_ops->allocate_segment(&sbi, i, true);
    LocateDirtySegment(old_curseg);
  }
}

#if 0  // porting needed
/*
const struct segment_allocation default_salloc_ops = {
        .allocate_segment = AllocateSegmentByDefault,
};
*/
#endif

#if 0  // porting needed (bio)
void SegMgr::F2fsEndIoWrite(struct bio *bio, int err) {
  // const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
  // struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
  // struct bio_private *p = bio->bi_private;

  // do {
  // 	struct page *page = bvec->bv_page;

  // 	if (--bvec >= bio->bi_io_vec)
  // 		prefetchw(&bvec->bv_page->flags);
  // 	if (!uptodate) {
  // 		SetPageError(page);
  // 		if (page->mapping)
  // 			set_bit(AS_EIO, &page->mapping->flags);
  // 		p->sbi->ckpt->ckpt_flags |= CP_ERROR_FLAG;
  // 		set_page_dirty(page);
  // 	}
  // 	end_page_writeback(page);
  // 	dec_page_count(p->sbi, F2FS_WRITEBACK);
  // } while (bvec >= bio->bi_io_vec);

  // if (p->is_sync)
  // 	complete(p->wait);
  // kfree(p);
  // bio_put(bio);
}
#endif

#if 0  // porting needed (bio)
struct bio *SegMgr::F2fsBioAlloc(struct block_device *bdev, sector_t first_sector, int nr_vecs,
                                 gfp_t gfp_flags) {
  // 	struct bio *bio;
  // repeat:
  // 	/* allocate new bio */
  // 	bio = bio_alloc(gfp_flags, nr_vecs);

  // 	if (bio == NULL && (current->flags & PF_MEMALLOC)) {
  // 		while (!bio && (nr_vecs /= 2))
  // 			bio = bio_alloc(gfp_flags, nr_vecs);
  // 	}
  // 	if (bio) {
  // 		bio->bi_bdev = bdev;
  // 		bio->bi_sector = first_sector;
  // retry:
  // 		bio->bi_private = kmalloc(sizeof(struct bio_private),
  // 						GFP_NOFS | __GFP_HIGH);
  // 		if (!bio->bi_private) {
  // 			cond_resched();
  // 			goto retry;
  // 		}
  // 	}
  // 	if (bio == NULL) {
  // 		cond_resched();
  // 		goto repeat;
  // 	}
  // 	return bio;
  return nullptr;
}
#endif

#if 0  // porting needed (bio)
void SegMgr::DoSubmitBio(enum page_type type, bool sync) {
  // int rw = sync ? kWriteSync : kWrite;
  // enum page_type btype = type > META ? META : type;

  // if (type >= META_FLUSH)
  // 	rw = kWriteFlushFua;

  // if (sbi->bio[btype]) {
  // 	struct bio_private *p = sbi->bio[btype]->bi_private;
  // 	p->sbi = sbi;
  // 	sbi->bio[btype]->bi_end_io = f2fs_end_io_write;
  // 	if (type == META_FLUSH) {
  // 		DECLARE_COMPLETION_ONSTACK(wait);
  // 		p->is_sync = true;
  // 		p->wait = &wait;
  // 		submit_bio(rw, sbi->bio[btype]);
  // 		wait_for_completion(&wait);
  // 	} else {
  // 		p->is_sync = false;
  // 		submit_bio(rw, sbi->bio[btype]);
  // 	}
  // 	sbi->bio[btype] = NULL;
  // }
}
#endif

#if 0  // porting needed (bio)
void SegMgr::F2fsSubmitBio(enum page_type type, bool sync) {
  // down_write(&sbi->bio_sem);
  // DoSubmitBio(type, sync);
  // up_write(&sbi->bio_sem);
}
#endif

void SegMgr::SubmitWritePage(Page *page, block_t blk_addr, enum page_type type) {

  zx_status_t ret = fs_->bc_->Writeblk(blk_addr, page->data);
  if (ret) {
    std::cout << "SubmitWritePage error " << ret << std::endl;
  }
#if 0  // porting needed (bio)
  //	fs_->bc_->Sync();

  // 	struct block_device *bdev = sbi->sb->s_bdev;

  // 	verify_block_addr(sbi, blk_addr);

  // 	down_write(&sbi->bio_sem);

  // 	inc_page_count(sbi, F2FS_WRITEBACK);

  // 	if (sbi->bio[type] && sbi->last_block_in_bio[type] != blk_addr - 1)
  // 		do_submit_bio(sbi, type, false);
  // alloc_new:
  // 	if (sbi->bio[type] == NULL)
  // 		sbi->bio[type] = f2fs_bio_alloc(bdev,
  // 				blk_addr << (sbi->log_blocksize - 9),
  // 				bio_get_nr_vecs(bdev), GFP_NOFS | __GFP_HIGH);

  // 	if (bio_add_page(sbi->bio[type], page, kPageCacheSize, 0) <
  // 							kPageCacheSize) {
  // 		do_submit_bio(sbi, type, false);
  // 		goto alloc_new;
  // 	}

  // 	sbi->last_block_in_bio[type] = blk_addr;

  // 	up_write(&sbi->bio_sem);
#endif
}

bool SegMgr::__HasCursegSpace(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, type);
  if (curseg->next_blkoff < sbi.blocks_per_seg) {
    return true;
  }
  return false;
}

int SegMgr::__GetSegmentType2(Page *page, enum page_type p_type) {
  if (p_type == DATA)
    return CURSEG_HOT_DATA;
  else
    return CURSEG_HOT_NODE;
}

int SegMgr::__GetSegmentType4(Page *page, enum page_type p_type) {
  if (p_type == DATA) {
    VnodeF2fs *vnode = static_cast<f2fs::VnodeF2fs *>(page->host);

    if (S_ISDIR(vnode->i_mode_))
      return CURSEG_HOT_DATA;
    else
      return CURSEG_COLD_DATA;
  } else {
    if (fs_->Nodemgr().IS_DNODE(page) && !NodeMgr::IsColdNode(page))
      return CURSEG_HOT_NODE;
    else
      return CURSEG_COLD_NODE;
    return 0;
  }
  return 0;
}

int SegMgr::__GetSegmentType6(Page *page, enum page_type p_type) {
  if (p_type == DATA) {
    VnodeF2fs *vnode = static_cast<f2fs::VnodeF2fs *>(page->host);

    if (S_ISDIR(vnode->i_mode_))
      return CURSEG_HOT_DATA;
    else if (NodeMgr::IsColdData(page) || NodeMgr::IsColdFile(vnode))
      return CURSEG_COLD_DATA;
    else
      return CURSEG_WARM_DATA;
  } else {
    if (fs_->Nodemgr().IS_DNODE(page))
      return NodeMgr::IsColdNode(page) ? CURSEG_WARM_NODE : CURSEG_HOT_NODE;
    else
      return CURSEG_COLD_NODE;
  }
  return 0;
}

int SegMgr::__GetSegmentType(Page *page, enum page_type p_type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  switch (sbi.active_logs) {
    case 2:
      return __GetSegmentType2(page, p_type);
    case 4:
      return __GetSegmentType4(page, p_type);
    case 6:
      return __GetSegmentType6(page, p_type);
    default:
      ZX_ASSERT(0);
  }
}

void SegMgr::DoWritePage(Page *page, block_t old_blkaddr, block_t *new_blkaddr,
                         struct f2fs_summary *sum, enum page_type p_type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  struct curseg_info *curseg;
  unsigned int old_cursegno;
  int type;

  type = __GetSegmentType(page, p_type);
  curseg = CURSEG_I(&sbi, type);

  mtx_lock(&curseg->curseg_mutex);
  *new_blkaddr = NEXT_FREE_BLKADDR(&sbi, curseg);
  old_cursegno = curseg->segno;

  /*
   * __add_sum_entry should be resided under the curseg_mutex
   * because, this function updates a summary entry in the
   * current summary block.
   */
  __AddSumEntry(type, sum, curseg->next_blkoff);

  mtx_lock(&sit_i->sentry_lock);
  __RefreshNextBlkoff(curseg);
  sbi.block_count[curseg->alloc_type]++;

  /*
   * SIT information should be updated before segment allocation,
   * since SSR needs latest valid block information.
   */
  RefreshSitEntry(old_blkaddr, *new_blkaddr);

  if (!__HasCursegSpace(type)) {
#if 0  // porting needed
    // sit_i->s_ops->allocate_segment(&sbi, type, false);
#endif
    AllocateSegmentByDefault(type, false);
  }

  LocateDirtySegment(old_cursegno);
  LocateDirtySegment(GET_SEGNO(&sbi, old_blkaddr));
  mtx_unlock(&sit_i->sentry_lock);

  if (p_type == NODE)
    fs_->Nodemgr().FillNodeFooterBlkaddr(page, NEXT_FREE_BLKADDR(&sbi, curseg));

  /* writeout dirty page into bdev */
  SubmitWritePage(page, *new_blkaddr, p_type);

  mtx_unlock(&curseg->curseg_mutex);
}

zx_status_t SegMgr::WriteMetaPage(Page *page, struct WritebackControl *wbc) {
#if 0  // porting needed
  // if (wbc && wbc->for_reclaim)
  // 	return kAopWritepageActivate;
#endif
  SetPageWriteback(page);
  SubmitWritePage(page, page->index, META);
  return ZX_OK;
}

void SegMgr::WriteNodePage(Page *page, unsigned int nid, block_t old_blkaddr,
                           block_t *new_blkaddr) {
  struct f2fs_summary sum;
  SetSummary(&sum, nid, 0, 0);
  DoWritePage(page, old_blkaddr, new_blkaddr, &sum, NODE);
}

void SegMgr::WriteDataPage(VnodeF2fs *vnode, Page *page, struct dnode_of_data *dn,
                           block_t old_blkaddr, block_t *new_blkaddr) {
  struct f2fs_summary sum;
  struct node_info ni;

  ZX_ASSERT(old_blkaddr != NULL_ADDR);
  fs_->Nodemgr().GetNodeInfo(dn->nid, &ni);
  SetSummary(&sum, dn->nid, dn->ofs_in_node, ni.version);

  DoWritePage(page, old_blkaddr, new_blkaddr, &sum, DATA);
}

void SegMgr::RewriteDataPage(Page *page, block_t old_blk_addr) {
  SubmitWritePage(page, old_blk_addr, DATA);
}

void SegMgr::RecoverDataPage(Page *page, struct f2fs_summary *sum, block_t old_blkaddr,
                             block_t new_blkaddr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  struct curseg_info *curseg;
  unsigned int segno, old_cursegno;
  struct seg_entry *se;
  int type;

  segno = GET_SEGNO(&sbi, new_blkaddr);
  se = GetSegEntry(segno);
  type = se->type;

  if (se->valid_blocks == 0 && !IS_CURSEG(&sbi, segno)) {
    if (old_blkaddr == NULL_ADDR) {
      type = CURSEG_COLD_DATA;
    } else {
      type = CURSEG_WARM_DATA;
    }
  }
  curseg = CURSEG_I(&sbi, type);

  mtx_lock(&curseg->curseg_mutex);
  mtx_lock(&sit_i->sentry_lock);

  old_cursegno = curseg->segno;

  /* change the current segment */
  if (segno != curseg->segno) {
    curseg->next_segno = segno;
    ChangeCurseg(type, true);
  }

  curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(&sbi, new_blkaddr) & (sbi.blocks_per_seg - 1);
  __AddSumEntry(type, sum, curseg->next_blkoff);

  RefreshSitEntry(old_blkaddr, new_blkaddr);

  LocateDirtySegment(old_cursegno);
  LocateDirtySegment(GET_SEGNO(&sbi, old_blkaddr));

  mtx_unlock(&sit_i->sentry_lock);
  mtx_unlock(&curseg->curseg_mutex);
}

void SegMgr::RewriteNodePage(Page *page, struct f2fs_summary *sum, block_t old_blkaddr,
                             block_t new_blkaddr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  int type = CURSEG_WARM_NODE;
  struct curseg_info *curseg;
  unsigned int segno, old_cursegno;
  block_t next_blkaddr = NodeMgr::NextBlkaddrOfNode(page);
  unsigned int next_segno = GET_SEGNO(&sbi, next_blkaddr);

  curseg = CURSEG_I(&sbi, type);

  mtx_lock(&curseg->curseg_mutex);
  mtx_lock(&sit_i->sentry_lock);

  segno = GET_SEGNO(&sbi, new_blkaddr);
  old_cursegno = curseg->segno;

  /* change the current segment */
  if (segno != curseg->segno) {
    curseg->next_segno = segno;
    ChangeCurseg(type, true);
  }
  curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(&sbi, new_blkaddr) & (sbi.blocks_per_seg - 1);
  __AddSumEntry(type, sum, curseg->next_blkoff);

  /* change the current log to the next block addr in advance */
  if (next_segno != segno) {
    curseg->next_segno = next_segno;
    ChangeCurseg(type, true);
  }
  curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(&sbi, next_blkaddr) & (sbi.blocks_per_seg - 1);

  /* rewrite node page */
  SetPageWriteback(page);
  SubmitWritePage(page, new_blkaddr, NODE);
#if 0  // porting needed
  F2fsSubmitBio(NODE, true);
#endif
  RefreshSitEntry(old_blkaddr, new_blkaddr);

  LocateDirtySegment(old_cursegno);
  LocateDirtySegment(GET_SEGNO(&sbi, old_blkaddr));

  mtx_unlock(&sit_i->sentry_lock);
  mtx_unlock(&curseg->curseg_mutex);
}

int SegMgr::ReadCompactedSummaries() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  struct curseg_info *seg_i;
  unsigned char *kaddr;
  Page *page;
  block_t start;
  int i, j, offset;

  start = StartSumBlock();

  page = fs_->GetMetaPage(start++);
  kaddr = static_cast<unsigned char *>(PageAddress(page));

  /* Step 1: restore nat cache */
  seg_i = CURSEG_I(&sbi, CURSEG_HOT_DATA);
  memcpy(&seg_i->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);

  /* Step 2: restore sit cache */
  seg_i = CURSEG_I(&sbi, CURSEG_COLD_DATA);
  memcpy(&seg_i->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE);
  offset = 2 * SUM_JOURNAL_SIZE;

  /* Step 3: restore summary entries */
  for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
    unsigned short blk_off;
    unsigned int segno;

    seg_i = CURSEG_I(&sbi, i);
    segno = LeToCpu(ckpt->cur_data_segno[i]);
    blk_off = LeToCpu(ckpt->cur_data_blkoff[i]);
    seg_i->next_segno = segno;
    ResetCurseg(i, 0);
    seg_i->alloc_type = ckpt->alloc_type[i];
    seg_i->next_blkoff = blk_off;

    if (seg_i->alloc_type == SSR)
      blk_off = sbi.blocks_per_seg;

    for (j = 0; j < blk_off; j++) {
      struct f2fs_summary *s;
      s = reinterpret_cast<struct f2fs_summary *>(kaddr + offset);
      seg_i->sum_blk->entries[j] = *s;
      offset += SUMMARY_SIZE;
      if (offset + SUMMARY_SIZE <= kPageCacheSize - SUM_FOOTER_SIZE)
        continue;

      F2fsPutPage(page, 1);
      page = nullptr;

      page = fs_->GetMetaPage(start++);
      kaddr = static_cast<unsigned char *>(PageAddress(page));
      offset = 0;
    }
  }
  F2fsPutPage(page, 1);
  return 0;
}

int SegMgr::ReadNormalSummaries(int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  struct f2fs_summary_block *sum;
  struct curseg_info *curseg;
  Page *new_page;
  unsigned short blk_off;
  unsigned int segno = 0;
  block_t blk_addr = 0;

  /* get segment number and block addr */
  if (IS_DATASEG(type)) {
    segno = LeToCpu(ckpt->cur_data_segno[type]);
    blk_off = LeToCpu(ckpt->cur_data_blkoff[type - CURSEG_HOT_DATA]);
    if (ckpt->ckpt_flags & CP_UMOUNT_FLAG) {
      blk_addr = SumBlkAddr(NR_CURSEG_TYPE, type);
    } else
      blk_addr = SumBlkAddr(NR_CURSEG_DATA_TYPE, type);
  } else {
    segno = LeToCpu(ckpt->cur_node_segno[type - CURSEG_HOT_NODE]);
    blk_off = LeToCpu(ckpt->cur_node_blkoff[type - CURSEG_HOT_NODE]);
    if (ckpt->ckpt_flags & CP_UMOUNT_FLAG) {
      blk_addr = SumBlkAddr(NR_CURSEG_NODE_TYPE, type - CURSEG_HOT_NODE);
    } else
      blk_addr = GET_SUM_BLOCK(&sbi, segno);
  }

  new_page = fs_->GetMetaPage(blk_addr);
  sum = (struct f2fs_summary_block *)PageAddress(new_page);

  if (IS_NODESEG(type)) {
    if (ckpt->ckpt_flags & CP_UMOUNT_FLAG) {
      struct f2fs_summary *ns = &sum->entries[0];
      unsigned int i;
      for (i = 0; i < sbi.blocks_per_seg; i++, ns++) {
        ns->version = 0;
        ns->ofs_in_node = 0;
      }
    } else {
      if (NodeMgr::RestoreNodeSummary(fs_, segno, sum)) {
        F2fsPutPage(new_page, 1);
        return -EINVAL;
      }
    }
  }

  /* set uncompleted segment to curseg */
  curseg = CURSEG_I(&sbi, type);
  mtx_lock(&curseg->curseg_mutex);
  memcpy(curseg->sum_blk, sum, kPageCacheSize);
  curseg->next_segno = segno;
  ResetCurseg(type, 0);
  curseg->alloc_type = ckpt->alloc_type[type];
  curseg->next_blkoff = blk_off;

  mtx_unlock(&curseg->curseg_mutex);
  F2fsPutPage(new_page, 1);
  return 0;
}

int SegMgr::RestoreCursegSummaries() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  int type = CURSEG_HOT_DATA;

  if (sbi.ckpt->ckpt_flags & CP_COMPACT_SUM_FLAG) {
    /* restore for compacted data summary */
    if (ReadCompactedSummaries())
      return -EINVAL;
    type = CURSEG_HOT_NODE;
  }

  for (; type <= CURSEG_COLD_NODE; type++) {
    if (ReadNormalSummaries(type))
      return -EINVAL;
  }
  return 0;
}

void SegMgr::WriteCompactedSummaries(block_t blkaddr) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  Page *page;
  unsigned char *kaddr;
  struct f2fs_summary *summary;
  struct curseg_info *seg_i;
  int written_size = 0;
  int i, j;

  page = fs_->GrabMetaPage(blkaddr++);
  kaddr = (unsigned char *)PageAddress(page);

  /* Step 1: write nat cache */
  seg_i = CURSEG_I(&sbi, CURSEG_HOT_DATA);
  memcpy(kaddr, &seg_i->sum_blk->n_nats, SUM_JOURNAL_SIZE);
  written_size += SUM_JOURNAL_SIZE;

  /* Step 2: write sit cache */
  seg_i = CURSEG_I(&sbi, CURSEG_COLD_DATA);
  memcpy(kaddr + written_size, &seg_i->sum_blk->n_sits, SUM_JOURNAL_SIZE);
  written_size += SUM_JOURNAL_SIZE;

  // set_page_dirty(page);
  FlushDirtyMetaPage(fs_, page);

  /* Step 3: write summary entries */
  for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
    unsigned short blkoff;
    seg_i = CURSEG_I(&sbi, i);
    if (sbi.ckpt->alloc_type[i] == SSR)
      blkoff = sbi.blocks_per_seg;
    else
      blkoff = CursegBlkoff(i);

    for (j = 0; j < blkoff; j++) {
      if (!page) {
        page = fs_->GrabMetaPage(blkaddr++);
        kaddr = (unsigned char *)PageAddress(page);
        written_size = 0;
      }
      summary = (struct f2fs_summary *)(kaddr + written_size);
      *summary = seg_i->sum_blk->entries[j];
      written_size += SUMMARY_SIZE;
#if 0  // porting needed
      // set_page_dirty(page);
#endif
      FlushDirtyMetaPage(fs_, page);

      if (written_size + SUMMARY_SIZE <= kPageCacheSize - SUM_FOOTER_SIZE)
        continue;

      F2fsPutPage(page, 1);
      page = nullptr;
    }
  }
  if (page)
    F2fsPutPage(page, 1);
}

void SegMgr::WriteNormalSummaries(block_t blkaddr, int type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  int i, end;

  if (IS_DATASEG(type))
    end = type + NR_CURSEG_DATA_TYPE;
  else
    end = type + NR_CURSEG_NODE_TYPE;

  for (i = type; i < end; i++) {
    struct curseg_info *sum = CURSEG_I(&sbi, i);
    mtx_lock(&sum->curseg_mutex);
    WriteSumPage(sum->sum_blk, blkaddr + (i - type));
    mtx_unlock(&sum->curseg_mutex);
  }
}

void SegMgr::WriteDataSummaries(block_t start_blk) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  if (sbi.ckpt->ckpt_flags & CP_COMPACT_SUM_FLAG)
    WriteCompactedSummaries(start_blk);
  else
    WriteNormalSummaries(start_blk, CURSEG_HOT_DATA);
}

void SegMgr::WriteNodeSummaries(block_t start_blk) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  if (sbi.ckpt->ckpt_flags & CP_UMOUNT_FLAG)
    WriteNormalSummaries(start_blk, CURSEG_HOT_NODE);
}

int SegMgr::LookupJournalInCursum(struct f2fs_summary_block *sum, int type, unsigned int val,
                                  int alloc) {
  int i;

  if (type == NAT_JOURNAL) {
    for (i = 0; i < nats_in_cursum(sum); i++) {
      if (LeToCpu(nid_in_journal(sum, i)) == val)
        return i;
    }
    if (alloc && nats_in_cursum(sum) < NAT_JOURNAL_ENTRIES)
      return update_nats_in_cursum(sum, 1);
  } else if (type == SIT_JOURNAL) {
    for (i = 0; i < sits_in_cursum(sum); i++) {
      if (LeToCpu(segno_in_journal(sum, i)) == val)
        return i;
    }
    if (alloc && sits_in_cursum(sum) < SIT_JOURNAL_ENTRIES)
      return update_sits_in_cursum(sum, 1);
  }
  return -1;
}

Page *SegMgr::GetCurrentSitPage(unsigned int segno) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
  block_t blk_addr = sit_i->sit_base_addr + offset;

  CheckSegRange(segno);

  /* calculate sit block address */
  if (f2fs_test_bit(offset, sit_i->sit_bitmap))
    blk_addr += sit_i->sit_blocks;

  return fs_->GetMetaPage(blk_addr);
}

Page *SegMgr::GetNextSitPage(unsigned int start) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  Page *src_page, *dst_page;
  pgoff_t src_off, dst_off;
  void *src_addr, *dst_addr;

  src_off = CurrentSitAddr(start);
  dst_off = NextSitAddr(src_off);

  /* get current sit block page without lock */
  src_page = fs_->GetMetaPage(src_off);
  dst_page = fs_->GrabMetaPage(dst_off);
  ZX_ASSERT(!PageDirty(src_page));

  src_addr = PageAddress(src_page);
  dst_addr = PageAddress(dst_page);
  memcpy(dst_addr, src_addr, kPageCacheSize);

#if 0  // porting needed
  // set_page_dirty(dst_page);
#endif
  F2fsPutPage(src_page, 1);

  SetToNextSit(sit_i, start);

  return dst_page;
}

bool SegMgr::FlushSitsInJournal() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *curseg = CURSEG_I(&sbi, CURSEG_COLD_DATA);
  struct f2fs_summary_block *sum = curseg->sum_blk;
  int i;

  /*
   * If the journal area in the current summary is full of sit entries,
   * all the sit entries will be flushed. Otherwise the sit entries
   * are not able to replace with newly hot sit entries.
   */
  if (sits_in_cursum(sum) >= SIT_JOURNAL_ENTRIES) {
    for (i = sits_in_cursum(sum) - 1; i >= 0; i--) {
      unsigned int segno;
      segno = LeToCpu(segno_in_journal(sum, i));
      __MarkSitEntryDirty(segno);
    }
    update_sits_in_cursum(sum, -sits_in_cursum(sum));
    return 1;
  }
  return 0;
}

/**
 * CP calls this function, which flushes SIT entries including sit_journal,
 * and moves prefree segs to free segs.
 */
void SegMgr::FlushSitEntries() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  unsigned long *bitmap = sit_i->dirty_sentries_bitmap;
  struct curseg_info *curseg = CURSEG_I(&sbi, CURSEG_COLD_DATA);
  struct f2fs_summary_block *sum = curseg->sum_blk;
  unsigned long nsegs = TOTAL_SEGS(&sbi);
  Page *page = nullptr;
  struct f2fs_sit_block *raw_sit = nullptr;
  unsigned int start = 0, end = 0;
  unsigned int segno = -1;
  bool flushed;

  mtx_lock(&curseg->curseg_mutex);
  mtx_lock(&sit_i->sentry_lock);

  /*
   * "flushed" indicates whether sit entries in journal are flushed
   * to the SIT area or not.
   */
  flushed = FlushSitsInJournal();

  while ((segno = find_next_bit_le(bitmap, nsegs, segno + 1)) < nsegs) {
    struct seg_entry *se = GetSegEntry(segno);
    int sit_offset, offset;

    sit_offset = SIT_ENTRY_OFFSET(sit_i, segno);

    if (flushed)
      goto to_sit_page;

    offset = LookupJournalInCursum(sum, SIT_JOURNAL, segno, 1);
    if (offset >= 0) {
      segno_in_journal(sum, offset) = CpuToLe(segno);
      SegInfoToRawSit(se, &sit_in_journal(sum, offset));
      goto flush_done;
    }
  to_sit_page:
    if (!page || (start > segno) || (segno > end)) {
      if (page) {
        // set_page_dirty(page, fs_);
        FlushDirtyMetaPage(fs_, page);
        F2fsPutPage(page, 1);
        page = nullptr;
      }

      start = START_SEGNO(sit_i, segno);
      end = start + SIT_ENTRY_PER_BLOCK - 1;

      /* read sit block that will be updated */
      page = GetNextSitPage(start);
      raw_sit = (struct f2fs_sit_block *)PageAddress(page);
    }

    /* udpate entry in SIT block */
    SegInfoToRawSit(se, &raw_sit->entries[sit_offset]);
  flush_done:
    __clear_bit(segno, bitmap);
    sit_i->dirty_sentries--;
  }
  mtx_unlock(&sit_i->sentry_lock);
  mtx_unlock(&curseg->curseg_mutex);

  /* writeout last modified SIT block */
#if 0  // porting needed
  // set_page_dirty(page, fs_);
#endif
  FlushDirtyMetaPage(fs_, page);
  F2fsPutPage(page, 1);

  SetPrefreeAsFreeSegments();
}

/*
 * Build
 */
int SegMgr::BuildSitInfo() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(&sbi);
  struct f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  struct sit_info *sit_i;
  unsigned int sit_segs, start;
  char *src_bitmap, *dst_bitmap;
  unsigned int bitmap_size;

  /* allocate memory for SIT information */
  sit_i = static_cast<sit_info *>(malloc(sizeof(struct sit_info)));
  memset(sit_i, 0, sizeof(struct sit_info));
  if (!sit_i)
    return -ENOMEM;

  SM_I(&sbi)->sit_info = sit_i;

  sit_i->sentries = static_cast<seg_entry *>(calloc(TOTAL_SEGS(&sbi), sizeof(struct seg_entry)));
  if (!sit_i->sentries)
    return -ENOMEM;

  bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(&sbi));
  sit_i->dirty_sentries_bitmap = static_cast<unsigned long *>(malloc(bitmap_size));
  memset(sit_i->dirty_sentries_bitmap, 0, bitmap_size);
  if (!sit_i->dirty_sentries_bitmap)
    return -ENOMEM;

  for (start = 0; start < TOTAL_SEGS(&sbi); start++) {
    sit_i->sentries[start].cur_valid_map =
        static_cast<unsigned char *>(malloc(SIT_VBLOCK_MAP_SIZE));
    memset(sit_i->sentries[start].cur_valid_map, 0, SIT_VBLOCK_MAP_SIZE);
    sit_i->sentries[start].ckpt_valid_map =
        static_cast<unsigned char *>(malloc(SIT_VBLOCK_MAP_SIZE));
    memset(sit_i->sentries[start].ckpt_valid_map, 0, SIT_VBLOCK_MAP_SIZE);
    if (!sit_i->sentries[start].cur_valid_map || !sit_i->sentries[start].ckpt_valid_map)
      return -ENOMEM;
  }

  if (sbi.segs_per_sec > 1) {
    sit_i->sec_entries =
        static_cast<sec_entry *>(calloc(sbi.total_sections, sizeof(struct sec_entry)));
    if (!sit_i->sec_entries)
      return -ENOMEM;
  }

  /* get information related with SIT */
  sit_segs = LeToCpu(raw_super->segment_count_sit) >> 1;

  /* setup SIT bitmap from ckeckpoint pack */
  bitmap_size = __bitmap_size(&sbi, SIT_BITMAP);
  src_bitmap = (char *)__bitmap_ptr(&sbi, SIT_BITMAP);

  dst_bitmap = static_cast<char *>(malloc(bitmap_size));
  memset(dst_bitmap, 0, bitmap_size);
  if (!dst_bitmap)
    return -ENOMEM;
  memcpy(dst_bitmap, src_bitmap, bitmap_size);

#if 0  // porting needed
  /* init SIT information */
  // sit_i->s_ops = &default_salloc_ops;
#endif
  auto cur_time = time(nullptr);

  sit_i->sit_base_addr = LeToCpu(raw_super->sit_blkaddr);
  sit_i->sit_blocks = sit_segs << sbi.log_blocks_per_seg;
  sit_i->written_valid_blocks = LeToCpu(ckpt->valid_block_count);
  sit_i->sit_bitmap = dst_bitmap;
  sit_i->bitmap_size = bitmap_size;
  sit_i->dirty_sentries = 0;
  sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
  sit_i->elapsed_time = LeToCpu(sbi.ckpt->elapsed_time);
  sit_i->mounted_time = cur_time;
  mtx_init(&sit_i->sentry_lock, mtx_plain);
  return 0;
}

int SegMgr::BuildFreeSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_sm_info *sm_info = SM_I(&sbi);
  struct free_segmap_info *free_i;
  unsigned int bitmap_size, sec_bitmap_size;

  /* allocate memory for free segmap information */
  free_i = static_cast<struct free_segmap_info *>(malloc(sizeof(struct free_segmap_info)));
  memset(free_i, 0, sizeof(struct free_segmap_info));

  if (!free_i)
    return -ENOMEM;

  SM_I(&sbi)->free_info = free_i;

  bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(&sbi));
  free_i->free_segmap = static_cast<unsigned long *>(malloc(bitmap_size));
  if (!free_i->free_segmap)
    return -ENOMEM;

  sec_bitmap_size = f2fs_bitmap_size(sbi.total_sections);
  free_i->free_secmap = static_cast<unsigned long *>(malloc(sec_bitmap_size));
  if (!free_i->free_secmap)
    return -ENOMEM;

  /* set all segments as dirty temporarily */
  memset(free_i->free_segmap, 0xff, bitmap_size);
  memset(free_i->free_secmap, 0xff, sec_bitmap_size);

  /* init free segmap information */
  free_i->start_segno = (unsigned int)GET_SEGNO_FROM_SEG0(&sbi, sm_info->main_blkaddr);
  free_i->free_segments = 0;
  free_i->free_sections = 0;

  RwlockInit(&free_i->segmap_lock);
  return 0;
}

int SegMgr::BuildCurseg() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  curseg_info *array = nullptr;
  int i;
  array = static_cast<curseg_info *>(calloc(NR_CURSEG_TYPE, sizeof(*array)));

  if (!array)
    return -ENOMEM;

  SM_I(&sbi)->curseg_array = array;

  for (i = 0; i < NR_CURSEG_TYPE; i++) {
    mtx_init(&array[i].curseg_mutex, mtx_plain);
    array[i].sum_blk = static_cast<f2fs_summary_block *>(malloc(kPageCacheSize));
    memset(array[i].sum_blk, 0, kPageCacheSize);
    if (!array[i].sum_blk)
      return -ENOMEM;
    array[i].segno = NULL_SEGNO;
    array[i].next_blkoff = 0;
  }
  return RestoreCursegSummaries();
}

void SegMgr::BuildSitEntries() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  struct curseg_info *curseg = CURSEG_I(&sbi, CURSEG_COLD_DATA);
  struct f2fs_summary_block *sum = curseg->sum_blk;
  unsigned int start;

  for (start = 0; start < TOTAL_SEGS(&sbi); start++) {
    struct seg_entry *se = &sit_i->sentries[start];
    struct f2fs_sit_block *sit_blk;
    struct f2fs_sit_entry sit;
    Page *page;
    int i;

    mtx_lock(&curseg->curseg_mutex);
    for (i = 0; i < sits_in_cursum(sum); i++) {
      if (LeToCpu(segno_in_journal(sum, i)) == start) {
        sit = sit_in_journal(sum, i);
        mtx_unlock(&curseg->curseg_mutex);
        goto got_it;
      }
    }
    mtx_unlock(&curseg->curseg_mutex);
    page = GetCurrentSitPage(start);
    sit_blk = (struct f2fs_sit_block *)PageAddress(page);
    sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
    F2fsPutPage(page, 1);
  got_it:
    CheckBlockCount(start, &sit);
    SegInfoFromRawSit(se, &sit);
    if (sbi.segs_per_sec > 1) {
      struct sec_entry *e = GetSecEntry(start);
      e->valid_blocks += se->valid_blocks;
    }
  }
}

void SegMgr::InitFreeSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  unsigned int start;
  int type;

  for (start = 0; start < TOTAL_SEGS(&sbi); start++) {
    struct seg_entry *sentry = GetSegEntry(start);
    if (!sentry->valid_blocks)
      __SetFree(start);
  }

  /* set use the current segments */
  for (type = CURSEG_HOT_DATA; type <= CURSEG_COLD_NODE; type++) {
    struct curseg_info *curseg_t = CURSEG_I(&sbi, type);
    __SetTestAndInuse(curseg_t->segno);
  }
}

void SegMgr::InitDirtySegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  struct free_segmap_info *free_i = FREE_I(&sbi);
  unsigned int segno = 0, offset = 0;
  unsigned short valid_blocks;
  int full_block_cnt = 0, dirty_block_cnt = 0;

  while (segno < TOTAL_SEGS(&sbi)) {
    /* find dirty segment based on free segmap */
    segno = FindNextInuse(free_i, TOTAL_SEGS(&sbi), offset);
    if (segno >= TOTAL_SEGS(&sbi))
      break;
    offset = segno + 1;
    valid_blocks = GetValidBlocks(segno, 0);
    if (valid_blocks >= sbi.blocks_per_seg || !valid_blocks) {
      full_block_cnt++;
      continue;
    }
    mtx_lock(&dirty_i->seglist_lock);
    __LocateDirtySegment(segno, DIRTY);
    dirty_block_cnt++;
    mtx_unlock(&dirty_i->seglist_lock);
  }

#ifdef F2FS_BU_DEBUG
  std::cout << "SegMgr::InitDirtySegmap, full_block_cnt=" << full_block_cnt
            << ", dirty_block_cnt=" << dirty_block_cnt << std::endl;
#endif
}

int SegMgr::InitVictimSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  unsigned int bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(&sbi));

  dirty_i->victim_segmap[FG_GC] = static_cast<unsigned long *>(malloc(bitmap_size));
  memset(dirty_i->victim_segmap[FG_GC], 0, bitmap_size);
  dirty_i->victim_segmap[BG_GC] = static_cast<unsigned long *>(malloc(bitmap_size));
  memset(dirty_i->victim_segmap[BG_GC], 0, bitmap_size);

  if (!dirty_i->victim_segmap[FG_GC] || !dirty_i->victim_segmap[BG_GC])
    return -ENOMEM;
  return 0;
}

int SegMgr::BuildDirtySegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i;
  unsigned int bitmap_size, i;

  dirty_i = static_cast<struct dirty_seglist_info *>(malloc(sizeof(struct dirty_seglist_info)));
  memset(dirty_i, 0, sizeof(struct dirty_seglist_info));
  if (!dirty_i)
    return -ENOMEM;

  SM_I(&sbi)->dirty_info = dirty_i;
  mtx_init(&dirty_i->seglist_lock, mtx_plain);

  bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(&sbi));

  for (i = 0; i < NR_DIRTY_TYPE; i++) {
    dirty_i->dirty_segmap[i] = static_cast<unsigned long *>(malloc(bitmap_size));
    memset(dirty_i->dirty_segmap[i], 0, bitmap_size);
    dirty_i->nr_dirty[i] = 0;
    if (!dirty_i->dirty_segmap[i])
      return -ENOMEM;
  }

  InitDirtySegmap();
  return InitVictimSegmap();
}

/**
 * Update min, max modified time for cost-benefit GC algorithm
 */
void SegMgr::InitMinMaxMtime() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  unsigned int segno;

  mtx_lock(&sit_i->sentry_lock);

  sit_i->min_mtime = LLONG_MAX;

  for (segno = 0; segno < TOTAL_SEGS(&sbi); segno += sbi.segs_per_sec) {
    unsigned int i;
    unsigned long long mtime = 0;

    for (i = 0; i < sbi.segs_per_sec; i++)
      mtime += GetSegEntry(segno + i)->mtime;

    mtime = DivU64(mtime, sbi.segs_per_sec);

    if (sit_i->min_mtime > mtime)
      sit_i->min_mtime = mtime;
  }
  sit_i->max_mtime = GetMtime();
  mtx_unlock(&sit_i->sentry_lock);
}

zx_status_t SegMgr::BuildSegmentManager() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(&sbi);
  struct f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  struct f2fs_sm_info *sm_info = nullptr;
  int err;

  sm_info = new f2fs_sm_info;
  if (!sm_info)
    return ZX_ERR_NO_MEMORY;

  /* init sm info */
  sbi.sm_info = sm_info;

  list_initialize(&sm_info->wblist_head);
  SpinLockInit(&sm_info->wblist_lock);
  sm_info->seg0_blkaddr = LeToCpu(raw_super->segment0_blkaddr);
  sm_info->main_blkaddr = LeToCpu(raw_super->main_blkaddr);
  sm_info->segment_count = LeToCpu(raw_super->segment_count);
  sm_info->reserved_segments = LeToCpu(ckpt->rsvd_segment_count);
  sm_info->ovp_segments = LeToCpu(ckpt->overprov_segment_count);
  sm_info->main_segments = LeToCpu(raw_super->segment_count_main);
  sm_info->ssa_blkaddr = LeToCpu(raw_super->ssa_blkaddr);

  err = BuildSitInfo();
  if (err)
    return err;

  err = BuildFreeSegmap();
  if (err)
    return err;

  err = BuildCurseg();
  if (err)
    return err;

  /* reinit free segmap based on SIT */
  BuildSitEntries();

  InitFreeSegmap();
  err = BuildDirtySegmap();
  if (err)
    return err;

#ifdef F2FS_BU_DEBUG
  std::cout << "SegMgr::BuildSegmentManager(), TOTAL_SEGS(&sbi)=" << TOTAL_SEGS(&sbi)
            << std::endl;
  std::cout << "SegMgr::BuildSegmentManager(), ReservedSections()=" << ReservedSections()
            << std::endl;
  std::cout << "SegMgr::BuildSegmentManager(), OverprovisionSections()=" << OverprovisionSections()
            << std::endl;
#endif

  InitMinMaxMtime();
  return ZX_OK;
}

void SegMgr::DiscardDirtySegmap(enum dirty_type dirty_type) {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);

  mtx_lock(&dirty_i->seglist_lock);
  free(dirty_i->dirty_segmap[dirty_type]);
  dirty_i->nr_dirty[dirty_type] = 0;
  mtx_unlock(&dirty_i->seglist_lock);
}

void SegMgr::ResetVictimSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  unsigned int bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(&sbi));
  memset(DIRTY_I(&sbi)->victim_segmap[FG_GC], 0, bitmap_size);
}

void SegMgr::DestroyVictimSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);

  free(dirty_i->victim_segmap[FG_GC]);
  free(dirty_i->victim_segmap[BG_GC]);
}

void SegMgr::DestroyDirtySegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct dirty_seglist_info *dirty_i = DIRTY_I(&sbi);
  int i;

  if (!dirty_i)
    return;

  /* discard pre-free/dirty segments list */
  for (i = 0; i < NR_DIRTY_TYPE; i++)
    DiscardDirtySegmap((dirty_type)i);

  DestroyVictimSegmap();
  SM_I(&sbi)->dirty_info = NULL;
  free(dirty_i);
}

// TODO: destroy_curseg
void SegMgr::DestroyCurseg() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct curseg_info *array = SM_I(&sbi)->curseg_array;
  int i;

  if (!array)
    return;
  SM_I(&sbi)->curseg_array = nullptr;
  for (i = 0; i < NR_CURSEG_TYPE; i++)
    free(array[i].sum_blk);
  free(array);
}

void SegMgr::DestroyFreeSegmap() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct free_segmap_info *free_i = SM_I(&sbi)->free_info;
  if (!free_i)
    return;
  SM_I(&sbi)->free_info = nullptr;
  free(free_i->free_segmap);
  free(free_i->free_secmap);
  free(free_i);
}

void SegMgr::DestroySitInfo() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct sit_info *sit_i = SIT_I(&sbi);
  unsigned int start;

  if (!sit_i)
    return;

  if (sit_i->sentries) {
    for (start = 0; start < TOTAL_SEGS(&sbi); start++) {
      free(sit_i->sentries[start].cur_valid_map);
      free(sit_i->sentries[start].ckpt_valid_map);
    }
  }
  free(sit_i->sentries);
  free(sit_i->sec_entries);
  free(sit_i->dirty_sentries_bitmap);

  SM_I(&sbi)->sit_info = nullptr;
  free(sit_i->sit_bitmap);
  free(sit_i);
}

void SegMgr::DestroySegmentManager() {
  f2fs_sb_info &sbi = fs_->SbInfo();
  struct f2fs_sm_info *sm_info = SM_I(&sbi);

	DestroyDirtySegmap();
  DestroyCurseg();
  DestroyFreeSegmap();
  DestroySitInfo();
  sbi.sm_info = nullptr;
  free(sm_info);
}

}  // namespace f2fs
