// 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 inc_valid_block_count(struct f2fs_sb_info *sbi, VnodeF2fs *vnode,
                                         blkcnt_t count) {
  block_t valid_block_count;

  spin_lock(&sbi->stat_lock);
  valid_block_count = sbi->total_valid_block_count + (block_t)count;
  if (valid_block_count > sbi->user_block_count) {
    spin_unlock(&sbi->stat_lock);
    return false;
  }
  vnode->i_blocks += count;
  sbi->total_valid_block_count = valid_block_count;
  sbi->alloc_valid_block_count += (block_t)count;
  spin_unlock(&sbi->stat_lock);
  return true;
}

// gc
block_t start_bidx_of_node(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(struct dnode_of_data *dn, block_t new_addr) {
  struct f2fs_node *rn;
  __le32 *addr_array;
  Page *node_page = dn->node_page;
  unsigned int ofs_in_node = dn->ofs_in_node;

  wait_on_page_writeback(node_page);

  rn = (struct f2fs_node *)page_address(node_page);

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

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

  if (is_inode_flag_set(&dn->vnode->fi, FI_NO_ALLOC))
    return -EPERM;
  if (!inc_valid_block_count(&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(struct inode *inode, pgoff_t pgofs,
//           struct buffer_head *bh_result)
// {
//   struct f2fs_inode_info *fi = F2FS_I(inode);
//   //struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
//   struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
//   pgoff_t start_fofs, end_fofs;
//   block_t start_blkaddr;

//   read_lock(&fi->ext.ext_lock);
//   if (fi->ext.len == 0) {
//     read_unlock(&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++;
//     read_unlock(&fi->ext.ext_lock);
//     return 1;
//   }
//   read_unlock(&fi->ext.ext_lock);
//   return 0;
// }
#endif

void VnodeF2fs::UpdateExtentCache(block_t blk_addr, struct dnode_of_data *dn) {
  struct 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 = start_bidx_of_node(Vfs()->Nodemgr().OfsOfNode(dn->node_page)) + dn->ofs_in_node;

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

  write_lock(&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;

  /* 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;
    }
    goto end_update;
  }

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

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

  /* 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;
    }
    goto end_update;
  }
  write_unlock(&fi->ext.ext_lock);
  return;

end_update:
  write_unlock(&fi->ext.ext_lock);
  Vfs()->Nodemgr().SyncInodePage(dn);
}

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

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

  SetNewDnode(&dn, this, NULL, NULL, 0);
  err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, RDONLY_NODE);
  if (err)
    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;

  page = grab_cache_page(this, ino_, index);
  if (!page)
    return ZX_ERR_NO_MEMORY;

  err = F2fsReadpage(Vfs(), page, dn.data_blkaddr, READ_SYNC);
  if (err) {
    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) {
  struct dnode_of_data dn;
  Page *page;
  zx_status_t err;

  page = nullptr;

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

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

  page = grab_cache_page(this, ino_, index);
  if (!page)
    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);

  err = VnodeF2fs::F2fsReadpage(fs_, page, dn.data_blkaddr, READ_SYNC);
  if (err) {
    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
  // struct address_space *mapping = inode->i_mapping;
#endif
  Page *page;
  struct dnode_of_data dn;
  zx_status_t err;

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

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

  page = grab_cache_page(this, ino_, index);
  if (!page)
    return ZX_ERR_NO_MEMORY;

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

  if (dn.data_blkaddr == NEW_ADDR) {
    zero_user_segment(page, 0, PAGE_CACHE_SIZE);
  } else {
    err = F2fsReadpage(fs_, page, dn.data_blkaddr, READ_SYNC);
    if (err) {
      F2fsPutPage(page, 1);
      return err;
    }
  }
  SetPageUptodate(page);

  // if (new_i_size &&
  //   i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
  //   i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
  //   mark_inode_dirty_sync(inode);
  // }
  if (new_i_size && i_size < (off_t)((index + 1) << PAGE_CACHE_SHIFT)) {
    i_size = (index + 1) << PAGE_CACHE_SHIFT;
#if 0   // porting needed
    // mark_inode_dirty_sync(inode);
#endif
  }

  *out = page;
  return ZX_OK;
}

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

//   do {
//     struct 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::F2fsReadpage(F2fs *fs, Page *page, block_t blk_addr, int type) {
#if 0   // porting needed
  //   struct block_device *bdev = sbi->sb->s_bdev;
  //   bool sync = (type == READ_SYNC);
  //   struct 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, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) {
  //     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(struct inode *inode, sector_t iblock,
//       struct buffer_head *bh_result, int create)
// {
//   unsigned int blkbits = inode->i_sb->s_blocksize_bits;
//   unsigned maxblocks = bh_result->b_size >> blkbits;
//   struct dnode_of_data dn;
//   pgoff_t pgofs;
//   //int err = 0;

//   /* Get the page offset from the block offset(iblock) */
//   pgofs =  (pgoff_t)(iblock >> (PAGE_CACHE_SHIFT - 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(struct file *file, struct page *page)
// {
//   return mpage_readpage(page, VnodeF2fs::GetDataBlockRo);
// }

// int VnodeF2fs::F2fsReadDataPages(struct file *file,
//       struct 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
  // struct inode *inode = page->mapping->host;
#endif
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();
  block_t old_blk_addr, new_blk_addr;
  struct dnode_of_data dn;
  zx_status_t err = ZX_OK;

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

  old_blk_addr = dn.data_blkaddr;

  /* This page is already truncated */
  if (old_blk_addr == NULL_ADDR)
    goto out_writepage;

  set_page_writeback(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 = le64_to_cpu(F2FS_CKPT(&sbi)->checkpoint_ver);
  }
out_writepage:
  F2fsPutDnode(&dn);
  return err;
}

zx_status_t VnodeF2fs::F2fsWriteDataPage(Page *page, struct writeback_control *wbc) {
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();
  const pgoff_t end_index = ((unsigned long long)i_size) >> PAGE_CACHE_SHIFT;
  unsigned offset;
  zx_status_t err = 0;

  if (page->index < end_index)
    goto out;

  /*
   * If the offset is out-of-range of file size,
   * this page does not have to be written to disk.
   */
  offset = i_size & (PAGE_CACHE_SIZE - 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
    }
    goto unlock_out;
  }

  zero_user_segment(page, offset, PAGE_CACHE_SIZE);
out:
  if (sbi.por_doing)
    goto redirty_out;

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

  mutex_lock_op(&sbi, DATA_WRITE);
  if (S_ISDIR(i_mode)) {
    DecPageCount(&sbi, F2FS_DIRTY_DENTS);
#if 0   // porting needed
    // inode_dec_dirty_dents(inode);
#endif
  }
  err = DoWriteDataPage(page);
  if (err && err != ZX_ERR_NOT_FOUND) {
#if 0   // porting needed
    // wbc->pages_skipped++;
    // set_page_dirty(page);
#endif
    FlushDirtyDataPage(Vfs(), page);
  }
  mutex_unlock_op(&sbi, DATA_WRITE);

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

  if (err == ZX_ERR_NOT_FOUND)
    goto unlock_out;

  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;

unlock_out:
#if 0   // porting needed
  // unlock_page(page);
#endif
  return (err == ZX_ERR_NOT_FOUND) ? 0 : err;

redirty_out:
#if 0   // porting needed
  // wbc->pages_skipped++;
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif
  return AOP_WRITEPAGE_ACTIVATE;
}

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

// int VnodeF2fs::F2fsWriteDataPages(/*struct address_space *mapping,*/
//                                   struct writeback_control *wbc) {
//   // struct inode *inode = mapping->host;
//   // struct 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::F2fsWriteBegin(size_t pos, size_t len, Page **pagep) {
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();
  pgoff_t index = ((unsigned long long)pos) >> PAGE_CACHE_SHIFT;
  struct dnode_of_data dn;
  zx_status_t err = 0;

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

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

  mutex_lock_op(&sbi, DATA_NEW);

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

  if (dn.data_blkaddr == NULL_ADDR) {
    err = ReserveNewBlock(&dn);
    if (err) {
      F2fsPutDnode(&dn);
      mutex_unlock_op(&sbi, DATA_NEW);
      F2fsPutPage(*pagep, 1);
      return err;
    }
  }
  F2fsPutDnode(&dn);

  mutex_unlock_op(&sbi, DATA_NEW);

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

  if (((loff_t)pos & PAGE_CACHE_MASK) >= i_size) {
    unsigned start = pos & (PAGE_CACHE_SIZE - 1);
    unsigned end = start + len;

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

  if (dn.data_blkaddr == NEW_ADDR) {
    zero_user_segment(*pagep, 0, PAGE_CACHE_SIZE);
  } else {
    err = F2fsReadpage(fs_, *pagep, dn.data_blkaddr, READ_SYNC);
    if (err) {
      F2fsPutPage(*pagep, 1);
      return err;
    }
  }
  SetPageUptodate(*pagep);
  Vfs()->Nodemgr().ClearColdData(*pagep);
  return ZX_OK;
}

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

//   // if (rw == WRITE)
//   //   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(struct Page *page, unsigned long offset)
// {
//   // struct inode *inode = page->mapping->host;
//   struct inode *inode = new struct inode();
//   struct 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(struct 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
