// 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 <dirent.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>

#include "src/storage/f2fs/f2fs.h"

namespace f2fs {

#ifdef __Fuchsia__
VnodeF2fs::VnodeF2fs(F2fs *fs, ino_t ino) : PagedVnode(fs), ino_(ino) {}
#else   // __Fuchsia__
VnodeF2fs::VnodeF2fs(F2fs *fs, ino_t ino) : Vnode(fs), ino_(ino) {}
#endif  // __Fuchsia__

fs::VnodeProtocolSet VnodeF2fs::GetProtocols() const {
  if (IsDir()) {
    return fs::VnodeProtocol::kDirectory;
  }
  return fs::VnodeProtocol::kFile;
}

void VnodeF2fs::SetMode(const umode_t &mode) { mode_ = mode; }

umode_t VnodeF2fs::GetMode() const { return mode_; }

bool VnodeF2fs::IsDir() const { return S_ISDIR(mode_); }

bool VnodeF2fs::IsReg() const { return S_ISREG(mode_); }

bool VnodeF2fs::IsLink() const { return S_ISLNK(mode_); }

bool VnodeF2fs::IsChr() const { return S_ISCHR(mode_); }

bool VnodeF2fs::IsBlk() const { return S_ISBLK(mode_); }

bool VnodeF2fs::IsSock() const { return S_ISSOCK(mode_); }

bool VnodeF2fs::IsFifo() const { return S_ISFIFO(mode_); }

bool VnodeF2fs::HasGid() const { return mode_ & S_ISGID; }

bool VnodeF2fs::IsNode() {
  SuperblockInfo &superblock_info = Vfs()->GetSuperblockInfo();
  return ino_ == superblock_info.GetNodeIno();
}

bool VnodeF2fs::IsMeta() {
  SuperblockInfo &superblock_info = Vfs()->GetSuperblockInfo();
  return ino_ == superblock_info.GetMetaIno();
}

#ifdef __Fuchsia__
zx_status_t VnodeF2fs::GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                              [[maybe_unused]] fs::Rights rights,
                                              fs::VnodeRepresentation *info) {
  if (IsDir()) {
    *info = fs::VnodeRepresentation::Directory();
  } else {
    *info = fs::VnodeRepresentation::File();
  }
  return ZX_OK;
}

