// 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 "f2fs.h"
#include <typeinfo>       // operator typeid

namespace f2fs {

/**
 * We guarantee no failure on the returned page.
 */

Page *F2fs::GrabMetaPage(pgoff_t index) {
  Page *page;
repeat:
  page = GrabCachePage(nullptr, F2FS_META_INO(sbi_), index);
  if (!page) {
#if 0  // porting needed
    // cond_resched();
#endif
    goto repeat;
  }
  /* We wait writeback only inside grab_meta_page() */
  WaitOnPageWriteback(page);
  SetPageUptodate(page);
  return page;
}

Page *F2fs::GetMetaPage(pgoff_t index) {
  Page *page;
repeat:
  page = GrabCachePage(nullptr, F2FS_META_INO(sbi_), index);
  if (!page) {
#if 0  // porting needed
    // cond_resched();
#endif
    goto repeat;
  }
  if (VnodeF2fs::Readpage(this, static_cast<struct Page *>(PageAddress(page)), index, kReadSync)) {
    F2fsPutPage(page, 1);
    goto repeat;
  }
#if 0  // porting needed
  // mark_page_accessed(page);
#endif

  /* We do not allow returning an errorneous page */
  return page;
}

zx_status_t F2fs::F2fsWriteMetaPage(Page *page, WritebackControl *wbc) {
  zx_status_t err;

  WaitOnPageWriteback(page);

  err = this->Segmgr().WriteMetaPage(page, wbc);
  if (err) {
#if 0  // porting needed
    // wbc->pages_skipped++;
    // set_page_dirty(page, this);
#else
    FlushDirtyMetaPage(this, page);
#endif
  }

  DecPageCount(&SbInfo(), F2FS_DIRTY_META);

  /* In this case, we should not unlock this page */
#if 0  // porting needed
  // if (err != kAopWritepageActivate)
  // unlock_page(page);
#endif
  return err;
}

#if 0  // porting needed
// int F2fs::F2fsWriteMetaPages(struct address_space *mapping, WritebackControl *wbc) {
//   struct block_device *bdev = sbi_->sb->s_bdev;
//   long written;

//   if (wbc->for_kupdate)
//   	return 0;

//   if (get_pages(sbi_, F2FS_DIRTY_META) == 0)
//   	return 0;

//   /* if mounting is failed, skip writing node pages */
//   mtx_lock(&sbi_->cp_mutex);
//   written = sync_meta_pages(sbi_.get(), META, bio_get_nr_vecs(bdev));
//   mtx_unlock(&sbi_->cp_mutex);
//   wbc->nr_to_write -= written;
//   return 0;
// }
#endif

int64_t F2fs::SyncMetaPages(enum page_type type, int64_t nr_to_write) {
#if 0  // porting needed
  // address_space *mapping = sbi->meta_inode->i_mapping;
  // pgoff_t index = 0, end = LONG_MAX;
  // pagevec pvec;
  // int64_t nwritten = 0;
  // struct WritebackControl wbc = {
  // 	.for_reclaim = 0,
  // };

  // pagevec_init(&pvec, 0);

  // while (index <= end) {
  // 	int i, nr_pages;
  // 	nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
  // 			PAGECACHE_TAG_DIRTY,
  // 			min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
  // 	if (nr_pages == 0)
  // 		break;

  // 	for (i = 0; i < nr_pages; i++) {
  // 		page *page = pvec.pages[i];
  // 		lock_page(page);
  // 		BUG_ON(page->mapping != mapping);
  // 		BUG_ON(!PageDirty(page));
  // 		ClearPageDirtyForIo(page);
  // 		f2fs_write_meta_page(page, &wbc);
  // 		if (nwritten++ >= nr_to_write)
  // 			break;
  // 	}
  // 	pagevec_release(&pvec);
  // 	cond_resched();
  // }

  // if (nwritten)
  // 	f2fs_submit_bio(sbi, type, nr_to_write == LONG_MAX);

  // return nwritten;
#else
  return 0;
#endif
}

#if 0  // porting needed
// int F2fs::F2fsSetMetaPageDirty(Page *page) {
//   SetPageUptodate(page);
//   if (!PageDirty(page)) {
//     // __set_page_dirty_nobuffers(page);
//     FlushDirtyMetaPage(this, page);
//     inc_page_count(&SbInfo(), F2FS_DIRTY_META);
//     F2FS_SET_SB_DIRT(&SbInfo());
//     return 1;
//   }
//   return 0;
// }
#endif

zx_status_t F2fs::CheckOrphanSpace() {
  f2fs_sb_info &sbi = SbInfo();
  uint32_t max_orphans;
  zx_status_t err = 0;

  /*
   * considering 512 blocks in a segment 5 blocks are needed for cp
   * and log segment summaries. Remaining blocks are used to keep
   * orphan entries with the limitation one reserved segment
   * for cp pack we can have max 1020*507 orphan entries
   */
  max_orphans = (sbi.blocks_per_seg - 5) * F2FS_ORPHANS_PER_BLOCK;
  mtx_lock(&sbi.orphan_inode_mutex);
  if (sbi.n_orphans >= max_orphans)
    err = ZX_ERR_NO_SPACE;
  mtx_unlock(&sbi.orphan_inode_mutex);
  return err;
}

void F2fs::AddOrphanInode(nid_t ino) {
  f2fs_sb_info &sbi = SbInfo();
  list_node_t *head, *this_node;
  orphan_inode_entry *new_entry = nullptr, *orphan = nullptr;

  mtx_lock(&sbi.orphan_inode_mutex);
  head = &sbi.orphan_inode_list;
  list_for_every(head, this_node) {
    orphan = containerof(this_node, orphan_inode_entry, list);
    if (orphan->ino == ino)
      goto out;
    if (orphan->ino > ino)
      break;
    orphan = nullptr;
  }
retry:
#if 0  // porting needed
  // new_entry = kmem_cache_alloc(orphan_entry_slab, GFP_ATOMIC);
#else
  new_entry = new orphan_inode_entry;
#endif
  if (!new_entry) {
#if 0  // porting needed
    // cond_resched();
#endif
    goto retry;
  }
  new_entry->ino = ino;
  list_initialize(&new_entry->list);

  /* add new_oentry into list which is sorted by inode number */
  if (orphan) {
    orphan_inode_entry *prev;

    /* get previous entry */
    prev = containerof(orphan->list.prev, orphan_inode_entry, list);
    if (&prev->list != head) {
      /* insert new orphan inode entry */
      list_add(&prev->list, &new_entry->list);
    } else {
      list_add(head, &new_entry->list);
    }
  } else {
    list_add_tail(head, &new_entry->list);
  }
  sbi.n_orphans++;
out:
  mtx_unlock(&sbi.orphan_inode_mutex);
}

void F2fs::RemoveOrphanInode(nid_t ino) {
  f2fs_sb_info &sbi = SbInfo();
  list_node_t *this_node, *next, *head;
  orphan_inode_entry *orphan;

  mtx_lock(&sbi.orphan_inode_mutex);
  head = &sbi.orphan_inode_list;
  list_for_every_safe(head, this_node, next) {
    orphan = containerof(this_node, orphan_inode_entry, list);
    if (orphan->ino == ino) {
      list_delete(&orphan->list);
#if 0  // porting needed
      // kmem_cache_free(orphan_entry_slab, orphan);
#endif
      delete orphan;
      sbi.n_orphans--;
      break;
    }
  }
  mtx_unlock(&sbi.orphan_inode_mutex);
}

void F2fs::RecoverOrphanInode(nid_t ino) {
  fbl::RefPtr<VnodeF2fs> vnode;
  zx_status_t ret;
  ret = VnodeF2fs::Vget(this, ino, &vnode);
  ZX_ASSERT(ret == ZX_OK);
  vnode->ClearNlink();

  /* truncate all the data during Iput */
  Iput(vnode.get());
  vnode.reset();
}

int F2fs::RecoverOrphanInodes() {
  f2fs_sb_info &sbi = SbInfo();
  block_t start_blk, orphan_blkaddr, i, j;

  if (!(F2FS_CKPT(&sbi)->ckpt_flags & CP_ORPHAN_PRESENT_FLAG))
    return 0;

  sbi.por_doing = 1;
  start_blk = __start_cp_addr(&sbi) + 1;
  orphan_blkaddr = __start_sum_addr(&sbi) - 1;

  for (i = 0; i < orphan_blkaddr; i++) {
    Page *page = GetMetaPage(start_blk + i);
    f2fs_orphan_block *orphan_blk;

    orphan_blk = static_cast<f2fs_orphan_block *>(PageAddress(page));
    for (j = 0; j < LeToCpu(orphan_blk->entry_count); j++) {
      nid_t ino = LeToCpu(orphan_blk->ino[j]);
      RecoverOrphanInode(ino);
    }
    F2fsPutPage(page, 1);
  }
  /* clear Orphan Flag */
  F2FS_CKPT(&sbi)->ckpt_flags &= (~CP_ORPHAN_PRESENT_FLAG);
  sbi.por_doing = 0;
  return 0;
}

void F2fs::WriteOrphanInodes(block_t start_blk) {
  f2fs_sb_info &sbi = SbInfo();
  list_node_t *head, *this_node, *next;
  f2fs_orphan_block *orphan_blk = nullptr;
  Page *page = nullptr;
  uint32_t nentries = 0;
  uint16_t index = 1;
  uint16_t orphan_blocks;

  orphan_blocks =
      static_cast<uint16_t>((sbi.n_orphans + (F2FS_ORPHANS_PER_BLOCK - 1)) / F2FS_ORPHANS_PER_BLOCK);

  mtx_lock(&sbi.orphan_inode_mutex);
  head = &sbi.orphan_inode_list;

  /* loop for each orphan inode entry and write them in Jornal block */
  list_for_every_safe(head, this_node, next) {
    orphan_inode_entry *orphan;

    orphan = containerof(this_node, orphan_inode_entry, list);

    if (nentries == F2FS_ORPHANS_PER_BLOCK) {
      /*
       * an orphan block is full of 1020 entries,
       * then we need to flush current orphan blocks
       * and bring another one in memory
       */
      orphan_blk->blk_addr = CpuToLe(index);
      orphan_blk->blk_count = CpuToLe(orphan_blocks);
      orphan_blk->entry_count = CpuToLe(nentries);
#if 0  // porting needed
      // set_page_dirty(page, this);
#else
      FlushDirtyMetaPage(this, page);
#endif
      F2fsPutPage(page, 1);
      index++;
      start_blk++;
      nentries = 0;
      page = nullptr;
    }
    if (page)
      goto page_exist;

    page = GrabMetaPage(start_blk);
    orphan_blk = static_cast<f2fs_orphan_block *>(PageAddress(page));
    memset(orphan_blk, 0, sizeof(*orphan_blk));
  page_exist:
    orphan_blk->ino[nentries++] = CpuToLe(orphan->ino);
  }
  if (!page)
    goto end;

  orphan_blk->blk_addr = CpuToLe(index);
  orphan_blk->blk_count = CpuToLe(orphan_blocks);
  orphan_blk->entry_count = CpuToLe(nentries);
#if 0  // porting needed
  // set_page_dirty(page, this);
#else
  FlushDirtyMetaPage(this, page);
#endif
  F2fsPutPage(page, 1);
end:
  mtx_unlock(&sbi.orphan_inode_mutex);
}

Page *F2fs::ValidateCheckpoint(block_t cp_addr, uint64_t *version) {
  Page *cp_page_1, *cp_page_2;
  uint64_t blk_size = sbi_->blocksize;
  f2fs_checkpoint *cp_block;
  uint64_t cur_version = 0, pre_version = 0;
  uint32_t crc = 0;
  size_t crc_offset;

  /* Read the 1st cp block in this CP pack */
  cp_page_1 = GetMetaPage(cp_addr);

  /* get the version number */
  cp_block = static_cast<f2fs_checkpoint *>(PageAddress(cp_page_1));
  crc_offset = LeToCpu(cp_block->checksum_offset);
  if (crc_offset >= blk_size)
    goto invalid_cp1;

  crc = *reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(cp_block) + crc_offset);
  if (!F2fsCrcValid(crc, cp_block, crc_offset))
    goto invalid_cp1;

