diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-08-30 19:22:42 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-08-30 19:28:42 +0100 |
commit | 68329fe3f6dcd5ec769dab52ba7cfd25ec1f5494 (patch) | |
tree | 5606f17a9cf8ca17fa907bfc658ac32a01e6aff6 /netfs/fuse | |
parent | EntryResolvers return where they got the resolution from (diff) | |
download | netfs-68329fe3f6dcd5ec769dab52ba7cfd25ec1f5494.tar.bz2 netfs-68329fe3f6dcd5ec769dab52ba7cfd25ec1f5494.tar.xz netfs-68329fe3f6dcd5ec769dab52ba7cfd25ec1f5494.zip |
Clang format all the code
Diffstat (limited to 'netfs/fuse')
-rw-r--r-- | netfs/fuse/fuseApp.cpp | 22 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.h | 220 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.impl.h | 8 | ||||
-rw-r--r-- | netfs/fuse/fuseAppBase.cpp | 143 | ||||
-rw-r--r-- | netfs/fuse/fuseAppBase.h | 236 | ||||
-rw-r--r-- | netfs/fuse/fuseConfigImpl.cpp | 3 | ||||
-rw-r--r-- | netfs/fuse/fuseDirs.cpp | 154 | ||||
-rw-r--r-- | netfs/fuse/fuseDirs.h | 9 | ||||
-rw-r--r-- | netfs/fuse/fuseFiles.cpp | 449 | ||||
-rw-r--r-- | netfs/fuse/fuseFiles.h | 35 | ||||
-rw-r--r-- | netfs/fuse/fuseMisc.cpp | 4 | ||||
-rw-r--r-- | netfs/fuse/fuseSystem.cpp | 1 | ||||
-rw-r--r-- | netfs/fuse/netfs.cpp | 81 |
13 files changed, 699 insertions, 666 deletions
diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index 29820b8..78a3a03 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -1,16 +1,16 @@ -#include <Glacier2/Router.h> -#include <cstring> #include "fuseApp.h" -#include "lockHelpers.h" #include "cache.impl.h" -#include <entCache.h> -#include <slicer/slicer.h> -#include <uriParse.h> -#include <safeMapFind.h> -#include <compileTimeFormatter.h> #include "fuseDirs.h" #include "fuseFiles.h" +#include "lockHelpers.h" +#include <Glacier2/Router.h> #include <boost/lexical_cast.hpp> +#include <compileTimeFormatter.h> +#include <cstring> +#include <entCache.h> +#include <safeMapFind.h> +#include <slicer/slicer.h> +#include <uriParse.h> namespace AdHoc { template class Cache<struct stat, std::string>; @@ -18,10 +18,7 @@ namespace AdHoc { } NetFS::FuseApp::FuseApp(Ice::StringSeq && a) : - iceArgs(std::move(a)), - sessionOpened(false), - openHandleId(0), - converter(userLookup, groupLookup) + iceArgs(std::move(a)), sessionOpened(false), openHandleId(0), converter(userLookup, groupLookup) { } @@ -283,4 +280,3 @@ NetFS::FuseApp::reqEnv() groupLookup.getName(c->gid, &re.grp); return re; } - diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h index 6869c01..d373e94 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -1,124 +1,122 @@ #ifndef NETFS_FUSE_H #define NETFS_FUSE_H -#include <shared_mutex> -#include <functional> -#include <filesystem> -#include <Ice/Ice.h> +#include "cache.h" +#include "fuseAppBase.h" +#include "fuseConfig.h" #include <Glacier2/Session.h> -#include <service.h> +#include <Ice/Ice.h> +#include <c++11Helpers.h> #include <entCache.h> +#include <filesystem> +#include <functional> +#include <service.h> +#include <shared_mutex> #include <typeConverter.h> -#include "fuseAppBase.h" -#include "fuseConfig.h" -#include "cache.h" #include <visibility.h> -#include <c++11Helpers.h> namespace NetFS { class DLL_PUBLIC FuseApp : public FuseAppBaseT<FuseApp> { - private: - class OpenDir; - using OpenDirPtr = std::shared_ptr<OpenDir>; - using OpenDirs = std::map<int, OpenDirPtr>; - - class OpenFile; - using OpenFilePtr = std::shared_ptr<OpenFile>; - using OpenFiles = std::map<int, OpenFilePtr>; - - public: - explicit FuseApp(Ice::StringSeq &&); - SPECIAL_MEMBERS_DELETE(FuseApp); - ~FuseApp() override; - - // lifecycle - void * init (struct fuse_conn_info * info, struct fuse_config * cfg) override; - static int opt_parse(void * data, const char * arg, int, struct fuse_args *); - - protected: - void connectSession(); - virtual void connectToService(); - void connectToVolume(); - void connectHandles(); - void verifyConnection(); - - public: - // misc - int access(const char * p, int a) override; - int getattr(const char *, struct stat *, struct fuse_file_info *) override; - int chmod(const char *, mode_t, struct fuse_file_info *) override; - int chown(const char *, uid_t, gid_t, struct fuse_file_info *) override; - int link(const char *, const char *) override; - int readlink(const char *, char *, size_t) override; - int rename(const char *, const char *, unsigned int) override; - int symlink(const char *, const char *) override; - int unlink(const char *) override; - // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - int utimens(const char *, const struct timespec tv[2], struct fuse_file_info *) override; - int mknod(const char *, mode_t, dev_t) override; - // dirs - int opendir(const char * p, struct fuse_file_info * fi) override; - int releasedir(const char *, struct fuse_file_info * fi) override; - int readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi, enum fuse_readdir_flags) override; - int mkdir(const char *, mode_t) override; - int rmdir(const char *) override; - // files - int open(const char * p, struct fuse_file_info * fi) override; - int create(const char *, mode_t, struct fuse_file_info *) override; - int flush(const char *, struct fuse_file_info * fi) override; - int release(const char *, struct fuse_file_info * fi) override; - int read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) override; - int write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) override; - ssize_t copy_file_range(const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, off_t, size_t, int) override; - int truncate(const char *, off_t, struct fuse_file_info *) override; - // fs - int statfs(const char *, struct statvfs *) override; - // stuff - int onError(const std::exception & err) noexcept override; - void beforeOperation() override; - - virtual struct fuse_context * fuse_get_context() = 0; - - static NetFS::Client::ResourcePtr configureFromFile(const std::filesystem::path &, const std::string &); - static NetFS::Client::ResourcePtr configureFromUri(const std::string &); - - protected: - template<typename Handle, typename ... Params> - void setProxy(uint64_t & fh, const Params & ...); - template<typename Handle> - Handle getProxy(uint64_t localID); - template<typename Handle> - void clearProxy(uint64_t localID); - template<typename Handle> - std::map<int, Handle> & getMap(); - - template<typename Rtn, typename F> static inline Rtn - waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f); - - ReqEnv reqEnv(); - - Ice::StringSeq iceArgs; - Ice::CommunicatorPtr ic; - Client::ResourcePtr fcr; - mutable std::shared_mutex _proxymaplock; - - NetFS::VolumePrxPtr volume; - NetFS::ServicePrxPtr service; - Glacier2::SessionPrxPtr session; - bool sessionOpened; - - std::string mountPoint; - - OpenDirs openDirs; - OpenFiles openFiles; - int openHandleId; - - EntCache<User> userLookup; - EntCache<Group> groupLookup; - EntryTypeConverter converter; - - using StatCache = AdHoc::Cache<struct stat, std::string>; - StatCache statCache; + private: + class OpenDir; + using OpenDirPtr = std::shared_ptr<OpenDir>; + using OpenDirs = std::map<int, OpenDirPtr>; + + class OpenFile; + using OpenFilePtr = std::shared_ptr<OpenFile>; + using OpenFiles = std::map<int, OpenFilePtr>; + + public: + explicit FuseApp(Ice::StringSeq &&); + SPECIAL_MEMBERS_DELETE(FuseApp); + ~FuseApp() override; + + // lifecycle + void * init(struct fuse_conn_info * info, struct fuse_config * cfg) override; + static int opt_parse(void * data, const char * arg, int, struct fuse_args *); + + protected: + void connectSession(); + virtual void connectToService(); + void connectToVolume(); + void connectHandles(); + void verifyConnection(); + + public: + // misc + int access(const char * p, int a) override; + int getattr(const char *, struct stat *, struct fuse_file_info *) override; + int chmod(const char *, mode_t, struct fuse_file_info *) override; + int chown(const char *, uid_t, gid_t, struct fuse_file_info *) override; + int link(const char *, const char *) override; + int readlink(const char *, char *, size_t) override; + int rename(const char *, const char *, unsigned int) override; + int symlink(const char *, const char *) override; + int unlink(const char *) override; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + int utimens(const char *, const struct timespec tv[2], struct fuse_file_info *) override; + int mknod(const char *, mode_t, dev_t) override; + // dirs + int opendir(const char * p, struct fuse_file_info * fi) override; + int releasedir(const char *, struct fuse_file_info * fi) override; + int readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi, + enum fuse_readdir_flags) override; + int mkdir(const char *, mode_t) override; + int rmdir(const char *) override; + // files + int open(const char * p, struct fuse_file_info * fi) override; + int create(const char *, mode_t, struct fuse_file_info *) override; + int flush(const char *, struct fuse_file_info * fi) override; + int release(const char *, struct fuse_file_info * fi) override; + int read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) override; + int write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) override; + ssize_t copy_file_range(const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, + off_t, size_t, int) override; + int truncate(const char *, off_t, struct fuse_file_info *) override; + // fs + int statfs(const char *, struct statvfs *) override; + // stuff + int onError(const std::exception & err) noexcept override; + void beforeOperation() override; + + virtual struct fuse_context * fuse_get_context() = 0; + + static NetFS::Client::ResourcePtr configureFromFile(const std::filesystem::path &, const std::string &); + static NetFS::Client::ResourcePtr configureFromUri(const std::string &); + + protected: + template<typename Handle, typename... Params> void setProxy(uint64_t & fh, const Params &...); + template<typename Handle> Handle getProxy(uint64_t localID); + template<typename Handle> void clearProxy(uint64_t localID); + template<typename Handle> std::map<int, Handle> & getMap(); + + template<typename Rtn, typename F> + static inline Rtn waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f); + + ReqEnv reqEnv(); + + Ice::StringSeq iceArgs; + Ice::CommunicatorPtr ic; + Client::ResourcePtr fcr; + mutable std::shared_mutex _proxymaplock; + + NetFS::VolumePrxPtr volume; + NetFS::ServicePrxPtr service; + Glacier2::SessionPrxPtr session; + bool sessionOpened; + + std::string mountPoint; + + OpenDirs openDirs; + OpenFiles openFiles; + int openHandleId; + + EntCache<User> userLookup; + EntCache<Group> groupLookup; + EntryTypeConverter converter; + + using StatCache = AdHoc::Cache<struct stat, std::string>; + StatCache statCache; }; } diff --git a/netfs/fuse/fuseApp.impl.h b/netfs/fuse/fuseApp.impl.h index 8dd9f1e..e433ee7 100644 --- a/netfs/fuse/fuseApp.impl.h +++ b/netfs/fuse/fuseApp.impl.h @@ -6,13 +6,14 @@ #include <safeMapFind.h> namespace NetFS { - template<typename Handle, typename ... Params> + template<typename Handle, typename... Params> void - FuseApp::setProxy(uint64_t & fh, const Params & ... params) + FuseApp::setProxy(uint64_t & fh, const Params &... params) { auto & map = getMap<Handle>(); Lock(_proxymaplock); - while (map.find(fh = ++openHandleId) != map.end()) ; + while (map.find(fh = ++openHandleId) != map.end()) + ; map.emplace(fh, std::make_shared<typename Handle::element_type>(params...)); } @@ -40,4 +41,3 @@ namespace NetFS { } #endif - diff --git a/netfs/fuse/fuseAppBase.cpp b/netfs/fuse/fuseAppBase.cpp index 4d06b44..f2c1f30 100644 --- a/netfs/fuse/fuseAppBase.cpp +++ b/netfs/fuse/fuseAppBase.cpp @@ -1,11 +1,11 @@ #include "fuseAppBase.h" -#include <cerrno> +#include <boost/assert.hpp> #include <cassert> +#include <cerrno> #include <cstdio> -#include <unistd.h> #include <cstdlib> #include <typeinfo> -#include <boost/assert.hpp> +#include <unistd.h> FuseAppBase * FuseAppBase::fuseApp; @@ -27,177 +27,221 @@ FuseAppBase::~FuseAppBase() // to call them in a realistic manner. They exist only as the default // implementation of the function which is never passed to libfuse // unless it is overridden. -void * FuseAppBase::init(fuse_conn_info*, fuse_config *) +void * +FuseAppBase::init(fuse_conn_info *, fuse_config *) { return nullptr; } -int FuseAppBase::access(const char *, int) +int +FuseAppBase::access(const char *, int) { return -ENOSYS; } -int FuseAppBase::chmod(const char *, mode_t, struct fuse_file_info *) +int +FuseAppBase::chmod(const char *, mode_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::chown(const char *, uid_t, gid_t, struct fuse_file_info *) +int +FuseAppBase::chown(const char *, uid_t, gid_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::create(const char *, mode_t, struct fuse_file_info *) +int +FuseAppBase::create(const char *, mode_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::getattr(const char *, struct stat *, struct fuse_file_info *) +int +FuseAppBase::getattr(const char *, struct stat *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::flush(const char *, struct fuse_file_info *) +int +FuseAppBase::flush(const char *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::fsync(const char *, int, struct fuse_file_info *) +int +FuseAppBase::fsync(const char *, int, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::fsyncdir(const char *, int, struct fuse_file_info *) +int +FuseAppBase::fsyncdir(const char *, int, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::truncate(const char *, off_t, struct fuse_file_info *) +int +FuseAppBase::truncate(const char *, off_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::getxattr(const char *, const char *, char *, size_t) +int +FuseAppBase::getxattr(const char *, const char *, char *, size_t) { return -ENOSYS; } -int FuseAppBase::link(const char *, const char *) +int +FuseAppBase::link(const char *, const char *) { return -ENOSYS; } -int FuseAppBase::listxattr(const char *, char *, size_t) +int +FuseAppBase::listxattr(const char *, char *, size_t) { return -ENOSYS; } -int FuseAppBase::mkdir(const char *, mode_t) +int +FuseAppBase::mkdir(const char *, mode_t) { return -ENOSYS; } -int FuseAppBase::mknod(const char *, mode_t, dev_t) +int +FuseAppBase::mknod(const char *, mode_t, dev_t) { return -ENOSYS; } -int FuseAppBase::open(const char *, struct fuse_file_info *) +int +FuseAppBase::open(const char *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::opendir(const char *, struct fuse_file_info *) +int +FuseAppBase::opendir(const char *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::read(const char *, char *, size_t, off_t, struct fuse_file_info *) +int +FuseAppBase::read(const char *, char *, size_t, off_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags) +int +FuseAppBase::readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags) { return -ENOSYS; } -int FuseAppBase::readlink(const char *, char *, size_t) +int +FuseAppBase::readlink(const char *, char *, size_t) { return -ENOSYS; } -int FuseAppBase::release(const char *, struct fuse_file_info *) +int +FuseAppBase::release(const char *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::releasedir(const char *, struct fuse_file_info *) +int +FuseAppBase::releasedir(const char *, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::removexattr(const char *, const char *) +int +FuseAppBase::removexattr(const char *, const char *) { return -ENOSYS; } -int FuseAppBase::rename(const char *, const char *, unsigned int) +int +FuseAppBase::rename(const char *, const char *, unsigned int) { return -ENOSYS; } -int FuseAppBase::rmdir(const char *) +int +FuseAppBase::rmdir(const char *) { return -ENOSYS; } -int FuseAppBase::setxattr(const char *, const char *, const char *, size_t, int) +int +FuseAppBase::setxattr(const char *, const char *, const char *, size_t, int) { return -ENOSYS; } -int FuseAppBase::statfs(const char *, struct statvfs *) +int +FuseAppBase::statfs(const char *, struct statvfs *) { return -ENOSYS; } -int FuseAppBase::symlink(const char *, const char *) +int +FuseAppBase::symlink(const char *, const char *) { return -ENOSYS; } -int FuseAppBase::unlink(const char *) +int +FuseAppBase::unlink(const char *) { return -ENOSYS; } -int FuseAppBase::write(const char *, const char *, size_t, off_t, struct fuse_file_info *) +int +FuseAppBase::write(const char *, const char *, size_t, off_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::lock(const char *, struct fuse_file_info *, int, struct flock *) +int +FuseAppBase::lock(const char *, struct fuse_file_info *, int, struct flock *) { return -ENOSYS; } // NOLINTNEXTLINE(modernize-avoid-c-arrays, hicpp-avoid-c-arrays) -int FuseAppBase::utimens(const char *, const struct timespec[2], struct fuse_file_info *) +int +FuseAppBase::utimens(const char *, const struct timespec[2], struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::bmap(const char *, size_t, uint64_t *) +int +FuseAppBase::bmap(const char *, size_t, uint64_t *) { return -ENOSYS; } -int FuseAppBase::ioctl(const char *, unsigned int, void *, struct fuse_file_info *, unsigned int, void *) +int +FuseAppBase::ioctl(const char *, unsigned int, void *, struct fuse_file_info *, unsigned int, void *) { return -ENOSYS; } -int FuseAppBase::poll(const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *) +int +FuseAppBase::poll(const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *) { return -ENOSYS; } -int FuseAppBase::write_buf(const char *, struct fuse_bufvec *, off_t, struct fuse_file_info *) +int +FuseAppBase::write_buf(const char *, struct fuse_bufvec *, off_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::read_buf(const char *, struct fuse_bufvec **, size_t, off_t, struct fuse_file_info *) +int +FuseAppBase::read_buf(const char *, struct fuse_bufvec **, size_t, off_t, struct fuse_file_info *) { return -ENOSYS; } -int FuseAppBase::flock(const char *, struct fuse_file_info *, int) +int +FuseAppBase::flock(const char *, struct fuse_file_info *, int) { return -ENOSYS; } -int FuseAppBase::fallocate(const char *, int, off_t, off_t, struct fuse_file_info *) +int +FuseAppBase::fallocate(const char *, int, off_t, off_t, struct fuse_file_info *) { return -ENOSYS; } -ssize_t FuseAppBase::copy_file_range(const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, off_t, size_t, int) +ssize_t +FuseAppBase::copy_file_range( + const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, off_t, size_t, int) { return -ENOSYS; } -off_t FuseAppBase::lseek(const char *, off_t, int, struct fuse_file_info *) +off_t +FuseAppBase::lseek(const char *, off_t, int, struct fuse_file_info *) { return -ENOSYS; } // LCOV_EXCL_STOP -void FuseAppBase::log(int level, const char * message) const noexcept +void +FuseAppBase::log(int level, const char * message) const noexcept { logf(level, "%s", message); } -void FuseAppBase::logf(int level, const char * fmt, ...) const noexcept +void +FuseAppBase::logf(int level, const char * fmt, ...) const noexcept { va_list args; va_start(args, fmt); @@ -205,13 +249,14 @@ void FuseAppBase::logf(int level, const char * fmt, ...) const noexcept va_end(args); } -int FuseAppBase::onError(const std::exception & e) noexcept +int +FuseAppBase::onError(const std::exception & e) noexcept { logf(LOG_ERR, "Unknown exception (what: %s)", e.what()); return -ENOSYS; } -void FuseAppBase::beforeOperation() +void +FuseAppBase::beforeOperation() { } - diff --git a/netfs/fuse/fuseAppBase.h b/netfs/fuse/fuseAppBase.h index 2709671..44f3c81 100644 --- a/netfs/fuse/fuseAppBase.h +++ b/netfs/fuse/fuseAppBase.h @@ -1,82 +1,89 @@ #ifndef FUSEAPP_H #define FUSEAPP_H -#include <fuse.h> -#include <typeinfo> -#include <exception> -#include <cstdio> +#include <c++11Helpers.h> #include <cerrno> +#include <cstdio> +#include <exception> +#include <fuse.h> +#include <lockHelpers.h> +#include <shared_mutex> #include <syslog.h> +#include <typeinfo> #include <visibility.h> -#include <c++11Helpers.h> -#include <shared_mutex> -#include <lockHelpers.h> class DLL_PUBLIC FuseAppBase { - public: - FuseAppBase(); - SPECIAL_MEMBERS_DELETE(FuseAppBase); - virtual ~FuseAppBase(); +public: + FuseAppBase(); + SPECIAL_MEMBERS_DELETE(FuseAppBase); + virtual ~FuseAppBase(); - virtual void * init (struct fuse_conn_info * info, struct fuse_config * cfg); - virtual int access(const char *, int); - virtual int chmod(const char *, mode_t, struct fuse_file_info *); - virtual int chown(const char *, uid_t, gid_t, struct fuse_file_info *); - virtual int create(const char *, mode_t, struct fuse_file_info *); - virtual int getattr(const char *, struct stat *, struct fuse_file_info *); - virtual int flush(const char *, struct fuse_file_info *); - virtual int fsync(const char *, int, struct fuse_file_info *); - virtual int fsyncdir(const char *, int, struct fuse_file_info *); - virtual int truncate(const char *, off_t, struct fuse_file_info *); - virtual int getxattr(const char *, const char *, char *, size_t); - virtual int link(const char *, const char *); - virtual int listxattr(const char *, char *, size_t); - virtual int mkdir(const char *, mode_t); - virtual int mknod(const char *, mode_t, dev_t); - virtual int open(const char *, struct fuse_file_info *); - virtual int opendir(const char *, struct fuse_file_info *); - virtual int read(const char *, char *, size_t, off_t, struct fuse_file_info *); - virtual int readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags); - virtual int readlink(const char *, char *, size_t); - virtual int release(const char *, struct fuse_file_info *); - virtual int releasedir(const char *, struct fuse_file_info *); - virtual int removexattr(const char *, const char *); - virtual int rename(const char *, const char *, unsigned int); - virtual int rmdir(const char *); - virtual int setxattr(const char *, const char *, const char *, size_t, int); - virtual int statfs(const char *, struct statvfs *); - virtual int symlink(const char *, const char *); - virtual int unlink(const char *); - virtual int write(const char *, const char *, size_t, off_t, struct fuse_file_info *); - virtual int lock(const char *, struct fuse_file_info *, int cmd, struct flock *); - // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - virtual int utimens(const char *, const struct timespec tv[2], struct fuse_file_info *); - virtual int bmap(const char *, size_t blocksize, uint64_t *idx); - virtual int ioctl(const char *, unsigned int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void * data); - virtual int poll(const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *); - virtual int write_buf(const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *); - virtual int read_buf(const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *); - virtual int flock(const char *, struct fuse_file_info *, int op); - virtual int fallocate(const char *, int, off_t, off_t, struct fuse_file_info *); - virtual ssize_t copy_file_range(const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, off_t, size_t, int); - virtual off_t lseek(const char *, off_t off, int whence, struct fuse_file_info *); - virtual int onError(const std::exception & err) noexcept; - virtual void beforeOperation(); - void log(int level, const char * message) const noexcept; - void logf(int level, const char * fmt, ...) const noexcept __attribute__ ((__format__ (__printf__, 3, 4))); - virtual void vlogf(int level, const char * fmt, va_list) const noexcept __attribute__ ((__format__ (__printf__, 3, 0))) = 0; + virtual void * init(struct fuse_conn_info * info, struct fuse_config * cfg); + virtual int access(const char *, int); + virtual int chmod(const char *, mode_t, struct fuse_file_info *); + virtual int chown(const char *, uid_t, gid_t, struct fuse_file_info *); + virtual int create(const char *, mode_t, struct fuse_file_info *); + virtual int getattr(const char *, struct stat *, struct fuse_file_info *); + virtual int flush(const char *, struct fuse_file_info *); + virtual int fsync(const char *, int, struct fuse_file_info *); + virtual int fsyncdir(const char *, int, struct fuse_file_info *); + virtual int truncate(const char *, off_t, struct fuse_file_info *); + virtual int getxattr(const char *, const char *, char *, size_t); + virtual int link(const char *, const char *); + virtual int listxattr(const char *, char *, size_t); + virtual int mkdir(const char *, mode_t); + virtual int mknod(const char *, mode_t, dev_t); + virtual int open(const char *, struct fuse_file_info *); + virtual int opendir(const char *, struct fuse_file_info *); + virtual int read(const char *, char *, size_t, off_t, struct fuse_file_info *); + virtual int readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags); + virtual int readlink(const char *, char *, size_t); + virtual int release(const char *, struct fuse_file_info *); + virtual int releasedir(const char *, struct fuse_file_info *); + virtual int removexattr(const char *, const char *); + virtual int rename(const char *, const char *, unsigned int); + virtual int rmdir(const char *); + virtual int setxattr(const char *, const char *, const char *, size_t, int); + virtual int statfs(const char *, struct statvfs *); + virtual int symlink(const char *, const char *); + virtual int unlink(const char *); + virtual int write(const char *, const char *, size_t, off_t, struct fuse_file_info *); + virtual int lock(const char *, struct fuse_file_info *, int cmd, struct flock *); + // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + virtual int utimens(const char *, const struct timespec tv[2], struct fuse_file_info *); + virtual int bmap(const char *, size_t blocksize, uint64_t * idx); + virtual int ioctl( + const char *, unsigned int cmd, void * arg, struct fuse_file_info *, unsigned int flags, void * data); + virtual int poll(const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *); + virtual int write_buf(const char *, struct fuse_bufvec * buf, off_t off, struct fuse_file_info *); + virtual int read_buf(const char *, struct fuse_bufvec ** bufp, size_t size, off_t off, struct fuse_file_info *); + virtual int flock(const char *, struct fuse_file_info *, int op); + virtual int fallocate(const char *, int, off_t, off_t, struct fuse_file_info *); + virtual ssize_t copy_file_range( + const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *, off_t, size_t, int); + virtual off_t lseek(const char *, off_t off, int whence, struct fuse_file_info *); + virtual int onError(const std::exception & err) noexcept; + virtual void beforeOperation(); + void log(int level, const char * message) const noexcept; + void logf(int level, const char * fmt, ...) const noexcept __attribute__((__format__(__printf__, 3, 4))); + virtual void vlogf(int level, const char * fmt, va_list) const noexcept + __attribute__((__format__(__printf__, 3, 0))) + = 0; - mutable std::shared_mutex _lock; - protected: - static FuseAppBase * fuseApp; + mutable std::shared_mutex _lock; + +protected: + static FuseAppBase * fuseApp; }; -template <typename FuseApp> -class FuseAppBaseT : public FuseAppBase { - public: -#define GetIntHelper(func) getInternalHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) -#define GetHelper(func) getHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) - FuseAppBaseT() : operations({ +template<typename FuseApp> class FuseAppBaseT : public FuseAppBase { +public: +#define GetIntHelper(func) \ + getInternalHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) +#define GetHelper(func) \ + getHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) + FuseAppBaseT() : + operations({ GetHelper(getattr), GetHelper(readlink), GetHelper(mknod), @@ -105,7 +112,7 @@ class FuseAppBaseT : public FuseAppBase { GetHelper(releasedir), GetHelper(fsyncdir), GetIntHelper(init), - nullptr, //fuseDestroy + nullptr, // fuseDestroy GetHelper(access), GetHelper(create), GetHelper(lock), @@ -119,64 +126,65 @@ class FuseAppBaseT : public FuseAppBase { GetHelper(fallocate), GetHelper(copy_file_range), GetHelper(lseek), - }) - { - } + }) + { + } #undef GetHelper #undef GetIntHelper - const struct fuse_operations operations; + const struct fuse_operations operations; - private: - template <typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename ... Args> - constexpr static auto getInternalHelper(Rtn(FuseAppBase::*)(Args...)) -> Rtn(*)(Args...) - { - if constexpr (!std::is_same<BFunc, IFunc>::value) { - return [](Args ... a) { - return (fuseApp->*bfunc)(a...); - }; - } - return nullptr; +private: + template<typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename... Args> + constexpr static auto getInternalHelper(Rtn (FuseAppBase::*)(Args...)) -> Rtn (*)(Args...) + { + if constexpr (!std::is_same<BFunc, IFunc>::value) { + return [](Args... a) { + return (fuseApp->*bfunc)(a...); + }; } - template <typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename ... Args> - constexpr static auto getHelper(Rtn(FuseAppBase::*)(Args...)) -> Rtn(*)(Args...) - { - if constexpr (!std::is_same<BFunc, IFunc>::value) { - return [](Args ... a) -> Rtn { - for (int t = 0; ; ++t) { - try { - fuseApp->beforeOperation(); - SharedLock(fuseApp->_lock); - return (fuseApp->*bfunc)(a...); - } - catch (const std::exception & ex) { - if (t < 10) { - if (int rtn = fuseApp->onError(ex)) { - return rtn; - } - } - else { - fuseApp->logf(LOG_ERR, "Retries expired with %s calling %s", ex.what(), typeid(bfunc).name()); - return -EIO; + return nullptr; + } + template<typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename... Args> + constexpr static auto getHelper(Rtn (FuseAppBase::*)(Args...)) -> Rtn (*)(Args...) + { + if constexpr (!std::is_same<BFunc, IFunc>::value) { + return [](Args... a) -> Rtn { + for (int t = 0;; ++t) { + try { + fuseApp->beforeOperation(); + SharedLock(fuseApp->_lock); + return (fuseApp->*bfunc)(a...); + } + catch (const std::exception & ex) { + if (t < 10) { + if (int rtn = fuseApp->onError(ex)) { + return rtn; } } - catch (...) { - fuseApp->logf(LOG_ERR, "Unknown exception calling %s", typeid(bfunc).name()); + else { + fuseApp->logf( + LOG_ERR, "Retries expired with %s calling %s", ex.what(), typeid(bfunc).name()); return -EIO; } } - }; - } - return nullptr; + catch (...) { + fuseApp->logf(LOG_ERR, "Unknown exception calling %s", typeid(bfunc).name()); + return -EIO; + } + } + }; } + return nullptr; + } - protected: - template <typename Func, Func f, typename ... Args> - static int internalHelper(Args ... a) - { - return (fuseApp->*f)(a...); - } +protected: + template<typename Func, Func f, typename... Args> + static int + internalHelper(Args... a) + { + return (fuseApp->*f)(a...); + } }; #endif - diff --git a/netfs/fuse/fuseConfigImpl.cpp b/netfs/fuse/fuseConfigImpl.cpp index 9129bfc..fa542fe 100644 --- a/netfs/fuse/fuseConfigImpl.cpp +++ b/netfs/fuse/fuseConfigImpl.cpp @@ -1,5 +1,5 @@ -#include <fuseConfig.h> #include <compileTimeFormatter.h> +#include <fuseConfig.h> AdHocFormatter(ResourceNotFoundMsg, "No such resource: %?"); void @@ -7,4 +7,3 @@ NetFS::Client::ResourceNotFound::ice_print(std::ostream & s) const { ResourceNotFoundMsg::write(s, resourceName); } - diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp index a1748d8..c1a91bd 100644 --- a/netfs/fuse/fuseDirs.cpp +++ b/netfs/fuse/fuseDirs.cpp @@ -1,98 +1,94 @@ #include "fuseDirs.h" -#include <lockHelpers.h> #include <entCache.h> +#include <lockHelpers.h> namespace NetFS { -FuseApp::OpenDir::OpenDir(DirectoryPrxPtr r, std::string p) : - remote(std::move(r)), - path(std::move(p)) -{ -} + FuseApp::OpenDir::OpenDir(DirectoryPrxPtr r, std::string p) : remote(std::move(r)), path(std::move(p)) { } -template<> -std::map<int, FuseApp::OpenDirPtr> & -FuseApp::getMap<FuseApp::OpenDirPtr>() -{ - return openDirs; -} - -int -FuseApp::opendir(const char * p, struct fuse_file_info * fi) -{ - try { - auto remote = volume->opendir(reqEnv(), p); - setProxy<OpenDirPtr>(fi->fh, remote, p); - return 0; - } - catch (SystemError & e) { - return -e.syserrno; + template<> + std::map<int, FuseApp::OpenDirPtr> & + FuseApp::getMap<FuseApp::OpenDirPtr>() + { + return openDirs; } -} -int -FuseApp::releasedir(const char *, struct fuse_file_info * fi) -{ - try { - auto remote = getProxy<OpenDirPtr>(fi->fh)->remote; - remote->close(); - clearProxy<OpenDirPtr>(fi->fh); - return 0; + int + FuseApp::opendir(const char * p, struct fuse_file_info * fi) + { + try { + auto remote = volume->opendir(reqEnv(), p); + setProxy<OpenDirPtr>(fi->fh, remote, p); + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } - catch (SystemError & e) { - clearProxy<OpenDirPtr>(fi->fh); - return -e.syserrno; + + int + FuseApp::releasedir(const char *, struct fuse_file_info * fi) + { + try { + auto remote = getProxy<OpenDirPtr>(fi->fh)->remote; + remote->close(); + clearProxy<OpenDirPtr>(fi->fh); + return 0; + } + catch (SystemError & e) { + clearProxy<OpenDirPtr>(fi->fh); + return -e.syserrno; + } } -} -int -FuseApp::readdir(const char * p, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi, enum fuse_readdir_flags flags) -{ - try { - auto od = getProxy<OpenDirPtr>(fi->fh); - std::string path(p); - auto expiry = time(nullptr) + 2; - if (flags == FUSE_READDIR_PLUS) { - for (const auto & e : od->remote->listdir()) { - filler(buf, e.first.c_str(), nullptr, 0, FUSE_FILL_DIR_PLUS); - std::string k(path + e.first); - statCache.remove(k); - statCache.add(k, converter.convert(e.second), expiry); + int + FuseApp::readdir(const char * p, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi, + enum fuse_readdir_flags flags) + { + try { + auto od = getProxy<OpenDirPtr>(fi->fh); + std::string path(p); + auto expiry = time(nullptr) + 2; + if (flags == FUSE_READDIR_PLUS) { + for (const auto & e : od->remote->listdir()) { + filler(buf, e.first.c_str(), nullptr, 0, FUSE_FILL_DIR_PLUS); + std::string k(path + e.first); + statCache.remove(k); + statCache.add(k, converter.convert(e.second), expiry); + } } - } - else { - for (const auto & e : od->remote->readdir()) { - filler(buf, e.c_str(), nullptr, 0, (fuse_fill_dir_flags)0); + else { + for (const auto & e : od->remote->readdir()) { + filler(buf, e.c_str(), nullptr, 0, (fuse_fill_dir_flags)0); + } } + return 0; + } + catch (SystemError & e) { + return -e.syserrno; } - return 0; - } - catch (SystemError & e) { - return -e.syserrno; } -} -int -FuseApp::mkdir(const char * p, mode_t m) -{ - try { - volume->mkdir(reqEnv(), p, m); - return 0; - } - catch (SystemError & e) { - return -e.syserrno; + int + FuseApp::mkdir(const char * p, mode_t m) + { + try { + volume->mkdir(reqEnv(), p, m); + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } -} -int -FuseApp::rmdir(const char * p) -{ - try { - volume->rmdir(reqEnv(), p); - return 0; - } - catch (SystemError & e) { - return -e.syserrno; + int + FuseApp::rmdir(const char * p) + { + try { + volume->rmdir(reqEnv(), p); + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } } -} - diff --git a/netfs/fuse/fuseDirs.h b/netfs/fuse/fuseDirs.h index 55088dd..bb02e65 100644 --- a/netfs/fuse/fuseDirs.h +++ b/netfs/fuse/fuseDirs.h @@ -5,13 +5,12 @@ namespace NetFS { class FuseApp::OpenDir { - public: - OpenDir(DirectoryPrxPtr remote, std::string path); + public: + OpenDir(DirectoryPrxPtr remote, std::string path); - DirectoryPrxPtr remote; - const std::string path; + DirectoryPrxPtr remote; + const std::string path; }; } #endif - diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp index 48b3f87..0a59252 100644 --- a/netfs/fuse/fuseFiles.cpp +++ b/netfs/fuse/fuseFiles.cpp @@ -1,282 +1,277 @@ -#include <cstring> -#include "fuseApp.impl.h" #include "fuseFiles.h" +#include "fuseApp.impl.h" #include "lockHelpers.h" +#include <cstring> #include <entCache.h> #include <mutex> namespace NetFS { -FuseApp::OpenFile::WriteState::WriteState() : - future(promise.get_future().share()) -{ -} - -FuseApp::OpenFile::OpenFile(FilePrxPtr r, std::string p, int f) : - remote(std::move(r)), - path(std::move(p)), - flags(f) -{ -} - -template<> -std::map<int, FuseApp::OpenFilePtr> & -FuseApp::getMap<FuseApp::OpenFilePtr>() -{ - return openFiles; -} + FuseApp::OpenFile::WriteState::WriteState() : future(promise.get_future().share()) { } -void -FuseApp::OpenFile::wait() const -{ - auto cbg = [this](){ - SharedLock(_lock); - return bg; - }(); - for (const auto & w : cbg) { - w.second->future.wait(); + FuseApp::OpenFile::OpenFile(FilePrxPtr r, std::string p, int f) : remote(std::move(r)), path(std::move(p)), flags(f) + { } -} -void -FuseApp::OpenFile::flush() -{ - auto first = [this]() { - SharedLock(_lock); - return bg.empty() ? nullptr : bg.begin()->second; - }; - while (auto w = first()) { - // background operations are void, so no need to actually get the return value - w->future.wait(); + template<> + std::map<int, FuseApp::OpenFilePtr> & + FuseApp::getMap<FuseApp::OpenFilePtr>() + { + return openFiles; } -} -FuseApp::OpenFile::BGs::interval_type -FuseApp::OpenFile::range(off_t o, size_t s) -{ - return OpenFile::BGs::interval_type::right_open(o, o + s); -} - -int -FuseApp::open(const char * p, struct fuse_file_info * fi) -{ - try { - auto remote = volume->open(reqEnv(), p, fi->flags); - setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags); - return 0; - } - catch (SystemError & e) { - return -e.syserrno; + void + FuseApp::OpenFile::wait() const + { + auto cbg = [this]() { + SharedLock(_lock); + return bg; + }(); + for (const auto & w : cbg) { + w.second->future.wait(); + } } -} -int -FuseApp::create(const char * p, mode_t m, struct fuse_file_info * fi) -{ - try { - auto remote = volume->create(reqEnv(), p, fi->flags, m); - setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags); - return 0; + void + FuseApp::OpenFile::flush() + { + auto first = [this]() { + SharedLock(_lock); + return bg.empty() ? nullptr : bg.begin()->second; + }; + while (auto w = first()) { + // background operations are void, so no need to actually get the return value + w->future.wait(); + } } - catch (SystemError & e) { - return -e.syserrno; + + FuseApp::OpenFile::BGs::interval_type + FuseApp::OpenFile::range(off_t o, size_t s) + { + return OpenFile::BGs::interval_type::right_open(o, o + s); } -} -int -FuseApp::release(const char *, struct fuse_file_info * fi) -{ - try { - auto of = getProxy<OpenFilePtr>(fi->fh); - auto remote = of->remote; + int + FuseApp::open(const char * p, struct fuse_file_info * fi) + { try { - of->flush(); + auto remote = volume->open(reqEnv(), p, fi->flags); + setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags); + return 0; } catch (SystemError & e) { + return -e.syserrno; } - remote->close(); - clearProxy<OpenFilePtr>(fi->fh); - return 0; - } - catch (SystemError & e) { - clearProxy<OpenFilePtr>(fi->fh); - return -e.syserrno; - } -} - -int -FuseApp::flush(const char *, struct fuse_file_info * fi) -{ - try { - getProxy<OpenFilePtr>(fi->fh)->flush(); - return 0; - } - catch (SystemError & e) { - return -e.syserrno; } -} -template<typename Rtn, typename F> -inline -Rtn -FuseApp::waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f) -{ - const auto key = OpenFile::range(o, s); - while (true) { - std::unique_lock<decltype(of->_lock)> _l(of->_lock); - // Acquire operations to wait for - auto R = of->bg.equal_range(key); - if (R.first == R.second) { - // Perform operation - return f(key); + int + FuseApp::create(const char * p, mode_t m, struct fuse_file_info * fi) + { + try { + auto remote = volume->create(reqEnv(), p, fi->flags, m); + setProxy<OpenFilePtr>(fi->fh, remote, p, fi->flags); + return 0; } - else { - std::vector<std::shared_ptr<OpenFile::WriteState>> overlap; - overlap.reserve(std::distance(R.first, R.second)); - for (auto i = R.first; i != R.second; i++) { - overlap.push_back(i->second); - } - // Wait for them whilst unlocked - _l.release()->unlock(); - for (const auto & r : overlap) { - r->future.wait(); - } - // Cause this thread to yield so the callback can acquire _lock - usleep(0); + catch (SystemError & e) { + return -e.syserrno; } } -} -int -FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) -{ - try { - auto cpy = [buf](const auto && data) { - memcpy(buf, &data.front(), data.size()); - return data.size(); - }; - auto of = getProxy<OpenFilePtr>(fi->fh); - auto remote = of->remote; - if (fcr->Async) { - auto p = waitOnWriteRangeAndThen<std::future<Buffer>>(s, o, of, [o, s, &remote](const auto &){ - return remote->readAsync(o, s); - }); - return cpy(p.get()); + int + FuseApp::release(const char *, struct fuse_file_info * fi) + { + try { + auto of = getProxy<OpenFilePtr>(fi->fh); + auto remote = of->remote; + try { + of->flush(); + } + catch (SystemError & e) { + } + remote->close(); + clearProxy<OpenFilePtr>(fi->fh); + return 0; } - else { - return cpy(remote->read(o, s)); + catch (SystemError & e) { + clearProxy<OpenFilePtr>(fi->fh); + return -e.syserrno; } } - catch (SystemError & e) { - return -e.syserrno; - } -} -int -FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) -{ - try { - auto of = getProxy<OpenFilePtr>(fi->fh); - auto remote = of->remote; - if (fcr->Async) { - waitOnWriteRangeAndThen<void>(s, o, of, [o, s, buf, &of, remote](const auto & key){ - auto p = std::make_shared<OpenFile::WriteState>(); - remote->writeAsync(o, s, Buffer(buf, buf + s), [p,of,key]() { - p->promise.set_value(); - ScopeLock(of->_lock) { - of->bg.erase(key); - } - }, [p,of,key](auto e) { - p->promise.set_exception(e); - ScopeLock(of->_lock) { - of->bg.erase(key); - } - }); - of->bg.insert({key, p}); - }); + int + FuseApp::flush(const char *, struct fuse_file_info * fi) + { + try { + getProxy<OpenFilePtr>(fi->fh)->flush(); + return 0; } - else { - remote->write(o, s, Buffer(buf, buf + s)); + catch (SystemError & e) { + return -e.syserrno; } - return s; - } - catch (SystemError & e) { - return -e.syserrno; } -} -ssize_t -FuseApp::copy_file_range(const char *, struct fuse_file_info *fi_in, off_t offset_in, const char *, struct fuse_file_info *fi_out, off_t offset_out, size_t size, int flags) -{ - try { - auto of_in = getProxy<OpenFilePtr>(fi_in->fh); - auto of_out = getProxy<OpenFilePtr>(fi_out->fh); - auto remote_in = of_in->remote; - auto remote_out = of_out->remote; - of_in->wait(); - of_out->wait(); - return remote_in->copyrange(remote_out, offset_in, offset_out, size, flags); - } - catch (SystemError & e) { - return -e.syserrno; + template<typename Rtn, typename F> + inline Rtn + FuseApp::waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f) + { + const auto key = OpenFile::range(o, s); + while (true) { + std::unique_lock<decltype(of->_lock)> _l(of->_lock); + // Acquire operations to wait for + auto R = of->bg.equal_range(key); + if (R.first == R.second) { + // Perform operation + return f(key); + } + else { + std::vector<std::shared_ptr<OpenFile::WriteState>> overlap; + overlap.reserve(std::distance(R.first, R.second)); + for (auto i = R.first; i != R.second; i++) { + overlap.push_back(i->second); + } + // Wait for them whilst unlocked + _l.release()->unlock(); + for (const auto & r : overlap) { + r->future.wait(); + } + // Cause this thread to yield so the callback can acquire _lock + usleep(0); + } + } } -} -int -FuseApp::truncate(const char * p, off_t o, fuse_file_info * fi) -{ - try { - if (fi) { + int + FuseApp::read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) + { + try { + auto cpy = [buf](const auto && data) { + memcpy(buf, &data.front(), data.size()); + return data.size(); + }; auto of = getProxy<OpenFilePtr>(fi->fh); - of->wait(); auto remote = of->remote; - remote->ftruncate(reqEnv(), o); + if (fcr->Async) { + auto p = waitOnWriteRangeAndThen<std::future<Buffer>>(s, o, of, [o, s, &remote](const auto &) { + return remote->readAsync(o, s); + }); + return cpy(p.get()); + } + else { + return cpy(remote->read(o, s)); + } } - else { - volume->truncate(reqEnv(), p, o); + catch (SystemError & e) { + return -e.syserrno; } - return 0; - } - catch (SystemError & e) { - return -e.syserrno; } -} -int -FuseApp::getattr(const char * p, struct stat * s, fuse_file_info * fi) -{ - try { - if (fi) { + int + FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) + { + try { auto of = getProxy<OpenFilePtr>(fi->fh); - of->wait(); auto remote = of->remote; - *s = converter.convert(remote->fgetattr(reqEnv())); - } - else { - if (auto cacehedStat = statCache.get(p)) { - *s = *cacehedStat; + if (fcr->Async) { + waitOnWriteRangeAndThen<void>(s, o, of, [o, s, buf, &of, remote](const auto & key) { + auto p = std::make_shared<OpenFile::WriteState>(); + remote->writeAsync( + o, s, Buffer(buf, buf + s), + [p, of, key]() { + p->promise.set_value(); + ScopeLock(of->_lock) { + of->bg.erase(key); + } + }, + [p, of, key](auto e) { + p->promise.set_exception(e); + ScopeLock(of->_lock) { + of->bg.erase(key); + } + }); + of->bg.insert({key, p}); + }); } else { - *s = converter.convert(volume->getattr(reqEnv(), p)); + remote->write(o, s, Buffer(buf, buf + s)); } + return s; + } + catch (SystemError & e) { + return -e.syserrno; + } + } + ssize_t + FuseApp::copy_file_range(const char *, struct fuse_file_info * fi_in, off_t offset_in, const char *, + struct fuse_file_info * fi_out, off_t offset_out, size_t size, int flags) + { + try { + auto of_in = getProxy<OpenFilePtr>(fi_in->fh); + auto of_out = getProxy<OpenFilePtr>(fi_out->fh); + auto remote_in = of_in->remote; + auto remote_out = of_out->remote; + of_in->wait(); + of_out->wait(); + return remote_in->copyrange(remote_out, offset_in, offset_out, size, flags); + } + catch (SystemError & e) { + return -e.syserrno; } - return 0; } - catch (SystemError & e) { - return -e.syserrno; + + int + FuseApp::truncate(const char * p, off_t o, fuse_file_info * fi) + { + try { + if (fi) { + auto of = getProxy<OpenFilePtr>(fi->fh); + of->wait(); + auto remote = of->remote; + remote->ftruncate(reqEnv(), o); + } + else { + volume->truncate(reqEnv(), p, o); + } + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } -} -int -FuseApp::unlink(const char * p) -{ - try { - volume->unlink(reqEnv(), p); - return 0; + int + FuseApp::getattr(const char * p, struct stat * s, fuse_file_info * fi) + { + try { + if (fi) { + auto of = getProxy<OpenFilePtr>(fi->fh); + of->wait(); + auto remote = of->remote; + *s = converter.convert(remote->fgetattr(reqEnv())); + } + else { + if (auto cacehedStat = statCache.get(p)) { + *s = *cacehedStat; + } + else { + *s = converter.convert(volume->getattr(reqEnv(), p)); + } + } + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } - catch (SystemError & e) { - return -e.syserrno; + + int + FuseApp::unlink(const char * p) + { + try { + volume->unlink(reqEnv(), p); + return 0; + } + catch (SystemError & e) { + return -e.syserrno; + } } } -} - diff --git a/netfs/fuse/fuseFiles.h b/netfs/fuse/fuseFiles.h index 4c9a31a..9143836 100644 --- a/netfs/fuse/fuseFiles.h +++ b/netfs/fuse/fuseFiles.h @@ -6,28 +6,27 @@ namespace NetFS { class FuseApp::OpenFile { - public: - OpenFile(FilePrxPtr remote, std::string path, int flags); + public: + OpenFile(FilePrxPtr remote, std::string path, int flags); - void flush(); - void wait() const; + void flush(); + void wait() const; - FilePrxPtr remote; - const std::string path; - const int flags; - class WriteState { - public: - WriteState(); + FilePrxPtr remote; + const std::string path; + const int flags; + class WriteState { + public: + WriteState(); - std::promise<void> promise; - std::shared_future<void> future; - }; - using BGs = boost::icl::interval_map<Ice::Long, std::shared_ptr<WriteState>>; - static BGs::interval_type range(off_t, size_t); - BGs bg; - mutable std::shared_mutex _lock; + std::promise<void> promise; + std::shared_future<void> future; + }; + using BGs = boost::icl::interval_map<Ice::Long, std::shared_ptr<WriteState>>; + static BGs::interval_type range(off_t, size_t); + BGs bg; + mutable std::shared_mutex _lock; }; } #endif - diff --git a/netfs/fuse/fuseMisc.cpp b/netfs/fuse/fuseMisc.cpp index c434333..36a695b 100644 --- a/netfs/fuse/fuseMisc.cpp +++ b/netfs/fuse/fuseMisc.cpp @@ -99,12 +99,10 @@ int NetFS::FuseApp::utimens(const char * path, const struct timespec times[2], fuse_file_info *) { try { - volume->utimens(reqEnv(), path, - times[0].tv_sec, times[0].tv_nsec, times[1].tv_sec, times[1].tv_nsec); + volume->utimens(reqEnv(), path, times[0].tv_sec, times[0].tv_nsec, times[1].tv_sec, times[1].tv_nsec); return 0; } catch (NetFS::SystemError & e) { return -e.syserrno; } } - diff --git a/netfs/fuse/fuseSystem.cpp b/netfs/fuse/fuseSystem.cpp index ac87d14..413bbda 100644 --- a/netfs/fuse/fuseSystem.cpp +++ b/netfs/fuse/fuseSystem.cpp @@ -11,4 +11,3 @@ NetFS::FuseApp::statfs(const char * p, struct statvfs * vfs) return -e.syserrno; } } - diff --git a/netfs/fuse/netfs.cpp b/netfs/fuse/netfs.cpp index 78a566b..9df3a75 100644 --- a/netfs/fuse/netfs.cpp +++ b/netfs/fuse/netfs.cpp @@ -2,49 +2,50 @@ #include <syslog.h> class FuseImpl : public fuse_args, public NetFS::FuseApp { - public: - FuseImpl(int c, char ** v) : - fuse_args(FUSE_ARGS_INIT(c, v)), - NetFS::FuseApp([this](){ - Ice::StringSeq iceArgs; - if (fuse_opt_parse(this, &iceArgs, nullptr, opt_parse) == -1) { - exit(-1); - } - return iceArgs; - }()) - { - openlog("netfs", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); - } - FuseImpl(const FuseImpl &) = delete; - FuseImpl(FuseImpl &&) = delete; - - ~FuseImpl() override - { - closelog(); - } - - void operator=(const FuseImpl &) = delete; - void operator=(FuseImpl &&) = delete; - - struct fuse_context * fuse_get_context() override - { - return ::fuse_get_context(); - } - - int run() - { - return ::fuse_main(argc, argv, &operations, this); - } - - void vlogf(int priority, const char * fmt, va_list args) const noexcept override - { - vsyslog(priority, fmt, args); - } +public: + FuseImpl(int c, char ** v) : + fuse_args(FUSE_ARGS_INIT(c, v)), NetFS::FuseApp([this]() { + Ice::StringSeq iceArgs; + if (fuse_opt_parse(this, &iceArgs, nullptr, opt_parse) == -1) { + exit(-1); + } + return iceArgs; + }()) + { + openlog("netfs", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); + } + FuseImpl(const FuseImpl &) = delete; + FuseImpl(FuseImpl &&) = delete; + + ~FuseImpl() override + { + closelog(); + } + + void operator=(const FuseImpl &) = delete; + void operator=(FuseImpl &&) = delete; + + struct fuse_context * + fuse_get_context() override + { + return ::fuse_get_context(); + } + + int + run() + { + return ::fuse_main(argc, argv, &operations, this); + } + + void + vlogf(int priority, const char * fmt, va_list args) const noexcept override + { + vsyslog(priority, fmt, args); + } }; int -main(int argc, char* argv[]) +main(int argc, char * argv[]) { return FuseImpl(argc, argv).run(); } - |