// 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 <sys/stat.h>

#include "f2fs.h"

namespace f2fs {

// Orinially in f2fs_internal.h
static inline bool IncValidBlockCount(f2fs_sb_info *sbi, VnodeF2fs *vnode,
                                         blkcnt_t count) {
  block_t valid_block_count;

  SpinLock(&sbi->stat_lock);
  valid_block_count = sbi->total_valid_block_count + static_cast<block_t>(count);
  if (valid_block_count > sbi->user_block_count) {
    SpinUnlock(&sbi->stat_lock);
    return false;
  }
  vnode->i_blocks_ += count;
  sbi->total_valid_block_count = valid_block_count;
  sbi->alloc_valid_block_count += static_cast<block_t>(count);
  SpinUnlock(&sbi->stat_lock);
  return true;
}

// gc
block_t StartBidxOfNode(unsigned int node_ofs) {
  block_t start_bidx;
  unsigned int bidx, indirect_blks;
  int dec;

  indirect_blks = 2 * NIDS_PER_BLOCK + 4;

  start_bidx = 1;
  if (node_ofs == 0) {
    start_bidx = 0;
  } else if (node_ofs <= 2) {
    bidx = node_ofs - 1;
  } else if (node_ofs <= indirect_blks) {
    dec = (node_ofs - 4) / (NIDS_PER_BLOCK + 1);
    bidx = node_ofs - 2 - dec;
  } else {
    dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1);
    bidx = node_ofs - 5 - dec;
  }

  if (start_bidx)
    start_bidx = bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE;
  return start_bidx;
}

/**
 * Lock ordering for the change of data block address:
 * ->data_page
 *  ->node_page
 *    update block addresses in the node page
 */
void VnodeF2fs::SetDataBlkaddr(dnode_of_data *dn, block_t new_addr) {
  f2fs_node *rn;
  uint32_t *addr_array;
  Page *node_page = dn->node_page;
  unsigned int ofs_in_node = dn->ofs_in_node;

  WaitOnPageWriteback(node_page);

  rn = static_cast<f2fs_node *>(PageAddress(node_page));

  /* Get physical address of data block */
  addr_array = blkaddr_in_node(rn);
  addr_array[ofs_in_node] = CpuToLe(new_addr);
#if 0  // porting needed
  // set_page_dirty(node_page);
#else
  FlushDirtyNodePage(Vfs(), node_page);
#endif
}

int VnodeF2fs::ReserveNewBlock(dnode_of_data *dn) {
  f2fs_sb_info &sbi = fs_->SbInfo();

  if (is_inode_flag_set(&dn->vnode->fi_, FI_NO_ALLOC))
    return -EPERM;
  if (!IncValidBlockCount(&sbi, dn->vnode, 1))
    return -ENOSPC;

  SetDataBlkaddr(dn, NEW_ADDR);
  dn->data_blkaddr = NEW_ADDR;
  fs_->Nodemgr().SyncInodePage(dn);
  return 0;
}

#if 0  // porting needed
// int VnodeF2fs::CheckExtentCache(inode *inode, pgoff_t pgofs,
//           buffer_head *bh_result)
// {
//   f2fs_inode_info *fi = F2FS_I(inode);
//   //f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
//   f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
//   pgoff_t start_fofs, end_fofs;
//   block_t start_blkaddr;

//   ReadLock(&fi->ext.ext_lock);
//   if (fi->ext.len == 0) {
//     ReadUnlock(&fi->ext.ext_lock);
//     return 0;
//   }

//   sbi->total_hit_ext++;
//   start_fofs = fi->ext.fofs;
//   end_fofs = fi->ext.fofs + fi->ext.len - 1;
//   start_blkaddr = fi->ext.blk_addr;

//   if (pgofs >= start_fofs && pgofs <= end_fofs) {
//     unsigned int blkbits = inode->i_sb->s_blocksize_bits;
//     size_t count;

//     clear_buffer_new(bh_result);
//     map_bh(bh_result, inode->i_sb,
//        start_blkaddr + pgofs - start_fofs);
//     count = end_fofs - pgofs + 1;
//     if (count < (UINT_MAX >> blkbits))
//       bh_result->b_size = (count << blkbits);
//     else
//       bh_result->b_size = UINT_MAX;