  pre_version = LeToCpu(cp_block->checkpoint_ver);

  /* Read the 2nd cp block in this CP pack */
  cp_addr += LeToCpu(cp_block->cp_pack_total_block_count) - 1;
  cp_page_2 = GetMetaPage(cp_addr);

  cp_block = static_cast<f2fs_checkpoint *>(PageAddress(cp_page_2));
  crc_offset = LeToCpu(cp_block->checksum_offset);
  if (crc_offset >= blk_size)
    goto invalid_cp2;

  crc = *reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(cp_block) + crc_offset);
  if (!F2fsCrcValid(crc, cp_block, crc_offset))
    goto invalid_cp2;

  cur_version = LeToCpu(cp_block->checkpoint_ver);

  if (cur_version == pre_version) {
    *version = cur_version;
    F2fsPutPage(cp_page_2, 1);
    return cp_page_1;
  }
invalid_cp2:
  F2fsPutPage(cp_page_2, 1);
invalid_cp1:
  F2fsPutPage(cp_page_1, 1);
  return nullptr;
}

zx_status_t F2fs::GetValidCheckpoint() {
  f2fs_checkpoint *cp_block;
  f2fs_super_block &fsb = RawSb();
  Page *cp1, *cp2, *cur_page;
  uint64_t blk_size = sbi_->blocksize;
  uint64_t cp1_version = 0, cp2_version = 0;
  uint64_t cp_start_blk_no;

  sbi_->ckpt = static_cast<f2fs_checkpoint *>(malloc(blk_size));
  if (!sbi_->ckpt)
    return -ENOMEM;
  /*
   * Finding out valid cp block involves read both
   * sets( cp pack1 and cp pack 2)
   */
  cp_start_blk_no = LeToCpu(fsb.cp_blkaddr);
  cp1 = ValidateCheckpoint(cp_start_blk_no, &cp1_version);

  /* The second checkpoint pack should start at the next segment */
  cp_start_blk_no += 1 << LeToCpu(fsb.log_blocks_per_seg);
  cp2 = ValidateCheckpoint(cp_start_blk_no, &cp2_version);

  if (cp1 && cp2) {
    if (VerAfter(cp2_version, cp1_version)) {
      cur_page = cp2;
    } else {
      cur_page = cp1;
    }
  } else if (cp1) {
    cur_page = cp1;
  } else if (cp2) {
    cur_page = cp2;
  } else {
    goto fail_no_cp;
  }

  cp_block = static_cast<f2fs_checkpoint *>(PageAddress(cur_page));
  memcpy(sbi_->ckpt, cp_block, blk_size);

#ifdef F2FS_BU_DEBUG
  int i;
  std::cout << std::endl << "F2fs::GetValidCheckpoint" << std::endl;
  for(i = 0; i < MAX_ACTIVE_NODE_LOGS; i++) {
    std::cout << "[" << i << "] cur_node_segno "<< cp_block->cur_node_segno[i]
              << ", cur_node_blkoff="
              << cp_block->cur_node_blkoff[i]
              << std::endl;
  }

  for(i = 0; i < MAX_ACTIVE_NODE_LOGS; i++) {
    std::cout << "[" << i << "] cur_data_segno "<< cp_block->cur_data_segno[i]
              << ", cur_data_blkoff="
              << cp_block->cur_data_blkoff[i]
              << std::endl;
  }
#endif

  F2fsPutPage(cp1, 1);
  F2fsPutPage(cp2, 1);
  return 0;

fail_no_cp:
  free(sbi_->ckpt);
  return -EINVAL;
}

