// 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 F2FS_VNODE_H_
#define 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, kF2fsHashBits); }

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

  void Sync(SyncCallback closure) final;

  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_; }
  f2fs_inode Inode() 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);
#if 0  // porting needed
  // void F2fsTruncate();
#endif
  int TruncateDataBlocksRange(dnode_of_data *dn, int count);
  void TruncateDataBlocks(dnode_of_data *dn);
  void TruncatePartialDataPage(uint64_t from);
#if 0  // porting needed
  // int TruncateBlocks(uint64_t from);
#endif
  zx_status_t TruncateHole(pgoff_t pg_start, pgoff_t pg_end);
#if 0  // porting needed
  // void F2fsEvictInode();
#endif

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

#if 0  // porting needed
  // static int CheckExtentCache(inode *inode, pgoff_t pgofs,
  //        buffer_head *bh_result);
#endif
  void UpdateExtentCache(block_t blk_addr, dnode_of_data *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_;

  fbl::StringPiece i_name_sp_;

  f2fs_inode_info fi_;

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

void MarkInodeDirty(VnodeF2fs *vnode);

}  // namespace f2fs

#endif  // F2FS_VNODE_H_