//     sbi->read_hit_ext++;
//     ReadUnlock(&fi->ext.ext_lock);
//     return 1;
//   }
//   ReadUnlock(&fi->ext.ext_lock);
//   return 0;
// }
#endif

void VnodeF2fs::UpdateExtentCache(block_t blk_addr, dnode_of_data *dn) {
  f2fs_inode_info *fi = &dn->vnode->fi_;
  pgoff_t fofs, start_fofs, end_fofs;
  block_t start_blkaddr, end_blkaddr;

  ZX_ASSERT(blk_addr != NEW_ADDR);
  fofs = StartBidxOfNode(Vfs()->Nodemgr().OfsOfNode(dn->node_page)) + dn->ofs_in_node;

  /* Update the page address in the parent node */
  SetDataBlkaddr(dn, blk_addr);

  WriteLock(&fi->ext.ext_lock);

  start_fofs = fi->ext.fofs;
  end_fofs = fi->ext.fofs + fi->ext.len - 1;
  start_blkaddr = fi->ext.blk_addr;
  end_blkaddr = fi->ext.blk_addr + fi->ext.len - 1;

  /* Drop and initialize the matched extent */
  if (fi->ext.len == 1 && fofs == start_fofs)
    fi->ext.len = 0;

  do {
    /* Initial extent */
    if (fi->ext.len == 0) {
      if (blk_addr != NULL_ADDR) {
        fi->ext.fofs = fofs;
        fi->ext.blk_addr = blk_addr;
        fi->ext.len = 1;
      }
      break;
    }

    /* Frone merge */
    if (fofs == start_fofs - 1 && blk_addr == start_blkaddr - 1) {
      fi->ext.fofs--;
      fi->ext.blk_addr--;
      fi->ext.len++;
      break;
    }

    /* Back merge */
    if (fofs == end_fofs + 1 && blk_addr == end_blkaddr + 1) {
      fi->ext.len++;
      break;
    }

    /* Split the existing extent */
    if (fi->ext.len > 1 && fofs >= start_fofs && fofs <= end_fofs) {
      if ((end_fofs - fofs) < (fi->ext.len >> 1)) {
        fi->ext.len = fofs - start_fofs;
      } else {
        fi->ext.fofs = fofs + 1;
        fi->ext.blk_addr = start_blkaddr + fofs - start_fofs + 1;
        fi->ext.len -= fofs - start_fofs + 1;
      }
      break;
    }
    WriteUnlock(&fi->ext.ext_lock);
    return;
  } while(false);

  WriteUnlock(&fi->ext.ext_lock);
  Vfs()->Nodemgr().SyncInodePage(dn);
}

zx_status_t VnodeF2fs::FindDataPage(pgoff_t index, Page **out) {
#if 0  // porting needed
  // address_space *mapping = inode->i_mapping;
#endif
  dnode_of_data dn;
  Page *page = nullptr;

#if 0  // porting needed
  // page = FindGetPage(mapping, index);
  // if (page && PageUptodate(page))
  //   return page;
  // F2fsPutPage(page, 0);
#endif

  SetNewDnode(&dn, this, NULL, NULL, 0);
  if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, RDONLY_NODE); err != ZX_OK)
    return err;
  F2fsPutDnode(&dn);

  if (dn.data_blkaddr == NULL_ADDR)
    return ZX_ERR_NOT_FOUND;

  /* By fallocate(), there is no cached page, but with NEW_ADDR */
  if (dn.data_blkaddr == NEW_ADDR)
    return ZX_ERR_INVALID_ARGS;

  if (page = GrabCachePage(this, ino_, index); page == nullptr)
    return ZX_ERR_NO_MEMORY;

  if (zx_status_t err = Readpage(Vfs(), page, dn.data_blkaddr, kReadSync); err != ZX_OK) {
    F2fsPutPage(page, 1);
    return err;
  }
#if 0  // porting needed
  // unlock_page(page);
#endif
  *out = page;
  return ZX_OK;
}

/**
 * If it tries to access a hole, return an error.
 * Because, the callers, functions in dir.c and GC, should be able to know
 * whether this page exists or not.
 */
