// 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"
#include "dir.h"
#include "file.h"

namespace f2fs {

Dir::Dir(F2fs *fs) : VnodeF2fs(fs) {}

Dir::Dir(F2fs *fs, ino_t ino) : VnodeF2fs(fs, ino) {}

Dir::~Dir() {}

unsigned long Dir::DirBlocks() {
  // return ((unsigned long long) (i_size_read(inode) + PAGE_CACHE_SIZE - 1))
  //             >> PAGE_CACHE_SHIFT;
  // return 0;
  // return Inode().i_blocks - 1;
  return (i_size + kF2fsBlockSize - 1) / kF2fsBlockSize;
}

unsigned int Dir::DirBuckets(unsigned int level) {
  if (level < MAX_DIR_HASH_DEPTH / 2)
    return 1 << level;
  else
    return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1);
}

unsigned int Dir::BucketBlocks(unsigned int level) {
  if (level < MAX_DIR_HASH_DEPTH / 2)
    return 2;
  else
    return 4;
}

void Dir::SetDeType(struct f2fs_dir_entry *de, VnodeF2fs *vnode) {
  de->file_type = f2fs_type_by_mode[(vnode->i_mode & S_IFMT) >> S_SHIFT];
}

unsigned long Dir::DirBlockIndex(unsigned int level, unsigned int idx) {
  unsigned long i;
  unsigned long bidx = 0;

  for (i = 0; i < level; i++)
    bidx += DirBuckets(i) * BucketBlocks(i);
  bidx += idx * BucketBlocks(level);
  return bidx;
}

bool Dir::EarlyMatchName(const char *name, int namelen, f2fs_hash_t namehash,
                         struct f2fs_dir_entry *de) {
  if (le16_to_cpu(de->name_len) != namelen)
    return false;

  if (le32_to_cpu(de->hash_code) != namehash)
    return false;

  return true;
}

// TODO: replace from some lib
typedef uint8_t BITARR_TYPE;

#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MIN_T(t, a, b) (((t)(a) < (t)(b)) ? (t)(a) : (t)(b))
#define DIV_ROUNDUP(n, m) (((n) + ((m)-1)) / (m))

#define BITARR_TYPE_NUM_BITS (sizeof(BITARR_TYPE) * 8)
#define BITARR_SIZE(num_bits) (DIV_ROUNDUP((num_bits), BITARR_TYPE_NUM_BITS))
#define BITARR(name, num_bits) BITARR_TYPE name[BITARR_SIZE(num_bits)]
#define BITARR_SET(name, bit) \
  (name)[(bit) / BITARR_TYPE_NUM_BITS] |= ((BITARR_TYPE)1 << ((bit) % BITARR_TYPE_NUM_BITS))
#define BITARR_CLEAR(name, bit) \
  (name)[(bit) / BITARR_TYPE_NUM_BITS] &= ~((BITARR_TYPE)1 << ((bit) % BITARR_TYPE_NUM_BITS))
#define BITARR_TEST(name, bit) \
  (((name)[(bit) / BITARR_TYPE_NUM_BITS] & ((BITARR_TYPE)1 << ((bit) % BITARR_TYPE_NUM_BITS))) != 0)

size_t find_first_bit(const BITARR_TYPE *bitarr, size_t num_bits) {
  size_t n = BITARR_SIZE(num_bits);
  for (size_t i = 0; i < n; ++i) {
    if (bitarr[i] != 0) {
      int bit = __builtin_ffsll(bitarr[i]) - 1;
      return MIN(i * BITARR_TYPE_NUM_BITS + bit, num_bits);
    }
  }
  return num_bits;
}

size_t find_next_bit_le(const BITARR_TYPE *bitarr, size_t num_bits, size_t bit_offset) {
  if (bit_offset >= num_bits) {
    return num_bits;
  }

  size_t word_offset = bit_offset / BITARR_TYPE_NUM_BITS;
  size_t offset_within_word = bit_offset % BITARR_TYPE_NUM_BITS;

  size_t rest = bitarr[word_offset] & (~0ULL << offset_within_word);
  if (rest != 0) {
    int bit = __builtin_ffsll(rest) - 1;
    return MIN(word_offset * BITARR_TYPE_NUM_BITS + bit, num_bits);
  }

  size_t skipped_bits = (word_offset + 1) * BITARR_TYPE_NUM_BITS;
  if (skipped_bits >= num_bits) {
    return num_bits;
  }

  return skipped_bits + find_first_bit(bitarr + word_offset + 1, num_bits - skipped_bits);
}