#if 0  // porting needed
// void F2fs::SetDirtyDirPage(VnodeF2fs *vnode, Page *page) {
//   f2fs_sb_info &sbi = SbInfo();
//   list_node_t *head = &sbi.dir_inode_list;
//   dir_inode_entry *new_entry;
//   list_node_t *this_node;

//   if (!S_ISDIR(vnode->i_mode_))
//     return;
// retry:
//   // new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
//   new_entry = new dir_inode_entry;
//   if (!new_entry) {
//     // cond_resched();
//     goto retry;
//   }
//   new_entry->vnode = vnode;
//   list_initialize(&new_entry->list);

//   SpinLock(&sbi.dir_inode_lock);
//   list_for_every(head, this_node) {
//     dir_inode_entry *entry;
//     entry = containerof(this_node, dir_inode_entry, list);
//     if (entry->vnode == vnode) {
//       // kmem_cache_free(inode_entry_slab, new_entry);
//       delete new_entry;
//       goto out;
//     }
//   }
//   list_add_tail(&new_entry->list, head);
//   sbi.n_dirty_dirs++;

//   BUG_ON(!S_ISDIR(inode->i_mode));
// out:
//   inc_page_count(&sbi, F2FS_DIRTY_DENTS);
//   InodeIncDirtyDents(vnode);
//   // SetPagePrivate(page);

