// 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_, &page);
  if (de) {
#if 0  // porting needed
    // kunmap(page);
#endif
    F2fsPutPage(page, 0);
  } else {
    dir->AddLink(vnode->i_name_sp_, 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
