// 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.

#ifndef THIRD_PARTY_F2FS_VNODE_H_
#define THIRD_PARTY_F2FS_VNODE_H_

namespace f2fs {

// Used by fsck
class F2fs;

class VnodeF2fs : public fs::Vnode,
                  public fbl::SinglyLinkedListable<VnodeF2fs *>,
                  public fbl::Recyclable<VnodeF2fs> {
 public:
  explicit VnodeF2fs(F2fs *fs);
  explicit VnodeF2fs(F2fs *fs, ino_t ino);
  ~VnodeF2fs() = default;

  static void Allocate(F2fs *fs, ino_t ino, uint32_t mode, fbl::RefPtr<VnodeF2fs> *out);
  static void Create(F2fs *fs, ino_t ino, fbl::RefPtr<VnodeF2fs> *out);

  ino_t GetKey() const { return ino_; }

  static size_t GetHash(ino_t key) { return fnv1a_tiny(key, kHashBits); }

  using fs::Vnode::Open;
  zx_status_t Open(ValidatedOptions options, fbl::RefPtr<Vnode> *out_redirect);
  zx_status_t Close();

  void Sync(SyncCallback closure) final;
  zx_status_t SyncFile(loff_t start, loff_t end, int datasync);
  int NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode);

  zx_status_t QueryFilesystem(fuchsia_io::wire::FilesystemInfo *info) final;

  void fbl_recycle() override;

  bool IsDirectory();

  F2fs *Vfs() const { return fs_; }
  ino_t Ino() const { return ino_; }
  Inode GetInode() const { return inode_; }

  zx_status_t GetAttributes(fs::VnodeAttributes *a) final;

  zx_status_t GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                     [[maybe_unused]] fs::Rights rights,
                                     fs::VnodeRepresentation *info) final;

  fs::VnodeProtocolSet GetProtocols() const final;

#if 0  // porting needed
  // void F2fsSetInodeFlags();
  // int F2fsIgetTest(void *data);
  // VnodeF2fs *F2fsIgetNowait(uint64_t ino);
#endif

  static zx_status_t Vget(F2fs *fs, uint64_t ino, fbl::RefPtr<VnodeF2fs> *out);
  void UpdateInode(Page *node_page);
  zx_status_t WriteInode(WritebackControl *wbc);
  zx_status_t DoTruncate();
  int TruncateDataBlocksRange(DnodeOfData *dn, int count);
  void TruncateDataBlocks(DnodeOfData *dn);
  void TruncatePartialDataPage(uint64_t from);
  zx_status_t TruncateBlocks(uint64_t from);
  zx_status_t TruncateHole(pgoff_t pg_start, pgoff_t pg_end);
#if 0  // porting needed
  // void F2fsEvictInode();
#endif

  void SetDataBlkaddr(DnodeOfData *dn, block_t new_addr);
  int ReserveNewBlock(DnodeOfData *dn);

#if 0  // porting needed
  // static int CheckExtentCache(inode *inode, pgoff_t pgofs,
  //        buffer_head *bh_result);
#endif
  void UpdateExtentCache(block_t blk_addr, DnodeOfData *dn);
  zx_status_t FindDataPage(pgoff_t index, Page **out);
  zx_status_t GetLockDataPage(pgoff_t index, Page **out);
  zx_status_t GetNewDataPage(pgoff_t index, bool new_i_size, Page **out);

  static zx_status_t Readpage(F2fs *fs, Page *page, block_t blk_addr, int type);
#if 0  // porting needed
  // static int GetDataBlockRo(inode *inode, sector_t iblock,
  //      buffer_head *bh_result, int create);
  // static int F2fsReadDataPage(file *file, page *page);
  // static int F2fsReadDataPages(file *file,
  //       address_space *mapping,
  //       list_head *pages, unsigned nr_pages);
#endif
  zx_status_t DoWriteDataPage(Page *page);
  zx_status_t WriteDataPageReq(Page *page, WritebackControl *wbc);
#if 0  // porting needed
  // int F2fsWriteDataPages(/*address_space *mapping,*/
  //                        WritebackControl *wbc);
#endif
  zx_status_t WriteBegin(size_t pos, size_t len, Page **page);
#if 0  // porting needed
  // ssize_t F2fsDirectIO(/*int rw, kiocb *iocb,
  //   const iovec *iov, */
  //                      loff_t offset, uint64_t nr_segs);
  //   [[maybe_unused]] static void F2fsInvalidateDataPage(Page *page, uint64_t offset);
  //   [[maybe_unused]] static int F2fsReleaseDataPage(Page *page, gfp_t wait);
  // int F2fsSetDataPageDirty(Page *page);
#endif

  void IncNlink();
  void DropNlink();
  void ClearNlink();
  void SetNlink(uint32_t nlink);

  // TODO(unknown): non-public member variables
  fbl::Mutex v_lock_;
  mtx_t i_mutex_;

  umode_t i_mode_;
  uid_t i_uid_;
  gid_t i_gid_;
  unsigned int i_nlink_;

  uint64_t i_size_;
  blkcnt_t i_blocks_;
  timespec i_atime_;
  timespec i_mtime_;
  timespec i_ctime_;
  uint32_t i_generation_;

  uint64_t i_state_;

  std::string_view i_name_sp_;

  InodeInfo fi_;

 private:
  F2fs *fs_;
  ino_t ino_{};
  Inode inode_{};
  uint32_t fd_count_{};
};

void MarkInodeDirty(VnodeF2fs *vnode);

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_VNODE_H_