zx_status_t VnodeF2fs::GetLockDataPage(pgoff_t index, Page **out) {
  dnode_of_data dn;
  Page *page;

  page = nullptr;

  SetNewDnode(&dn, this, NULL, NULL, 0);
  if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, RDONLY_NODE); err != ZX_OK)
    return err;
  F2fsPutDnode(&dn);

  if (dn.data_blkaddr == NULL_ADDR) {
    return ZX_ERR_NOT_FOUND;
  }

  if (page = GrabCachePage(this, ino_, index); page == nullptr)
    return ZX_ERR_NO_MEMORY;

  if (PageUptodate(page)) {
    *out = page;
    return ZX_OK;
  }

  ZX_ASSERT(dn.data_blkaddr != NEW_ADDR);
  ZX_ASSERT(dn.data_blkaddr != NULL_ADDR);

  if (zx_status_t err = VnodeF2fs::Readpage(fs_, page, dn.data_blkaddr, kReadSync); err != ZX_OK) {
    F2fsPutPage(page, 1);
    return err;
  }
  *out = page;
  return ZX_OK;
}

/**
 * Caller ensures that this data page is never allocated.
 * A new zero-filled data page is allocated in the page cache.
 */
zx_status_t VnodeF2fs::GetNewDataPage(pgoff_t index, bool new_i_size, Page **out) {
#if 0  // porting needed
  // address_space *mapping = inode->i_mapping;
#endif
  Page *page;
  dnode_of_data dn;

  SetNewDnode(&dn, this, NULL, NULL, 0);
  if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, 0); err != ZX_OK)
    return err;

  if (dn.data_blkaddr == NULL_ADDR) {
    if (ReserveNewBlock(&dn)) {
      F2fsPutDnode(&dn);
      return ZX_ERR_NO_SPACE;
    }
  }
  F2fsPutDnode(&dn);

  if (page = GrabCachePage(this, ino_, index); page == nullptr)
    return ZX_ERR_NO_MEMORY;

  if (PageUptodate(page)) {
    *out = page;
    return ZX_OK;
  }

  if (dn.data_blkaddr == NEW_ADDR) {
    ZeroUserSegment(page, 0, kPageCacheSize);
  } else {
    if (zx_status_t err = Readpage(fs_, page, dn.data_blkaddr, kReadSync); err != ZX_OK) {
      F2fsPutPage(page, 1);
      return err;
    }
  }
  SetPageUptodate(page);

  // if (new_i_size &&
  //   i_size_read(inode) < ((index + 1) << kPageCacheShift)) {
  //   i_size_write(inode, ((index + 1) << kPageCacheShift));
  //   mark_inode_dirty_sync(inode);
  // }
  if (new_i_size && static_cast<uint64_t>(i_size_) < (index + 1) << kPageCacheShift) {
    i_size_ = (index + 1) << kPageCacheShift;
#if 0  // porting needed
    // mark_inode_dirty_sync(inode);
#endif
  }

  *out = page;
  return ZX_OK;
}

#if 0  // porting needed
// static void read_end_io(bio *bio, int err)
// {
//   const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
//   bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;

//   do {
//     page *page = bvec->bv_page;

//     if (--bvec >= bio->bi_io_vec)
//       prefetchw(&bvec->bv_page->flags);

//     if (uptodate) {
//       SetPageUptodate(page);
//     } else {
//       ClearPageUptodate(page);
//       SetPageError(page);
//     }
//     unlock_page(page);
//   } while (bvec >= bio->bi_io_vec);
//   kfree(bio->bi_private);
//   bio_put(bio);
// }
#endif

/**
 * Fill the locked page with data located in the block address.
 * Read operation is synchronous, and caller must unlock the page.
 */
