| // 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_DIR_H_ |
| #define F2FS_DIR_H_ |
| |
| #include <dirent.h> |
| #include <sys/stat.h> |
| |
| namespace f2fs { |
| |
| static unsigned char filetype_table[F2FS_FT_MAX] = { |
| [F2FS_FT_UNKNOWN] = DT_UNKNOWN, [F2FS_FT_REG_FILE] = DT_REG, [F2FS_FT_DIR] = DT_DIR, |
| [F2FS_FT_CHRDEV] = DT_CHR, [F2FS_FT_BLKDEV] = DT_BLK, [F2FS_FT_FIFO] = DT_FIFO, |
| [F2FS_FT_SOCK] = DT_SOCK, [F2FS_FT_SYMLINK] = DT_LNK, |
| }; |
| |
| constexpr unsigned int kStatShift = 12; |
| |
| static unsigned char type_by_mode[S_IFMT >> kStatShift] = { |
| [S_IFREG >> kStatShift] = F2FS_FT_REG_FILE, [S_IFDIR >> kStatShift] = F2FS_FT_DIR, |
| [S_IFCHR >> kStatShift] = F2FS_FT_CHRDEV, [S_IFBLK >> kStatShift] = F2FS_FT_BLKDEV, |
| [S_IFIFO >> kStatShift] = F2FS_FT_FIFO, [S_IFSOCK >> kStatShift] = F2FS_FT_SOCK, |
| [S_IFLNK >> kStatShift] = F2FS_FT_SYMLINK, |
| }; |
| |
| class Dir : public VnodeF2fs { |
| public: |
| explicit Dir(F2fs *fs); |
| explicit Dir(F2fs *fs, ino_t ino); |
| ~Dir() = default; |
| |
| zx_status_t Lookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> *out) final; |
| zx_status_t Readdir(fs::VdirCookie *cookie, void *dirents, size_t len, size_t *out_actual) final; |
| zx_status_t Create(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) final; |
| zx_status_t Link(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> _target) final; |
| zx_status_t Unlink(fbl::StringPiece name, bool must_be_dir) final; |
| zx_status_t Rename(fbl::RefPtr<fs::Vnode> _newdir, fbl::StringPiece oldname, |
| fbl::StringPiece newname, bool src_must_be_dir, bool dst_must_be_dir); |
| |
| uint64_t DirBlocks(); |
| static unsigned int DirBuckets(unsigned int level); |
| static unsigned int BucketBlocks(unsigned int level); |
| void SetDeType(f2fs_dir_entry *de, VnodeF2fs *vnode); |
| static uint64_t DirBlockIndex(unsigned int level, unsigned int idx); |
| bool EarlyMatchName(const char *name, int namelen, f2fs_hash_t namehash, |
| f2fs_dir_entry *de); |
| f2fs_dir_entry *FindInBlock(Page *dentry_page, const char *name, int namelen, |
| int *max_slots, f2fs_hash_t namehash, Page **res_page); |
| f2fs_dir_entry *FindInLevel(unsigned int level, fbl::StringPiece name, int namelen, |
| f2fs_hash_t namehash, Page **res_page); |
| f2fs_dir_entry *FindEntry(fbl::StringPiece name, Page **res_page); |
| f2fs_dir_entry *ParentDir(Page **p); |
| ino_t InodeByName(fbl::StringPiece name); |
| void SetLink(f2fs_dir_entry *de, Page *page, VnodeF2fs *inode); |
| void InitDentInode(VnodeF2fs *vnode, Page *ipage); |
| #if 0 // porting needed |
| // zx_status_t InitInodeMetadata(VnodeF2fs *vnode, dentry *dentry); |
| #else |
| zx_status_t InitInodeMetadata(VnodeF2fs *vnode); |
| #endif |
| void UpdateParentMetadata(VnodeF2fs *inode, unsigned int current_depth); |
| int RoomForFilename(f2fs_dentry_block *dentry_blk, int slots); |
| zx_status_t AddLink(fbl::StringPiece name, VnodeF2fs *vnode); |
| void DeleteEntry(f2fs_dir_entry *dentry, Page *page, VnodeF2fs *vnode); |
| zx_status_t MakeEmpty(VnodeF2fs *vnode, VnodeF2fs *parent); |
| bool IsEmptyDir(); |
| |
| zx_status_t NewInode(uint32_t mode, fbl::RefPtr<VnodeF2fs> *out); |
| int IsMultimediaFile(const char *s, const char *sub); |
| void SetColdFile(const char *name); |
| zx_status_t DoCreate(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out); |
| #if 0 // porting needed |
| // int F2fsLink(dentry *old_dentry, dentry *dentry); |
| // dentry *F2fsGetParent(dentry *child); |
| #endif |
| zx_status_t DoUnlink(VnodeF2fs *vnode, fbl::StringPiece name); |
| #if 0 // porting needed |
| // int F2fsSymlink(dentry *dentry, const char *symname); |
| #endif |
| zx_status_t Mkdir(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out); |
| zx_status_t Rmdir(Dir *vnode, fbl::StringPiece name); |
| #if 0 // porting needed |
| // int F2fsMknod(dentry *dentry, umode_t mode, dev_t rdev); |
| #endif |
| zx_status_t DoLookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> *out); |
| }; |
| |
| } // namespace f2fs |
| |
| #endif // F2FS_DIR_H_ |