//   SpinUnlock(&sbi.dir_inode_lock);
// }

// void F2fs::RemoveDirtyDirInode(VnodeF2fs *vnode) {
//   f2fs_sb_info &sbi = SbInfo();
//   list_node_t *head = &sbi.dir_inode_list;
//   list_node_t *this_node;

//   if (!S_ISDIR(vnode->i_mode_))
//     return;

//   SpinLock(&sbi.dir_inode_lock);
//   // if (AtomicRead(&F2FS_I(vnode)->dirty_dents))
//   if (vnode->fi_.dirty_dents)
//     goto out;

//   list_for_every(head, this_node) {
//     dir_inode_entry *entry;
//     entry = containerof(this_node, dir_inode_entry, list);
//     if (entry->vnode == vnode) {
//       list_delete(&entry->list);
//       // kmem_cache_free(inode_entry_slab, entry);
//       delete entry;
//       sbi.n_dirty_dirs--;
//       break;
//     }
//   }
// out:
//   SpinUnlock(&sbi.dir_inode_lock);
// }
#endif

void F2fs::SyncDirtyDirInodes() {
  f2fs_sb_info &sbi = SbInfo();
  list_node_t *head = &sbi.dir_inode_list;
  dir_inode_entry *entry;
  fbl::RefPtr<VnodeF2fs> vnode;

retry:
  SpinLock(&sbi.dir_inode_lock);
  if (list_is_empty(head)) {
    SpinUnlock(&sbi.dir_inode_lock);
    return;
  }
  entry = containerof(head->next, dir_inode_entry, list);
  vnode.reset(static_cast<VnodeF2fs *>(Igrab(entry->vnode)));
  SpinUnlock(&sbi.dir_inode_lock);
  if (vnode) {
#if 0  // porting needed
    // filemap_flush(vnode->i_mapping);
#endif
    Iput(vnode.get());
    vnode.reset();
  } else {
    /*
     * We should submit bio, since it exists several
     * wribacking dentry pages in the freeing inode.
     */
    // TODO(unknown): bio[type] is empty
    // Segmgr().F2fsSubmitBio(DATA, true);
  }
  goto retry;
}

