From dbdd3e22fca1088408522e85c3315978d04bda30 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 26 Jun 2020 16:50:49 -0400 Subject: [PATCH] additional readdir refactor cleanup Differences between readdir and getdents is minimal at best. Leaving code for now to allow for possible expansion later. --- LICENSE | 2 +- libfuse/include/fuse_dirents.h | 18 +++--- libfuse/include/linux_dirent.h | 9 +++ libfuse/include/linux_dirent64.h | 12 ---- libfuse/lib/fuse_dirents.c | 33 ++++++----- src/config.cpp | 2 + src/config.hpp | 2 + src/config_readdir.cpp | 49 ++++++++++++++++ src/config_readdir.hpp | 29 ++++++++++ src/enum.hpp | 2 + src/fs_base_fstatat.hpp | 2 + src/fs_base_getdents.cpp | 37 ++++++++++++ src/fs_base_getdents.hpp | 27 +++++++++ src/fs_copydata_copy_file_range.cpp | 2 + src/fs_copydata_copy_file_range.hpp | 4 +- src/fs_glob.hpp | 2 + src/fs_statvfs_cache.hpp | 2 + src/fuse_readdir.cpp | 37 ++++++++++-- ...ddir_linux.icpp => fuse_readdir_linux.cpp} | 50 +++++----------- src/fuse_readdir_linux.hpp | 33 +++++++++++ src/fuse_readdir_plus.cpp | 45 ++++++++++++-- src/fuse_readdir_plus.hpp | 4 -- ...linux.icpp => fuse_readdir_plus_linux.cpp} | 58 ++++++------------- src/fuse_readdir_plus_linux.hpp | 35 +++++++++++ ...posix.icpp => fuse_readdir_plus_posix.cpp} | 37 ++++-------- src/fuse_readdir_plus_posix.hpp | 35 +++++++++++ ...ddir_posix.icpp => fuse_readdir_posix.cpp} | 29 ++-------- src/fuse_readdir_posix.hpp | 33 +++++++++++ 28 files changed, 453 insertions(+), 177 deletions(-) create mode 100644 libfuse/include/linux_dirent.h delete mode 100644 libfuse/include/linux_dirent64.h create mode 100644 src/config_readdir.cpp create mode 100644 src/config_readdir.hpp create mode 100644 src/fs_base_getdents.cpp create mode 100644 src/fs_base_getdents.hpp rename src/{fuse_readdir_linux.icpp => fuse_readdir_linux.cpp} (67%) create mode 100644 src/fuse_readdir_linux.hpp rename src/{fuse_readdir_plus_linux.icpp => fuse_readdir_plus_linux.cpp} (67%) create mode 100644 src/fuse_readdir_plus_linux.hpp rename src/{fuse_readdir_plus_posix.icpp => fuse_readdir_plus_posix.cpp} (78%) create mode 100644 src/fuse_readdir_plus_posix.hpp rename src/{fuse_readdir_posix.icpp => fuse_readdir_posix.cpp} (77%) create mode 100644 src/fuse_readdir_posix.hpp diff --git a/LICENSE b/LICENSE index 3718c1dc..f867f7d7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ /* ISC License - Copyright (c) 2019, Antonio SJ Musumeci + Copyright (c) 2020, Antonio SJ Musumeci Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/libfuse/include/fuse_dirents.h b/libfuse/include/fuse_dirents.h index 4c0e06d8..8bd9e82f 100644 --- a/libfuse/include/fuse_dirents.h +++ b/libfuse/include/fuse_dirents.h @@ -25,7 +25,7 @@ extern "C" { #include "fuse_dirent.h" #include "fuse_direntplus.h" #include "fuse_entry.h" -#include "linux_dirent64.h" +#include "linux_dirent.h" #include #include @@ -63,14 +63,14 @@ int fuse_dirents_add_plus(fuse_dirents_t *d, const uint64_t namelen, const fuse_entry_t *entry, const struct stat *st); -int fuse_dirents_add_linux(fuse_dirents_t *d, - const struct linux_dirent64 *de, - const uint64_t namelen); -int fuse_dirents_add_linux_plus(fuse_dirents_t *d, - const struct linux_dirent64 *de, - const uint64_t namelen, - const fuse_entry_t *entry, - const struct stat *st); +int fuse_dirents_add_linux(fuse_dirents_t *d, + const struct linux_dirent *de, + const uint64_t namelen); +int fuse_dirents_add_linux_plus(fuse_dirents_t *d, + const struct linux_dirent *de, + const uint64_t namelen, + const fuse_entry_t *entry, + const struct stat *st); void *fuse_dirents_find(fuse_dirents_t *d, const uint64_t ino); diff --git a/libfuse/include/linux_dirent.h b/libfuse/include/linux_dirent.h new file mode 100644 index 00000000..67b6b00d --- /dev/null +++ b/libfuse/include/linux_dirent.h @@ -0,0 +1,9 @@ +#pragma once + +struct linux_dirent +{ + unsigned long ino; + unsigned long off; + unsigned short reclen; + char name[]; +}; diff --git a/libfuse/include/linux_dirent64.h b/libfuse/include/linux_dirent64.h deleted file mode 100644 index 5ba8e328..00000000 --- a/libfuse/include/linux_dirent64.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -struct linux_dirent64 -{ - uint64_t d_ino; - int64_t d_off; - uint16_t d_reclen; - uint8_t d_type; - char d_name[]; -}; diff --git a/libfuse/lib/fuse_dirents.c b/libfuse/lib/fuse_dirents.c index 8c8c6157..a59f9222 100644 --- a/libfuse/lib/fuse_dirents.c +++ b/libfuse/lib/fuse_dirents.c @@ -5,7 +5,7 @@ #include "fuse_direntplus.h" #include "fuse_dirents.h" #include "fuse_entry.h" -#include "linux_dirent64.h" +#include "linux_dirent.h" #include "stat_utils.h" #include @@ -16,7 +16,8 @@ #include #include -#define DEFAULT_SIZE (1024 * 16) +/* 32KB - same as glibc getdents buffer size */ +#define DEFAULT_SIZE (1024 * 32) static uint64_t @@ -308,9 +309,9 @@ fuse_dirents_add_plus(fuse_dirents_t *d_, } int -fuse_dirents_add_linux(fuse_dirents_t *d_, - const struct linux_dirent64 *dirent_, - const uint64_t namelen_) +fuse_dirents_add_linux(fuse_dirents_t *d_, + const struct linux_dirent *dirent_, + const uint64_t namelen_) { uint64_t size; fuse_dirent_t *d; @@ -332,21 +333,21 @@ fuse_dirents_add_linux(fuse_dirents_t *d_, if(d == NULL) return -ENOMEM; - d->ino = dirent_->d_ino; + d->ino = dirent_->ino; d->off = d_->data_len; d->namelen = namelen_; - d->type = dirent_->d_type; - memcpy(d->name,dirent_->d_name,namelen_); + d->type = *((char*)dirent_ + dirent_->reclen - 1); + memcpy(d->name,dirent_->name,namelen_); return 0; } int -fuse_dirents_add_linux_plus(fuse_dirents_t *d_, - const struct linux_dirent64 *dirent_, - const uint64_t namelen_, - const fuse_entry_t *entry_, - const struct stat *st_) +fuse_dirents_add_linux_plus(fuse_dirents_t *d_, + const struct linux_dirent *dirent_, + const uint64_t namelen_, + const fuse_entry_t *entry_, + const struct stat *st_) { uint64_t size; fuse_direntplus_t *d; @@ -368,11 +369,11 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_, if(d == NULL) return -ENOMEM; - d->dirent.ino = dirent_->d_ino; + d->dirent.ino = dirent_->ino; d->dirent.off = d_->data_len; d->dirent.namelen = namelen_; - d->dirent.type = dirent_->d_type; - memcpy(d->dirent.name,dirent_->d_name,namelen_); + d->dirent.type = *((char*)dirent_ + dirent_->reclen - 1); + memcpy(d->dirent.name,dirent_->name,namelen_); d->entry = *entry_; diff --git a/src/config.cpp b/src/config.cpp index 772669c2..93297e65 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -90,6 +90,7 @@ Config::Config() nullrw(false), pid(::getpid()), posix_acl(false), + readdir(ReadDir::ENUM::POSIX), readdirplus(false), security_capability(true), srcmounts(branches), @@ -149,6 +150,7 @@ Config::Config() _map["nullrw"] = &nullrw; _map["pid"] = &pid; _map["posix_acl"] = &posix_acl; + // _map["readdir"] = &readdir; _map["readdirplus"] = &readdirplus; _map["security_capability"] = &security_capability; _map["srcmounts"] = &srcmounts; diff --git a/src/config.hpp b/src/config.hpp index 3d3d9ea7..26e32f99 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -17,6 +17,7 @@ #pragma once #include "branch.hpp" +#include "config_readdir.hpp" #include "enum.hpp" #include "errno.hpp" #include "func_category.hpp" @@ -110,6 +111,7 @@ public: ConfigBOOL nullrw; ConfigUINT64 pid; ConfigBOOL posix_acl; + ReadDir readdir; ConfigBOOL readdirplus; ConfigBOOL security_capability; SrcMounts srcmounts; diff --git a/src/config_readdir.cpp b/src/config_readdir.cpp new file mode 100644 index 00000000..ebe796e9 --- /dev/null +++ b/src/config_readdir.cpp @@ -0,0 +1,49 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "config_readdir.hpp" +#include "ef.hpp" + +template<> +int +ReadDir::from_string(const std::string &s_) +{ + if(s_ == "posix") + _data = ReadDir::ENUM::POSIX; + ef(s_ == "linux") + _data = ReadDir::ENUM::LINUX; + else + return -EINVAL; + + return 0; +} + +template<> +std::string +ReadDir::to_string(void) const +{ + switch(_data) + { + case ReadDir::ENUM::POSIX: + return "posix"; + case ReadDir::ENUM::LINUX: + return "linux"; + } + + return "invalid"; +} diff --git a/src/config_readdir.hpp b/src/config_readdir.hpp new file mode 100644 index 00000000..fe041d87 --- /dev/null +++ b/src/config_readdir.hpp @@ -0,0 +1,29 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "enum.hpp" + +enum class ReadDirEnum + { + POSIX, + LINUX + }; + +typedef Enum ReadDir; diff --git a/src/enum.hpp b/src/enum.hpp index 14243c4a..6f0dd35a 100644 --- a/src/enum.hpp +++ b/src/enum.hpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma once + #include "tofrom_string.hpp" #include diff --git a/src/fs_base_fstatat.hpp b/src/fs_base_fstatat.hpp index 21ddd6ca..47c7ac77 100644 --- a/src/fs_base_fstatat.hpp +++ b/src/fs_base_fstatat.hpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma once + #include #include #include diff --git a/src/fs_base_getdents.cpp b/src/fs_base_getdents.cpp new file mode 100644 index 00000000..5810610b --- /dev/null +++ b/src/fs_base_getdents.cpp @@ -0,0 +1,37 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#if defined __linux__ +#include +#include +#endif + +namespace fs +{ + int + getdents(unsigned int fd_, + void *dirp_, + unsigned int count_) + { +#if defined SYS_getdents64 + return ::syscall(SYS_getdents,fd_,dirp_,count_); +#else + return (errno=ENOTSUP,-1); +#endif + } +} diff --git a/src/fs_base_getdents.hpp b/src/fs_base_getdents.hpp new file mode 100644 index 00000000..fbaed28f --- /dev/null +++ b/src/fs_base_getdents.hpp @@ -0,0 +1,27 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +namespace fs +{ + int + getdents(unsigned int fd, + void *dirp, + unsigned int count); +} diff --git a/src/fs_copydata_copy_file_range.cpp b/src/fs_copydata_copy_file_range.cpp index a3bff9d9..debc1662 100644 --- a/src/fs_copydata_copy_file_range.cpp +++ b/src/fs_copydata_copy_file_range.cpp @@ -18,6 +18,8 @@ #include "fs_base_stat.hpp" #include "fs_copy_file_range.hpp" +#include + namespace l { int64_t diff --git a/src/fs_copydata_copy_file_range.hpp b/src/fs_copydata_copy_file_range.hpp index f23299c4..6b0f7567 100644 --- a/src/fs_copydata_copy_file_range.hpp +++ b/src/fs_copydata_copy_file_range.hpp @@ -16,9 +16,11 @@ #pragma once +#include + namespace fs { - int + int64_t copydata_copy_file_range(const int src_fd, const int dst_fd); } diff --git a/src/fs_glob.hpp b/src/fs_glob.hpp index 82f28f44..4f5f92d3 100644 --- a/src/fs_glob.hpp +++ b/src/fs_glob.hpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma once + #include #include diff --git a/src/fs_statvfs_cache.hpp b/src/fs_statvfs_cache.hpp index 7ebce2b2..a97f4e60 100644 --- a/src/fs_statvfs_cache.hpp +++ b/src/fs_statvfs_cache.hpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma once + #include #include diff --git a/src/fuse_readdir.cpp b/src/fuse_readdir.cpp index d2e9580b..5212a03f 100644 --- a/src/fuse_readdir.cpp +++ b/src/fuse_readdir.cpp @@ -16,8 +16,35 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef __linux__ -# include "fuse_readdir_linux.icpp" -#else -# include "fuse_readdir_posix.icpp" -#endif +#include "fuse_readdir_posix.hpp" +#include "fuse_readdir_linux.hpp" + +#include "config.hpp" +#include "dirinfo.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +namespace FUSE +{ + int + readdir(fuse_file_info *ffi_, + fuse_dirents_t *buf_) + { + DirInfo *di = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::ro(); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard guard(&config.branches.lock); + + switch(config.readdir) + { + case ReadDir::ENUM::LINUX: + return FUSE::readdir_linux(config.branches,di->fusepath.c_str(),buf_); + default: + case ReadDir::ENUM::POSIX: + return FUSE::readdir_posix(config.branches,di->fusepath.c_str(),buf_); + } + } +} diff --git a/src/fuse_readdir_linux.icpp b/src/fuse_readdir_linux.cpp similarity index 67% rename from src/fuse_readdir_linux.icpp rename to src/fuse_readdir_linux.cpp index 02689e41..7c5221aa 100644 --- a/src/fuse_readdir_linux.icpp +++ b/src/fuse_readdir_linux.cpp @@ -14,22 +14,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define _DEFAULT_SOURCE - -#include "config.hpp" -#include "dirinfo.hpp" +#include "branch.hpp" #include "errno.hpp" #include "fs_base_close.hpp" +#include "fs_base_getdents.hpp" #include "fs_base_open.hpp" #include "fs_base_stat.hpp" #include "fs_devid.hpp" #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "linux_dirent64.h" +#include "linux_dirent.h" #include "mempools.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" #include #include @@ -38,23 +34,12 @@ #include #include -#include using std::string; using std::vector; namespace l { - static - inline - int - getdents64(unsigned int fd_, - char *dirp_, - unsigned int count_) - { - return syscall(SYS_getdents64,fd_,dirp_,count_); - } - static int close_free_ret_enomem(int fd_, @@ -77,7 +62,7 @@ namespace l HashSet names; string basepath; uint64_t namelen; - struct linux_dirent64 *d; + struct linux_dirent *d; buf = (char*)g_DENTS_BUF_POOL.alloc(); if(buf == NULL) @@ -100,22 +85,22 @@ namespace l for(;;) { - nread = l::getdents64(dirfd,buf,g_DENTS_BUF_POOL.size()); + nread = fs::getdents(dirfd,buf,g_DENTS_BUF_POOL.size()); if(nread == -1) break; if(nread == 0) break; - for(int64_t pos = 0; pos < nread; pos += d->d_reclen) + for(int64_t pos = 0; pos < nread; pos += d->reclen) { - d = (struct linux_dirent64*)(buf + pos); - namelen = (strlen(d->d_name) + 1); + d = (struct linux_dirent*)(buf + pos); + namelen = strlen(d->name); - rv = names.put(d->d_name,namelen); + rv = names.put(d->name,namelen); if(rv == 0) continue; - d->d_ino = fs::inode::recompute(d->d_ino,dev); + d->ino = fs::inode::recompute(d->ino,dev); rv = fuse_dirents_add_linux(buf_,d,namelen); if(rv) @@ -135,17 +120,10 @@ namespace l namespace FUSE { int - readdir(fuse_file_info *ffi_, - fuse_dirents_t *buf_) + readdir_linux(const Branches &branches_, + const char *dirname_, + fuse_dirents_t *buf_) { - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::ro(); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches.lock); - - return l::readdir(config.branches, - di->fusepath.c_str(), - buf_); + return l::readdir(branches_,dirname_,buf_); } } diff --git a/src/fuse_readdir_linux.hpp b/src/fuse_readdir_linux.hpp new file mode 100644 index 00000000..d6b9b09d --- /dev/null +++ b/src/fuse_readdir_linux.hpp @@ -0,0 +1,33 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "branch.hpp" + +#include + +#include + +namespace FUSE +{ + int + readdir_linux(const Branches &branches, + const char *dirname, + fuse_dirents_t *buf); +} diff --git a/src/fuse_readdir_plus.cpp b/src/fuse_readdir_plus.cpp index bb46542f..6b12c324 100644 --- a/src/fuse_readdir_plus.cpp +++ b/src/fuse_readdir_plus.cpp @@ -16,8 +16,43 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef __linux__ -# include "fuse_readdir_plus_linux.icpp" -#else -# include "fuse_readdir_plus_posix.icpp" -#endif +#include "fuse_readdir_plus_linux.hpp" +#include "fuse_readdir_plus_posix.hpp" + +#include "config.hpp" +#include "dirinfo.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +namespace FUSE +{ + int + readdir_plus(fuse_file_info *ffi_, + fuse_dirents_t *buf_) + { + DirInfo *di = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::ro(); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard guard(&config.branches.lock); + + switch(config.readdir) + { + case ReadDir::ENUM::LINUX: + return FUSE::readdir_plus_linux(config.branches, + di->fusepath.c_str(), + config.cache_entry, + config.cache_attr, + buf_); + default: + case ReadDir::ENUM::POSIX: + return FUSE::readdir_plus_posix(config.branches, + di->fusepath.c_str(), + config.cache_entry, + config.cache_attr, + buf_); + } + } +} diff --git a/src/fuse_readdir_plus.hpp b/src/fuse_readdir_plus.hpp index f24b8768..17f198e9 100644 --- a/src/fuse_readdir_plus.hpp +++ b/src/fuse_readdir_plus.hpp @@ -18,10 +18,6 @@ #include -#include -#include -#include - namespace FUSE { int diff --git a/src/fuse_readdir_plus_linux.icpp b/src/fuse_readdir_plus_linux.cpp similarity index 67% rename from src/fuse_readdir_plus_linux.icpp rename to src/fuse_readdir_plus_linux.cpp index 1c5c3c88..e8cf4b27 100644 --- a/src/fuse_readdir_plus_linux.icpp +++ b/src/fuse_readdir_plus_linux.cpp @@ -14,23 +14,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define _DEFAULT_SOURCE - -#include "config.hpp" -#include "dirinfo.hpp" +#include "branch.hpp" #include "errno.hpp" #include "fs_base_close.hpp" #include "fs_base_fstatat.hpp" +#include "fs_base_getdents.hpp" #include "fs_base_open.hpp" #include "fs_base_stat.hpp" #include "fs_devid.hpp" #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "linux_dirent64.h" +#include "linux_dirent.h" #include "mempools.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" #include #include @@ -39,23 +35,12 @@ #include #include -#include using std::string; using std::vector; namespace l { - static - inline - int - getdents64(unsigned int fd_, - char *dirp_, - unsigned int count_) - { - return syscall(SYS_getdents64,fd_,dirp_,count_); - } - int close_free_ret_enomem(int fd_, void *buf_) @@ -81,7 +66,7 @@ namespace l uint64_t namelen; struct stat st; fuse_entry_t entry; - struct linux_dirent64 *d; + struct linux_dirent *d; buf = (char*)g_DENTS_BUF_POOL.alloc(); @@ -108,27 +93,27 @@ namespace l for(;;) { - nread = l::getdents64(dirfd,buf,g_DENTS_BUF_POOL.size()); + nread = fs::getdents(dirfd,buf,g_DENTS_BUF_POOL.size()); if(nread == -1) break; if(nread == 0) break; - for(int64_t pos = 0; pos < nread; pos += d->d_reclen) + for(int64_t pos = 0; pos < nread; pos += d->reclen) { - d = (struct linux_dirent64*)(buf + pos); - namelen = (strlen(d->d_name) + 1); + d = (struct linux_dirent*)(buf + pos); + namelen = (strlen(d->name) + 1); - rv = names.put(d->d_name,namelen); + rv = names.put(d->name,namelen); if(rv == 0) continue; - rv = fs::fstatat_nofollow(dirfd,d->d_name,&st); + rv = fs::fstatat_nofollow(dirfd,d->name,&st); if(rv == -1) memset(&st,0,sizeof(st)); - d->d_ino = fs::inode::recompute(d->d_ino,dev); - st.st_ino = d->d_ino; + d->ino = fs::inode::recompute(d->ino,dev); + st.st_ino = d->ino; rv = fuse_dirents_add_linux_plus(buf_,d,namelen,&entry,&st); if(rv) @@ -148,19 +133,12 @@ namespace l namespace FUSE { int - readdir_plus(fuse_file_info *ffi_, - fuse_dirents_t *buf_) + readdir_plus_linux(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) { - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::ro(); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard guard(&config.branches.lock); - - return l::readdir_plus(config.branches, - di->fusepath.c_str(), - config.cache_entry, - config.cache_attr, - buf_); + return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_); } } diff --git a/src/fuse_readdir_plus_linux.hpp b/src/fuse_readdir_plus_linux.hpp new file mode 100644 index 00000000..132ca77a --- /dev/null +++ b/src/fuse_readdir_plus_linux.hpp @@ -0,0 +1,35 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "branch.hpp" + +#include + +#include + +namespace FUSE +{ + int + readdir_plus_linux(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_); +} diff --git a/src/fuse_readdir_plus_posix.icpp b/src/fuse_readdir_plus_posix.cpp similarity index 78% rename from src/fuse_readdir_plus_posix.icpp rename to src/fuse_readdir_plus_posix.cpp index aadb2558..e167465b 100644 --- a/src/fuse_readdir_plus_posix.icpp +++ b/src/fuse_readdir_plus_posix.cpp @@ -16,8 +16,7 @@ #define _DEFAULT_SOURCE -#include "config.hpp" -#include "dirinfo.hpp" +#include "branch.hpp" #include "errno.hpp" #include "fs_base_closedir.hpp" #include "fs_base_dirfd.hpp" @@ -29,8 +28,6 @@ #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" #include #include @@ -58,17 +55,12 @@ namespace l #endif } - static - uint64_t - dirent_alloc_namelen(const struct dirent *d_) - { - return (dirent_exact_namelen(d_) + 1); - } - static int readdir_plus(const Branches &branches_, const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, fuse_dirents_t *buf_) { dev_t dev; @@ -80,8 +72,8 @@ namespace l entry.nodeid = 0; entry.generation = 0; - entry.entry_valid = 1; - entry.attr_valid = 1; + entry.entry_valid = entry_timeout_; + entry.attr_valid = attr_timeout_; entry.entry_valid_nsec = 0; entry.attr_valid_nsec = 0; for(size_t i = 0, ei = branches_.size(); i != ei; i++) @@ -104,7 +96,7 @@ namespace l rv = 0; for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) { - namelen = l::dirent_alloc_namelen(de); + namelen = l::dirent_exact_namelen(de); rv = names.put(de->d_name,namelen); if(rv == 0) @@ -132,17 +124,12 @@ namespace l namespace FUSE { int - readdir_plus(fuse_file_info *ffi_, - fuse_dirents_t *buf_) + readdir_plus_posix(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) { - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::ro(); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard guard(&config.branches.lock); - - return l::readdir_plus(config.branches, - di->fusepath.c_str(), - buf_); + return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_); } } diff --git a/src/fuse_readdir_plus_posix.hpp b/src/fuse_readdir_plus_posix.hpp new file mode 100644 index 00000000..236f5b80 --- /dev/null +++ b/src/fuse_readdir_plus_posix.hpp @@ -0,0 +1,35 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "branch.hpp" + +#include + +#include + +namespace FUSE +{ + int + readdir_plus_posix(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_); +} diff --git a/src/fuse_readdir_posix.icpp b/src/fuse_readdir_posix.cpp similarity index 77% rename from src/fuse_readdir_posix.icpp rename to src/fuse_readdir_posix.cpp index eded8a80..78646d40 100644 --- a/src/fuse_readdir_posix.icpp +++ b/src/fuse_readdir_posix.cpp @@ -16,8 +16,7 @@ #define _DEFAULT_SOURCE -#include "config.hpp" -#include "dirinfo.hpp" +#include "branch.hpp" #include "errno.hpp" #include "fs_base_closedir.hpp" #include "fs_base_dirfd.hpp" @@ -28,8 +27,6 @@ #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" #include #include @@ -57,13 +54,6 @@ namespace l #endif } - static - uint64_t - dirent_alloc_namelen(const struct dirent *d_) - { - return (dirent_exact_namelen(d_) + 1); - } - static int readdir(const Branches &branches_, @@ -95,7 +85,7 @@ namespace l rv = 0; for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) { - namelen = l::dirent_alloc_namelen(de); + namelen = l::dirent_exact_namelen(de); rv = names.put(de->d_name,namelen); if(rv == 0) @@ -118,17 +108,10 @@ namespace l namespace FUSE { int - readdir(fuse_file_info *ffi_, - fuse_dirents_t *buf_) + readdir_posix(const Branches &branches_, + const char *dirname_, + fuse_dirents_t *buf_) { - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::ro(); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard guard(&config.branches.lock); - - return l::readdir(config.branches, - di->fusepath.c_str(), - buf_); + return l::readdir(branches_,dirname_,buf_); } } diff --git a/src/fuse_readdir_posix.hpp b/src/fuse_readdir_posix.hpp new file mode 100644 index 00000000..04eea9d3 --- /dev/null +++ b/src/fuse_readdir_posix.hpp @@ -0,0 +1,33 @@ +/* + ISC License + + Copyright (c) 2020, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "branch.hpp" + +#include + +#include + +namespace FUSE +{ + int + readdir_posix(const Branches &branches, + const char *dirname, + fuse_dirents_t *buf); +}