#pragma message "using readdir" #define MAX_ENTRIES_PER_LOOP 64 #include "fs_opendir.hpp" #include "fs_closedir.hpp" #include "hashset.hpp" #include "scope_guard.hpp" #include "fs_readdir.hpp" #include "fs_inode.hpp" #include "fuse_dirents.hpp" #include #include static u64 _dirent_exact_namelen(const struct dirent *d_) { #ifdef _D_EXACT_NAMLEN return _D_EXACT_NAMLEN(d_); #elif defined _DIRENT_HAVE_D_NAMLEN return d_->d_namlen; #else return strlen(d_->d_name); #endif } static inline int _readdir(const fs::path &branch_path_, const fs::path &rel_dirpath_, HashSet &names_, fuse_dirents_t *dirents_, std::mutex &mutex_) { DIR *dir; fs::path rel_filepath; fs::path abs_dirpath; abs_dirpath = branch_path_ / rel_dirpath_; errno = 0; dir = fs::opendir(abs_dirpath); if(dir == NULL) return -errno; DEFER{ fs::closedir(dir); }; rel_filepath = rel_dirpath_ / "dummy"; while(true) { std::lock_guard lk(mutex_); for(int i = 0; i < MAX_ENTRIES_PER_LOOP; i++) { int rv; int namelen; dirent *de; errno = 0; de = fs::readdir(dir); if(de == NULL) return -errno; namelen = ::_dirent_exact_namelen(de); rv = names_.put(de->d_name,namelen); if(rv == 0) continue; rel_filepath.replace_filename(de->d_name); de->d_ino = fs::inode::calc(branch_path_, rel_filepath, DTTOIF(de->d_type), de->d_ino); fuse_dirents_add(dirents_,de,namelen); } } return 0; }