/**
 * Freeze all the FS-operations for checkpoint.
 */
void F2fs::BlockOperations() TA_NO_THREAD_SAFETY_ANALYSIS {
  f2fs_sb_info &sbi = SbInfo();
  int t;
  struct WritebackControl wbc = {
#if 0  // porting needed
      // .nr_to_write = LONG_MAX,
      // .sync_mode = WB_SYNC_ALL,

      // .for_reclaim = 0,
#endif
  };

  /* Stop renaming operation */
  mutex_lock_op(&sbi, RENAME);
  mutex_lock_op(&sbi, DENTRY_OPS);

retry_dents:
  /* write all the dirty dentry pages */
  SyncDirtyDirInodes();

  mutex_lock_op(&sbi, DATA_WRITE);
  if (get_pages(&sbi, F2FS_DIRTY_DENTS)) {
    mutex_unlock_op(&sbi, DATA_WRITE);
    goto retry_dents;
  }

  /* block all the operations */
  for (t = DATA_NEW; t <= NODE_TRUNC; t++)
    mutex_lock_op(&sbi, static_cast<lock_type>(t));

  mtx_lock(&sbi.write_inode);

  /*
   * POR: we should ensure that there is no dirty node pages
   * until finishing nat/sit flush.
   */
retry:
  Nodemgr().SyncNodePages(0, &wbc);

  mutex_lock_op(&sbi, NODE_WRITE);

  if (get_pages(&sbi, F2FS_DIRTY_NODES)) {
    mutex_unlock_op(&sbi, NODE_WRITE);
    goto retry;
  }
  mtx_unlock(&sbi.write_inode);
}

void F2fs::UnblockOperations() TA_NO_THREAD_SAFETY_ANALYSIS {
  f2fs_sb_info &sbi = SbInfo();
  int t;
  for (t = NODE_WRITE; t >= RENAME; t--)
    mutex_unlock_op(&sbi, static_cast<lock_type>(t));
}

