// 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(SbInfo *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(uint32_t node_ofs) {
  block_t start_bidx;
  unsigned int bidx, indirect_blks;
  int dec;

  indirect_blks = 2 * kNidsPerBlock + 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) / (kNidsPerBlock + 1);
    bidx = node_ofs - 2 - dec;
  } else {
    dec = (node_ofs - indirect_blks - 3) / (kNidsPerBlock + 1);
    bidx = node_ofs - 5 - dec;
  }

  if (start_bidx)
    start_bidx = bidx * kAddrsPerBlock + kAddrsPerInode;
  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(DnodeOfData *dn, block_t new_addr) {
  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<Node *>(PageAddress(node_page));

  /* Get physical address of data block */
  addr_array = BlkaddrInNode(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(DnodeOfData *dn) {
  SbInfo &sbi = fs_->GetSbInfo();

  if (IsInodeFlagSet(&dn->vnode->fi_, InodeInfoFlag::kNoAlloc))
    return -EPERM;
  if (!IncValidBlockCount(&sbi, dn->vnode, 1))
    return -ENOSPC;

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

#if 0  // porting needed
// int VnodeF2fs::CheckExtentCache(inode *inode, pgoff_t pgofs,
//           buffer_head *bh_result)
// {
//   Inode_info *fi = F2FS_I(inode);
//   //SbInfo *sbi = F2FS_SB(inode->i_sb);
//   SbInfo *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, DnodeOfData *dn) {
  InodeInfo *fi = &dn->vnode->fi_;
  pgoff_t fofs, start_fofs, end_fofs;
  block_t start_blkaddr, end_blkaddr;

  ZX_ASSERT(blk_addr != kNewAddr);
  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 != kNullAddr) {
        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
  DnodeOfData 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, kRdOnlyNode); err != ZX_OK)
    return err;
  F2fsPutDnode(&dn);

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

  /* By fallocate(), there is no cached page, but with kNewAddr */
  if (dn.data_blkaddr == kNewAddr)
    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) {
  DnodeOfData dn;
  Page *page;

  page = nullptr;

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

  if (dn.data_blkaddr == kNullAddr) {
    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 != kNewAddr);
  ZX_ASSERT(dn.data_blkaddr != kNullAddr);

  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;
  DnodeOfData 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 == kNullAddr) {
    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 == kNewAddr) {
    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;
//   DnodeOfData 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_DnodeOfData(&dn, pgofs, kRdOnlyNode);
//   if (err)
//     return (err == ZX_ERR_NOT_FOUND) ? 0 : err; */

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

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

//     end_offset = IsInode(dn.node_page) ?
//         kAddrsPerInode :
//         kAddrsPerBlock;

//     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 (((DatablockAddr(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
  SbInfo &sbi = Vfs()->GetSbInfo();
  block_t old_blk_addr, new_blk_addr;
  DnodeOfData dn;

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

  old_blk_addr = dn.data_blkaddr;

  /* This page is already truncated */
  if (old_blk_addr == kNullAddr) {
    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 != kNewAddr && !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(GetCheckpoint(&sbi)->checkpoint_ver);
  }

  F2fsPutDnode(&dn);
  return ZX_OK;
}

zx_status_t VnodeF2fs::WriteDataPageReq(Page *page, WritebackControl *wbc) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  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, CountType::kDirtyDents);
#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[static_cast<int>(LockType::kDataWrtie)]);
    if (S_ISDIR(i_mode_)) {
      DecPageCount(&sbi, CountType::kDirtyDents);
#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().BalanceFs();
#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;
//   // SbInfo &sbi = Vfs()->GetSbInfo();
//   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().SubmitBio(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) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  pgoff_t index = (static_cast<uint64_t>(pos)) >> kPageCacheShift;
  DnodeOfData dn;

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

#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[static_cast<int>(LockType::kDataNew)]);

    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 == kNullAddr) {
      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 (dn.data_blkaddr == kNewAddr) {
    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();
//   SbInfo *sbi = F2FS_SB(inode->i_sb);
//   if (S_ISDIR(inode->i_mode) && PageDirty(page)) {
//     DecPageCount(sbi, CountType::kDirtyDents);
//     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