zx_status_t VnodeF2fs::Readpage(F2fs *fs, Page *page, block_t blk_addr, int type) {
#if 0  // porting needed
  //   block_device *bdev = sbi->sb->s_bdev;
  //   bool sync = (type == kReadSync);
  //   bio *bio;

  //   /* This page can be already read by other threads */
  //   if (PageUptodate(page)) {
  //     if (!sync)
  //       unlock_page(page);
  //     return 0;
  //   }

  //   down_read(&sbi->bio_sem);

  //   /* Allocate a new bio */
  //   bio = f2fs_bio_alloc(bdev, blk_addr << (sbi->log_blocksize - 9),
  //         1, GFP_NOFS | __GFP_HIGH);

  //   /* Initialize the bio */
  //   bio->bi_end_io = read_end_io;
  //   if (bio_add_page(bio, page, kPageCacheSize, 0) < kPageCacheSize) {
  //     kfree(bio->bi_private);
  //     bio_put(bio);
  //     up_read(&sbi->bio_sem);
  //     return -EFAULT;
  //   }

  //   submit_bio(type, bio);
  //   up_read(&sbi->bio_sem);

  //   /* wait for read completion if sync */
  //   if (sync) {
  //     lock_page(page);
  //     if (PageError(page))
  //       return -EIO;
  //   }
  // return 0;
#else
  return fs->bc_->Readblk(blk_addr, page->data);
#endif
}

/**
 * This function should be used by the data read flow only where it
 * does not check the "create" flag that indicates block allocation.
 * The reason for this special functionality is to exploit VFS readahead
 * mechanism.
 */
#if 0  // porting needed
// int VnodeF2fs::GetDataBlockRo(inode *inode, sector_t iblock,
//       buffer_head *bh_result, int create)
// {
//   unsigned int blkbits = inode->i_sb->s_blocksize_bits;
//   unsigned maxblocks = bh_result->b_size >> blkbits;
//   dnode_of_data dn;
//   pgoff_t pgofs;
//   //int err = 0;

//   /* Get the page offset from the block offset(iblock) */
//   pgofs =  (pgoff_t)(iblock >> (kPageCacheShift - blkbits));

//   if (VnodeF2fs::CheckExtentCache(inode, pgofs, bh_result))
//     return 0;

//   /* When reading holes, we need its node page */
//   //TODO(unknown): inode should be replaced with vnodef2fs
//   //SetNewDnode(&dn, inode, NULL, NULL, 0);
//   // TODO(unknown): shoud be replaced with NodeMgr->GetDnodeOfData
//   /*err = get_dnode_of_data(&dn, pgofs, RDONLY_NODE);
//   if (err)
//     return (err == ZX_ERR_NOT_FOUND) ? 0 : err; */

//   /* It does not support data allocation */
//   ZX_ASSERT(!create);

//   if (dn.data_blkaddr != NEW_ADDR && dn.data_blkaddr != NULL_ADDR) {
//     unsigned int i;
//     unsigned int end_offset;

//     end_offset = IS_INODE(dn.node_page) ?
//         ADDRS_PER_INODE :
//         ADDRS_PER_BLOCK;

//     clear_buffer_new(bh_result);

//     /* Give more consecutive addresses for the read ahead */
//     for (i = 0; i < end_offset - dn.ofs_in_node; i++)
//       if (((datablock_addr(dn.node_page,
//               dn.ofs_in_node + i))
//         != (dn.data_blkaddr + i)) || maxblocks == i)
//         break;
//     //map_bh(bh_result, inode->i_sb, dn.data_blkaddr);
//     bh_result->b_size = (i << blkbits);
//   }
//   F2fsPutDnode(&dn);
//   return 0;
// }

// int VnodeF2fs::F2fsReadDataPage(file *file, page *page)
// {
//   return mpage_readpage(page, VnodeF2fs::GetDataBlockRo);
// }

// int VnodeF2fs::F2fsReadDataPages(file *file,
//       address_space *mapping,
//       list_node_t *pages, unsigned nr_pages)
// {
//   return mpage_readpages(mapping, pages, nr_pages, VnodeF2fs::GetDataBlockRo);
// }
#endif