void F2fs::DoCheckpoint(bool is_umount) {
  f2fs_sb_info &sbi = SbInfo();
  f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  nid_t last_nid = 0;
  block_t start_blk;
  Page *cp_page;
  uint32_t data_sum_blocks, orphan_blocks;
  void *kaddr;
  uint32_t crc32 = 0;
  int i;

  /* Flush all the NAT/SIT pages */
  while (get_pages(&sbi, F2FS_DIRTY_META))
    SyncMetaPages(META, LONG_MAX);

  Nodemgr().NextFreeNid(&last_nid);

  /*
   * modify checkpoint
   * version number is already updated
   */
  ckpt->elapsed_time = CpuToLe(static_cast<uint64_t>(Segmgr().GetMtime()));
  ckpt->valid_block_count = CpuToLe(valid_user_blocks(&sbi));
  ckpt->free_segment_count = CpuToLe(Segmgr().FreeSegments());
  for (i = 0; i < 3; i++) {
    ckpt->cur_node_segno[i] = CpuToLe(Segmgr().CursegSegno(i + CURSEG_HOT_NODE));
    ckpt->cur_node_blkoff[i] = CpuToLe(Segmgr().CursegBlkoff(i + CURSEG_HOT_NODE));
    ckpt->alloc_type[i + CURSEG_HOT_NODE] = Segmgr().CursegAllocType(i + CURSEG_HOT_NODE);
  }
  for (i = 0; i < 3; i++) {
    ckpt->cur_data_segno[i] = CpuToLe(Segmgr().CursegSegno(i + CURSEG_HOT_DATA));
    ckpt->cur_data_blkoff[i] = CpuToLe(Segmgr().CursegBlkoff(i + CURSEG_HOT_DATA));
    ckpt->alloc_type[i + CURSEG_HOT_DATA] = Segmgr().CursegAllocType(i + CURSEG_HOT_DATA);

#ifdef F2FS_BU_DEBUG
  std::cout << std::endl << "F2fs::DoCheckpoint " << std::endl;
  std::cout << "[" << i << "] cur_data_segno "<< ckpt->cur_data_segno[i]
            << ", cur_data_blkoff=" <<  ckpt->cur_data_blkoff[i]
            << std::endl;

  std::cout << "[" << i << "] cur_node_segno "<< ckpt->cur_node_segno[i]
            << ", cur_node_blkoff=" <<  ckpt->cur_node_blkoff[i]
            << std::endl;
#endif
  }

  ckpt->valid_node_count = CpuToLe(valid_node_count(&sbi));
  ckpt->valid_inode_count = CpuToLe(valid_inode_count(&sbi));
  ckpt->next_free_nid = CpuToLe(last_nid);

  /* 2 cp  + n data seg summary + orphan inode blocks */
  data_sum_blocks = Segmgr().NpagesForSummaryFlush();
  if (data_sum_blocks < 3) {
    ckpt->ckpt_flags |= CP_COMPACT_SUM_FLAG;
  } else {
    ckpt->ckpt_flags &= (~CP_COMPACT_SUM_FLAG);
  }

  orphan_blocks = (sbi.n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) / F2FS_ORPHANS_PER_BLOCK;
  ckpt->cp_pack_start_sum = 1 + orphan_blocks;
  ckpt->cp_pack_total_block_count = 2 + data_sum_blocks + orphan_blocks;

  if (is_umount) {
    ckpt->ckpt_flags |= CP_UMOUNT_FLAG;
    ckpt->cp_pack_total_block_count += NR_CURSEG_NODE_TYPE;
  } else {
    ckpt->ckpt_flags &= (~CP_UMOUNT_FLAG);
  }

  if (sbi.n_orphans) {
    ckpt->ckpt_flags |= CP_ORPHAN_PRESENT_FLAG;
  } else {
    ckpt->ckpt_flags &= (~CP_ORPHAN_PRESENT_FLAG);
  }

  /* update SIT/NAT bitmap */
  Segmgr().GetSitBitmap(__bitmap_ptr(&sbi, SIT_BITMAP));
  Nodemgr().GetNatBitmap(__bitmap_ptr(&sbi, NAT_BITMAP));

  crc32 = F2fsCrc32(ckpt, LeToCpu(ckpt->checksum_offset));
  *reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(ckpt) +
    LeToCpu(ckpt->checksum_offset)) = CpuToLe(crc32);

  start_blk = __start_cp_addr(&sbi);

  /* write out checkpoint buffer at block 0 */
  cp_page = GrabMetaPage(start_blk++);
  kaddr = PageAddress(cp_page);
  memcpy(kaddr, ckpt, (1 << sbi.log_blocksize));
#if 0  // porting needed
  // set_page_dirty(cp_page, this);
#else
  FlushDirtyMetaPage(this, cp_page);