struct f2fs_dir_entry *Dir::FindInBlock(Page *dentry_page, const char *name, int namelen,
                                        int *max_slots, f2fs_hash_t namehash, Page **res_page) {
  struct f2fs_dir_entry *de;
  unsigned long bit_pos, end_pos, next_pos;
#if 0   // porting needed
  // struct f2fs_dentry_block *dentry_blk = kmap(dentry_page);
#else
  struct f2fs_dentry_block *dentry_blk = (struct f2fs_dentry_block *)dentry_page;
#endif
  int slots;

  bit_pos =
      find_next_bit_le((const BITARR_TYPE *)&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, 0);
  while (bit_pos < NR_DENTRY_IN_BLOCK) {
    de = &dentry_blk->dentry[bit_pos];
    slots = (le16_to_cpu(de->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;

    if (EarlyMatchName(name, namelen, namehash, de)) {
      if (!memcmp(dentry_blk->filename[bit_pos], name, namelen)) {
        *res_page = dentry_page;
        goto found;
      }
    }
    next_pos = bit_pos + slots;
    bit_pos = find_next_bit_le((const BITARR_TYPE *)&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK,
                               next_pos);
    if (bit_pos >= NR_DENTRY_IN_BLOCK)
      end_pos = NR_DENTRY_IN_BLOCK;
    else
      end_pos = bit_pos;
    if ((unsigned long)*max_slots < end_pos - next_pos)
      *max_slots = end_pos - next_pos;
  }

  de = nullptr;
#if 0   // porting needed
//   kunmap(dentry_page);
#endif
found:
  return de;
}

struct f2fs_dir_entry *Dir::FindInLevel(unsigned int level, fbl::StringPiece name, int namelen,
                                        f2fs_hash_t namehash, Page **res_page) {
  int s = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  unsigned int nbucket, nblock;
  unsigned int bidx, end_block;
  Page *dentry_page = nullptr;
  struct f2fs_dir_entry *de = nullptr;
  bool room = false;
  int max_slots = 0;
  zx_status_t ret;

  ZX_ASSERT(level <= MAX_DIR_HASH_DEPTH);

  nbucket = DirBuckets(level);
  nblock = BucketBlocks(level);

  bidx = DirBlockIndex(level, namehash % nbucket);
  end_block = bidx + nblock;

  for (; bidx < end_block; bidx++) {
    /* no need to allocate new dentry pages to all the indices */
    ret = FindDataPage(bidx, &dentry_page);
    if (ret) {
      room = true;
      continue;
    }

    de = FindInBlock(dentry_page, name.data(), namelen, &max_slots, namehash, res_page);
    if (de)
      break;

    if (max_slots >= s)
      room = true;
    F2fsPutPage(dentry_page, 0);
  }

  if (!de && room && fi.chash != namehash) {
    fi.chash = namehash;
    fi.clevel = level;
  }

  return de;
}

/*
 * Find an entry in the specified directory with the wanted name.
 * It returns the page where the entry was found (as a parameter - res_page),
 * and the entry itself. Page is returned mapped and unlocked.
 * Entry is guaranteed to be valid.
 */
struct f2fs_dir_entry *Dir::F2fsFindEntry(fbl::StringPiece name, Page **res_page) {
  unsigned long npages = DirBlocks();
  struct f2fs_dir_entry *de = nullptr;
  f2fs_hash_t name_hash;
  unsigned int max_depth;
  unsigned int level;

  if (npages == 0)
    return nullptr;

  *res_page = nullptr;

  name_hash = F2fsDentryHash(name.data(), name.length());
  max_depth = fi.i_current_depth;

  for (level = 0; level < max_depth; level++) {
    de = FindInLevel(level, name, name.length(), name_hash, res_page);
    if (de)
      break;
  }
  if (!de && fi.chash != name_hash) {
    fi.chash = name_hash;
    fi.clevel = level - 1;
  }
  return de;
}

struct f2fs_dir_entry *Dir::F2fsParentDir(Page **p) {
  Page *page = nullptr;
  struct f2fs_dir_entry *de = nullptr;
  struct f2fs_dentry_block *dentry_blk = nullptr;
  zx_status_t ret;

  ret = GetLockDataPage(0, &page);
  if (ret)
    return nullptr;

#if 0   // porting needed
  // dentry_blk = kmap(page);
#endif
  dentry_blk = (f2fs_dentry_block *)page_address(page);
  de = &dentry_blk->dentry[1];
  *p = page;
#if 0   // porting needed
  // unlock_page(page);
#endif
  return de;
}

ino_t Dir::F2fsInodeByName(fbl::StringPiece name) {
  ino_t res = 0;
  struct f2fs_dir_entry *de;
  Page *page;

  de = F2fsFindEntry(name, &page);
  if (de) {
    res = le32_to_cpu(de->ino);
#if 0   // porting needed
    // kunmap(page);
#endif
    F2fsPutPage(page, 0);
  }

  return res;
}

void Dir::F2fsSetLink(struct f2fs_dir_entry *de, Page *page, VnodeF2fs *vnode) {
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();

  mutex_lock_op(&sbi, DENTRY_OPS);
#if 0   // porting needed
  // lock_page(page);
#endif
  wait_on_page_writeback(page);
  de->ino = cpu_to_le32(vnode->Ino());
  SetDeType(de, vnode);
#if 0   // porting needed
  // kunmap(page);
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;
  mark_inode_dirty(this);
  F2fsPutPage(page, 1);
  mutex_unlock_op(&sbi, DENTRY_OPS);
}

void Dir::InitDentInode(VnodeF2fs *vnode, Page *ipage) {
#if 0   // porting needed
  // struct inode *dir = dentry->d_parent->d_inode;
#endif
  struct f2fs_node *rn;

  if (!ipage)
    return;

  wait_on_page_writeback(ipage);

  /* copy dentry info. to this inode page */
  rn = (struct f2fs_node *)page_address(ipage);
  rn->i.i_pino = cpu_to_le32(Ino());
  rn->i.i_namelen = cpu_to_le32(vnode->i_name_sp.length());
  memcpy(rn->i.i_name, vnode->i_name_sp.data(), vnode->i_name_sp.length());
#if 0   // porting needed
  // set_page_dirty(ipage);
#else
  FlushDirtyNodePage(Vfs(), ipage);
#endif
}

zx_status_t Dir::InitInodeMetadata(VnodeF2fs *vnode, struct dentry *dentry) {
#if 0   // porting needed
  // struct inode *dir = dentry->d_parent->d_inode;
#endif

  if (is_inode_flag_set(&vnode->fi, FI_NEW_INODE)) {
    int err;
    err = Vfs()->Nodemgr().NewInodePage(this, vnode);
    if (err)
      return err;

    if (S_ISDIR(vnode->i_mode)) {
      err = F2fsMakeEmpty(vnode, this);
      if (err) {
        Vfs()->Nodemgr().RemoveInodePage(vnode);
        return err;
      }
    }

#if 0   // porting needed
    // err = f2fs_init_acl(inode, dir);
    // if (err) {
    //   remove_inode_page(inode);
    //   return err;
    // }
#endif
  } else {
    Page *ipage = nullptr;
    zx_status_t err;
    err = Vfs()->Nodemgr().GetNodePage(vnode->Ino(), &ipage);
    if (err)
      return err;
    InitDentInode(vnode, ipage);
    F2fsPutPage(ipage, 1);
  }
  if (is_inode_flag_set(&vnode->fi, FI_INC_LINK)) {
    vnode->IncNlink();
    vnode->F2fsWriteInode(NULL);
  }
  return 0;
}

void Dir::UpdateParentMetadata(VnodeF2fs *vnode, unsigned int current_depth) {
  bool need_dir_update = false;

  if (is_inode_flag_set(&vnode->fi, FI_NEW_INODE)) {
    if (S_ISDIR(vnode->i_mode)) {
      IncNlink();
      need_dir_update = true;
    }
    clear_inode_flag(&vnode->fi, FI_NEW_INODE);
  }

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;
  if (fi.i_current_depth != current_depth) {
    fi.i_current_depth = current_depth;
    need_dir_update = true;
  }

  if (need_dir_update)
    F2fsWriteInode(NULL);
  else
    mark_inode_dirty(this);

  if (is_inode_flag_set(&vnode->fi, FI_INC_LINK))
    clear_inode_flag(&vnode->fi, FI_INC_LINK);
}

int Dir::RoomForFilename(struct f2fs_dentry_block *dentry_blk, int slots) {
  int bit_start = 0;
  int zero_start, zero_end;
next:
  zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_start);
  if (zero_start >= NR_DENTRY_IN_BLOCK)
    return NR_DENTRY_IN_BLOCK;

  zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, zero_start);
  if (zero_end - zero_start >= slots)
    return zero_start;

  bit_start = zero_end + 1;

  if (zero_end + 1 >= NR_DENTRY_IN_BLOCK)
    return NR_DENTRY_IN_BLOCK;
  goto next;
}

