| // 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; |
| |
| // TODO: divide into Directory and File child classes |
| 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() override; |
| |
| 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(unsigned long ino); |
| #endif |
| |
| static zx_status_t F2fsVget(F2fs *fs, unsigned long ino, fbl::RefPtr<VnodeF2fs> *out); |
| void UpdateInode(Page *node_page); |
| zx_status_t F2fsWriteInode(struct writeback_control *wbc); |
| #if 0 // porting needed |
| // void F2fsTruncate(); |
| #endif |
| int TruncateDataBlocksRange(struct dnode_of_data *dn, int count); |
| void TruncateDataBlocks(struct dnode_of_data *dn); |
| void TruncatePartialDataPage(uint64_t from); |
| #if 0 // porting needed |
| // int TruncateBlocks(uint64_t from); |
| #endif |
| int TruncateHole(pgoff_t pg_start, pgoff_t pg_end); |
| #if 0 // porting needed |
| // void F2fsEvictInode(); |
| #endif |
| |
| void __SetDataBlkaddr(struct dnode_of_data *dn, block_t new_addr); |
| int ReserveNewBlock(struct dnode_of_data *dn); |
| |
| #if 0 // porting needed |
| // static int CheckExtentCache(struct inode *inode, pgoff_t pgofs, |
| // struct buffer_head *bh_result); |
| #endif |
| void UpdateExtentCache(block_t blk_addr, struct 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 F2fsReadpage(F2fs *fs, Page *page, block_t blk_addr, int type); |
| #if 0 // porting needed |
| // static int GetDataBlockRo(struct inode *inode, sector_t iblock, |
| // struct buffer_head *bh_result, int create); |
| // static int F2fsReadDataPage(struct file *file, struct page *page); |
| // static int F2fsReadDataPages(struct file *file, |
| // struct address_space *mapping, |
| // struct list_head *pages, unsigned nr_pages); |
| #endif |
| zx_status_t DoWriteDataPage(Page *page); |
| zx_status_t F2fsWriteDataPage(Page *page, struct writeback_control *wbc); |
| #if 0 // porting needed |
| // int F2fsWriteDataPages(/*struct address_space *mapping,*/ |
| // struct writeback_control *wbc); |
| #endif |
| zx_status_t F2fsWriteBegin(size_t pos, size_t len, Page **page); |
| #if 0 // porting needed |
| // ssize_t F2fsDirectIO(/*int rw, struct kiocb *iocb, |
| // const struct iovec *iov, */ |
| // loff_t offset, unsigned long nr_segs); |
| // [[maybe_unused]] static void F2fsInvalidateDataPage(struct Page *page, unsigned long offset); |
| // [[maybe_unused]] static int F2fsReleaseDataPage(struct Page *page, gfp_t wait); |
| // int F2fsSetDataPageDirty(Page *page); |
| #endif |
| |
| void IncNlink(); |
| void DropNlink(); |
| void ClearNlink(); |
| void SetNlink(uint32_t nlink); |
| |
| fbl::Mutex v_lock; |
| mtx_t i_mutex; |
| |
| umode_t i_mode; |
| uid_t i_uid; |
| gid_t i_gid; |
| unsigned int i_nlink; |
| |
| loff_t i_size; |
| blkcnt_t i_blocks; |
| struct timespec i_atime; |
| struct timespec i_mtime; |
| struct timespec i_ctime; |
| uint32_t i_generation; |
| |
| unsigned long i_state; |
| |
| fbl::StringPiece i_name_sp; |
| |
| struct f2fs_inode_info fi; |
| |
| private: |
| F2fs *fs_; |
| ino_t ino_{}; |
| f2fs_inode inode_{}; |
| uint32_t fd_count_{}; |
| }; |
| |
| void mark_inode_dirty(VnodeF2fs *vnode); |
| |
| } // namespace f2fs |
| |
| #endif // F2FS_VNODE_H_ |