#endif
  F2fsPutPage(cp_page, 1);

  if (sbi.n_orphans) {
    WriteOrphanInodes(start_blk);
    start_blk += orphan_blocks;
  }

  Segmgr().WriteDataSummaries(start_blk);
  start_blk += data_sum_blocks;
  if (is_umount) {
    Segmgr().WriteNodeSummaries(start_blk);
    start_blk += NR_CURSEG_NODE_TYPE;
  }

  /* writeout checkpoint block */
  cp_page = GrabMetaPage(start_blk);
  kaddr = PageAddress(cp_page);
  memcpy(kaddr, ckpt, (1 << sbi.log_blocksize));
#if 0  // porting needed
  // set_page_dirty(cp_page, this);
#else
  FlushDirtyMetaPage(this, cp_page);
#endif
  F2fsPutPage(cp_page, 1);

  /* wait for previous submitted node/meta pages writeback */
#if 0  // porting needed
  // while (get_pages(&sbi, F2FS_WRITEBACK))
  //	congestion_wait(BLK_RW_ASYNC, HZ / 50);

  // filemap_fdatawait_range(sbi.node_inode->i_mapping, 0, LONG_MAX);
  // filemap_fdatawait_range(sbi.meta_inode->i_mapping, 0, LONG_MAX);
#endif

  /* update user_block_counts */
  sbi.last_valid_block_count = sbi.total_valid_block_count;
  sbi.alloc_valid_block_count = 0;

  /* Here, we only have one bio having CP pack */
#if 0  // porting needed
  // if (sbi.ckpt->ckpt_flags & CP_ERROR_FLAG)
  //	sbi->sb->s_flags |= MS_RDONLY;
  // else
#endif
  SyncMetaPages(META_FLUSH, LONG_MAX);

  Segmgr().ClearPrefreeSegments();
  F2FS_RESET_SB_DIRT(&sbi);
}

/**
 * We guarantee that this checkpoint procedure should not fail.
 */
void F2fs::WriteCheckpoint(bool blocked, bool is_umount) {
  f2fs_sb_info &sbi = SbInfo();
  f2fs_checkpoint *ckpt = F2FS_CKPT(&sbi);
  uint64_t ckpt_ver;

  // TODO(unknown): Need to confirm if blocked is true
  // if (!blocked) {
  mtx_lock(&sbi.cp_mutex);
  BlockOperations();
  //}

#if 0  // porting needed (bio[type] is empty)
  // Segmgr().F2fsSubmitBio(DATA, true);
  // Segmgr().F2fsSubmitBio(NODE, true);
  // Segmgr().F2fsSubmitBio(META, true);
#endif

  /*
   * update checkpoint pack index
   * Increase the version number so that
   * SIT entries and seg summaries are written at correct place
   */
  ckpt_ver = LeToCpu(ckpt->checkpoint_ver);
  ckpt->checkpoint_ver = CpuToLe(static_cast<uint64_t>(++ckpt_ver));

  /* write cached NAT/SIT entries to NAT/SIT area */
  Nodemgr().FlushNatEntries();
  Segmgr().FlushSitEntries();

  Segmgr().ResetVictimSegmap();

  /* unlock all the fs_lock[] in do_checkpoint() */
  DoCheckpoint(is_umount);

  UnblockOperations();
  mtx_unlock(&sbi.cp_mutex);
}

void F2fs::InitOrphanInfo() {
  f2fs_sb_info &sbi = SbInfo();
  mtx_init(&sbi.orphan_inode_mutex, mtx_plain);
  list_initialize(&sbi.orphan_inode_list);
  sbi.n_orphans = 0;
}

#if 0  // porting needed
// int F2fs::CreateCheckpointCaches() {
//   orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry",
//   		sizeof(orphan_inode_entry), nullptr);
//   if (unlikely(!orphan_entry_slab))
//   	return -ENOMEM;
//   inode_entry_slab = f2fs_kmem_cache_create("f2fs_dirty_dir_entry",
//   		sizeof(dir_inode_entry), nullptr);
//   if (unlikely(!inode_entry_slab)) {
//   	kmem_cache_destroy(orphan_entry_slab);
//   	return -ENOMEM;
//   }
//   return 0;
// }

// void F2fs::DestroyCheckpointCaches(void) {
//   // kmem_cache_destroy(orphan_entry_slab);
//   // kmem_cache_destroy(inode_entry_slab);
// }
#endif

}  // namespace f2fs