zx_status_t Dir::F2fsAddLink(fbl::StringPiece name, VnodeF2fs *vnode) {
  unsigned int bit_pos;
  unsigned int level;
  unsigned int current_depth;
  unsigned long bidx, block;
  f2fs_hash_t dentry_hash;
  struct f2fs_dir_entry *de;
  unsigned int nbucket, nblock;
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();
  int namelen = name.length();
  Page *dentry_page = nullptr;
  struct f2fs_dentry_block *dentry_blk = nullptr;
  int slots = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  zx_status_t err = 0;
  int i;

  dentry_hash = F2fsDentryHash(name.data(), namelen);
  level = 0;
  current_depth = fi.i_current_depth;
  if (fi.chash == dentry_hash) {
    level = fi.clevel;
    fi.chash = 0;
  }

start:
  if (current_depth == MAX_DIR_HASH_DEPTH)
    return ZX_ERR_OUT_OF_RANGE;

  /* Increase the depth, if required */
  if (level == current_depth)
    ++current_depth;

  nbucket = DirBuckets(level);
  nblock = BucketBlocks(level);

  bidx = DirBlockIndex(level, (dentry_hash % nbucket));

  for (block = bidx; block <= (bidx + nblock - 1); block++) {
    mutex_lock_op(&sbi, DENTRY_OPS);
    err = GetNewDataPage(block, true, &dentry_page);
    if (err) {
      mutex_unlock_op(&sbi, DENTRY_OPS);
      return err;
    }

#if 0   // porting needed
    // dentry_blk = kmap(dentry_page);
#else
    dentry_blk = (struct f2fs_dentry_block *)dentry_page->data;
#endif
    bit_pos = RoomForFilename(dentry_blk, slots);
    if (bit_pos < NR_DENTRY_IN_BLOCK)
      goto add_dentry;

#if 0   // porting needed
    // kunmap(dentry_page);
#endif
    F2fsPutPage(dentry_page, 1);
    mutex_unlock_op(&sbi, DENTRY_OPS);
  }

  /* Move to next level to find the empty slot for new dentry */
  ++level;
  goto start;
add_dentry:
#if 0   // porting needed
  // err = InitInodeMetadata(vnode, dentry);
#else
  err = InitInodeMetadata(vnode, nullptr);
#endif
  if (err)
    goto fail;

  wait_on_page_writeback(dentry_page);

  de = &dentry_blk->dentry[bit_pos];
  de->hash_code = cpu_to_le32(dentry_hash);
  de->name_len = cpu_to_le16(namelen);
  memcpy(dentry_blk->filename[bit_pos], name.data(), namelen);
  de->ino = cpu_to_le32(vnode->Ino());
  SetDeType(de, vnode);
  for (i = 0; i < slots; i++)
    test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
#if 0   // porting needed
  // set_page_dirty(dentry_page);
#else
  FlushDirtyDataPage(Vfs(), dentry_page);
#endif
  UpdateParentMetadata(vnode, current_depth);
fail:
#if 0   // porting needed
  // kunmap(dentry_page);
#endif
  F2fsPutPage(dentry_page, 1);
  mutex_unlock_op(&sbi, DENTRY_OPS);
  return err;
}

