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

#include "f2fs.h"

namespace f2fs {

#if 0  // porting needed
// static kmem_cache *Inode_cachep;

// enum {
//   Opt_gc_background_off,
//   Opt_disable_roll_forward,
//   Opt_discard,
//   Opt_noheap,
//   Opt_nouser_xattr,
//   Opt_noacl,
//   Opt_active_logs,
//   Opt_disable_ext_identify,
//   Opt_err,
// };

// static match_table_t f2fs_tokens = {
//   {Opt_gc_background_off, "background_gc_off"},
//   {Opt_disable_roll_forward, "disable_roll_forward"},
//   {Opt_discard, "discard"},
//   {Opt_noheap, "no_heap"},
//   {Opt_nouser_xattr, "nouser_xattr"},
//   {Opt_noacl, "noacl"},
//   {Opt_active_logs, "active_logs=%u"},
//   {Opt_disable_ext_identify, "disable_ext_identify"},
//   {Opt_err, NULL},
// };

// void F2fs::InitOnce(void *foo)
// {
//   InodeInfo *fi = (InodeInfo *) foo;

//   memset(fi, 0, sizeof(*fi));
//   inode_init_once(&fi->vfs_inode);
// }

// VnodeF2fs *F2fs::F2fsAllocInode() {
  // InodeInfo *fi;

  // // fi = kmem_cache_alloc(Inode_cachep, GFP_NOFS | __GFP_ZERO);
  // // if (!fi)
  // //   return NULL;
  // fi = new InodeInfo();

  // InitOnce((void *) fi);

  // /* Initilize f2fs-specific inode info */
  // AtomicSet(&fi->vfs_inode.i_version, 1);
  // AtomicSet(&fi->dirty_dents, 0);
  // fi->i_current_depth = 1;
  // fi->i_advise = 0;
  // RwlockInit(&fi->ext.ext_lock);

  // SetInodeFlag(fi, InodeInfoFlag::kNewInode);

  // return &fi->vfs_inode;
// }

// void F2fs::F2fsICallback(rcu_head *head)
// {
//   [[maybe_unused]] inode *inode = container_of(head, inode, i_rcu);
//   // kmem_cache_free(Inode_cachep, F2FS_I(inode));
// }

// void F2fs::F2fsDestroyInode(inode *inode)
// {
//   call_rcu(&inode->i_rcu, F2fsICallback);
// }
#endif

void F2fs::PutSuper() {
  DestroyStats(sbi_.get());
#if 0  // porting needed
  // StopGcThread(sbi_.get());
#endif

  WriteCheckpoint(false, true);

#if 0  // porting needed
  // Iput(sbi_->node_inode);
  // Iput(sbi_->meta_inode);
#endif
  fbl::AutoLock lock(&vnode_table_lock_);
  vnode_table_.erase(NodeIno(sbi_.get()));
  vnode_table_.erase(MetaIno(sbi_.get()));

  /* destroy f2fs internal modules */
  node_mgr_->DestroyNodeManager();
  seg_mgr_->DestroySegmentManager();

  delete sbi_->ckpt;

#if 0  // porting needed
  //   brelse(sbi_->raw_super_buf);
#endif
  node_mgr_.reset();
  seg_mgr_.reset();
  raw_sb_.reset();
  sbi_.reset();
}

zx_status_t F2fs::SyncFs(int sync) {
#ifdef F2FS_BU_DEBUG
  std::cout << "F2fs::SyncFs, sbi_->s_dirty=" << sbi_->s_dirty << std::endl;
#endif

#if 0  // porting needed
  //if (!sbi_->s_dirty && !GetPages(sbi_.get(), CountType::kDirtyNodes))
  //  return 0;
#endif

  if (sync)
    WriteCheckpoint(false, false);

  return ZX_OK;
}

#if 0  // porting needed
// int F2fs::F2fsStatfs(dentry *dentry /*, kstatfs *buf*/) {
  // super_block *sb = dentry->d_sb;
  // SbInfo *sbi = F2FS_SB(sb);
  // u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
  // block_t total_count, user_block_count, start_count, ovp_count;