zx_status_t VnodeF2fs::DoWriteDataPage(Page *page) {
#if 0  // porting needed
  // inode *inode = page->mapping->host;
#endif
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  block_t old_blk_addr, new_blk_addr;
  dnode_of_data dn;

  SetNewDnode(&dn, this, NULL, NULL, 0);
  if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, page->index, RDONLY_NODE); err != ZX_OK)
    return err;

  old_blk_addr = dn.data_blkaddr;

  /* This page is already truncated */
  if (old_blk_addr == NULL_ADDR) {
    F2fsPutDnode(&dn);
    return ZX_OK;
  }

  SetPageWriteback(page);

  /*
   * If current allocation needs SSR,
   * it had better in-place writes for updated data.
   */
  if (old_blk_addr != NEW_ADDR && !Vfs()->Nodemgr().IsColdData(page) &&
      Vfs()->Segmgr().NeedInplaceUpdate(this)) {
    Vfs()->Segmgr().RewriteDataPage(page, old_blk_addr);
  } else {
    Vfs()->Segmgr().WriteDataPage(this, page, &dn, old_blk_addr, &new_blk_addr);
    UpdateExtentCache(new_blk_addr, &dn);
    fi_.data_version = LeToCpu(F2FS_CKPT(&sbi)->checkpoint_ver);
  }

  F2fsPutDnode(&dn);
  return ZX_OK;
}

zx_status_t VnodeF2fs::WriteDataPageReq(Page *page, WritebackControl *wbc) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  const pgoff_t end_index = (static_cast<uint64_t>(i_size_)) >> kPageCacheShift;
  unsigned offset;
  zx_status_t err;

  if (page->index >= end_index) {
    /*
    * If the offset is out-of-range of file size,
    * this page does not have to be written to disk.
    */
    offset = i_size_ & (kPageCacheSize - 1);
    if ((page->index >= end_index + 1) || !offset) {
      if (S_ISDIR(i_mode_)) {
        DecPageCount(&sbi, F2FS_DIRTY_DENTS);
#if 0  // porting needed
        // inode_dec_dirty_dents(inode);
#endif
      }

#if 0  // porting needed
      // unlock_page(page);
#endif
      return ZX_OK;
    }

    ZeroUserSegment(page, offset, kPageCacheSize);
  }

  if (sbi.por_doing) {
#if 0  // porting needed
    // wbc->pages_skipped++;
    // set_page_dirty(page);
#else
    FlushDirtyDataPage(Vfs(), page);
#endif
    return kAopWritepageActivate;
  }

#if 0  // porting needed
  // if (wbc->for_reclaim && !S_ISDIR(i_mode_) && !Vfs()->Nodemgr().IsColdData(page))
  //   goto redirty_out;
#endif

  do {
    fbl::AutoLock lock(&sbi.fs_lock[DATA_WRITE]);
    if (S_ISDIR(i_mode_)) {
      DecPageCount(&sbi, F2FS_DIRTY_DENTS);
#if 0  // porting needed
      // inode_dec_dirty_dents(inode);
#endif
    }

    if (err = DoWriteDataPage(page); (err != ZX_OK && err != ZX_ERR_NOT_FOUND)) {
#if 0  // porting needed
      // wbc->pages_skipped++;
      // set_page_dirty(page);
#endif
      FlushDirtyDataPage(Vfs(), page);
    }
  } while(false);

#if 0  // porting needed
  // if (wbc->for_reclaim)
  //   f2fs_submit_bio(sbi, DATA, true);
#endif

  if (err == ZX_ERR_NOT_FOUND) {
#if 0  // porting needed
    // unlock_page(page);
#endif
    return ZX_OK;
  }

  Vfs()->Nodemgr().ClearColdData(page);
#if 0  // porting needed
  // unlock_page(page);

  // if (!wbc->for_reclaim && !S_ISDIR(i_mode_))
  //   fs->Segmgr().F2fsBalanceFs();
#endif
  return ZX_OK;
}

#if 0  // porting needed
// #define MAX_DESIRED_PAGES_WP 4096

// int VnodeF2fs::F2fsWriteDataPages(/*address_space *mapping,*/
//                                   WritebackControl *wbc) {
//   // inode *inode = mapping->host;
//   // f2fs_sb_info &sbi = Vfs()->SbInfo();
//   int ret;
//   // long excess_nrtw = 0, desired_nrtw;

//   // if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
//   //   desired_nrtw = MAX_DESIRED_PAGES_WP;
//   //   excess_nrtw = desired_nrtw - wbc->nr_to_write;
//   //   wbc->nr_to_write = desired_nrtw;
//   // }