/**
 * It only removes the dentry from the dentry page,corresponding name
 * entry in name page does not need to be touched during deletion.
 */
void Dir::F2fsDeleteEntry(struct f2fs_dir_entry *dentry, Page *page, VnodeF2fs *vnode) {
  struct f2fs_dentry_block *dentry_blk;
  unsigned int bit_pos;
#if 0   // porting needed
  // struct address_space *mapping = page->mapping;
#endif
  struct f2fs_sb_info &sbi = Vfs()->SbInfo();
  int slots = (le16_to_cpu(dentry->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  void *kaddr = page_address(page);
  int i;

  mutex_lock_op(&sbi, DENTRY_OPS);

#if 0   // porting needed
  // lock_page(page);
#endif
  wait_on_page_writeback(page);

  dentry_blk = (struct f2fs_dentry_block *)kaddr;
  bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry;
  for (i = 0; i < slots; i++)
    test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);

  /* Let's check and deallocate this dentry page */
  bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, 0);
#if 0   // porting needed
  // kunmap(page); /* kunmap - pair of f2fs_find_entry */
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;

  if (vnode && S_ISDIR(vnode->i_mode)) {
    DropNlink();
    F2fsWriteInode(NULL);
  } else {
    mark_inode_dirty(this);
  }

  if (vnode) {
    cur_time = time(nullptr);
    i_ctime.tv_sec = cur_time;
    i_ctime.tv_nsec = 0;
    i_mtime.tv_sec = cur_time;
    i_mtime.tv_nsec = 0;
    vnode->i_ctime.tv_sec = cur_time;
    vnode->i_ctime.tv_nsec = 0;
    vnode->DropNlink();
    if (S_ISDIR(vnode->i_mode)) {
      vnode->DropNlink();
      vnode->i_size = 0;
    }
    vnode->F2fsWriteInode(NULL);
    if (vnode->i_nlink == 0)
      Vfs()->AddOrphanInode(vnode->Ino());
  }

  if (bit_pos == NR_DENTRY_IN_BLOCK) {
    loff_t page_offset;
    TruncateHole(page->index, page->index + 1);
    clear_page_dirty_for_io(page);
#if 0   // porting needed
    // ClearPageUptodate(page);
#endif
    DecPageCount(&sbi, F2FS_DIRTY_DENTS);
    InodeDecDirtyDents(this);
    page_offset = page->index << PAGE_CACHE_SHIFT;
    F2fsPutPage(page, 1);
  } else {
    F2fsPutPage(page, 1);
  }
  mutex_unlock_op(&sbi, DENTRY_OPS);
}