  // total_count = LeToCpu(sbi->raw_super->block_count);
  // user_block_count = sbi->user_block_count;
  // start_count = LeToCpu(sbi->raw_super->segment0_blkaddr);
  // ovp_count = GetSmInfo(sbi)->ovp_segments << sbi->log_blocks_per_seg;
  // buf->f_type = kF2fsSuperMagic;
  // buf->f_bsize = sbi->blocksize;

  // buf->f_blocks = total_count - start_count;
  // buf->f_bfree = buf->f_blocks - ValidUserBlocks(sbi) - ovp_count;
  // buf->f_bavail = user_block_count - ValidUserBlocks(sbi);

  // buf->f_files = ValidInodeCount(sbi);
  // buf->f_ffree = sbi->total_node_count - ValidNodeCount(sbi);

  // buf->f_namelen = kMaxNameLen;
  // buf->f_fsid.val[0] = (u32)id;
  // buf->f_fsid.val[1] = (u32)(id >> 32);

  // return 0;
// }

// int F2fs::F2fsShowOptions(/*seq_file *seq*/) {
  // if (TestOpt(sbi, kMountBgGC))
  //   seq_puts(seq, ",background_gc_on");
  // else
  //   seq_puts(seq, ",background_gc_off");
  // if (TestOpt(sbi, kMountDisableRollForward))
  //   seq_puts(seq, ",disable_roll_forward");
  // if (TestOpt(sbi, kMountDiscard))
  //   seq_puts(seq, ",discard");
  // if (TestOpt(sbi, kMountNoheap))
  //   seq_puts(seq, ",no_heap_alloc");
  // if (TestOpt(sbi, kMountDisableExtIdentify))
  //   seq_puts(seq, ",disable_ext_indentify");

  // seq_printf(seq, ",active_logs=%u", sbi->active_logs);

  // return 0;
// }

// VnodeF2fs *F2fs::F2fsNfsGetInode(uint64_t ino, uint32_t generation) {
//   fbl::RefPtr<VnodeF2fs> vnode_refptr;
//   VnodeF2fs *vnode = nullptr;
//   int err;

//   if (ino < RootIno(sbi_.get()))
//     return (VnodeF2fs *)ErrPtr(-ESTALE);

//   /*
//    * f2fs_iget isn't quite right if the inode is currently unallocated!
//    * However f2fs_iget currently does appropriate checks to handle stale
//    * inodes so everything is OK.
//    */
//   err = VnodeF2fs::Vget(this, ino, &vnode_refptr);
//   if (err)
//     return (VnodeF2fs *)ErrPtr(err);
//   vnode = vnode_refptr.get();
//   if (generation && vnode->i_generation != generation) {
//     /* we didn't find the right inode.. */
//     Iput(vnode);
//     return (VnodeF2fs *)ErrPtr(-ESTALE);
//   }
//   return vnode;
// }

// struct fid {};

// dentry *F2fs::F2fsFhToDentry(fid *fid, int fh_len, int fh_type) {
//   return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
//             f2fs_nfs_get_inode);
// }

// dentry *F2fs::F2fsFhToParent(fid *fid, int fh_len, int fh_type) {
//   return generic_fh_to_parent(sb, fid, fh_len, fh_type,
//             f2fs_nfs_get_inode);
// }

// int F2fs::ParseOptions(char *options) {
  // substring_t args[MAX_OPT_ARGS];
  // char *p;
  // int arg = 0;

  // if (!options)
  //   return 0;

  // while ((p = strsep(&options, ",")) != NULL) {
  //   int token;
  //   if (!*p)
  //     continue;
  //   /*
  //    * Initialize args struct so we know whether arg was
  //    * found; some options take optional arguments.
  //    */
  //   args[0].to = args[0].from = NULL;
  //   token = match_token(p, f2fs_tokens, args);