zx_status_t VnodeF2fs::GetVmo(fuchsia_io::wire::VmoFlags flags, zx::vmo *out_vmo,
                              size_t *out_size) {
  if (flags & fuchsia_io::wire::VmoFlags::kExecute) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  if ((flags & fuchsia_io::wire::VmoFlags::kSharedBuffer) &&
      (flags & fuchsia_io::wire::VmoFlags::kWrite)) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  std::lock_guard lock(mutex_);
  ZX_DEBUG_ASSERT(open_count() > 0);

  if (!IsReg()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  size_t rounded_size = fbl::round_up(size_, static_cast<size_t>(PAGE_SIZE));
  ZX_DEBUG_ASSERT(rounded_size >= size_);
  if (rounded_size == 0) {
    rounded_size = PAGE_SIZE;
  }

  if (auto status = CreatePagedVmo(rounded_size); status != ZX_OK) {
    return status;
  }

  return ClonePagedVmo(flags, rounded_size, out_vmo, out_size);
}

zx_status_t VnodeF2fs::CreatePagedVmo(size_t size) {
  if (!paged_vmo()) {
    if (auto status = EnsureCreatePagedVmo(size); status.is_error()) {
      return status.error_value();
    }
    SetPagedVmoName();
  } else {
    // TODO: Resize paged_vmo() if slice clone is available on a resizable VMO support.
    // It should not return an error because mmapped area can be smaller than file size.
    size_t vmo_size;
    paged_vmo().get_size(&vmo_size);
    if (size > vmo_size) {
      FX_LOGS(WARNING) << "Memory mapped VMO size may be smaller than the file size. (VMO size="
                       << vmo_size << ", File size=" << size << ")";
    }
  }
  return ZX_OK;
}

void VnodeF2fs::SetPagedVmoName() {
  fbl::StringBuffer<ZX_MAX_NAME_LEN> name;
  name.Clear();
  name.AppendPrintf("%s-%.8s", "f2fs", GetNameView().data());
  paged_vmo().set_property(ZX_PROP_NAME, name.data(), name.size());
}

zx_status_t VnodeF2fs::ClonePagedVmo(fuchsia_io::wire::VmoFlags flags, size_t size,
                                     zx::vmo *out_vmo, size_t *out_size) {
  if (!paged_vmo()) {
    return ZX_ERR_NOT_FOUND;
  }

  zx_rights_t rights = ZX_RIGHTS_BASIC | ZX_RIGHT_MAP | ZX_RIGHTS_PROPERTY;
  rights |= (flags & fuchsia_io::wire::VmoFlags::kRead) ? ZX_RIGHT_READ : 0;
  rights |= (flags & fuchsia_io::wire::VmoFlags::kWrite) ? ZX_RIGHT_WRITE : 0;

  uint32_t options;
  if (flags & fuchsia_io::wire::VmoFlags::kSharedBuffer) {
    options = ZX_VMO_CHILD_SLICE;
  } else {
    options = ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE;
  }
  if (!(flags & fuchsia_io::wire::VmoFlags::kWrite)) {
    options |= ZX_VMO_CHILD_NO_WRITE;
  }

  zx::vmo clone;
  size_t clone_size = 0;
  paged_vmo().get_size(&clone_size);
  if (auto status = paged_vmo().create_child(options, 0, clone_size, &clone); status != ZX_OK) {
    FX_LOGS(ERROR) << "Faild to create child VMO" << zx_status_get_string(status);
    return status;
  }
  DidClonePagedVmo();

  if (auto status = clone.replace(rights, &clone); status != ZX_OK) {
    return status;
  }

  *out_size = clone_size;
  *out_vmo = std::move(clone);
  return ZX_OK;
}

void VnodeF2fs::VmoRead(uint64_t offset, uint64_t length) {
  ZX_DEBUG_ASSERT(kBlockSize == PAGE_SIZE);
  ZX_DEBUG_ASSERT(offset % kBlockSize == 0);
  ZX_DEBUG_ASSERT(length);
  ZX_DEBUG_ASSERT(length % kBlockSize == 0);

  // It tries to create and populate a vmo with locked Pages first.
  // The mmap flag for the Pages will be cleared in RecycleNode() when there is no reference to
  // |this|.
  auto vmo_or = PopulateAndGetMmappedVmo(offset, length);
  fs::SharedLock rlock(mutex_);
  if (!paged_vmo()) {
    // Races with calling FreePagedVmo() on another thread can result in stale read requests. Ignore
    // them if the VMO is gone.
    FX_LOGS(WARNING) << "A pager-backed VMO is already freed: " << ZX_ERR_NOT_FOUND;
    return;
  }

  if (vmo_or.is_error()) {
    FX_LOGS(ERROR) << "Failed to read a VMO at " << offset << " + " << length << ", "
                   << vmo_or.status_string();
    ReportPagerError(offset, length, ZX_ERR_BAD_STATE);
    return;
  }

  if (auto ret =
          paged_vfs()->SupplyPages(paged_vmo(), offset, length, std::move(vmo_or.value()), 0);
      ret.is_error()) {
    FX_LOGS(ERROR) << "Failed to supply a VMO to " << offset << " + " << length << ", "
                   << vmo_or.status_string();
    ReportPagerError(offset, length, ZX_ERR_BAD_STATE);
  }
}

zx::status<zx::vmo> VnodeF2fs::PopulateAndGetMmappedVmo(const size_t offset, const size_t length) {
  zx::vmo vmo;
  // It creates a zero-filled vmo, so we don't need to fill an invalidated area with zero.
  if (auto status = vmo.create(length, 0, &vmo); status != ZX_OK) {
    return zx::error(status);
  }

  // Populate |vmo| from its node block if it has inline data.
  if (TestFlag(InodeInfoFlag::kInlineData)) {
    if (auto ret = PopulateVmoWithInlineData(vmo); ret.is_error()) {
      return zx::error(ret.status_value());
    }
    return zx::ok(std::move(vmo));
  }

  pgoff_t block_index = safemath::CheckDiv<pgoff_t>(offset, kBlockSize).ValueOrDie();
  for (size_t copied_bytes = 0; copied_bytes < length; copied_bytes += kBlockSize, ++block_index) {
    LockedPage data_page;
    if (zx_status_t status = GetLockDataPage(block_index, &data_page); status != ZX_OK) {
      // If |data_page| is not a valid Page, just grab one.
      if (status = GrabCachePage(block_index, &data_page); status != ZX_OK) {
        return zx::error(status);
      }
      // Just set a mmapped flag for an invalid page.
      ZX_DEBUG_ASSERT(!data_page->IsUptodate());
      data_page->SetMmapped();
    } else {
      ZX_DEBUG_ASSERT(data_page->IsUptodate());
      // If it is a valid Page, fill |vmo| with |data_page|.
      data_page->SetMmapped();
      vmo.write(data_page->GetAddress(), copied_bytes, kBlockSize);
    }
  }
  return zx::ok(std::move(vmo));
}

void VnodeF2fs::OnNoPagedVmoClones() {
  // Override PagedVnode::OnNoPagedVmoClones().
  // We intend to keep PagedVnode::paged_vmo alive while this vnode has any reference. Here, we just
  // set a ZX_VMO_OP_DONT_NEED hint to allow mm to reclaim the committed pages when there is no
  // clone. This way can avoid a race condition between page fault and paged_vmo release.
  ZX_DEBUG_ASSERT(!has_clones());
  size_t vmo_size;
  paged_vmo().get_size(&vmo_size);
  zx_status_t status = paged_vmo().op_range(ZX_VMO_OP_DONT_NEED, 0, vmo_size, nullptr, 0);
  if (status != ZX_OK) {
    FX_LOGS(WARNING) << "Hinting DONT_NEED on f2fs failed: " << zx_status_get_string(status);
  }
}

void VnodeF2fs::ReportPagerError(const uint64_t offset, const uint64_t length,
                                 const zx_status_t err) {
  if (auto result = paged_vfs()->ReportPagerError(paged_vmo(), offset, length, err);
      result.is_error()) {
    FX_LOGS(ERROR) << "Failed to report pager error to kernel: " << result.status_string();
  }
}
#endif  // __Fuchsia__

zx_status_t VnodeF2fs::InvalidatePagedVmo(uint64_t offset, size_t len) {
  zx_status_t ret = ZX_OK;
#ifdef __Fuchsia__
  fs::SharedLock rlock(mutex_);
  if (paged_vmo()) {
    ret = paged_vmo().op_range(ZX_VMO_OP_ZERO, offset, len, nullptr, 0);
  }
#endif  // __Fuchsia
  return ret;
}

zx_status_t VnodeF2fs::WritePagedVmo(const void *buffer_address, uint64_t offset, size_t len) {
  zx_status_t ret = ZX_OK;
#ifdef __Fuchsia__
  fs::SharedLock rlock(mutex_);
  if (paged_vmo()) {
    ret = paged_vmo().write(buffer_address, offset, len);
  }
#endif  // __Fuchsia
  return ret;
}

void VnodeF2fs::Allocate(F2fs *fs, ino_t ino, uint32_t mode, fbl::RefPtr<VnodeF2fs> *out) {
  // Check if ino is within scope
  fs->GetNodeManager().CheckNidRange(ino);
  if (S_ISDIR(mode)) {
    *out = fbl::MakeRefCounted<Dir>(fs, ino);
  } else {
    *out = fbl::MakeRefCounted<File>(fs, ino);
  }
  (*out)->Init();
}

zx_status_t VnodeF2fs::Create(F2fs *fs, ino_t ino, fbl::RefPtr<VnodeF2fs> *out) {
  if (ino == fs->GetSuperblockInfo().GetNodeIno() || ino == fs->GetSuperblockInfo().GetMetaIno()) {
    *out = fbl::MakeRefCounted<VnodeF2fs>(fs, ino);
    return ZX_OK;
  }

  /* Check if ino is within scope */
  fs->GetNodeManager().CheckNidRange(ino);

  LockedPage node_page;
  if (fs->GetNodeManager().GetNodePage(ino, &node_page) != ZX_OK) {
    return ZX_ERR_NOT_FOUND;
  }

  Node *rn = node_page->GetAddress<Node>();
  Inode &ri = rn->i;

  if (S_ISDIR(ri.i_mode)) {
    *out = fbl::MakeRefCounted<Dir>(fs, ino);
  } else {
    *out = fbl::MakeRefCounted<File>(fs, ino);
  }

  VnodeF2fs *vnode = out->get();

  vnode->Init();
  vnode->SetMode(LeToCpu(ri.i_mode));
  vnode->SetUid(LeToCpu(ri.i_uid));
  vnode->SetGid(LeToCpu(ri.i_gid));
  vnode->SetNlink(ri.i_links);
  vnode->SetSize(LeToCpu(ri.i_size));
  vnode->SetBlocks(LeToCpu(ri.i_blocks));
  vnode->SetATime(LeToCpu(ri.i_atime), LeToCpu(ri.i_atime_nsec));
  vnode->SetCTime(LeToCpu(ri.i_ctime), LeToCpu(ri.i_ctime_nsec));
  vnode->SetMTime(LeToCpu(ri.i_mtime), LeToCpu(ri.i_mtime_nsec));
  vnode->SetGeneration(LeToCpu(ri.i_generation));
  vnode->SetParentNid(LeToCpu(ri.i_pino));
  vnode->SetCurDirDepth(LeToCpu(ri.i_current_depth));
  vnode->SetXattrNid(LeToCpu(ri.i_xattr_nid));
  vnode->SetInodeFlags(LeToCpu(ri.i_flags));
  vnode->SetDirLevel(ri.i_dir_level);
  vnode->fi_.data_version = LeToCpu(fs->GetSuperblockInfo().GetCheckpoint().checkpoint_ver) - 1;
  vnode->SetAdvise(ri.i_advise);
  vnode->GetExtentInfo(ri.i_ext);
  std::string_view name(reinterpret_cast<char *>(ri.i_name), std::min(kMaxNameLen, ri.i_namelen));
  if (ri.i_namelen != name.length() ||
      (ino != fs->GetSuperblockInfo().GetRootIno() && !fs::IsValidName(name))) {
    // TODO: Need to repair the file or set NeedFsck flag when fsck supports repair feature.
    // For now, we set kBad and clear link, so that it can be deleted without purging.
    fbl::RefPtr<VnodeF2fs> failed = std::move(*out);
    failed->ClearNlink();
    failed->SetFlag(InodeInfoFlag::kBad);
    failed.reset();
    out = nullptr;
    return ZX_ERR_NOT_FOUND;
  }

  vnode->SetName(name);

  if (ri.i_inline & kInlineDentry) {
    vnode->SetFlag(InodeInfoFlag::kInlineDentry);
  }
  if (ri.i_inline & kInlineData) {
    vnode->SetFlag(InodeInfoFlag::kInlineData);
  }
  if (ri.i_inline & kExtraAttr) {
    vnode->SetExtraISize(ri.i_extra_isize);
  }
  if (ri.i_inline & kDataExist) {
    vnode->SetFlag(InodeInfoFlag::kDataExist);
  }

  return ZX_OK;
}

zx_status_t VnodeF2fs::OpenNode([[maybe_unused]] ValidatedOptions options,
                                fbl::RefPtr<Vnode> *out_redirect) {
  return ZX_OK;
}

zx_status_t VnodeF2fs::CloseNode() { return ZX_OK; }

void VnodeF2fs::RecycleNode() {
  {
    std::lock_guard lock(mutex_);
    ZX_ASSERT_MSG(open_count() == 0, "RecycleNode[%s:%u]: open_count must be zero (%lu)",
                  GetNameView().data(), GetKey(), open_count());
  }
  ReleasePagedVmo();
  if (GetNlink()) {
    // f2fs removes the last reference to a dirty vnode from the dirty vnode list
    // when there is no dirty Page for the vnode at checkpoint time.
    if (GetDirtyPageCount()) {
      // It can happen only when CpFlag::kCpErrorFlag is set.
      FX_LOGS(WARNING) << "RecycleNode[" << GetNameView().data() << ":" << GetKey()
                       << "]: GetDirtyPageCount() must be zero but " << GetDirtyPageCount()
                       << ". CpFlag::kCpErrorFlag is "
                       << (Vfs()->GetSuperblockInfo().TestCpFlags(CpFlag::kCpErrorFlag)
                               ? "set."
                               : "not set.");
    }
    file_cache_.Reset();
#ifdef __Fuchsia__
    vmo_manager_.Reset();
#endif  // __Fuchsia__
    Vfs()->GetVCache().Downgrade(this);
  } else {
    EvictVnode();
    Deactivate();
    file_cache_.Reset();
#ifdef __Fuchsia__
    vmo_manager_.Reset();
#endif  // __Fuchsia__
    delete this;
  }
}

zx_status_t VnodeF2fs::GetAttributes(fs::VnodeAttributes *a) {
  *a = fs::VnodeAttributes();

  fs::SharedLock rlock(mutex_);
  a->mode = mode_;
  a->inode = ino_;
  a->content_size = size_;
  a->storage_size = GetBlockCount() * kBlockSize;
  a->link_count = nlink_;
  a->creation_time = zx_time_add_duration(ZX_SEC(ctime_.tv_sec), ctime_.tv_nsec);
  a->modification_time = zx_time_add_duration(ZX_SEC(mtime_.tv_sec), mtime_.tv_nsec);

  return ZX_OK;
}

zx_status_t VnodeF2fs::SetAttributes(fs::VnodeAttributesUpdate attr) {
  bool need_inode_sync = false;

  {
    std::lock_guard wlock(mutex_);
    if (attr.has_creation_time()) {
      SetCTime(zx_timespec_from_duration(attr.take_creation_time()));
      need_inode_sync = true;
    }
    if (attr.has_modification_time()) {
      SetMTime(zx_timespec_from_duration(attr.take_modification_time()));
      need_inode_sync = true;
    }
  }

  if (attr.any()) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (need_inode_sync) {
    MarkInodeDirty();
  }

  return ZX_OK;
}

struct f2fs_iget_args {
  uint64_t ino;
  int on_free;
};

#if 0  // porting needed
// void VnodeF2fs::F2fsSetInodeFlags() {
  // uint64_t &flags = fi.i_flags;

  // inode_.i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE |
  //     S_NOATIME | S_DIRSYNC);

  // if (flags & FS_SYNC_FL)
  //   inode_.i_flags |= S_SYNC;
  // if (flags & FS_APPEND_FL)
  //   inode_.i_flags |= S_APPEND;
  // if (flags & FS_IMMUTABLE_FL)
  //   inode_.i_flags |= S_IMMUTABLE;
  // if (flags & FS_NOATIME_FL)
  //   inode_.i_flags |= S_NOATIME;
  // if (flags & FS_DIRSYNC_FL)
  //   inode_.i_flags |= S_DIRSYNC;
// }

// int VnodeF2fs::F2fsIgetTest(void *data) {
  // f2fs_iget_args *args = (f2fs_iget_args *)data;

  // if (ino_ != args->ino)
  //   return 0;
  // if (i_state & (I_FREEING | I_WILL_FREE)) {
  //   args->on_free = 1;
  //   return 0;
  // }
  // return 1;
// }

// VnodeF2fs *VnodeF2fs::F2fsIgetNowait(uint64_t ino) {
//   fbl::RefPtr<VnodeF2fs> vnode_refptr;
//   VnodeF2fs *vnode = nullptr;
//   f2fs_iget_args args = {.ino = ino, .on_free = 0};
//   vnode = ilookup5(sb, ino, F2fsIgetTest, &args);

//   if (vnode)
//     return vnode;
//   if (!args.on_free) {
//     Vget(Vfs(), ino, &vnode_refptr);
//     vnode = vnode_refptr.get();
//     return vnode;
//   }
//   return static_cast<VnodeF2fs *>(ErrPtr(ZX_ERR_NOT_FOUND));
// }
#endif

zx_status_t VnodeF2fs::Vget(F2fs *fs, ino_t ino, fbl::RefPtr<VnodeF2fs> *out) {
  fbl::RefPtr<VnodeF2fs> vnode_refptr;

  if (fs->LookupVnode(ino, &vnode_refptr) == ZX_OK) {
    vnode_refptr->WaitForInit();
    *out = std::move(vnode_refptr);
    return ZX_OK;
  }

  if (zx_status_t status = Create(fs, ino, &vnode_refptr); status != ZX_OK) {
    return status;
  }

  if (!(ino == fs->GetSuperblockInfo().GetNodeIno() ||
        ino == fs->GetSuperblockInfo().GetMetaIno())) {
    if (!fs->GetSuperblockInfo().IsOnRecovery() && vnode_refptr->GetNlink() == 0) {
      vnode_refptr->SetFlag(InodeInfoFlag::kBad);
      vnode_refptr.reset();
      *out = nullptr;
      return ZX_ERR_NOT_FOUND;
    }
  }

  if (zx_status_t status = fs->InsertVnode(vnode_refptr.get()); status != ZX_OK) {
    vnode_refptr->SetFlag(InodeInfoFlag::kBad);
    vnode_refptr.reset();
    if (fs->LookupVnode(ino, &vnode_refptr) == ZX_OK) {
      vnode_refptr->WaitForInit();
      *out = std::move(vnode_refptr);
      return ZX_OK;
    }
  }

  vnode_refptr->UnlockNewInode();
  *out = std::move(vnode_refptr);

  return ZX_OK;
}

void VnodeF2fs::UpdateInode(Page *node_page) {
  Node *rn;
  Inode *ri;

  node_page->WaitOnWriteback();

  rn = node_page->GetAddress<Node>();
  ri = &(rn->i);

  ri->i_mode = CpuToLe(GetMode());
  ri->i_advise = GetAdvise();
  ri->i_uid = CpuToLe(GetUid());
  ri->i_gid = CpuToLe(GetGid());
  ri->i_links = CpuToLe(GetNlink());
  ri->i_size = CpuToLe(GetSize());
  ri->i_blocks = CpuToLe(GetBlocks());
  SetRawExtent(ri->i_ext);

  ri->i_atime = CpuToLe(static_cast<uint64_t>(atime_.tv_sec));
  ri->i_ctime = CpuToLe(static_cast<uint64_t>(ctime_.tv_sec));
  ri->i_mtime = CpuToLe(static_cast<uint64_t>(mtime_.tv_sec));
  ri->i_atime_nsec = CpuToLe(static_cast<uint32_t>(atime_.tv_nsec));
  ri->i_ctime_nsec = CpuToLe(static_cast<uint32_t>(ctime_.tv_nsec));
  ri->i_mtime_nsec = CpuToLe(static_cast<uint32_t>(mtime_.tv_nsec));
  ri->i_current_depth = CpuToLe(static_cast<uint32_t>(GetCurDirDepth()));
  ri->i_xattr_nid = CpuToLe(GetXattrNid());
  ri->i_flags = CpuToLe(GetInodeFlags());
  ri->i_pino = CpuToLe(GetParentNid());
  ri->i_generation = CpuToLe(GetGeneration());
  ri->i_dir_level = GetDirLevel();

  std::string_view name = GetNameView();
  // double check |name|
  ZX_DEBUG_ASSERT(IsValidNameLength(name));
  auto size = safemath::checked_cast<uint32_t>(name.size());
  ri->i_namelen = CpuToLe(size);
  name.copy(reinterpret_cast<char *>(&ri->i_name[0]), size);

  if (TestFlag(InodeInfoFlag::kInlineData)) {
    ri->i_inline |= kInlineData;
  } else {
    ri->i_inline &= ~kInlineData;
  }
  if (TestFlag(InodeInfoFlag::kInlineDentry)) {
    ri->i_inline |= kInlineDentry;
  } else {
    ri->i_inline &= ~kInlineDentry;
  }
  if (GetExtraISize()) {
    ri->i_inline |= kExtraAttr;
    ri->i_extra_isize = GetExtraISize();
  }
  if (TestFlag(InodeInfoFlag::kDataExist)) {
    ri->i_inline |= kDataExist;
  } else {
    ri->i_inline &= ~kDataExist;
  }

  node_page->SetDirty();
}

zx_status_t VnodeF2fs::WriteInode(bool is_reclaim) {
  SuperblockInfo &superblock_info = Vfs()->GetSuperblockInfo();
  zx_status_t ret = ZX_OK;

  if (ino_ == superblock_info.GetNodeIno() || ino_ == superblock_info.GetMetaIno()) {
    return ret;
  }

  if (IsDirty()) {
    fs::SharedLock rlock(superblock_info.GetFsLock(LockType::kNodeOp));
    LockedPage node_page;
    if (ret = Vfs()->GetNodeManager().GetNodePage(ino_, &node_page); ret != ZX_OK) {
      return ret;
    }
    UpdateInode(node_page.get());
  }

  return ZX_OK;
}

zx_status_t VnodeF2fs::DoTruncate(size_t len) {
  zx_status_t ret;

  if (ret = TruncateBlocks(len); ret == ZX_OK) {
    SetSize(len);
    if (GetSize() == 0) {
      ClearFlag(InodeInfoFlag::kDataExist);
    }

    timespec cur_time;
    clock_gettime(CLOCK_REALTIME, &cur_time);
    SetCTime(cur_time);
    SetMTime(cur_time);
    MarkInodeDirty();
  }

  Vfs()->GetSegmentManager().BalanceFs();
  return ret;
}

int VnodeF2fs::TruncateDataBlocksRange(NodePage &node_page, uint32_t ofs_in_node, uint32_t count) {
  int nr_free = 0;
  Node *raw_node = node_page.GetAddress<Node>();

  for (; count > 0; --count, ++ofs_in_node) {
    uint32_t *addr = BlkaddrInNode(*raw_node) + ofs_in_node;
    block_t blkaddr = LeToCpu(*addr);
    if (blkaddr == kNullAddr)
      continue;
    SetDataBlkaddr(node_page, ofs_in_node, kNullAddr);
    UpdateExtentCache(kNullAddr, node_page.StartBidxOfNode() + ofs_in_node);
    Vfs()->GetSegmentManager().InvalidateBlocks(blkaddr);
    Vfs()->DecValidBlockCount(this, 1);
    ++nr_free;
  }
  if (nr_free) {
    node_page.SetDirty();
    MarkInodeDirty();
  }
  return nr_free;
}

void VnodeF2fs::TruncateDataBlocks(NodePage &node_page) {
  TruncateDataBlocksRange(node_page, 0, kAddrsPerBlock);
}

void VnodeF2fs::TruncatePartialDataPage(uint64_t from) {
  size_t offset = from & (kPageSize - 1);
  fbl::RefPtr<Page> page;

  if (!offset)
    return;

  if (FindDataPage(from >> kPageCacheShift, &page) != ZX_OK)
    return;

  LockedPage locked_page(page);
  locked_page->WaitOnWriteback();
  locked_page->ZeroUserSegment(static_cast<uint32_t>(offset), kPageSize);
  locked_page->SetDirty();

  if (locked_page->IsMmapped()) {
    ZX_ASSERT(WritePagedVmo(locked_page->GetAddress(), (from >> kPageCacheShift) * kBlockSize,
                            kBlockSize) == ZX_OK);
  }
}

zx_status_t VnodeF2fs::TruncateBlocks(uint64_t from) {
  SuperblockInfo &superblock_info = Vfs()->GetSuperblockInfo();
  uint32_t blocksize = superblock_info.GetBlocksize();
  int count = 0;
  zx_status_t err;

  if (from > GetSize())
    return ZX_OK;

  pgoff_t free_from =
      static_cast<pgoff_t>((from + blocksize - 1) >> (superblock_info.GetLogBlocksize()));

  {
    fs::SharedLock rlock(superblock_info.GetFsLock(LockType::kFileOp));
    auto locked_data_pages = InvalidatePages(free_from);

    do {
      LockedPage node_page;
      err = Vfs()->GetNodeManager().FindLockedDnodePage(*this, free_from, &node_page);
      if (err) {
        if (err == ZX_ERR_NOT_FOUND)
          break;
        return err;
      }

      if (IsInode(*node_page)) {
        count = kAddrsPerInode;
      } else {
        count = kAddrsPerBlock;
      }

      uint32_t ofs_in_node;
      if (auto result = Vfs()->GetNodeManager().GetOfsInDnode(*this, free_from);
          result.is_error()) {
        return result.error_value();
      } else {
        ofs_in_node = result.value();
      }
      count -= ofs_in_node;
      ZX_ASSERT(count >= 0);

      if (ofs_in_node || IsInode(*node_page)) {
        TruncateDataBlocksRange(node_page.GetPage<NodePage>(), ofs_in_node, count);
        free_from += count;
      }
    } while (false);

    err = Vfs()->GetNodeManager().TruncateInodeBlocks(*this, free_from);
  }
  // lastly zero out the first data page
  TruncatePartialDataPage(from);

  return err;
}

zx_status_t VnodeF2fs::TruncateHole(pgoff_t pg_start, pgoff_t pg_end) {
  std::vector<LockedPage> locked_data_pages = InvalidatePages(pg_start, pg_end);
  for (pgoff_t index = pg_start; index < pg_end; ++index) {
    LockedPage dnode_page;
    if (zx_status_t err = Vfs()->GetNodeManager().GetLockedDnodePage(*this, index, &dnode_page);
        err != ZX_OK) {
      if (err == ZX_ERR_NOT_FOUND) {
        continue;
      }
      return err;
    }

    uint32_t ofs_in_dnode;
    if (auto result = Vfs()->GetNodeManager().GetOfsInDnode(*this, index); result.is_error()) {
      if (result.error_value() == ZX_ERR_NOT_FOUND) {
        continue;
      }
      return result.error_value();
    } else {
      ofs_in_dnode = result.value();
    }

    if (DatablockAddr(&dnode_page.GetPage<NodePage>(), ofs_in_dnode) != kNullAddr) {
      TruncateDataBlocksRange(dnode_page.GetPage<NodePage>(), ofs_in_dnode, 1);
    }
  }
  return ZX_OK;
}

void VnodeF2fs::TruncateToSize() {
  if (!(IsDir() || IsReg() || IsLink()))
    return;

  if (zx_status_t ret = TruncateBlocks(GetSize()); ret == ZX_OK) {
    timespec cur_time;
    clock_gettime(CLOCK_REALTIME, &cur_time);
    SetMTime(cur_time);
    SetCTime(cur_time);
  }
}

void VnodeF2fs::ReleasePagedVmo() {
  zx::status<bool> valid_vmo_or;
  {
    std::lock_guard lock(mutex_);
    valid_vmo_or = ReleasePagedVmoUnsafe();
    ZX_DEBUG_ASSERT(valid_vmo_or.is_ok());
  }
  // If necessary, clear the mmap flag in its node Page after releasing its paged VMO.
  if (valid_vmo_or.value() && TestFlag(InodeInfoFlag::kInlineData)) {
    LockedPage inline_page;
    if (zx_status_t ret = Vfs()->GetNodeManager().GetNodePage(Ino(), &inline_page); ret == ZX_OK) {
      inline_page->ClearMmapped();
    } else {
      FX_LOGS(WARNING) << "Failed to get the inline data page. " << ret;
    }
  }
}

zx::status<bool> VnodeF2fs::ReleasePagedVmoUnsafe() {
#ifdef __Fuchsia__
  if (paged_vmo()) {
    fbl::RefPtr<fs::Vnode> pager_reference = FreePagedVmo();
    ZX_DEBUG_ASSERT(!pager_reference);
    return zx::ok(true);
  }
#endif
  return zx::ok(false);
}

// Called at Recycle if nlink_ is zero
void VnodeF2fs::EvictVnode() {
  SuperblockInfo &superblock_info = Vfs()->GetSuperblockInfo();

  if (ino_ == superblock_info.GetNodeIno() || ino_ == superblock_info.GetMetaIno())
    return;

  if (GetNlink() || IsBad())
    return;

  SetFlag(InodeInfoFlag::kNoAlloc);
  SetSize(0);

  if (HasBlocks())
    TruncateToSize();

  {
    fs::SharedLock rlock(superblock_info.GetFsLock(LockType::kFileOp));
    Vfs()->GetNodeManager().RemoveInodePage(this);
    ZX_ASSERT(GetDirtyPageCount() == 0);
  }
  Vfs()->EvictVnode(this);
}

void VnodeF2fs::Init() {
  SetCurDirDepth(1);
  SetFlag(InodeInfoFlag::kInit);
  Activate();
}

void VnodeF2fs::MarkInodeDirty() {
  if (SetFlag(InodeInfoFlag::kDirty)) {
    return;
  }
  if (IsNode() || IsMeta()) {
    return;
  }
  if (!GetNlink()) {
    return;
  }
  ZX_ASSERT(Vfs()->GetVCache().AddDirty(this) == ZX_OK);
}

#ifdef __Fuchsia__
void VnodeF2fs::Sync(SyncCallback closure) {
  closure(SyncFile(0, safemath::checked_cast<loff_t>(GetSize()), 0));
}
#endif  // __Fuchsia__

bool VnodeF2fs::NeedDoCheckpoint() {
  if (!IsReg()) {
    return true;
  }
  if (GetNlink() != 1) {
    return true;
  }
  if (TestFlag(InodeInfoFlag::kNeedCp)) {
    return true;
  }
  if (!Vfs()->SpaceForRollForward()) {
    return true;
  }
  if (NeedToSyncDir()) {
    return true;
  }
  if (Vfs()->GetSuperblockInfo().TestOpt(kMountDisableRollForward)) {
    return true;
  }
  return false;
}

zx_status_t VnodeF2fs::SyncFile(loff_t start, loff_t end, int datasync) {
  // When kCpErrorFlag is set, write is not allowed.
  if (Vfs()->GetSuperblockInfo().TestCpFlags(CpFlag::kCpErrorFlag)) {
    return ZX_ERR_BAD_STATE;
  }

  // TODO: When fdatasync is available, check if it should be written.
  if (!IsDirty()) {
    return ZX_OK;
  }

  // Write out dirty data pages and wait for completion
  WritebackOperation op = {.bSync = true};
  Writeback(op);

  // TODO: STRICT mode will be supported when FUA interface is added.
  // Currently, only POSIX mode is supported.
  // TODO: We should consider fdatasync for WriteInode().
  WriteInode(false);
  bool need_cp = NeedDoCheckpoint();

  if (need_cp) {
    Vfs()->SyncFs();
    ClearFlag(InodeInfoFlag::kNeedCp);
    // Check if checkpoint errors happen during fsync().
    if (Vfs()->GetSuperblockInfo().TestCpFlags(CpFlag::kCpErrorFlag)) {
      return ZX_ERR_BAD_STATE;
    }
  } else {
    // Write dnode pages
    Vfs()->GetNodeManager().FsyncNodePages(*this);
    Vfs()->GetBc().Flush();

    // TODO: Add flags to log recovery information to NAT entries and decide whether to write inode
    // or not.
  }
  return ZX_OK;
}

bool VnodeF2fs::NeedToSyncDir() {
  ZX_ASSERT(GetParentNid() < kNullIno);
  return !Vfs()->GetNodeManager().IsCheckpointedNode(GetParentNid());
}

#ifdef __Fuchsia__
void VnodeF2fs::Notify(std::string_view name, fuchsia_io::wire::WatchEvent event) {
  watcher_.Notify(name, event);
}

zx_status_t VnodeF2fs::WatchDir(fs::Vfs *vfs, fuchsia_io::wire::WatchMask mask, uint32_t options,
                                fidl::ServerEnd<fuchsia_io::DirectoryWatcher> watcher) {
  return watcher_.WatchDir(vfs, this, mask, options, std::move(watcher));
}
#endif  // __Fuchsia__

void VnodeF2fs::GetExtentInfo(const Extent &i_ext) {
  std::lock_guard lock(fi_.ext.ext_lock);
  fi_.ext.fofs = LeToCpu(i_ext.fofs);
  fi_.ext.blk_addr = LeToCpu(i_ext.blk_addr);
  fi_.ext.len = LeToCpu(i_ext.len);
}

void VnodeF2fs::SetRawExtent(Extent &i_ext) {
  fs::SharedLock lock(fi_.ext.ext_lock);
  i_ext.fofs = CpuToLe(static_cast<uint32_t>(fi_.ext.fofs));
  i_ext.blk_addr = CpuToLe(fi_.ext.blk_addr);
  i_ext.len = CpuToLe(fi_.ext.len);
}

void VnodeF2fs::UpdateVersion() {
  fi_.data_version = LeToCpu(Vfs()->GetSuperblockInfo().GetCheckpoint().checkpoint_ver);
}

}  // namespace f2fs
