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

namespace f2fs {

bool F2fs::SpaceForRollForward() {
  SbInfo &sbi = GetSbInfo();
  if (sbi.last_valid_block_count + sbi.alloc_valid_block_count > sbi.user_block_count)
    return false;
  return true;
}

FsyncInodeEntry *F2fs::GetFsyncInode(list_node_t *head, nid_t ino) {
  list_node_t *this_node;
  FsyncInodeEntry *entry;

  list_for_every(head, this_node) {
    entry = containerof(this_node, FsyncInodeEntry, list);
    if (entry->vnode->Ino() == ino)
      return entry;
  }
  return nullptr;
}

zx_status_t F2fs::RecoverDentry(Page *ipage, VnodeF2fs *vnode) {
  Node *raw_node = static_cast<Node *>(PageAddress(ipage));
  Inode *raw_inode = &(raw_node->i);
  fbl::RefPtr<VnodeF2fs> dir_refptr;
  Dir *dir;
  DirEntry *de;
  Page *page;
  zx_status_t err = ZX_OK;

  if (!Nodemgr().IsDentDnode(ipage))
    goto out;

  err = VnodeF2fs::Vget(this, LeToCpu(raw_inode->i_pino), &dir_refptr);
  if (err != ZX_OK) {
    goto out;
  }

  dir = static_cast<Dir *>(dir_refptr.get());

#if 0  // porting needed
  // parent.d_inode = dir;
  // dent.d_parent = &parent;
  // dent.d_name.len = LeToCpu(raw_inode->i_namelen);
  // dent.d_name.name = raw_inode->i_name;
#endif

  de = dir->FindEntry(vnode->i_name_sp_.GetStringView(), &page);
  if (de) {
#if 0  // porting needed
    // kunmap(page);
#endif
    F2fsPutPage(page, 0);
  } else {
    dir->AddLink(vnode->i_name_sp_.GetStringView(), vnode);
  }
  Iput(dir);
out:
#if 0  // porting needed
  // kunmap(ipage);
#endif
  return err;
}

zx_status_t F2fs::RecoverInode(VnodeF2fs *vnode, Page *node_page) {
  void *kaddr = PageAddress(node_page);
  struct Node *raw_node = static_cast<Node *>(kaddr);
  struct Inode *raw_inode = &(raw_node->i);

  vnode->i_mode_ = LeToCpu(raw_inode->i_mode);
  vnode->i_size_ = LeToCpu(raw_inode->i_size);
  vnode->i_atime_.tv_sec = LeToCpu(raw_inode->i_mtime);
  vnode->i_ctime_.tv_sec = LeToCpu(raw_inode->i_ctime);
  vnode->i_mtime_.tv_sec = LeToCpu(raw_inode->i_mtime);
  vnode->i_atime_.tv_nsec = LeToCpu(raw_inode->i_mtime_nsec);
  vnode->i_ctime_.tv_nsec = LeToCpu(raw_inode->i_ctime_nsec);
  vnode->i_mtime_.tv_nsec = LeToCpu(raw_inode->i_mtime_nsec);

  return RecoverDentry(node_page, vnode);
}

zx_status_t F2fs::FindFsyncDnodes(list_node_t *head) {
  SbInfo &sbi = GetSbInfo();
  uint64_t cp_ver = LeToCpu(sbi.ckpt->checkpoint_ver);
  CursegInfo *curseg;
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  Page *page;
  block_t blkaddr;
  Inode *ri;
  Node *rn;
  zx_status_t err = 0;

  /* get node pages in the current segment */
  curseg = SegMgr::CURSEG_I(&sbi, CursegType::kCursegWarmNode);
  blkaddr = StartBlock(&sbi, curseg->segno) + curseg->next_blkoff;

  /* read node page */
  page = GrabCachePage(nullptr, NodeIno(sbi_.get()), blkaddr);
  if (!page)
    return ZX_ERR_NO_MEMORY;
#if 0  // porting needed
  // lock_page(page);
#endif

  while (true) {
    FsyncInodeEntry *entry;
    void *kaddr = PageAddress(page);
    rn = static_cast<Node *>(kaddr);

    if (VnodeF2fs::Readpage(this, page, blkaddr, kReadSync)) {
      goto out;
    }

#ifdef F2FS_BU_DEBUG
    std::cout << "F2fs::FindFsyncDnodes, blkaddr=" << blkaddr << ", ino=" << rn->footer.ino
              << ", nid=" << rn->footer.nid << ", flag=" << rn->footer.flag
              << ", cp_ver=" << rn->footer.cp_ver << ", next_blkaddr=" << rn->footer.next_blkaddr
              << std::endl;
#endif

    if (cp_ver != Nodemgr().CpverOfNode(page)) {
      goto out;
    }

    if (!Nodemgr().IsFsyncDnode(page)) {
      goto next;
    }

    entry = GetFsyncInode(head, Nodemgr().InoOfNode(page));
    if (entry) {
      entry->blkaddr = blkaddr;
      if (IsInode(page) && Nodemgr().IsDentDnode(page)) {
        SetInodeFlag(&entry->vnode->fi_, InodeInfoFlag::kIncLink);
      }
    } else {
      if (IsInode(page) && Nodemgr().IsDentDnode(page)) {
        if (Nodemgr().RecoverInodePage(page)) {
          err = ZX_ERR_NO_MEMORY;
          goto out;
        }
      }

      /* add this fsync inode to the list */
      // entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS);
      entry = new FsyncInodeEntry;
      if (!entry) {
        err = ZX_ERR_NO_MEMORY;
        goto out;
      }
      list_initialize(&entry->list);
      list_add_tail(&entry->list, head);
      // vnode_refptr.reset(entry->vnode);
      // err = VnodeF2fs::Vget(this, Nodemgr().InoOfNode(page), &vnode_refptr);
      rn = static_cast<Node *>(PageAddress(page));
      ri = &(rn->i);

      entry->vnode = vnode_refptr.get();
      if (entry->vnode == nullptr) {
        err = ZX_ERR_NO_MEMORY;
        goto out;
      }
      entry->blkaddr = blkaddr;
    }
    if (IsInode(page)) {
      err = RecoverInode(entry->vnode, page);
      if (err) {
        goto out;
      }
    }
  next:
    /* check next segment */
    blkaddr = NodeMgr::NextBlkaddrOfNode(page);
    ClearPageUptodate(page);
  }
out:
#if 0  // porting needed
  // unlock_page(page);
  //__free_pages(page, 0);
#endif
  delete page;
  return err;
}

void F2fs::DestroyFsyncDnodes(list_node_t *head) {
  list_node_t *this_node;
  FsyncInodeEntry *entry;
  list_for_every(head, this_node) {
    entry = containerof(this_node, FsyncInodeEntry, list);
    Iput(entry->vnode);
    list_delete(&entry->list);
#if 0  // porting needed
    // kmem_cache_free(fsync_entry_slab, entry);
#endif
    delete entry;
  }
}

void F2fs::CheckIndexInPrevNodes(block_t blkaddr) {
  SbInfo &sbi = GetSbInfo();
  SegEntry *sentry;
  uint32_t segno = GetSegNo(&sbi, blkaddr);
  uint16_t blkoff = GetSegOffFromSeg0(&sbi, blkaddr) & (sbi.blocks_per_seg - 1);
  Summary sum;
  nid_t ino;
  void *kaddr;
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode;
  Page *node_page = nullptr;
  block_t bidx;
  int i;
  zx_status_t err = 0;

  sentry = Segmgr().GetSegEntry(segno);
  if (!f2fs_test_bit(blkoff, reinterpret_cast<char *>(sentry->cur_valid_map)))
    return;

  /* Get the previous summary */
  for (i = static_cast<int>(CursegType::kCursegWarmData);
       i <= static_cast<int>(CursegType::kCursegColdData); i++) {
    CursegInfo *curseg = Segmgr().CURSEG_I(&sbi, static_cast<CursegType>(i));
    if (curseg->segno == segno) {
      sum = curseg->sum_blk->entries[blkoff];
      break;
    }
  }
  if (i > static_cast<int>(CursegType::kCursegColdData)) {
    Page *sum_page = Segmgr().GetSumPage(segno);
    SummaryBlock *sum_node;
    kaddr = PageAddress(sum_page);
    sum_node = static_cast<SummaryBlock *>(kaddr);
    sum = sum_node->entries[blkoff];
    F2fsPutPage(sum_page, 1);
  }

  /* Get the node page */
  err = Nodemgr().GetNodePage(LeToCpu(sum.nid), &node_page);
#ifdef F2FS_BU_DEBUG
  if (err) {
    std::cout << "F2fs::CheckIndexInPrevNodes, GetNodePage Error!!!" << std::endl;
    return;
  }
#endif
  bidx = StartBidxOfNode(Nodemgr().OfsOfNode(node_page)) + LeToCpu(sum.ofs_in_node);
  ino = Nodemgr().InoOfNode(node_page);
  F2fsPutPage(node_page, 1);

  /* Deallocate previous index in the node page */
#if 0  // porting needed
  // vnode = F2fsIgetNowait(ino);
#else
  VnodeF2fs::Vget(this, ino, &vnode_refptr);
  vnode = vnode_refptr.get();
#endif
  vnode->TruncateHole(bidx, bidx + 1);
  Iput(vnode);
}

void F2fs::DoRecoverData(VnodeF2fs *vnode, Page *page, block_t blkaddr) {
  uint32_t start, end;
  DnodeOfData dn;
  Summary sum;
  NodeInfo ni;

  start = StartBidxOfNode(Nodemgr().OfsOfNode(page));
  if (IsInode(page)) {
    end = start + kAddrsPerInode;
  } else {
    end = start + kAddrsPerBlock;
  }

  SetNewDnode(&dn, vnode, nullptr, nullptr, 0);
  if (Nodemgr().GetDnodeOfData(&dn, start, 0))
    return;

  WaitOnPageWriteback(dn.node_page);

  Nodemgr().GetNodeInfo(dn.nid, &ni);
  ZX_ASSERT(ni.ino == Nodemgr().InoOfNode(page));
  ZX_ASSERT(Nodemgr().OfsOfNode(dn.node_page) == Nodemgr().OfsOfNode(page));

  for (; start < end; start++) {
    block_t src, dest;

    src = DatablockAddr(dn.node_page, dn.ofs_in_node);
    dest = DatablockAddr(page, dn.ofs_in_node);

    if (src != dest && dest != kNewAddr && dest != kNullAddr) {
      if (src == kNullAddr) {
        int err = vnode->ReserveNewBlock(&dn);
        /* We should not get -ENOSPC */
        ZX_ASSERT(!err);
      }

      /* Check the previous node page having this index */
      CheckIndexInPrevNodes(dest);

      Segmgr().SetSummary(&sum, dn.nid, dn.ofs_in_node, ni.version);

      /* write dummy data page */
      Segmgr().RecoverDataPage(nullptr, &sum, src, dest);
      vnode->UpdateExtentCache(dest, &dn);
    }
    dn.ofs_in_node++;
  }

  /* write node page in place */
  Segmgr().SetSummary(&sum, dn.nid, 0, 0);
  if (IsInode(dn.node_page))
    Nodemgr().SyncInodePage(&dn);

  Nodemgr().CopyNodeFooter(dn.node_page, page);
  Nodemgr().FillNodeFooter(dn.node_page, dn.nid, ni.ino, Nodemgr().OfsOfNode(page), false);
#if 0  // porting needed
  // set_page_dirty(dn.node_page, this);
#else
  FlushDirtyNodePage(this, dn.node_page);
#endif

  Nodemgr().RecoverNodePage(dn.node_page, &sum, &ni, blkaddr);
  F2fsPutDnode(&dn);
}

void F2fs::RecoverData(list_node_t *head, CursegType type) {
  SbInfo &sbi = GetSbInfo();
  uint64_t cp_ver = LeToCpu(sbi.ckpt->checkpoint_ver);
  CursegInfo *curseg;
  Page *page;
  block_t blkaddr;

  /* get node pages in the current segment */
  curseg = SegMgr::CURSEG_I(&sbi, type);
  blkaddr = NextFreeBlkAddr(&sbi, curseg);

  /* read node page */
  page = GrabCachePage(nullptr, NodeIno(sbi_.get()), blkaddr);
  if (page == nullptr)
    return;
#if 0  // porting needed
  // lock_page(page);
#endif

  while (true) {
    FsyncInodeEntry *entry;

    if (VnodeF2fs::Readpage(this, page, blkaddr, kReadSync))
      goto out;

    if (cp_ver != Nodemgr().CpverOfNode(page))
      goto out;

    entry = GetFsyncInode(head, Nodemgr().InoOfNode(page));
    if (!entry)
      goto next;

    DoRecoverData(entry->vnode, page, blkaddr);

    if (entry->blkaddr == blkaddr) {
      Iput(entry->vnode);
      list_delete(&entry->list);
#if 0  // porting needed
      // kmem_cache_free(fsync_entry_slab, entry);
#endif
      delete entry;
    }
  next:
    /* check next segment */
    blkaddr = NodeMgr::NextBlkaddrOfNode(page);
    ClearPageUptodate(page);
  }
out:
#if 0  // porting needed
  // unlock_page(page);
  //__free_pages(page, 0);
#endif
  F2fsPutPage(page, 1);

  Segmgr().AllocateNewSegments();
}

void F2fs::RecoverFsyncData() {
  SbInfo &sbi = GetSbInfo();
  list_node_t inode_list;

#if 0  // porting needed
  // fsync_entry_slab = KmemCacheCreate("f2fs_FsyncInodeEntry",
  // 		sizeof(FsyncInodeEntry), NULL);
  // if (unlikely(!fsync_entry_slab))
  // 	return;
#endif

  list_initialize(&inode_list);

  /* step #1: find fsynced inode numbers */
  if (FindFsyncDnodes(&inode_list)) {
    goto out;
  }

  if (list_is_empty(&inode_list)) {
    goto out;
  }

  /* step #2: recover data */
  sbi.por_doing = 1;
  RecoverData(&inode_list, CursegType::kCursegWarmNode);
  sbi.por_doing = 0;
  ZX_ASSERT(list_is_empty(&inode_list));
out:
  DestroyFsyncDnodes(&inode_list);
#if 0  // porting needed
  // kmem_cache_destroy(fsync_entry_slab);
#endif
  WriteCheckpoint(false, false);
}

}  // namespace f2fs
