mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
Add getdents based readdir functions for Linux (#1533)
This commit is contained in:
parent
95ab37fdd2
commit
2f3e807e9d
33 changed files with 886 additions and 904 deletions
|
|
@ -18,99 +18,19 @@
|
|||
|
||||
#include "fuse_readdir_seq.hpp"
|
||||
|
||||
#include "error.hpp"
|
||||
#include "branches.hpp"
|
||||
#include "config.hpp"
|
||||
#include "dirinfo.hpp"
|
||||
#include "errno.hpp"
|
||||
#include "fs_closedir.hpp"
|
||||
#include "fs_dirfd.hpp"
|
||||
#include "fs_inode.hpp"
|
||||
#include "fs_opendir.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_readdir.hpp"
|
||||
#include "fs_stat.hpp"
|
||||
#include "hashset.hpp"
|
||||
#include "scope_guard.hpp"
|
||||
#include "supported_getdents64.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
||||
#include "fuse.h"
|
||||
#include "fuse_dirents.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
static
|
||||
uint64_t
|
||||
_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;
|
||||
#ifdef MERGERFS_SUPPORTED_GETDENTS64
|
||||
#include "fuse_readdir_seq_getdents.icpp"
|
||||
#else
|
||||
return strlen(d_->d_name);
|
||||
#include "fuse_readdir_seq_readdir.icpp"
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_readdir(const Branches::Ptr &branches_,
|
||||
const fs::path &rel_dirpath_,
|
||||
fuse_dirents_t *buf_)
|
||||
{
|
||||
Err err;
|
||||
HashSet names;
|
||||
fs::path rel_filepath;
|
||||
fs::path abs_dirpath;
|
||||
|
||||
fuse_dirents_reset(buf_);
|
||||
|
||||
rel_filepath = rel_dirpath_ / "dummy";
|
||||
for(const auto &branch : *branches_)
|
||||
{
|
||||
int rv;
|
||||
DIR *dh;
|
||||
|
||||
abs_dirpath = branch.path / rel_dirpath_;
|
||||
|
||||
errno = 0;
|
||||
dh = fs::opendir(abs_dirpath);
|
||||
err = -errno;
|
||||
if(!dh)
|
||||
continue;
|
||||
|
||||
DEFER{ fs::closedir(dh); };
|
||||
|
||||
rv = 0;
|
||||
for(dirent *de = fs::readdir(dh); de; de = fs::readdir(dh))
|
||||
{
|
||||
std::uint64_t namelen;
|
||||
|
||||
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);
|
||||
|
||||
rv = fuse_dirents_add(buf_,de,namelen);
|
||||
if(rv)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_,
|
||||
fuse_dirents_t *buf_)
|
||||
fuse_dirents_t *dirents_)
|
||||
{
|
||||
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||
const fuse_context *fc = fuse_get_context();
|
||||
|
|
@ -118,5 +38,5 @@ FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_,
|
|||
|
||||
return ::_readdir(cfg.branches,
|
||||
di->fusepath,
|
||||
buf_);
|
||||
dirents_);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue