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

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);
}

int 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 0;
}

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
