blob: d1df00824b968c00426cc28ebb44fa66d26f1921 [file] [log] [blame]
// 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_
#include "namestring.h"
namespace f2fs {
constexpr uint32_t kNullIno = std::numeric_limits<uint32_t>::max();
// 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();
zx_status_t QueryFilesystem(fuchsia_io::wire::FilesystemInfo *info) final;
void fbl_recycle() { RecycleNode(); };
bool IsDirectory();
F2fs *Vfs() const { return fs_; }
ino_t Ino() const { return ino_; }
zx_status_t GetAttributes(fs::VnodeAttributes *a) final;
zx_status_t SetAttributes(fs::VnodeAttributesUpdate attr) 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);
void UpdateParentNid(uint32_t pino) { i_pino_ = pino; };
#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);
uint64_t GetBlockCount();
void Notify(std::string_view name, unsigned event) final;
zx_status_t WatchDir(fs::Vfs *vfs, uint32_t mask, uint32_t options, zx::channel watcher) final;
// 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_;
NameString i_name_sp_;
uint32_t i_pino_{kNullIno};
InodeInfo fi_;
protected:
void RecycleNode() override;
private:
F2fs *fs_;
ino_t ino_{};
uint32_t fd_count_{};
fs::WatcherContainer watcher_{};
};
void MarkInodeDirty(VnodeF2fs *vnode);
} // namespace f2fs
#endif // THIRD_PARTY_F2FS_VNODE_H_