//   // if (!S_ISDIR(i_mode_))
//   //   mutex_lock(&sbi->writepages);
//   // ret = generic_writepages(mapping, wbc);
//   ret = 0;
//   // if (!S_ISDIR(i_mode_))
//   //   mutex_unlock(&sbi->writepages);
//   // Vfs()->Segmgr().F2fsSubmitBio(DATA, (wbc->sync_mode == WB_SYNC_ALL));

//   Vfs()->RemoveDirtyDirInode(this);

//   // wbc->nr_to_write -= excess_nrtw;
//   return ret;
// }
#endif

zx_status_t VnodeF2fs::WriteBegin(size_t pos, size_t len, Page **pagep) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  pgoff_t index = (static_cast<uint64_t>(pos)) >> kPageCacheShift;
  dnode_of_data dn;

  Vfs()->Segmgr().F2fsBalanceFs();

#if 0  // porting needed
  // page = GrabCachePage_write_begin(/*mapping,*/ index, flags);
#else
  *pagep = GrabCachePage(this, ino_, index);
  if (!*pagep)
    return ZX_ERR_NO_MEMORY;
#endif

  do {
    fbl::AutoLock lock(&sbi.fs_lock[DATA_NEW]);

    SetNewDnode(&dn, this, NULL, NULL, 0);
    if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, 0); err != ZX_OK) {
      F2fsPutPage(*pagep, 1);
      return err;
    }

    if (dn.data_blkaddr == NULL_ADDR) {
      if (zx_status_t err = ReserveNewBlock(&dn); err != ZX_OK) {
        F2fsPutDnode(&dn);
        F2fsPutPage(*pagep, 1);
        return err;
      }
    }
    F2fsPutDnode(&dn);
  } while(false);

  if ((len == kPageCacheSize) || PageUptodate(*pagep))
    return ZX_OK;

  if ((static_cast<loff_t>(pos) & kPageCacheMask) >= i_size_) {
    unsigned start = pos & (kPageCacheSize - 1);
    unsigned end = start + len;

    /* Reading beyond i_size is simple: memset to zero */
    ZeroUserSegments(*pagep, 0, start, end, kPageCacheSize);
    return ZX_OK;
  }

  if (dn.data_blkaddr == NEW_ADDR) {
    ZeroUserSegment(*pagep, 0, kPageCacheSize);
  } else {
    if (zx_status_t err = Readpage(fs_, *pagep, dn.data_blkaddr, kReadSync); err != ZX_OK) {
      F2fsPutPage(*pagep, 1);
      return err;
    }
  }
  SetPageUptodate(*pagep);
  Vfs()->Nodemgr().ClearColdData(*pagep);
  return ZX_OK;
}

#if 0  // porting needed
// ssize_t VnodeF2fs::F2fsDirectIO(/*int rw, kiocb *iocb,
//     const iovec *iov, */ loff_t offset, uint64_t nr_segs) {
//   // file *file = iocb->ki_filp;
//   // inode *inode = file->f_mapping->host;

//   // if (rw == kWrite)
//   //   return 0;

//   // /* Needs synchronization with the cleaner */
//   // return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
//   //             get_data_block_ro);
//   return 0;
// }

// void VnodeF2fs::F2fsInvalidateDataPage(Page *page, uint64_t offset)
// {
//   // inode *inode = page->mapping->host;
//   inode *inode = new inode();
//   f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
//   if (S_ISDIR(inode->i_mode) && PageDirty(page)) {
//     DecPageCount(sbi, F2FS_DIRTY_DENTS);
//     InodeDecDirtyDents(inode);
//   }
//   ClearPagePrivate(page);
// }

// int VnodeF2fs::F2fsReleaseDataPage(Page *page, gfp_t wait)
// {
//   ClearPagePrivate(page);
//   return 0;
// }

// int VnodeF2fs::F2fsSetDataPageDirty(Page *page) {
//   SetPageUptodate(page);
//   if (!PageDirty(page)) {
//     // __set_page_dirty_nobuffers(page);
//     FlushDirtyDataPage(Vfs(), page);
//     Vfs()->SetDirtyDirPage(this, page);
//     return 1;
//   }
//   return 0;
// }
#endif

}  // namespace f2fs