zx_status_t Dir::F2fsMakeEmpty(VnodeF2fs *vnode, VnodeF2fs *parent) {
  Page *dentry_page = nullptr;
  struct f2fs_dentry_block *dentry_blk;
  struct f2fs_dir_entry *de;
  void *kaddr;
  zx_status_t err;

  err = vnode->GetNewDataPage(0, true, &dentry_page);
  if (err)
    return err;

#if 0   // porting needed
  // kaddr = kmap_atomic(dentry_page);
#else
  kaddr = dentry_page->data;
#endif
  dentry_blk = (struct f2fs_dentry_block *)kaddr;

  de = &dentry_blk->dentry[0];
  de->name_len = cpu_to_le16(1);
  de->hash_code = 0;
  de->ino = cpu_to_le32(vnode->Ino());
  memcpy(dentry_blk->filename[0], ".", 1);
  SetDeType(de, vnode);

  de = &dentry_blk->dentry[1];
  de->hash_code = 0;
  de->name_len = cpu_to_le16(2);
  de->ino = cpu_to_le32(parent->Ino());
  memcpy(dentry_blk->filename[1], "..", 2);
  SetDeType(de, vnode);

  test_and_set_bit_le(0, &dentry_blk->dentry_bitmap);
  test_and_set_bit_le(1, &dentry_blk->dentry_bitmap);
#if 0   // porting needed
  // kunmap_atomic(kaddr);
  // set_page_dirty(dentry_page);
#else
  FlushDirtyDataPage(Vfs(), dentry_page);
#endif
  F2fsPutPage(dentry_page, 1);
  return 0;
}