  //   switch (token) {
  //   case Opt_gc_background_off:
  //     ClearOpt(&sbi_.get(), kMountBgGC);
  //     break;
  //   case Opt_disable_roll_forward:
  //     SetOpt(sbi_.get(), kMountDisableRollForward);
  //     break;
  //   case Opt_discard:
  //     SetOpt(sbi_.get(), kMountDiscard);
  //     break;
  //   case Opt_noheap:
  //     SetOpt(sbi_.get(), kMountNoheap);
  //     break;
  //   case Opt_active_logs:
  //     if (args->from && match_int(args, &arg))
  //       return -EINVAL;
  //     if (arg != 2 && arg != 4 && arg != 6)
  //       return -EINVAL;
  //     sbi_.get()->active_logs = arg;
  //     break;
  //   case Opt_disable_ext_identify:
  //     SetOpt(sbi_.get(), kMountDisableExtIdentify);
  //     break;
  //   default:
  //     return -EINVAL;
  //   }
  // }
  // return 0;
// }
#endif

loff_t F2fs::MaxFileSize(unsigned bits) {
  loff_t result = kAddrsPerInode;
  loff_t leaf_count = kAddrsPerBlock;

  /* two direct node blocks */
  result += (leaf_count * 2);

  /* two indirect node blocks */
  leaf_count *= kNidsPerBlock;
  result += (leaf_count * 2);

  /* one double indirect node block */
  leaf_count *= kNidsPerBlock;
  result += leaf_count;

  result <<= bits;
  return result;
}

int F2fs::SanityCheckRawSuper() {
  unsigned int blocksize;

  if (kF2fsSuperMagic != LeToCpu(raw_sb_->magic))
    return 1;

  /* Currently, support only 4KB block size */
  blocksize = 1 << LeToCpu(raw_sb_->log_blocksize);
  if (blocksize != kPageCacheSize)
    return 1;
  if (LeToCpu(raw_sb_->log_sectorsize) != kLogSectorSize)
    return 1;
  if (LeToCpu(raw_sb_->log_sectors_per_block) != kLogSectorsPerBlock)
    return 1;
  return 0;
}

int F2fs::SanityCheckCkpt() {
  unsigned int total, fsmeta;

  total = LeToCpu(raw_sb_->segment_count);
  fsmeta = LeToCpu(raw_sb_->segment_count_ckpt);
  fsmeta += LeToCpu(raw_sb_->segment_count_sit);
  fsmeta += LeToCpu(raw_sb_->segment_count_nat);
  fsmeta += LeToCpu(sbi_->ckpt->rsvd_segment_count);
  fsmeta += LeToCpu(raw_sb_->segment_count_ssa);

  if (fsmeta >= total)
    return 1;
  return 0;
}

void F2fs::InitSbInfo() {
  int i;

  sbi_->log_sectors_per_block = LeToCpu(RawSb().log_sectors_per_block);
  sbi_->log_blocksize = LeToCpu(RawSb().log_blocksize);
  sbi_->blocksize = 1 << sbi_->log_blocksize;
  sbi_->log_blocks_per_seg = LeToCpu(RawSb().log_blocks_per_seg);
  sbi_->blocks_per_seg = 1 << sbi_->log_blocks_per_seg;
  sbi_->segs_per_sec = LeToCpu(RawSb().segs_per_sec);
  sbi_->secs_per_zone = LeToCpu(RawSb().secs_per_zone);
  sbi_->total_sections = LeToCpu(RawSb().section_count);
  sbi_->total_node_count =
      (LeToCpu(RawSb().segment_count_nat) / 2) * sbi_->blocks_per_seg * kNatEntryPerBlock;
  sbi_->root_ino_num = LeToCpu(RawSb().root_ino);
  sbi_->node_ino_num = LeToCpu(RawSb().node_ino);
  sbi_->meta_ino_num = LeToCpu(RawSb().meta_ino);

  for (i = 0; i < static_cast<int>(CountType::kNrCountType); i++)
    AtomicSet(&sbi_->nr_pages[i], 0);
}

zx_status_t F2fs::FillSuper() {
#if 0  // porting needed
  //   SuperBlock *raw_super;
  //   buffer_head *raw_super_buf = NULL;
#endif
  VnodeF2fs *root;
  zx_status_t err = ZX_ERR_INVALID_ARGS;

  /* allocate memory for f2fs-specific super block info */
  sbi_ = std::make_unique<SbInfo>();
  if (!sbi_)
    return ZX_ERR_NO_MEMORY;
  memset(sbi_.get(), 0, sizeof(SbInfo));

#if 0  // porting needed
  // super_block *sb = sbi_->sb;

  /* set a temporary block size */
  // if (!SbSetBlocksize(sb, kBlkSize))
  //  goto free_sbi;
#endif

  /* mount options are fixed as below */
  ClearOpt(sbi_.get(), kMountBgGC);
  ClearOpt(sbi_.get(), kMountDiscard);
  SetOpt(sbi_.get(), kMountNoheap);
  ClearOpt(sbi_.get(), kMountXattrUser);
  ClearOpt(sbi_.get(), kMountPosixAcl);
  sbi_->active_logs = kNrCursegType;
  SetOpt(sbi_.get(), kMountDisableExtIdentify);

#if 0  // porting needed
  /* parse mount options */
  // if (ParseOptions((char *)data))
  //   goto free_sb_buf;
#endif

  /* sanity checking of raw super */
  if (SanityCheckRawSuper())
    goto free_sb_buf;

#if 0  // porting needed
  // sb->s_maxbytes = MaxFileSize(RawSb().log_blocksize);
  // sb->s_max_links = kLinkMax;

  // For NFS support
  // get_random_bytes(&sbi->s_next_generation, sizeof(uint32_t));

  // sb->s_op = &f2fs_sops;
  //  sb->s_xattr = f2fs_xattr_handlers;
  //  sb->s_export_op = &f2fs_export_ops;
  // sb->s_magic = kF2fsSuperMagic;
  // sb->s_fs_info = sbi_.get();
  // sb->s_time_gran = 1;
  // sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
  //  (TestOpt(sbi_.get(), kMountPosixAcl) ? MS_POSIXACL : 0);
  // memcpy(&sb->s_uuid, RawSb().uuid, sizeof(RawSb().uuid));

  /* init f2fs-specific super block info */
  //   sbi->sb = sb;
#endif
  sbi_->raw_super = raw_sb_.get();
#if 0  // porting needed
  //   sbi_->raw_super_buf = raw_super_buf;
#endif
  sbi_->por_doing = 0;
  SpinLockInit(&sbi_->stat_lock);
#if 0  // porting needed
  // init_rwsem(&sbi->bio_sem);
#endif
  InitSbInfo();

  /* get an inode for meta space */
#if 0  // porting needed
  // err = VnodeF2fs::Vget(this, MetaIno(sbi_), &sbi_->meta_vnode);
  // if (err) {
  //   goto free_sb_buf;
  // }
#endif

  err = GetValidCheckpoint();
  if (err)
    goto free_meta_inode;

  /* sanity checking of checkpoint */
  err = ZX_ERR_INVALID_ARGS;
  if (SanityCheckCkpt())
    goto free_cp;

  sbi_->total_valid_node_count = LeToCpu(sbi_->ckpt->valid_node_count);
  sbi_->total_valid_inode_count = LeToCpu(sbi_->ckpt->valid_inode_count);
  sbi_->user_block_count = LeToCpu(sbi_->ckpt->user_block_count);
  sbi_->total_valid_block_count = LeToCpu(sbi_->ckpt->valid_block_count);
  sbi_->last_valid_block_count = sbi_->total_valid_block_count;
  sbi_->alloc_valid_block_count = 0;
  list_initialize(&sbi_->dir_inode_list);
  SpinLockInit(&sbi_->dir_inode_lock);

  /* init super block */
#if 0  // porting needed
  // if (!SbSetBlocksize(sb, sbi_->blocksize))
  //  goto free_cp;
#endif

  InitOrphanInfo();

  /* setup f2fs internal modules */
  seg_mgr_ = std::make_unique<SegMgr>(this);
  err = seg_mgr_->BuildSegmentManager();
  if (err)
    goto free_sm;

  node_mgr_ = std::make_unique<NodeMgr>(this);
  err = node_mgr_->BuildNodeManager();
  if (err)
    goto free_nm;

#if 0  // porting needed
  // BuildGcManager(sbi);

  /* get an inode for node space */
  // err = VnodeF2fs::Vget(this, NodeIno(sbi_), &sbi_->node_vnode);
  // if (err) {
  //   goto free_nm;
  // }
#endif

  /* if there are nt orphan nodes free them */
  err = ZX_ERR_INVALID_ARGS;
  if (!(sbi_->ckpt->ckpt_flags & kCpUmountFlag) && RecoverOrphanInodes())
    goto free_node_inode;

  /* read root inode and dentry */
  err = VnodeF2fs::Vget(this, RootIno(sbi_.get()), &root_vnode_);
  if (err) {
    goto free_node_inode;
  }
  root = root_vnode_.get();
  if (!S_ISDIR(root->i_mode_) || !root->i_blocks_ || !root->i_size_)
    goto free_root_inode;

#if 0  // porting needed
  // sb->s_root = DMakeRoot(root); /* allocate root dentry */
  // if (!sb->s_root) {
  //   err = ZX_ERR_NO_MEMORY;
  //   goto free_root_inode;
  // }
#endif

  /* recover fsynced data */
  if (!(sbi_->ckpt->ckpt_flags & kCpUmountFlag) && !TestOpt(sbi_.get(), kMountDisableExtIdentify)) {
    RecoverFsyncData();
  }

#if 0  // porting needed
  /* After POR, we can run background GC thread */
  // err = StartGcThread(sbi);
  // if (err)
  //   goto fail;
#endif

  err = BuildStats(sbi_.get());
  if (err)
    goto fail;

  return ZX_OK;

fail:
#if 0  // porting needed
  // StopGcThread(sbi);
#endif
free_root_inode:
#if 0  // porting needed
//  dput(sb->s_root);
//  sb->s_root = NULL;
#endif
free_node_inode:
#if 0  // porting needed
  // Iput(sbi_->node_inode);
#endif
free_nm:
  node_mgr_->DestroyNodeManager();
  node_mgr_.reset();
free_sm:
  seg_mgr_->DestroySegmentManager();
  seg_mgr_.reset();
free_cp:
  delete sbi_->ckpt;
free_meta_inode:
#if 0  // porting needed
  // MakeBadInode(sbi_->meta_inode);
  // Iput(sbi_->meta_inode);
#endif
free_sb_buf:
#if 0  // porting needed
  //   brelse(raw_super_buf);
  // free_sbi:
#endif
  sbi_.reset();
  return err;
}

#if 0  // porting needed
// dentry *F2fs::F2fsMount(file_system_type *fs_type, int flags,
//       const char *dev_name, void *data)
// {
// //   return mount_bdev(fs_type, flags, dev_name, data, F2fs::FillSuper);
//   return mount_bdev(fs_type, flags, dev_name, data, NULL);
// }

// int F2fs::InitInodecache(void) {
//   Inode_cachep = KmemCacheCreate("Inode_cache",
//       sizeof(InodeInfo), NULL);
//   if (Inode_cachep == NULL)
//     return -ENOMEM;
// }

// void F2fs::DestroyInodecache(void) {
//   /*
//    * Make sure all delayed rcu free inodes are flushed before we
//    * destroy cache.
//    */
//   rcu_barrier();
//   kmem_cache_destroy(Inode_cachep);
// }

// int /*__init*/ F2fs::initF2fsFs(void)
// {
//   int err;

//   err = InitInodecache();
//   if (err)
//     goto fail;
//   // TODO(unknown): should decide how to use slab cache before it
//   //err = CreateNodeManagerCaches();
//   if (err)
//     goto fail;
//   return register_filesystem(&f2fs_fs_type);
// fail:
//   return err;
// }

// void /*__exit*/ F2fs::exitF2fsFs(void)
// {
//   unregister_filesystem(&f2fs_fs_type);
//   // TODO(unknown): should decide how to use slab cache before it
//   //DestroyNodeManagerCaches();
//   DestroyInodecache();
// }
#endif

}  // namespace f2fs
