2.0.0-rc (#9)

### Issues

* \#1 \[bug\] Unable to mount S3 due to 'item_not_found' exception
* \#2 Require bucket name for S3 mounts
* \#3 \[bug\] File size is not being updated in S3 mount
* \#4 Upgrade to libfuse-3.x.x
* \#5 Switch to renterd for Sia support
* \#6 Switch to cpp-httplib to further reduce dependencies
* \#7 Remove global_data and calculate used disk space per provider
* \#8 Switch to libcurl for S3 mount support

### Changes from v1.x.x

* Added read-only encrypt provider
  * Pass-through mount point that transparently encrypts source data using `XChaCha20-Poly1305`
* Added S3 encryption support via `XChaCha20-Poly1305`
* Added replay protection to remote mounts
* Added support base64 writes in remote FUSE
* Created static linked Linux binaries for `amd64` and `aarch64` using `musl-libc`
* Removed legacy Sia renter support
* Removed Skynet support
* Fixed multiple remote mount WinFSP API issues on \*NIX servers
* Implemented chunked read and write
  * Writes for non-cached files are performed in chunks of 8Mib
* Removed `repertory-ui` support
* Removed `FreeBSD` support
* Switched to `libsodium` over `CryptoPP`
* Switched to `XChaCha20-Poly1305` for remote mounts
* Updated `GoogleTest` to v1.14.0
* Updated `JSON for Modern C++` to v3.11.2
* Updated `OpenSSL` to v1.1.1w
* Updated `RocksDB` to v8.5.3
* Updated `WinFSP` to 2023
* Updated `boost` to v1.78.0
* Updated `cURL` to v8.3.0
* Updated `zlib` to v1.3
* Use `upload_manager` for all providers
  * Adds a delay to uploads to prevent excessive API calls
  * Supports re-upload after mount restart for incomplete uploads
  * NOTE: Uploads for all providers are full file (no resume support)
    * Multipart upload support is planned for S3

Reviewed-on: #9
This commit is contained in:
2023-10-29 06:55:59 +00:00
parent 8560c362a0
commit dc410bfe5b
839 changed files with 98214 additions and 92959 deletions

View File

@@ -1,35 +1,36 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
#define INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "drives/fuse/fuse_base.hpp"
#include "drives/open_file_table.hpp"
#include "drives/fuse/fuse_drive_base.hpp"
#include "file_manager/file_manager.hpp"
namespace repertory {
class i_provider;
class app_config;
class console_consumer;
class directory_cache;
class download_manager;
class eviction;
class full_server;
class lock_data;
@@ -38,7 +39,7 @@ namespace remote_fuse {
class remote_server;
}
class fuse_drive final : public fuse_base {
class fuse_drive final : public fuse_drive_base {
public:
fuse_drive(app_config &config, lock_data &lock_data, i_provider &provider);
@@ -50,166 +51,276 @@ private:
std::shared_ptr<console_consumer> console_consumer_;
std::shared_ptr<directory_cache> directory_cache_;
std::shared_ptr<download_manager> download_manager_;
std::shared_ptr<eviction> eviction_;
std::shared_ptr<file_manager> fm_;
std::shared_ptr<logging_consumer> logging_consumer_;
std::shared_ptr<open_file_table<open_file_data>> oft_;
std::shared_ptr<remote_fuse::remote_server> remote_server_;
std::shared_ptr<full_server> server_;
bool was_mounted_ = false;
private:
void update_accessed_time(const std::string &api_path);
protected:
#ifdef __APPLE__
api_error chflags_impl(std::string api_path, uint32_t flags) override;
[[nodiscard]] auto chflags_impl(std::string api_path, uint32_t flags)
-> api_error override;
#endif // __APPLE__
api_error chmod_impl(std::string api_path, mode_t mode) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
-> api_error override;
#endif
api_error chown_impl(std::string api_path, uid_t uid, gid_t gid) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
-> api_error override;
#endif
api_error create_impl(std::string api_path, mode_t mode, struct fuse_file_info *fi) override;
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
void destroy_impl(void *ptr) override;
api_error fallocate_impl(std::string api_path, int mode, off_t offset, off_t length,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fallocate_impl(std::string api_path, int mode,
off_t offset, off_t length,
struct fuse_file_info *fi)
-> api_error override;
api_error fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#ifdef __APPLE__
api_error fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fsetattr_x_impl(std::string api_path,
struct setattr_x *attr,
struct fuse_file_info *fi)
-> api_error override;
#endif // __APPLE__
api_error fsync_impl(std::string api_path, int datasync, struct fuse_file_info *fi) override;
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *fi)
-> api_error override;
api_error ftruncate_impl(std::string api_path, off_t size, struct fuse_file_info *fi) override;
#if FUSE_USE_VERSION < 30
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#endif
api_error getattr_impl(std::string api_path, struct stat *st) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st)
-> api_error override;
#endif
#ifdef __APPLE__
api_error getxtimes_impl(std::string api_path, struct timespec *bkuptime,
struct timespec *crtime) override;
[[nodiscard]] auto getxtimes_impl(std::string api_path,
struct timespec *bkuptime,
struct timespec *crtime)
-> api_error override;
#endif // __APPLE__
void *init_impl(struct fuse_conn_info *conn) override;
#if FUSE_USE_VERSION >= 30
auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void * override;
#else
auto init_impl(struct fuse_conn_info *conn) -> void * override;
#endif
api_error mkdir_impl(std::string api_path, mode_t mode) override;
[[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode)
-> api_error override;
api_error open_impl(std::string api_path, struct fuse_file_info *fi) override;
void notify_fuse_main_exit(int &ret) override;
api_error opendir_impl(std::string api_path, struct fuse_file_info *fi) override;
[[nodiscard]] auto open_impl(std::string api_path, struct fuse_file_info *fi)
-> api_error override;
api_error read_impl(std::string api_path, char *buffer, size_t read_size, off_t read_offset,
struct fuse_file_info *fi, std::size_t &bytes_read) override;
[[nodiscard]] auto opendir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi) override;
[[nodiscard]] auto read_impl(std::string api_path, char *buffer,
size_t read_size, off_t read_offset,
struct fuse_file_info *fi,
std::size_t &bytes_read) -> api_error override;
api_error release_impl(std::string api_path, struct fuse_file_info *fi) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi,
fuse_readdir_flags flags)
-> api_error override;
#else
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi)
-> api_error override;
#endif
api_error releasedir_impl(std::string api_path, struct fuse_file_info *fi) override;
[[nodiscard]] auto release_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error rename_impl(std::string from_api_path, std::string to_api_path) override;
[[nodiscard]] auto releasedir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error rmdir_impl(std::string api_path) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path, unsigned int flags)
-> api_error override;
#else
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path) -> api_error override;
#endif
[[nodiscard]] auto rmdir_impl(std::string api_path) -> api_error override;
#ifdef HAS_SETXATTR
api_error getxattr_common(std::string api_path, const char *name, char *value, size_t size,
int &attribute_size, uint32_t *position);
[[nodiscard]] auto getxattr_common(std::string api_path, const char *name,
char *value, size_t size,
int &attribute_size, uint32_t *position)
-> api_error;
#ifdef __APPLE__
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
uint32_t position, int &attribute_size) override;
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
char *value, size_t size,
[[nodiscard]] uint32_t position,
int &attribute_size) -> api_error override;
#else // __APPLE__
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
int &attribute_size) override;
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
char *value, size_t size,
int &attribute_size) -> api_error override;
#endif // __APPLE__
api_error listxattr_impl(std::string api_path, char *buffer, size_t size, int &required_size,
bool &return_size) override;
[[nodiscard]] auto listxattr_impl(std::string api_path, char *buffer,
size_t size, int &required_size,
bool &return_size) -> api_error override;
api_error removexattr_impl(std::string api_path, const char *name) override;
[[nodiscard]] auto removexattr_impl(std::string api_path, const char *name)
-> api_error override;
#ifdef __APPLE__
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
int flags, uint32_t position) override;
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
const char *value, size_t size, int flags,
uint32_t position) -> api_error override;
#else // __APPLE__
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
int flags) override;
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
const char *value, size_t size, int flags)
-> api_error override;
#endif // __APPLE__
#endif // HAS_SETXATTR
#ifdef __APPLE__
api_error setattr_x_impl(std::string api_path, struct setattr_x *attr) override;
[[nodiscard]] auto setattr_x_impl(std::string api_path,
struct setattr_x *attr)
-> api_error override;
api_error setbkuptime_impl(std::string api_path, const struct timespec *bkuptime) override;
[[nodiscard]] auto setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime)
-> api_error override;
api_error setchgtime_impl(std::string api_path, const struct timespec *chgtime) override;
[[nodiscard]] auto setchgtime_impl(std::string api_path,
const struct timespec *chgtime)
-> api_error override;
api_error setcrtime_impl(std::string api_path, const struct timespec *crtime) override;
[[nodiscard]] auto setcrtime_impl(std::string api_path,
const struct timespec *crtime)
-> api_error override;
api_error setvolname_impl(const char *volname) override;
[[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override;
api_error statfs_x_impl(std::string api_path, struct statfs *stbuf) override;
[[nodiscard]] auto statfs_x_impl(std::string api_path, struct statfs *stbuf)
-> api_error override;
#else // __APPLE__
api_error statfs_impl(std::string api_path, struct statvfs *stbuf) override;
[[nodiscard]] auto statfs_impl(std::string api_path, struct statvfs *stbuf)
-> api_error override;
#endif // __APPLE__
api_error truncate_impl(std::string api_path, off_t size) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
-> api_error override;
#endif
api_error unlink_impl(std::string api_path) override;
[[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override;
api_error utimens_impl(std::string api_path, const struct timespec tv[2]) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2],
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2])
-> api_error override;
#endif
api_error write_impl(std::string api_path, const char *buffer, size_t write_size,
off_t write_offset, struct fuse_file_info *fi,
std::size_t &bytes_written) override;
protected:
void notify_fuse_args_parsed(const std::vector<std::string> &args) override;
void notify_fuse_main_exit(int &ret) override;
int shutdown() override;
void update_accessed_time(const std::string &api_path);
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
size_t write_size, off_t write_offset,
struct fuse_file_info *fi,
std::size_t &bytes_written)
-> api_error override;
public:
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
directory_item_list get_directory_items(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
-> directory_item_list override;
std::uint64_t get_file_size(const std::string &api_path) const override;
[[nodiscard]] auto get_file_size(const std::string &api_path) const
-> std::uint64_t override;
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error override;
api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &name,
std::string &value) const
-> api_error override;
std::uint64_t get_total_drive_space() const override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
std::uint64_t get_total_item_count() const override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
std::uint64_t get_used_drive_space() const override;
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const override;
bool is_processing(const std::string &api_path) const override;
[[nodiscard]] auto is_processing(const std::string &api_path) const
-> bool override;
void populate_stat(const directory_item &di, struct stat &st) const override;
int rename_directory(const std::string &from_api_path, const std::string &to_api_path) override;
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
const std::string &to_api_path)
-> int override;
int rename_file(const std::string &from_api_path, const std::string &to_api_path,
const bool &overwrite) override;
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite)
-> int override;
void set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) override;
void update_directory_item(directory_item &di) const override;
};
} // namespace repertory