bool Dir::F2fsEmptyDir() {
  unsigned long bidx;
  Page *dentry_page = nullptr;
  unsigned int bit_pos;
  struct f2fs_dentry_block *dentry_blk;
  unsigned long nblock = DirBlocks();
  zx_status_t ret;

  for (bidx = 0; bidx < nblock; bidx++) {
    void *kaddr;
    ret = GetLockDataPage(bidx, &dentry_page);
    if (ret) {
      if (ret == -ENOENT)
        continue;
      else
        return false;
    }

#if 0   // porting needed
    // kaddr = kmap_atomic(dentry_page);
#else
    kaddr = dentry_page->data;
#endif
    dentry_blk = (struct f2fs_dentry_block *)kaddr;
    if (bidx == 0)
      bit_pos = 2;
    else
      bit_pos = 0;
    bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_pos);
#if 0   // porting needed
    // kunmap_atomic(kaddr);
#endif

    F2fsPutPage(dentry_page, 1);

    if (bit_pos < NR_DENTRY_IN_BLOCK)
      return false;
  }
  return true;
}

zx_status_t Dir::Readdir(fs::VdirCookie *cookie, void *dirents, size_t len, size_t *out_actual) {
  fs::DirentFiller df(dirents, len);
  unsigned long *pos_cookie = reinterpret_cast<unsigned long *>(cookie);
  unsigned long pos = *pos_cookie;
  unsigned long npages = DirBlocks();
  unsigned char *types = nullptr;
  unsigned int bit_pos = 0, start_bit_pos = 0;
  struct f2fs_dentry_block *dentry_blk = nullptr;
  struct f2fs_dir_entry *de = nullptr;
  Page *dentry_page = nullptr;
  unsigned int n = 0;
  unsigned char d_type = DT_UNKNOWN;
  int slots;
  zx_status_t ret = ZX_OK;

  mtx_lock(&i_mutex);

  types = f2fs_filetype_table;
  bit_pos = (pos % NR_DENTRY_IN_BLOCK);
  n = (pos / NR_DENTRY_IN_BLOCK);

  for (; n < npages; n++) {
    ret = GetLockDataPage(n, &dentry_page);
    if (ret)
      continue;

    start_bit_pos = bit_pos;
#if 0   // porting needed
    //     dentry_blk = kmap(dentry_page);
#else
    dentry_blk = (struct f2fs_dentry_block *)dentry_page;
#endif
    while (bit_pos < NR_DENTRY_IN_BLOCK) {
      d_type = DT_UNKNOWN;
      bit_pos = find_next_bit_le((const BITARR_TYPE *)&dentry_blk->dentry_bitmap,
                                 NR_DENTRY_IN_BLOCK, bit_pos);
      if (bit_pos >= NR_DENTRY_IN_BLOCK)
        break;

      de = &dentry_blk->dentry[bit_pos];
      if (types && de->file_type < F2FS_FT_MAX)
        d_type = types[de->file_type];

      fbl::StringPiece name((char *)dentry_blk->filename[bit_pos], le16_to_cpu(de->name_len));

      if ((ret = df.Next(name, d_type, le32_to_cpu(de->ino))) != ZX_OK) {
        *pos_cookie += bit_pos - start_bit_pos;
        goto done;
      }

      slots = (le16_to_cpu(de->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
      bit_pos += slots;
    }
    bit_pos = 0;
    *pos_cookie = (n + 1) * NR_DENTRY_IN_BLOCK;

#if 0   // porting needed
    //     kunmap(dentry_page);
#endif
    F2fsPutPage(dentry_page, 1);
    dentry_page = nullptr;
  }
done:
  if (dentry_page && !ret) {
#if 0   // porting needed
    //     kunmap(dentry_page);
#endif
    F2fsPutPage(dentry_page, 1);
  }

  *out_actual = df.BytesFilled();

  mtx_unlock(&i_mutex);
  return ret;
}

#if 0   // porting needed
// const struct file_operations f2fs_dir_operations = {
//   .llseek    = generic_file_llseek,
//   .read    = generic_read_dir,
//   .readdir  = f2fs_readdir,
// };
#endif

}  // namespace f2fs
