From b58314c6d30f9ade0d49b2796eee1661375ffedc Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 25 Sep 2025 11:23:48 -0500 Subject: [PATCH] implemented posix-compliant unlink() with fuse hard_remove --- .cspell/words.txt | 1 + CHANGELOG.md | 3 +- .../include/drives/directory_iterator.hpp | 2 +- .../include/drives/fuse/fuse_base.hpp | 15 +- .../include/drives/fuse/fuse_drive.hpp | 8 + .../include/drives/fuse/i_fuse_drive.hpp | 6 + .../fuse/remotefuse/i_remote_instance.hpp | 214 +++++++++--------- .../drives/fuse/remotefuse/remote_client.hpp | 103 ++++----- .../drives/fuse/remotefuse/remote_server.hpp | 105 ++++----- .../include/drives/remote/i_remote_json.hpp | 4 +- .../drives/remote/remote_open_file_table.hpp | 8 +- .../winfsp/remotewinfsp/remote_client.hpp | 4 +- .../winfsp/remotewinfsp/remote_server.hpp | 98 ++++---- .../include/file_manager/file_manager.hpp | 8 +- .../include/file_manager/i_open_file.hpp | 14 +- .../include/file_manager/open_file.hpp | 4 - .../include/file_manager/open_file_base.hpp | 9 +- .../librepertory/include/types/repertory.hpp | 2 + .../include/utils/unix/unix_utils.hpp | 5 +- .../include/utils/windows/windows_utils.hpp | 2 +- .../src/drives/directory_iterator.cpp | 2 +- .../src/drives/fuse/fuse_base.cpp | 19 +- .../src/drives/fuse/fuse_drive.cpp | 63 +++++- .../drives/fuse/remotefuse/remote_client.cpp | 116 +++++----- .../fuse/remotefuse/remote_fuse_drive.cpp | 11 +- .../drives/fuse/remotefuse/remote_server.cpp | 200 ++++++++-------- .../drives/remote/remote_open_file_table.cpp | 8 +- .../winfsp/remotewinfsp/remote_client.cpp | 4 +- .../winfsp/remotewinfsp/remote_server.cpp | 90 ++++---- .../src/file_manager/file_manager.cpp | 97 ++++++-- .../src/file_manager/open_file.cpp | 20 +- .../src/file_manager/open_file_base.cpp | 21 +- .../librepertory/src/types/repertory.cpp | 2 + .../src/utils/unix/unix_utils.cpp | 15 +- .../src/utils/windows/windows_utils.cpp | 2 +- .../include/mocks/mock_open_file.hpp | 11 +- .../repertory_test/src/file_manager_test.cpp | 66 ++++++ .../src/fuse_drive_unlink_test.cpp | 9 +- .../repertory_test/src/open_file_test.cpp | 8 +- 39 files changed, 814 insertions(+), 565 deletions(-) diff --git a/.cspell/words.txt b/.cspell/words.txt index 232718e4..05e23079 100644 --- a/.cspell/words.txt +++ b/.cspell/words.txt @@ -198,6 +198,7 @@ pistream pkgconfig plarge_integer plex +posix println project_enable_fontconfig project_enable_gtkmm diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fba25d..939466dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,8 @@ * Added check version support to remote mounts * Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux * Fixed intermittent client hang on remote mount server disconnect -* Fixed `unlink()` return `EBADF` if open file handles exist when removed +* Implemented POSIX-compliant `unlink()` with FUSE `hard_remove` + * Open handles remain valid after `unlink()` ## v2.0.7-release diff --git a/repertory/librepertory/include/drives/directory_iterator.hpp b/repertory/librepertory/include/drives/directory_iterator.hpp index 372ef86c..d8a0874d 100644 --- a/repertory/librepertory/include/drives/directory_iterator.hpp +++ b/repertory/librepertory/include/drives/directory_iterator.hpp @@ -47,7 +47,7 @@ private: public: #if !defined(_WIN32) - [[nodiscard]] auto fill_buffer(const remote::file_offset &offset, + [[nodiscard]] auto fill_buffer(remote::file_offset offset, fuse_fill_dir_t filler_function, void *buffer, populate_stat_callback populate_stat) -> int; #endif // !defined(_WIN32) diff --git a/repertory/librepertory/include/drives/fuse/fuse_base.hpp b/repertory/librepertory/include/drives/fuse/fuse_base.hpp index b8404ac2..0ef7c20b 100644 --- a/repertory/librepertory/include/drives/fuse/fuse_base.hpp +++ b/repertory/librepertory/include/drives/fuse/fuse_base.hpp @@ -159,6 +159,10 @@ private: [[nodiscard]] static auto init_(struct fuse_conn_info *conn) -> void *; #endif // FUSE_USE_VERSION >= 30 + [[nodiscard]] static auto ioctl_(const char *path, int cmd, void *arg, + struct fuse_file_info *f_info, + unsigned int flags, void *data) -> int; + [[nodiscard]] static auto mkdir_(const char *path, mode_t mode) -> int; [[nodiscard]] static auto open_(const char *path, @@ -394,6 +398,13 @@ protected: virtual auto init_impl(struct fuse_conn_info *conn) -> void *; #endif // FUSE_USE_VERSION >= 30 + [[nodiscard]] virtual auto ioctl_impl(std::string /*api_path*/, int /* cmd */, + void * /* arg */, + struct fuse_file_info * /*f_info*/) + -> api_error { + return api_error::no_tty; + } + [[nodiscard]] virtual auto mkdir_impl(std::string /*api_path*/, mode_t /*mode*/) -> api_error { return api_error::not_implemented; @@ -471,14 +482,14 @@ protected: getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/, size_t /*size*/, uint32_t /*position*/, int & /*attribute_size*/) -> api_error { - return api_error::not_implemented; + return api_error::xattr_not_found; } #else // !defined(__APPLE__) [[nodiscard]] virtual auto getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/, size_t /*size*/, int & /*attribute_size*/) -> api_error { - return api_error::not_implemented; + return api_error::xattr_not_found; } #endif // defined(__APPLE__) diff --git a/repertory/librepertory/include/drives/fuse/fuse_drive.hpp b/repertory/librepertory/include/drives/fuse/fuse_drive.hpp index dfba150e..4c8b3e91 100644 --- a/repertory/librepertory/include/drives/fuse/fuse_drive.hpp +++ b/repertory/librepertory/include/drives/fuse/fuse_drive.hpp @@ -150,6 +150,10 @@ protected: auto init_impl(struct fuse_conn_info *conn) -> void * override; #endif // FUSE_USE_VERSION >= 30 + [[nodiscard]] auto ioctl_impl(std::string api_path, int cmd, void *arg, + struct fuse_file_info *f_info) + -> api_error override; + [[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode) -> api_error override; @@ -307,6 +311,10 @@ public: std::string &value) const -> api_error override; + [[nodiscard]] auto get_item_stat(std::uint64_t handle, + struct stat64 *u_stat) const + -> api_error override; + [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; diff --git a/repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp b/repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp index e70624f7..d51143b7 100644 --- a/repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp +++ b/repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp @@ -26,6 +26,8 @@ #include "types/repertory.hpp" namespace repertory { +inline constexpr const int repertory_ioctl_fd_command = 0x102010; + class i_fuse_drive { INTERFACE_SETUP(i_fuse_drive); @@ -57,6 +59,10 @@ public: std::string &value) const -> api_error = 0; + [[nodiscard]] virtual auto get_item_stat(std::uint64_t handle, + struct stat64 *u_stat) const + -> api_error = 0; + [[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0; [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; diff --git a/repertory/librepertory/include/drives/fuse/remotefuse/i_remote_instance.hpp b/repertory/librepertory/include/drives/fuse/remotefuse/i_remote_instance.hpp index 4999da86..68bbcd1d 100644 --- a/repertory/librepertory/include/drives/fuse/remotefuse/i_remote_instance.hpp +++ b/repertory/librepertory/include/drives/fuse/remotefuse/i_remote_instance.hpp @@ -30,166 +30,170 @@ class i_remote_instance : public virtual i_remote_json { INTERFACE_SETUP(i_remote_instance); public: - [[nodiscard]] virtual auto - fuse_access(const char *path, - const std::int32_t &mask) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_access(const char *path, std::int32_t mask) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_chflags(const char *path, std::uint32_t flags) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_chmod(const char *path, + remote::file_mode mode) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_chflags(const char *path, std::uint32_t flags) -> packet::error_type = 0; + fuse_create(const char *path, remote::file_mode mode, + const remote::open_flags &flags, remote::file_handle &handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_chmod(const char *path, - const remote::file_mode &mode) -> packet::error_type = 0; - - [[nodiscard]] virtual auto - fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) -> packet::error_type = 0; - - [[nodiscard]] virtual auto - fuse_create(const char *path, const remote::file_mode &mode, - const remote::open_flags &flags, - remote::file_handle &handle) -> packet::error_type = 0; [[nodiscard]] virtual auto fuse_destroy() -> packet::error_type = 0; /*[[nodiscard]] virtual packet::error_type fuse_fallocate(const char *path, - const std::int32_t &mode, const remote::file_offset &offset, const - remote::file_offset &length, const remote::file_offset &length, const - remote::file_handle &handle) = 0;*/ + std::int32_t mode, remote::file_offset offset, const + remote::file_offset length, remote::file_offset length, const + remote::file_handle handle) = 0;*/ [[nodiscard]] virtual auto fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, - const remote::file_handle &handle) -> packet::error_type = 0; + remote::file_handle handle) -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_fsetattr_x(const char *path, + const remote::setattr_x &attr, + remote::file_handle handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_ftruncate(const char *path, const remote::file_offset &size, - const remote::file_handle &handle) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_ftruncate(const char *path, + remote::file_offset size, + remote::file_handle handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_getattr(const char *path, remote::stat &r_stat, - bool &directory) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_getattr(const char *path, + remote::stat &r_stat, bool &directory) + -> packet::error_type = 0; /*[[nodiscard]] virtual packet::error_type fuse_getxattr(const char *path, - const char *name, char *value, const remote::file_size &size) = 0; + const char *name, char *value, remote::file_size size) = 0; [[nodiscard]] virtual packet::error_type fuse_getxattrOSX(const char *path, - const char *name, char *value, const remote::file_size &size, std::uint32_t + const char *name, char *value, remote::file_size size, std::uint32_t position) = 0;*/ - [[nodiscard]] virtual auto - fuse_getxtimes(const char *path, remote::file_time &bkuptime, - remote::file_time &crtime) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_getxtimes(const char *path, + remote::file_time &bkuptime, + remote::file_time &crtime) + -> packet::error_type = 0; [[nodiscard]] virtual auto fuse_init() -> packet::error_type = 0; [[nodiscard]] /*virtual packet::error_type fuse_listxattr(const char *path, - char *buffer, const remote::file_size &size) = 0;*/ + char *buffer, remote::file_size size) = 0;*/ [[nodiscard]] virtual auto - fuse_mkdir(const char *path, - const remote::file_mode &mode) -> packet::error_type = 0; + fuse_mkdir(const char *path, remote::file_mode mode) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_open(const char *path, + const remote::open_flags &flags, + remote::file_handle &handle) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_opendir(const char *path, + remote::file_handle &handle) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_open(const char *path, const remote::open_flags &flags, - remote::file_handle &handle) -> packet::error_type = 0; + fuse_read(const char *path, char *buffer, remote::file_size read_size, + remote::file_offset read_offset, remote::file_handle handle) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_opendir(const char *path, - remote::file_handle &handle) -> packet::error_type = 0; + fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, std::string &item_path) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_read(const char *path, char *buffer, const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_release(const char *path, + remote::file_handle handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_readdir(const char *path, const remote::file_offset &offset, - const remote::file_handle &handle, - std::string &item_path) -> packet::error_type = 0; - - [[nodiscard]] virtual auto - fuse_release(const char *path, - const remote::file_handle &handle) -> packet::error_type = 0; - - [[nodiscard]] virtual auto - fuse_releasedir(const char *path, - const remote::file_handle &handle) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_releasedir(const char *path, + remote::file_handle handle) + -> packet::error_type = 0; //[[nodiscard]] virtual packet::error_type fuse_removexattr(const char *path, // const char *name) = // 0; - [[nodiscard]] virtual auto - fuse_rename(const char *from, const char *to) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_rename(const char *from, const char *to) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_rmdir(const char *path) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_rmdir(const char *path) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_setattr_x(const char *path, - remote::setattr_x &attr) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_setattr_x(const char *path, + remote::setattr_x &attr) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_setbkuptime(const char *path, + remote::file_time bkuptime) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_setchgtime(const char *path, - const remote::file_time &chgtime) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_setchgtime(const char *path, + remote::file_time chgtime) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_setcrtime(const char *path, - const remote::file_time &crtime) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_setcrtime(const char *path, + remote::file_time crtime) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_setvolname(const char *volname) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_setvolname(const char *volname) + -> packet::error_type = 0; /*[[nodiscard]] virtual packet::error_type fuse_setxattr(const char *path, - const char *name, const char *value, const remote::file_size &size, const + const char *name, const char *value, remote::file_size size, const std::int32_t &flags) = 0; [[nodiscard]] virtual packet::error_type fuse_setxattr_osx(const char *path, - const char *name, const char *value, const remote::file_size &size, const + const char *name, const char *value, remote::file_size size, const std::int32_t &flags, std::uint32_t position) = 0;*/ - [[nodiscard]] virtual auto - fuse_statfs(const char *path, std::uint64_t frsize, - remote::statfs &r_stat) -> packet::error_type = 0; + [[nodiscard]] virtual auto fuse_statfs(const char *path, std::uint64_t frsize, + remote::statfs &r_stat) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_statfs_x(const char *path, std::uint64_t bsize, - remote::statfs_x &r_stat) -> packet::error_type = 0; + fuse_statfs_x(const char *path, std::uint64_t bsize, remote::statfs_x &r_stat) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_truncate(const char *path, + remote::file_offset size) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_unlink(const char *path) + -> packet::error_type = 0; + + [[nodiscard]] virtual auto fuse_utimens(const char *path, + const remote::file_time *tv, + std::uint64_t op0, std::uint64_t op1) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_truncate(const char *path, - const remote::file_offset &size) -> packet::error_type = 0; + fuse_write(const char *path, const char *buffer, remote::file_size writeSize, + remote::file_offset writeOffset, remote::file_handle handle) + -> packet::error_type = 0; [[nodiscard]] virtual auto - fuse_unlink(const char *path) -> packet::error_type = 0; + fuse_write_base64(const char *path, const char *buffer, + remote::file_size writeSize, + remote::file_offset writeOffset, remote::file_handle handle) + -> packet::error_type = 0; - [[nodiscard]] virtual auto - fuse_utimens(const char *path, const remote::file_time *tv, std::uint64_t op0, - std::uint64_t op1) -> packet::error_type = 0; - - [[nodiscard]] virtual auto - fuse_write(const char *path, const char *buffer, - const remote::file_size &writeSize, - const remote::file_offset &writeOffset, - const remote::file_handle &handle) -> packet::error_type = 0; - - [[nodiscard]] virtual auto fuse_write_base64( - const char *path, const char *buffer, const remote::file_size &writeSize, - const remote::file_offset &writeOffset, - const remote::file_handle &handle) -> packet::error_type = 0; - - virtual void set_fuse_uid_gid(const remote::user_id &uid, - const remote::group_id &gid) = 0; + virtual void set_fuse_uid_gid(remote::user_id uid, remote::group_id gid) = 0; }; using remote_instance_factory = diff --git a/repertory/librepertory/include/drives/fuse/remotefuse/remote_client.hpp b/repertory/librepertory/include/drives/fuse/remotefuse/remote_client.hpp index 92577046..4ce8e184 100644 --- a/repertory/librepertory/include/drives/fuse/remotefuse/remote_client.hpp +++ b/repertory/librepertory/include/drives/fuse/remotefuse/remote_client.hpp @@ -43,43 +43,41 @@ private: public: [[nodiscard]] auto check() -> packet::error_type; - [[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask) + [[nodiscard]] auto fuse_access(const char *path, std::int32_t mask) -> packet::error_type override; [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) -> packet::error_type override; - [[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode) + [[nodiscard]] auto fuse_chmod(const char *path, remote::file_mode mode) -> packet::error_type override; - [[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) + [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override; [[nodiscard]] /*packet::error_type fuse_fallocate(const char *path, const - std::int32_t &mode, const remote::file_offset &offset, const - remote::file_offset &length, const remote::file_handle + std::int32_t &mode, remote::file_offset offset, const + remote::file_offset length, const remote::file_handle &handle) override ;*/ [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, - const remote::file_handle &handle) - -> packet::error_type override; + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_ftruncate(const char *path, remote::file_offset size, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, @@ -87,10 +85,10 @@ public: -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char - *name, char *value, const remote::file_size &size) override ; + *name, char *value, remote::file_size size) override ; [[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char - *name, char *value, const remote::file_size &size, std::uint32_t position) + *name, char *value, remote::file_size size, std::uint32_t position) override ;*/ [[nodiscard]] auto fuse_getxtimes(const char *path, @@ -101,17 +99,17 @@ public: [[nodiscard]] auto fuse_init() -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_listxattr(const char *path, char - *buffer, const remote::file_size &size) override ;*/ + *buffer, remote::file_size size) override ;*/ - [[nodiscard]] auto fuse_mkdir(const char *path, const remote::file_mode &mode) + [[nodiscard]] auto fuse_mkdir(const char *path, remote::file_mode mode) -> packet::error_type override; [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle) -> packet::error_type override; - [[nodiscard]] auto - fuse_create(const char *path, const remote::file_mode &mode, - const remote::open_flags &flags, remote::file_handle &handle) + [[nodiscard]] auto fuse_create(const char *path, remote::file_mode mode, + const remote::open_flags &flags, + remote::file_handle &handle) -> packet::error_type override; [[nodiscard]] auto fuse_open(const char *path, @@ -119,26 +117,24 @@ public: remote::file_handle &handle) -> packet::error_type override; - [[nodiscard]] auto fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + [[nodiscard]] auto + fuse_read(const char *path, char *buffer, remote::file_size read_size, + remote::file_offset read_offset, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_rename(const char *from, const char *to) -> packet::error_type override; - [[nodiscard]] auto - fuse_readdir(const char *path, const remote::file_offset &offset, - const remote::file_handle &handle, std::string &item_path) + [[nodiscard]] auto fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, + std::string &item_path) -> packet::error_type override; - [[nodiscard]] auto fuse_release(const char *path, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_releasedir(const char *path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const @@ -152,26 +148,25 @@ public: -> packet::error_type override; [[nodiscard]] auto fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) + remote::file_time bkuptime) -> packet::error_type override; [[nodiscard]] auto fuse_setchgtime(const char *path, - const remote::file_time &chgtime) + remote::file_time chgtime) -> packet::error_type override; - [[nodiscard]] auto fuse_setcrtime(const char *path, - const remote::file_time &crtime) + [[nodiscard]] auto fuse_setcrtime(const char *path, remote::file_time crtime) -> packet::error_type override; [[nodiscard]] auto fuse_setvolname(const char *volname) -> packet::error_type override; [[nodiscard]] /*packet::error_type fuse_setxattr(const char *path, const char - *name, const char *value, const remote::file_size &size, const std::int32_t + *name, const char *value, remote::file_size size, const std::int32_t &flags) override ; [[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const - char *name, const char *value, const remote::file_size &size, const + char *name, const char *value, remote::file_size size, const std::int32_t &flags, std::uint32_t position) override ;*/ [[nodiscard]] auto @@ -182,8 +177,7 @@ public: remote::statfs_x &r_stat) -> packet::error_type override; - [[nodiscard]] auto fuse_truncate(const char *path, - const remote::file_offset &size) + [[nodiscard]] auto fuse_truncate(const char *path, remote::file_offset size) -> packet::error_type override; [[nodiscard]] auto fuse_unlink(const char *path) @@ -193,33 +187,32 @@ public: std::uint64_t op0, std::uint64_t op1) -> packet::error_type override; - [[nodiscard]] auto fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + [[nodiscard]] auto + fuse_write(const char *path, const char *buffer, remote::file_size write_size, + remote::file_offset write_offset, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto json_create_directory_snapshot(const std::string &path, json &json_data) -> packet::error_type override; - [[nodiscard]] auto json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type override; - - [[nodiscard]] auto - json_release_directory_snapshot(const std::string &path, - const remote::file_handle &handle) + [[nodiscard]] auto json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) -> packet::error_type override; - void set_fuse_uid_gid(const remote::user_id &uid, - const remote::group_id &gid) override; + [[nodiscard]] auto json_release_directory_snapshot(const std::string &path, + remote::file_handle handle) + -> packet::error_type override; + + void set_fuse_uid_gid(remote::user_id uid, remote::group_id gid) override; }; } // namespace remote_fuse } // namespace repertory diff --git a/repertory/librepertory/include/drives/fuse/remotefuse/remote_server.hpp b/repertory/librepertory/include/drives/fuse/remotefuse/remote_server.hpp index d5e73e14..048203bb 100644 --- a/repertory/librepertory/include/drives/fuse/remotefuse/remote_server.hpp +++ b/repertory/librepertory/include/drives/fuse/remotefuse/remote_server.hpp @@ -53,8 +53,8 @@ private: remote::file_info &r_info) -> packet::error_type; - void populate_file_info(const std::string &api_path, const UINT64 &file_size, - const UINT32 &attributes, remote::file_info &r_info); + void populate_file_info(const std::string &api_path, UINT64 file_size, + UINT32 attributes, remote::file_info &r_info); static void populate_stat(const struct stat64 &u_stat, remote::stat &r_stat); @@ -63,48 +63,46 @@ private: public: // FUSE Layer - [[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask) + [[nodiscard]] auto fuse_access(const char *path, std::int32_t mask) -> packet::error_type override; [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) -> packet::error_type override; - [[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode) + [[nodiscard]] auto fuse_chmod(const char *path, remote::file_mode mode) -> packet::error_type override; - [[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) + [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) -> packet::error_type override; - [[nodiscard]] auto - fuse_create(const char *path, const remote::file_mode &mode, - const remote::open_flags &flags, remote::file_handle &handle) + [[nodiscard]] auto fuse_create(const char *path, remote::file_mode mode, + const remote::open_flags &flags, + remote::file_handle &handle) -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_fallocate(const char *path, const - std::int32_t &mode, const remote::file_offset &offset, const - remote::file_offset &length, const remote::file_handle &handle) override + std::int32_t &mode, remote::file_offset offset, const + remote::file_offset length, remote::file_handle handle) override ;*/ [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, - bool &directory, - const remote::file_handle &handle) + bool &directory, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_ftruncate(const char *path, remote::file_offset size, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, @@ -112,10 +110,10 @@ public: -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char - *name, char *value, const remote::file_size &size) override ; + *name, char *value, remote::file_size size) override ; [[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char - *name, char *value, const remote::file_size &size, std::uint32_t position) + *name, char *value, remote::file_size size, std::uint32_t position) override ;*/ [[nodiscard]] auto fuse_getxtimes(const char *path, @@ -126,10 +124,10 @@ public: [[nodiscard]] auto fuse_init() -> packet::error_type override; [[nodiscard]] /*packet::error_type fuse_listxattr(const char *path, char - *buffer, const remote::file_size &size) override ;*/ + *buffer, remote::file_size size) override ;*/ [[nodiscard]] auto - fuse_mkdir(const char *path, const remote::file_mode &mode) + fuse_mkdir(const char *path, remote::file_mode mode) -> packet::error_type override; [[nodiscard]] auto fuse_open(const char *path, @@ -140,26 +138,24 @@ public: [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle) -> packet::error_type override; - [[nodiscard]] auto fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + [[nodiscard]] auto + fuse_read(const char *path, char *buffer, remote::file_size read_size, + remote::file_offset read_offset, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_rename(const char *from, const char *to) -> packet::error_type override; - [[nodiscard]] auto - fuse_readdir(const char *path, const remote::file_offset &offset, - const remote::file_handle &handle, std::string &item_path) + [[nodiscard]] auto fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, + std::string &item_path) -> packet::error_type override; - [[nodiscard]] auto fuse_release(const char *path, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_releasedir(const char *path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const @@ -173,26 +169,25 @@ public: -> packet::error_type override; [[nodiscard]] auto fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) + remote::file_time bkuptime) -> packet::error_type override; [[nodiscard]] auto fuse_setchgtime(const char *path, - const remote::file_time &chgtime) + remote::file_time chgtime) -> packet::error_type override; - [[nodiscard]] auto fuse_setcrtime(const char *path, - const remote::file_time &crtime) + [[nodiscard]] auto fuse_setcrtime(const char *path, remote::file_time crtime) -> packet::error_type override; [[nodiscard]] auto fuse_setvolname(const char *volname) -> packet::error_type override; /*[[nodiscard]] packet::error_type fuse_setxattr(const char *path, const char - *name, const char *value, const remote::file_size &size, const std::int32_t + *name, const char *value, remote::file_size size, const std::int32_t &flags) override ; [[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const - char *name, const char *value, const remote::file_size &size, const + char *name, const char *value, remote::file_size size, const std::int32_t &flags, std::uint32_t position) override ;*/ [[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize, @@ -203,8 +198,7 @@ public: remote::statfs_x &r_stat) -> packet::error_type override; - [[nodiscard]] auto fuse_truncate(const char *path, - const remote::file_offset &size) + [[nodiscard]] auto fuse_truncate(const char *path, remote::file_offset size) -> packet::error_type override; [[nodiscard]] auto fuse_unlink(const char *path) @@ -214,20 +208,18 @@ public: std::uint64_t op0, std::uint64_t op1) -> packet::error_type override; - [[nodiscard]] auto fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + [[nodiscard]] auto + fuse_write(const char *path, const char *buffer, remote::file_size write_size, + remote::file_offset write_offset, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type override; - void set_fuse_uid_gid(const remote::user_id &, - const remote::group_id &) override {} + void set_fuse_uid_gid(remote::user_id, remote::group_id) override {} // JSON Layer [[nodiscard]] auto winfsp_get_dir_buffer(PVOID /*file_desc*/, @@ -240,13 +232,14 @@ public: json &json_data) -> packet::error_type override; - [[nodiscard]] auto json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type override; + [[nodiscard]] auto json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) + -> packet::error_type override; - [[nodiscard]] auto - json_release_directory_snapshot(const std::string &path, - const remote::file_handle &handle) + [[nodiscard]] auto json_release_directory_snapshot(const std::string &path, + remote::file_handle handle) -> packet::error_type override; // WinFSP Layer diff --git a/repertory/librepertory/include/drives/remote/i_remote_json.hpp b/repertory/librepertory/include/drives/remote/i_remote_json.hpp index 74067975..48265c13 100644 --- a/repertory/librepertory/include/drives/remote/i_remote_json.hpp +++ b/repertory/librepertory/include/drives/remote/i_remote_json.hpp @@ -34,12 +34,12 @@ public: json &json_data) -> packet::error_type = 0; [[nodiscard]] virtual auto json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, + const std::string &path, remote::file_handle handle, std::uint32_t page, json &json_data) -> packet::error_type = 0; [[nodiscard]] virtual auto json_release_directory_snapshot( const std::string &path, - const remote::file_handle &handle) -> packet::error_type = 0; + remote::file_handle handle) -> packet::error_type = 0; }; } // namespace repertory diff --git a/repertory/librepertory/include/drives/remote/remote_open_file_table.hpp b/repertory/librepertory/include/drives/remote/remote_open_file_table.hpp index f21bf480..826cde0c 100644 --- a/repertory/librepertory/include/drives/remote/remote_open_file_table.hpp +++ b/repertory/librepertory/include/drives/remote/remote_open_file_table.hpp @@ -80,7 +80,7 @@ protected: [[nodiscard]] auto has_open_directory(const std::string &client_id, std::uint64_t handle) -> bool; - [[nodiscard]] auto has_compat_open_info(const remote::file_handle &handle, + [[nodiscard]] auto has_compat_open_info(remote::file_handle handle, int error_return) -> int; template @@ -95,7 +95,7 @@ protected: void remove_and_close_all(const native_handle &handle); - void remove_compat_open_info(const remote::file_handle &handle); + void remove_compat_open_info(remote::file_handle handle); auto remove_directory(const std::string &client_id, std::uint64_t handle) -> bool; @@ -104,10 +104,10 @@ protected: void set_client_id(const native_handle &handle, const std::string &client_id); - void set_compat_client_id(const remote::file_handle &handle, + void set_compat_client_id(remote::file_handle handle, const std::string &client_id); - void set_compat_open_info(const remote::file_handle &handle, + void set_compat_open_info(remote::file_handle handle, const std::string &file_path); void set_open_info(const native_handle &handle, open_info op_info); diff --git a/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_client.hpp b/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_client.hpp index 226c52bb..36879427 100644 --- a/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_client.hpp +++ b/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_client.hpp @@ -55,12 +55,12 @@ public: -> packet::error_type override; [[nodiscard]] auto json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, + const std::string &path, remote::file_handle handle, std::uint32_t page, json &json_data) -> packet::error_type override; [[nodiscard]] auto json_release_directory_snapshot(const std::string &path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) diff --git a/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_server.hpp b/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_server.hpp index d7c662fc..3644f46c 100644 --- a/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_server.hpp +++ b/repertory/librepertory/include/drives/winfsp/remotewinfsp/remote_server.hpp @@ -58,42 +58,41 @@ private: public: // FUSE Layer - [[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask) + [[nodiscard]] auto fuse_access(const char *path, std::int32_t mask) -> packet::error_type override; [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) -> packet::error_type override; - [[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode) + [[nodiscard]] auto fuse_chmod(const char *path, remote::file_mode mode) -> packet::error_type override; - [[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) + [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override; /*packet::error_type fuse_fallocate(const char *path, const std::int32_t - &mode, const remote::file_offset &offset, const remote::file_offset - &length, const remote::file_handle &handle) override ;*/ + &mode, remote::file_offset offset, const remote::file_offset + &length, remote::file_handle handle) override ;*/ [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, - bool &directory, - const remote::file_handle &handle) + bool &directory, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) + remote::file_offset size, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, @@ -101,10 +100,10 @@ public: -> packet::error_type override; /*packet::error_type fuse_getxattr(const char *path, const char *name, char - *value, const remote::file_size &size) override ; + *value, remote::file_size size) override ; packet::error_type fuse_getxattrOSX(const char *path, const char *name, char - *value, const remote::file_size &size, std::uint32_t position) override ;*/ + *value, remote::file_size size, std::uint32_t position) override ;*/ [[nodiscard]] auto fuse_getxtimes(const char *path, remote::file_time &bkuptime, @@ -114,57 +113,55 @@ public: [[nodiscard]] auto fuse_init() -> packet::error_type override; /*packet::error_type fuse_listxattr(const char *path, char *buffer, - const remote::file_size &size) override + remote::file_size size) override ;*/ - [[nodiscard]] auto fuse_mkdir(const char *path, const remote::file_mode &mode) + [[nodiscard]] auto fuse_mkdir(const char *path, remote::file_mode mode) -> packet::error_type override; - [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle) + [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto - fuse_create(const char *path, const remote::file_mode &mode, - const remote::open_flags &flags, remote::file_handle &handle) + fuse_create(const char *path, remote::file_mode mode, + const remote::open_flags &flags, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_open(const char *path, const remote::open_flags &flags, - remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; - [[nodiscard]] auto fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + [[nodiscard]] auto + fuse_read(const char *path, char *buffer, remote::file_size read_size, + remote::file_offset read_offset, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_rename(const char *from, const char *to) -> packet::error_type override; [[nodiscard]] auto fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto - fuse_readdir(const char *path, const remote::file_offset &offset, - const remote::file_handle &handle, std::string &item_path) + fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, std::string &item_path) -> packet::error_type override; - [[nodiscard]] auto fuse_release(const char *path, - const remote::file_handle &handle) + [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle) -> packet::error_type override; [[nodiscard]] auto fuse_releasedir(const char *path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type override; /*packet::error_type fuse_removexattr(const char *path, const char *name) @@ -177,26 +174,26 @@ public: -> packet::error_type override; [[nodiscard]] auto fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) + remote::file_time bkuptime) -> packet::error_type override; [[nodiscard]] auto fuse_setchgtime(const char *path, - const remote::file_time &chgtime) + remote::file_time chgtime) -> packet::error_type override; [[nodiscard]] auto fuse_setcrtime(const char *path, - const remote::file_time &crtime) + remote::file_time crtime) -> packet::error_type override; [[nodiscard]] auto fuse_setvolname(const char *volname) -> packet::error_type override; /*packet::error_type fuse_setxattr(const char *path, const char *name, const - char *value, const remote::file_size &size, const std::int32_t &flags) + char *value, remote::file_size size, std::int32_t flags) override ; packet::error_type fuse_setxattr_osx(const char *path, const char *name, const - char *value, const remote::file_size &size, const std::int32_t &flags, + char *value, remote::file_size size, std::int32_t flags, std::uint32_t position) override ;*/ [[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize, @@ -208,7 +205,7 @@ public: -> packet::error_type override; [[nodiscard]] auto fuse_truncate(const char *path, - const remote::file_offset &size) + remote::file_offset size) -> packet::error_type override; [[nodiscard]] auto fuse_unlink(const char *path) @@ -218,21 +215,22 @@ public: std::uint64_t op0, std::uint64_t op1) -> packet::error_type override; - void set_fuse_uid_gid(const remote::user_id & /* uid */, - const remote::group_id & /* gid */) override {} + void set_fuse_uid_gid(remote::user_id /* uid */, + remote::group_id /* gid */) override {} // JSON Layer [[nodiscard]] auto json_create_directory_snapshot(const std::string &path, json &json_data) -> packet::error_type override; - [[nodiscard]] auto json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type override; + [[nodiscard]] auto json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) + -> packet::error_type override; - [[nodiscard]] auto - json_release_directory_snapshot(const std::string &path, - const remote::file_handle &handle) + [[nodiscard]] auto json_release_directory_snapshot(const std::string &path, + remote::file_handle handle) -> packet::error_type override; // WinFSP Layer diff --git a/repertory/librepertory/include/file_manager/file_manager.hpp b/repertory/librepertory/include/file_manager/file_manager.hpp index 0b32d626..975972b9 100644 --- a/repertory/librepertory/include/file_manager/file_manager.hpp +++ b/repertory/librepertory/include/file_manager/file_manager.hpp @@ -77,7 +77,8 @@ private: private: void close_timed_out_files(); - [[nodiscard]] auto get_open_file_by_handle(std::uint64_t handle) const + [[nodiscard]] auto get_open_file_by_handle(std::uint64_t handle, + bool &is_closed) const -> std::shared_ptr; [[nodiscard]] auto get_open_file_count(const std::string &api_path) const @@ -92,7 +93,7 @@ private: -> api_error; void queue_upload(const std::string &api_path, const std::string &source_path, - bool no_lock); + bool is_unlinked, bool no_lock); void remove_resume(const std::string &api_path, const std::string &source_path, bool no_lock); @@ -145,6 +146,9 @@ public: [[nodiscard]] auto get_directory_items(const std::string &api_path) const -> directory_item_list override; + [[nodiscard]] auto get_open_file(const std::string &api_path, + std::shared_ptr &file) -> bool; + [[nodiscard]] auto get_open_file(std::uint64_t handle, bool write_supported, std::shared_ptr &file) -> bool; diff --git a/repertory/librepertory/include/file_manager/i_open_file.hpp b/repertory/librepertory/include/file_manager/i_open_file.hpp index 48f41281..6d6bdef7 100644 --- a/repertory/librepertory/include/file_manager/i_open_file.hpp +++ b/repertory/librepertory/include/file_manager/i_open_file.hpp @@ -64,13 +64,17 @@ public: [[nodiscard]] virtual auto get_source_path() const -> std::string = 0; + [[nodiscard]] virtual auto get_unlinked_meta() const -> api_meta_map = 0; + + [[nodiscard]] virtual auto has_handle(std::uint64_t handle) const -> bool = 0; + [[nodiscard]] virtual auto is_complete() const -> bool = 0; [[nodiscard]] virtual auto is_directory() const -> bool = 0; - [[nodiscard]] virtual auto is_write_supported() const -> bool = 0; + [[nodiscard]] virtual auto is_unlinked() const -> bool = 0; - [[nodiscard]] virtual auto has_handle(std::uint64_t handle) const -> bool = 0; + [[nodiscard]] virtual auto is_write_supported() const -> bool = 0; [[nodiscard]] virtual auto native_operation(native_operation_callback callback) -> api_error = 0; @@ -97,7 +101,7 @@ class i_closeable_open_file : public i_open_file { INTERFACE_SETUP(i_closeable_open_file); public: - virtual void add(std::uint64_t handle, open_file_data ofd) = 0; + virtual void add(std::uint64_t handle, open_file_data ofd, bool notify) = 0; [[nodiscard]] virtual auto can_close() const -> bool = 0; @@ -110,13 +114,13 @@ public: [[nodiscard]] virtual auto is_modified() const -> bool = 0; - [[nodiscard]] virtual auto is_unlinked() const -> bool = 0; - virtual void remove(std::uint64_t handle) = 0; virtual void remove_all() = 0; virtual void set_unlinked(bool value) = 0; + + virtual void set_unlinked_meta(api_meta_map meta) = 0; }; } // namespace repertory diff --git a/repertory/librepertory/include/file_manager/open_file.hpp b/repertory/librepertory/include/file_manager/open_file.hpp index b21dc102..9e2492c0 100644 --- a/repertory/librepertory/include/file_manager/open_file.hpp +++ b/repertory/librepertory/include/file_manager/open_file.hpp @@ -111,8 +111,6 @@ public: [[nodiscard]] auto is_complete() const -> bool override; - [[nodiscard]] auto is_removed() const -> bool override; - [[nodiscard]] auto is_write_supported() const -> bool override { return true; } @@ -133,8 +131,6 @@ public: [[nodiscard]] auto resize(std::uint64_t new_file_size) -> api_error override; - void set_removed(bool value) override; - [[nodiscard]] auto write(std::uint64_t write_offset, const data_buffer &data, std::size_t &bytes_written) -> api_error override; }; diff --git a/repertory/librepertory/include/file_manager/open_file_base.hpp b/repertory/librepertory/include/file_manager/open_file_base.hpp index addab380..5cb866d9 100644 --- a/repertory/librepertory/include/file_manager/open_file_base.hpp +++ b/repertory/librepertory/include/file_manager/open_file_base.hpp @@ -119,9 +119,8 @@ private: }; bool modified_{false}; bool removed_{false}; -#if !defined(_WIN32) bool unlinked_{false}; -#endif // !defined(_WIN32) + api_meta_map unlinked_meta_; private: void file_io_thread(); @@ -167,7 +166,7 @@ protected: void wait_for_io(stop_type_callback stop_requested_cb); public: - void add(std::uint64_t handle, open_file_data ofd) override; + void add(std::uint64_t handle, open_file_data ofd, bool notify) override; [[nodiscard]] auto can_close() const -> bool override; @@ -205,6 +204,8 @@ public: [[nodiscard]] auto get_source_path() const -> std::string override; + [[nodiscard]] auto get_unlinked_meta() const -> api_meta_map override; + [[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override; [[nodiscard]] auto is_directory() const -> bool override { @@ -222,6 +223,8 @@ public: void set_api_path(const std::string &api_path) override; void set_unlinked(bool value) override; + + void set_unlinked_meta(api_meta_map meta) override; }; } // namespace repertory diff --git a/repertory/librepertory/include/types/repertory.hpp b/repertory/librepertory/include/types/repertory.hpp index 26cf8d54..1d9cfaaf 100644 --- a/repertory/librepertory/include/types/repertory.hpp +++ b/repertory/librepertory/include/types/repertory.hpp @@ -125,9 +125,11 @@ enum class api_error { no_disk_space, not_implemented, not_supported, + no_tty, os_error, out_of_memory, permission_denied, + stale_descriptor, upload_failed, xattr_buffer_small, xattr_exists, diff --git a/repertory/librepertory/include/utils/unix/unix_utils.hpp b/repertory/librepertory/include/utils/unix/unix_utils.hpp index e95ddb65..7ab195e9 100644 --- a/repertory/librepertory/include/utils/unix/unix_utils.hpp +++ b/repertory/librepertory/include/utils/unix/unix_utils.hpp @@ -45,9 +45,8 @@ inline const std::array attribute_namespaces = { [[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t; -void windows_create_to_unix(const UINT32 &create_options, - const UINT32 &granted_access, std::uint32_t &flags, - remote::file_mode &mode); +void windows_create_to_unix(UINT32 create_options, UINT32 granted_access, + std::uint32_t &flags, remote::file_mode &mode); } // namespace repertory::utils #endif // !defined(_WIN32) diff --git a/repertory/librepertory/include/utils/windows/windows_utils.hpp b/repertory/librepertory/include/utils/windows/windows_utils.hpp index 4d4f9769..b12395dc 100644 --- a/repertory/librepertory/include/utils/windows/windows_utils.hpp +++ b/repertory/librepertory/include/utils/windows/windows_utils.hpp @@ -45,7 +45,7 @@ namespace repertory::utils { [[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int; [[nodiscard]] auto -unix_open_flags_to_flags_and_perms(const remote::file_mode &mode, +unix_open_flags_to_flags_and_perms(remote::file_mode mode, const remote::open_flags &flags, std::int32_t &perms) -> int; } // namespace repertory::utils diff --git a/repertory/librepertory/src/drives/directory_iterator.cpp b/repertory/librepertory/src/drives/directory_iterator.cpp index 92efb8eb..63aaa51c 100644 --- a/repertory/librepertory/src/drives/directory_iterator.cpp +++ b/repertory/librepertory/src/drives/directory_iterator.cpp @@ -26,7 +26,7 @@ namespace repertory { #if !defined(_WIN32) -auto directory_iterator::fill_buffer(const remote::file_offset &offset, +auto directory_iterator::fill_buffer(remote::file_offset offset, fuse_fill_dir_t filler_function, void *buffer, populate_stat_callback populate_stat) diff --git a/repertory/librepertory/src/drives/fuse/fuse_base.cpp b/repertory/librepertory/src/drives/fuse/fuse_base.cpp index 5f80b8d6..453fa5c1 100644 --- a/repertory/librepertory/src/drives/fuse/fuse_base.cpp +++ b/repertory/librepertory/src/drives/fuse/fuse_base.cpp @@ -52,6 +52,7 @@ fuse_base::fuse_base(app_config &config) : config_(config) { fuse_ops_.fsync = fuse_base::fsync_; fuse_ops_.getattr = fuse_base::getattr_; fuse_ops_.init = fuse_base::init_; + fuse_ops_.ioctl = fuse_base::ioctl_; fuse_ops_.mkdir = fuse_base::mkdir_; fuse_ops_.open = fuse_base::open_; fuse_ops_.opendir = fuse_base::opendir_; @@ -211,8 +212,9 @@ auto fuse_base::execute_callback( const std::function &cb, bool disable_logging) -> int { - auto from_api_file = utils::path::create_api_path(from ? from : ""); - auto to_api_file = utils::path::create_api_path(to ? to : ""); + auto from_api_file = + utils::path::create_api_path(from == nullptr ? "" : from); + auto to_api_file = utils::path::create_api_path(to == nullptr ? "" : to); auto res = utils::from_api_error(cb(from_api_file, to_api_file)); raise_fuse_event(function_name, "from|" + from_api_file + "|to|" + to_api_file, res, @@ -224,7 +226,7 @@ auto fuse_base::execute_callback( std::string_view function_name, const char *path, const std::function &cb, bool disable_logging) -> int { - auto api_path = utils::path::create_api_path(path ? path : ""); + auto api_path = utils::path::create_api_path(path == nullptr ? "" : path); auto res = utils::from_api_error(cb(api_path)); raise_fuse_event(function_name, api_path, res, disable_logging); return res; @@ -389,6 +391,17 @@ auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * { return this; } +auto fuse_base::ioctl_(const char *path, int cmd, void *arg, + struct fuse_file_info *f_info, unsigned int /* flags */, + void * /* data */) -> int { + REPERTORY_USES_FUNCTION_NAME(); + + return instance().execute_callback( + function_name, path, [&](std::string api_path) -> api_error { + return instance().ioctl_impl(std::move(api_path), cmd, arg, f_info); + }); +} + auto fuse_base::mkdir_(const char *path, mode_t mode) -> int { REPERTORY_USES_FUNCTION_NAME(); diff --git a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp index 002a4102..45eed6b8 100644 --- a/repertory/librepertory/src/drives/fuse/fuse_drive.cpp +++ b/repertory/librepertory/src/drives/fuse/fuse_drive.cpp @@ -44,6 +44,7 @@ #include "utils/base64.hpp" #include "utils/collection.hpp" #include "utils/common.hpp" +#include "utils/config.hpp" #include "utils/error_utils.hpp" #include "utils/polling.hpp" #include "utils/time.hpp" @@ -385,14 +386,25 @@ auto fuse_drive::fgetattr_impl(std::string api_path, struct stat *u_stat, return api_error::invalid_handle; } + auto is_unlinked{ + not open_file->is_directory() && open_file->is_unlinked(), + }; + api_meta_map meta{}; - auto res = provider_.get_item_meta(api_path, meta); - if (res != api_error::success) { - return res; + if (is_unlinked) { + meta = open_file->get_unlinked_meta(); + } else { + auto res = provider_.get_item_meta(api_path, meta); + if (res != api_error::success) { + return res; + } } fuse_drive_base::populate_stat(api_path, open_file->get_file_size(), meta, open_file->is_directory(), provider_, u_stat); + if (is_unlinked) { + u_stat->st_nlink = 0; + } return api_error::success; } @@ -498,9 +510,36 @@ auto fuse_drive::get_item_meta(const std::string &api_path, return ret; } +auto fuse_drive::get_item_stat(std::uint64_t handle, + struct stat64 *u_stat) const -> api_error { + std::shared_ptr open_file; + if (not fm_->get_open_file(handle, false, open_file)) { + return api_error::invalid_handle; + } + + api_meta_map meta{}; + if (open_file->is_unlinked()) { + meta = open_file->get_unlinked_meta(); + } else { + auto ret = provider_.get_item_meta(open_file->get_api_path(), meta); + if (ret != api_error::success) { + return ret; + } + } + + fuse_drive_base::populate_stat(open_file->get_api_path(), + open_file->get_file_size(), meta, + open_file->is_directory(), provider_, u_stat); + return api_error::success; +} + #if FUSE_USE_VERSION >= 30 auto fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat, - struct fuse_file_info * /*f_info*/) -> api_error { + struct fuse_file_info *f_info) -> api_error { + if (f_info != nullptr && f_info->fh != 0 && + f_info->fh != static_cast(REPERTORY_INVALID_HANDLE)) { + return fgetattr_impl(api_path, u_stat, f_info); + } #else auto fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat) -> api_error { @@ -637,6 +676,20 @@ auto fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * { return ret; } +auto fuse_drive::ioctl_impl(std::string /* api_path */, int cmd, void *arg, + struct fuse_file_info *f_info) -> api_error { + if (cmd == repertory_ioctl_fd_command) { + if (arg == nullptr) { + return api_error::invalid_operation; + } + + std::memcpy(arg, &f_info->fh, sizeof(f_info->fh)); + return api_error::success; + } + + return api_error::no_tty; +} + auto fuse_drive::is_processing(const std::string &api_path) const -> bool { return fm_->is_processing(api_path); } @@ -1406,6 +1459,8 @@ auto fuse_drive::write_impl(std::string /*api_path*/ const char *buffer, size_t write_size, off_t write_offset, struct fuse_file_info *f_info, std::size_t &bytes_written) -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + std::shared_ptr open_file; if (not fm_->get_open_file(f_info->fh, true, open_file)) { return api_error::item_not_found; diff --git a/repertory/librepertory/src/drives/fuse/remotefuse/remote_client.cpp b/repertory/librepertory/src/drives/fuse/remotefuse/remote_client.cpp index f86d7f6f..11a0267e 100644 --- a/repertory/librepertory/src/drives/fuse/remotefuse/remote_client.cpp +++ b/repertory/librepertory/src/drives/fuse/remotefuse/remote_client.cpp @@ -37,7 +37,7 @@ auto remote_client::check() -> packet::error_type { return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_access(const char *path, const std::int32_t &mask) +auto remote_client::fuse_access(const char *path, std::int32_t mask) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -61,7 +61,7 @@ auto remote_client::fuse_chflags(const char *path, std::uint32_t flags) return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_chmod(const char *path, const remote::file_mode &mode) +auto remote_client::fuse_chmod(const char *path, remote::file_mode mode) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -73,9 +73,8 @@ auto remote_client::fuse_chmod(const char *path, const remote::file_mode &mode) return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) - -> packet::error_type { +auto remote_client::fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); packet request; @@ -95,8 +94,8 @@ auto remote_client::fuse_destroy() -> packet::error_type { } /*packet::error_type remote_client::fuse_fallocate(const char *path, const -std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset -&length, const remote::file_handle &handle) { packet request; +std::int32_t &mode, remote::file_offset offset, const remote::file_offset +&length, remote::file_handle handle) { packet request; request.encode(path); request.encode(mode); request.encode(offset); @@ -108,8 +107,7 @@ std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset }*/ auto remote_client::fuse_fgetattr(const char *path, remote::stat &r_stat, - bool &directory, - const remote::file_handle &handle) + bool &directory, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -124,10 +122,12 @@ auto remote_client::fuse_fgetattr(const char *path, remote::stat &r_stat, auto ret = packet_client_.send(function_name, request, response, service_flags); if (ret == 0) { - if ((ret = response.decode(r_stat)) == 0) { - std::uint8_t d{}; - if ((ret = response.decode(d)) == 0) { - directory = static_cast(d); + ret = response.decode(r_stat); + if (ret == 0) { + std::uint8_t is_dir{}; + ret = response.decode(is_dir); + if (ret == 0) { + directory = static_cast(is_dir); } } } @@ -137,7 +137,7 @@ auto remote_client::fuse_fgetattr(const char *path, remote::stat &r_stat, auto remote_client::fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -150,8 +150,8 @@ auto remote_client::fuse_fsetattr_x(const char *path, return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) +auto remote_client::fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -164,9 +164,8 @@ auto remote_client::fuse_fsync(const char *path, const std::int32_t &datasync, return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) +auto remote_client::fuse_ftruncate(const char *path, remote::file_offset size, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -193,10 +192,12 @@ auto remote_client::fuse_getattr(const char *path, remote::stat &r_stat, auto ret = packet_client_.send(function_name, request, response, service_flags); if (ret == 0) { - if ((ret = response.decode(r_stat)) == 0) { - std::uint8_t d = 0; - if ((ret = response.decode(d)) == 0) { - directory = static_cast(d); + ret = response.decode(r_stat); + if (ret == 0) { + std::uint8_t is_dir{}; + ret = response.decode(is_dir); + if (ret == 0) { + directory = static_cast(is_dir); } } } @@ -205,7 +206,7 @@ auto remote_client::fuse_getattr(const char *path, remote::stat &r_stat, } /*packet::error_type remote_client::fuse_getxattr(const char *path, const char -*name, char *value, const remote::file_size &size) { packet::error_type ret = 0; +*name, char *value, remote::file_size size) { packet::error_type ret = 0; if (size > std::numeric_limits::max()) { ret = -ERANGE; } else { packet request; request.encode(path); request.encode(name); request.encode(size); @@ -226,7 +227,7 @@ response.CurrentPointer(), static_cast(size2)); } packet::error_type remote_client::fuse_getxattr_osx(const char *path, const char -*name, char *value, const remote::file_size &size, std::uint32_t position) { +*name, char *value, remote::file_size size, std::uint32_t position) { packet::error_type ret = 0; if (size > std::numeric_limits::max()) { ret = -ERANGE; } else { packet request; request.encode(path); request.encode(name); @@ -277,7 +278,7 @@ auto remote_client::fuse_init() -> packet::error_type { } /*packet::error_type remote_client::fuse_listxattr(const char *path, char -*buffer, const remote::file_size &size) { packet::error_type ret = 0; if (size > +*buffer, remote::file_size size) { packet::error_type ret = 0; if (size > std::numeric_limits::max()) { ret = -ERANGE; } else { packet request; request.encode(path); request.encode(size); @@ -297,7 +298,7 @@ static_cast(size2)); return ret; }*/ -auto remote_client::fuse_mkdir(const char *path, const remote::file_mode &mode) +auto remote_client::fuse_mkdir(const char *path, remote::file_mode mode) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -327,7 +328,7 @@ auto remote_client::fuse_opendir(const char *path, remote::file_handle &handle) return ret; } -auto remote_client::fuse_create(const char *path, const remote::file_mode &mode, +auto remote_client::fuse_create(const char *path, remote::file_mode mode, const remote::open_flags &flags, remote::file_handle &handle) -> packet::error_type { @@ -370,9 +371,9 @@ auto remote_client::fuse_open(const char *path, const remote::open_flags &flags, } auto remote_client::fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + remote::file_size read_size, + remote::file_offset read_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -406,9 +407,9 @@ auto remote_client::fuse_rename(const char *from, const char *to) } auto remote_client::fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -428,9 +429,9 @@ auto remote_client::fuse_write(const char *path, const char *buffer, } auto remote_client::fuse_write_base64(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -449,9 +450,8 @@ auto remote_client::fuse_write_base64(const char *path, const char *buffer, return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_readdir(const char *path, - const remote::file_offset &offset, - const remote::file_handle &handle, +auto remote_client::fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, std::string &item_path) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -471,8 +471,7 @@ auto remote_client::fuse_readdir(const char *path, return ret; } -auto remote_client::fuse_release(const char *path, - const remote::file_handle &handle) +auto remote_client::fuse_release(const char *path, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -485,7 +484,7 @@ auto remote_client::fuse_release(const char *path, } auto remote_client::fuse_releasedir(const char *path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -528,7 +527,7 @@ auto remote_client::fuse_setattr_x(const char *path, remote::setattr_x &attr) } auto remote_client::fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) + remote::file_time bkuptime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -540,8 +539,7 @@ auto remote_client::fuse_setbkuptime(const char *path, return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_setchgtime(const char *path, - const remote::file_time &chgtime) +auto remote_client::fuse_setchgtime(const char *path, remote::file_time chgtime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -553,8 +551,7 @@ auto remote_client::fuse_setchgtime(const char *path, return packet_client_.send(function_name, request, service_flags); } -auto remote_client::fuse_setcrtime(const char *path, - const remote::file_time &crtime) +auto remote_client::fuse_setcrtime(const char *path, remote::file_time crtime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -577,7 +574,7 @@ auto remote_client::fuse_setvolname(const char *volname) -> packet::error_type { } /*packet::error_type remote_client::fuse_setxattr(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags) { packet::error_type ret = 0; if (size > std::numeric_limits::max()) { ret = -ERANGE; } else { packet request; request.encode(path); request.encode(name); request.encode(size); @@ -592,7 +589,7 @@ request; request.encode(path); request.encode(name); request.encode(size); } packet::error_type remote_client::fuse_setxattr_osx(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags, const std::uint32_t &position) override { packet::error_type ret = 0; if (size > std::numeric_limits::max()) { ret = -ERANGE; } else { packet request; request.encode(path); request.Encode(name); @@ -645,8 +642,7 @@ auto remote_client::fuse_statfs_x(const char *path, std::uint64_t bsize, return ret; } -auto remote_client::fuse_truncate(const char *path, - const remote::file_offset &size) +auto remote_client::fuse_truncate(const char *path, remote::file_offset size) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -702,9 +698,11 @@ auto remote_client::json_create_directory_snapshot(const std::string &path, return ret; } -auto remote_client::json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type { +auto remote_client::json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) + -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); packet request; @@ -723,8 +721,8 @@ auto remote_client::json_read_directory_snapshot( return ret; } -auto remote_client::json_release_directory_snapshot( - const std::string &path, const remote::file_handle &handle) +auto remote_client::json_release_directory_snapshot(const std::string &path, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -736,8 +734,8 @@ auto remote_client::json_release_directory_snapshot( return packet_client_.send(function_name, request, service_flags); } -void remote_client::set_fuse_uid_gid(const remote::user_id &uid, - const remote::group_id &gid) { +void remote_client::set_fuse_uid_gid(remote::user_id uid, + remote::group_id gid) { uid_ = uid; gid_ = gid; } diff --git a/repertory/librepertory/src/drives/fuse/remotefuse/remote_fuse_drive.cpp b/repertory/librepertory/src/drives/fuse/remotefuse/remote_fuse_drive.cpp index d3ce5e2b..e783d229 100644 --- a/repertory/librepertory/src/drives/fuse/remotefuse/remote_fuse_drive.cpp +++ b/repertory/librepertory/src/drives/fuse/remotefuse/remote_fuse_drive.cpp @@ -171,7 +171,6 @@ auto remote_fuse_drive::fsetattr_x_impl(std::string api_path, auto remote_fuse_drive::fsync_impl(std::string api_path, int datasync, struct fuse_file_info *f_info) -> api_error { - return utils::to_api_error( remote_instance_->fuse_fsync(api_path.c_str(), datasync, f_info->fh)); } @@ -187,8 +186,12 @@ auto remote_fuse_drive::ftruncate_impl(std::string api_path, off_t size, #if FUSE_USE_VERSION >= 30 auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat, - struct fuse_file_info * /*f_info*/) + struct fuse_file_info *f_info) -> api_error { + if (f_info != nullptr && f_info->fh != 0 && + f_info->fh != static_cast(REPERTORY_INVALID_HANDLE)) { + return fgetattr_impl(api_path, u_stat, f_info); + } #else // FUSE_USE_VERSION < 30 auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat) -> api_error { @@ -407,7 +410,7 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf, std::memset(p_stat.get(), 0, sizeof(struct stat)); if (item_path == ".") { #if FUSE_USE_VERSION >= 30 - stat_res = getattr_impl(api_path, p_stat.get(), f_info); + stat_res = getattr_impl(api_path, p_stat.get(), nullptr); #else // FUSE_USE_VERSION < 30 stat_res = getattr_impl(api_path, p_stat.get()); #endif // FUSE_USE_VERSION >= 30 @@ -422,7 +425,7 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf, } else { #if FUSE_USE_VERSION >= 30 stat_res = getattr_impl(utils::path::get_parent_api_path(api_path), - p_stat.get(), f_info); + p_stat.get(), nullptr); #else // FUSE_USE_VERSION < 30 stat_res = getattr_impl(utils::path::get_parent_api_path(api_path), p_stat.get()); diff --git a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp index 102bb1e4..db6d6331 100644 --- a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp +++ b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp @@ -105,8 +105,7 @@ auto remote_server::populate_file_info(const std::string &api_path, } void remote_server::populate_file_info(const std::string &api_path, - const UINT64 &file_size, - const UINT32 &attributes, + UINT64 file_size, UINT32 attributes, remote::file_info &r_info) { REPERTORY_USES_FUNCTION_NAME(); @@ -188,7 +187,7 @@ void remote_server::populate_stat(const struct stat64 &u_stat, r_stat.st_uid = u_stat.st_uid; } -auto remote_server::fuse_access(const char *path, const std::int32_t &mask) +auto remote_server::fuse_access(const char *path, std::int32_t mask) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -221,7 +220,7 @@ auto remote_server::fuse_chflags(const char *path, std::uint32_t flags) return ret; } -auto remote_server::fuse_chmod(const char *path, const remote::file_mode &mode) +auto remote_server::fuse_chmod(const char *path, remote::file_mode mode) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -232,9 +231,8 @@ auto remote_server::fuse_chmod(const char *path, const remote::file_mode &mode) return ret; } -auto remote_server::fuse_chown(const char *path, const remote::user_id &uid, - const remote::group_id &gid) - -> packet::error_type { +auto remote_server::fuse_chown(const char *path, remote::user_id uid, + remote::group_id gid) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); @@ -244,7 +242,7 @@ auto remote_server::fuse_chown(const char *path, const remote::user_id &uid, return ret; } -auto remote_server::fuse_create(const char *path, const remote::file_mode &mode, +auto remote_server::fuse_create(const char *path, remote::file_mode mode, const remote::open_flags &flags, remote::file_handle &handle) -> packet::error_type { @@ -256,10 +254,10 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode, if (res >= 0) { handle = static_cast(res); set_open_info(res, open_info{ - "", - nullptr, - {}, - file_path, + .client_id = "", + .directory_buffer = nullptr, + .handles = {}, + .path = file_path, }); } @@ -276,8 +274,8 @@ auto remote_server::fuse_destroy() -> packet::error_type { } /*packet::error_type remote_server::fuse_fallocate(const char *path, const -std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset -&length, const remote::file_handle &handle) { const auto file_path = +std::int32_t &mode, remote::file_offset offset, const remote::file_offset +&length, remote::file_handle handle) { const auto file_path = ConstructPath(path); auto ret = HasOpenFileInfo(handle, -EBADF); if (ret == 0) { #if defined(__APPLE__) ret = STATUS_NOT_IMPLEMENTED; @@ -313,22 +311,35 @@ length); ret = ((res < 0) ? -errno : 0); #endif return ret; }*/ -auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat, - bool &directory, - const remote::file_handle &handle) +auto remote_server::fuse_fgetattr(const char * /* path */, remote::stat &r_stat, + bool &directory, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); r_stat = {}; - auto file_path = construct_path(path); - - auto res = has_open_info(static_cast(handle), EBADF); - if (res == 0) { - directory = utils::file::directory(file_path).exists(); + auto res = -1; + auto file_path = get_open_file_path(static_cast(handle)); + if (file_path.empty()) { + errno = EBADF; + } else { struct stat64 u_stat{}; res = fstat64(static_cast(handle), &u_stat); + if (res == -1 && errno == ESTALE) { + std::uint64_t internal_handle{}; + res = ioctl(static_cast(handle), + repertory_ioctl_fd_command, &internal_handle); + if (res == 0) { + auto err = drive_.get_item_stat(internal_handle, &u_stat); + if (err != api_error::success) { + res = -1; + errno = std::abs(utils::from_api_error(err)); + } + } + } + if (res == 0) { + directory = S_ISDIR(u_stat.st_mode); populate_stat(u_stat, r_stat); } } @@ -340,7 +351,7 @@ auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat, auto remote_server::fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -434,42 +445,34 @@ auto remote_server::fuse_fsetattr_x(const char *path, return ret; } -auto remote_server::fuse_fsync(const char *path, const std::int32_t &datasync, - const remote::file_handle &handle) +auto remote_server::fuse_fsync(const char *path, std::int32_t datasync, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); - auto res = has_open_info(static_cast(handle), EBADF); - if (res == 0) { #if defined(__APPLE__) - res = datasync ? fcntl(static_cast(handle), F_FULLFSYNC) - : fsync(static_cast(handle)); + auto res = datasync ? fcntl(static_cast(handle), F_FULLFSYNC) + : fsync(static_cast(handle)); #else // !defined(__APPLE__) - res = datasync ? fdatasync(static_cast(handle)) - : fsync(static_cast(handle)); + auto res = datasync ? fdatasync(static_cast(handle)) + : fsync(static_cast(handle)); #endif // defined(__APPLE__) - } auto ret = ((res < 0) ? -errno : 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); return ret; } -auto remote_server::fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) +auto remote_server::fuse_ftruncate(const char *path, remote::file_offset size, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); - - auto res = has_open_info(static_cast(handle), EBADF); - if (res == 0) { - res = - ftruncate(static_cast(handle), static_cast(size)); - } + auto res = + ftruncate(static_cast(handle), static_cast(size)); auto ret = ((res < 0) ? -errno : 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); @@ -482,15 +485,13 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat, auto api_path = utils::path::create_api_path(path); auto file_path = construct_path(api_path); - auto parent_api_path = utils::path::get_parent_api_path(api_path); r_stat = {}; - directory = utils::file::directory(file_path).exists(); - struct stat64 u_stat{}; auto res = stat64(file_path.c_str(), &u_stat); if (res == 0) { + directory = S_ISDIR(u_stat.st_mode); populate_stat(u_stat, r_stat); } @@ -500,7 +501,7 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat, } /*packet::error_type remote_server::fuse_getxattr(const char *path, const char -*name, char *value, const remote::file_size &size) { const auto api_path = +*name, char *value, remote::file_size size) { const auto api_path = utils::path::create_api_path(path); const auto file_path = ConstructPath(api_path); const auto parentApiPath = utils::path::get_parent_api_path(api_path); @@ -542,7 +543,7 @@ filePath, ret); return ret; } packet::error_type remote_server::fuse_getxattrOSX(const char *path, const char -*name, char *value, const remote::file_size &size, std::uint32_t position) { +*name, char *value, remote::file_size size, std::uint32_t position) { const auto file_path = ConstructPath(path); #if defined(__APPLE__) && defined(HAS_SETXATTR) // TODO: CheckParentAccess(api_path, X_OK) @@ -594,7 +595,7 @@ auto remote_server::fuse_init() -> packet::error_type { } /*packet::error_type remote_server::fuse_listxattr(const char *path, char -*buffer, const remote::file_size &size) { const auto file_path = +*buffer, remote::file_size size) { const auto file_path = ConstructPath(path); #if defined(HAS_SETXATTR) #if defined(__APPLE__) const auto res = listxattr(file_path.c_str(), buffer, size, FSOPT_NOFOLLOW); #else const auto res = listxattr(file_path.c_str(), buffer, size); #endif auto ret = ((res < @@ -603,7 +604,7 @@ auto res = listxattr(file_path.c_str(), buffer, size); #endif auto ret = ((res < return ret; }*/ -auto remote_server::fuse_mkdir(const char *path, const remote::file_mode &mode) +auto remote_server::fuse_mkdir(const char *path, remote::file_mode mode) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -625,12 +626,13 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags, if (res >= 0) { handle = static_cast(res); set_open_info(res, open_info{ - "", - nullptr, - {}, - file_path, + .client_id = "", + .directory_buffer = nullptr, + .handles = {}, + .path = file_path, }); } + auto ret = ((res < 0) ? -errno : 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); return ret; @@ -662,21 +664,18 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle) } auto remote_server::fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + remote::file_size read_size, + remote::file_offset read_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); auto &data = *reinterpret_cast(buffer); - ssize_t bytes_read{has_open_info(static_cast(handle), EBADF)}; - if (bytes_read == 0) { - data.resize(read_size); - bytes_read = pread64(static_cast(handle), data.data(), - read_size, static_cast(read_offset)); - } + data.resize(read_size); + auto bytes_read = pread64(static_cast(handle), data.data(), + read_size, static_cast(read_offset)); auto ret = ((bytes_read < 0) ? -errno : bytes_read); if (ret < 0) { @@ -699,9 +698,8 @@ auto remote_server::fuse_rename(const char *from, const char *to) return ret; } -auto remote_server::fuse_readdir(const char *path, - const remote::file_offset &offset, - const remote::file_handle &handle, +auto remote_server::fuse_readdir(const char *path, remote::file_offset offset, + remote::file_handle handle, std::string &item_path) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -725,19 +723,15 @@ auto remote_server::fuse_readdir(const char *path, return ret; } -auto remote_server::fuse_release(const char *path, - const remote::file_handle &handle) +auto remote_server::fuse_release(const char *path, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); packet::error_type ret = 0; auto file_path = construct_path(path); - auto res = has_open_info(static_cast(handle), EBADF); - if (res == 0) { - res = close(static_cast(handle)); - remove_open_info(static_cast(handle)); - } + auto res = close(static_cast(handle)); + remove_open_info(static_cast(handle)); ret = ((res < 0) ? -errno : 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); @@ -745,7 +739,7 @@ auto remote_server::fuse_release(const char *path, } auto remote_server::fuse_releasedir(const char *path, - const remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -792,7 +786,7 @@ auto remote_server::fuse_setattr_x(const char *path, remote::setattr_x &attr) } auto remote_server::fuse_setbkuptime(const char *path, - const remote::file_time &bkuptime) + remote::file_time bkuptime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -812,8 +806,7 @@ auto remote_server::fuse_setbkuptime(const char *path, return ret; } -auto remote_server::fuse_setchgtime(const char *path, - const remote::file_time &chgtime) +auto remote_server::fuse_setchgtime(const char *path, remote::file_time chgtime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -833,8 +826,7 @@ auto remote_server::fuse_setchgtime(const char *path, return ret; } -auto remote_server::fuse_setcrtime(const char *path, - const remote::file_time &crtime) +auto remote_server::fuse_setcrtime(const char *path, remote::file_time crtime) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -862,7 +854,7 @@ auto remote_server::fuse_setvolname(const char *volname) -> packet::error_type { } /*packet::error_type remote_server::fuse_setxattr(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags) { const auto file_path = ConstructPath(path); #if defined(__APPLE__{} || !defined(HAS_SETXATTR) auto ret = STATUS_NOT_IMPLEMENTED; #else const auto res = setxattr(file_path.c_str(), name, value, size, flags); auto ret = ((res < 0) ? @@ -871,7 +863,7 @@ ret); return ret; } packet::error_type remote_server::fuse_setxattrOSX(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags, const std::uint32_t &position) { const auto file_path = ConstructPath(path); #if defined(__APPLE__) && defined(HAS_SETXATTR) const auto res = setxattr(file_path.c_str(), name, value, size, position, flags); auto ret @@ -926,8 +918,7 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize, return 0; } -auto remote_server::fuse_truncate(const char *path, - const remote::file_offset &size) +auto remote_server::fuse_truncate(const char *path, remote::file_offset size) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -955,10 +946,10 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv, auto file_path = construct_path(path); - struct timespec tv2[2] = {{0, 0}}; - const auto process_timespec = [](auto op, const auto &src, auto &dst) { - if ((op == UTIME_NOW) || (op == UTIME_OMIT)) { - dst.tv_nsec = static_cast(op); + std::array tv2{}; + const auto process_timespec = [](auto cur_op, const auto &src, auto &dst) { + if ((cur_op == UTIME_NOW) || (cur_op == UTIME_OMIT)) { + dst.tv_nsec = static_cast(cur_op); dst.tv_sec = 0; return; } @@ -970,27 +961,23 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv, process_timespec(op0, tv[0U], tv2[0U]); process_timespec(op1, tv[1U], tv2[1U]); - auto res = utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW); + auto res = utimensat(0, file_path.c_str(), tv2.data(), AT_SYMLINK_NOFOLLOW); auto ret = ((res < 0) ? -errno : 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); return ret; } auto remote_server::fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); - ssize_t bytes_written{ - has_open_info(static_cast(handle), EBADF)}; - if (bytes_written == 0) { - bytes_written = pwrite64(static_cast(handle), buffer, - write_size, static_cast(write_offset)); - } + auto bytes_written = pwrite64(static_cast(handle), buffer, + write_size, static_cast(write_offset)); auto ret = ((bytes_written < 0) ? -errno : bytes_written); if (ret < 0) { @@ -1000,11 +987,12 @@ auto remote_server::fuse_write(const char *path, const char *buffer, return static_cast(ret); } -auto remote_server::fuse_write_base64( - const char * /*path*/, const char * /*buffer*/, - const remote::file_size & /*write_size*/, - const remote::file_offset & /*write_offset*/, - const remote::file_handle & /*handle*/) -> packet::error_type { +auto remote_server::fuse_write_base64(const char * /*path*/, + const char * /*buffer*/, + remote::file_size /*write_size*/, + remote::file_offset /*write_offset*/, + remote::file_handle /*handle*/) + -> packet::error_type { // DOES NOTHING return 0; } @@ -1662,9 +1650,11 @@ auto remote_server::json_create_directory_snapshot(const std::string &path, return ret; } -auto remote_server::json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type { +auto remote_server::json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) + -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); int res{-EBADF}; @@ -1693,8 +1683,8 @@ auto remote_server::json_read_directory_snapshot( return ret; } -auto remote_server::json_release_directory_snapshot( - const std::string &path, const remote::file_handle &handle) +auto remote_server::json_release_directory_snapshot(const std::string &path, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); diff --git a/repertory/librepertory/src/drives/remote/remote_open_file_table.cpp b/repertory/librepertory/src/drives/remote/remote_open_file_table.cpp index 83312e3f..9dd5ef94 100644 --- a/repertory/librepertory/src/drives/remote/remote_open_file_table.cpp +++ b/repertory/librepertory/src/drives/remote/remote_open_file_table.cpp @@ -148,7 +148,7 @@ auto remote_open_file_table::has_open_directory(const std::string &client_id, } auto remote_open_file_table::has_compat_open_info( - const remote::file_handle &handle, int error_return) -> int { + remote::file_handle handle, int error_return) -> int { recur_mutex_lock compat_lock(file_mutex_); auto res = compat_handle_lookup_.contains(handle) ? 0 : -1; if (res == -1) { @@ -194,7 +194,7 @@ void remote_open_file_table::remove_all(const std::string &file_path) { } void remote_open_file_table::remove_compat_open_info( - const remote::file_handle &handle) { + remote::file_handle handle) { recur_mutex_lock compat_lock(file_mutex_); if (not compat_handle_lookup_.contains(handle)) { return; @@ -273,7 +273,7 @@ void remote_open_file_table::remove_and_close_all(const native_handle &handle) { } void remote_open_file_table::set_compat_client_id( - const remote::file_handle &handle, const std::string &client_id) { + remote::file_handle handle, const std::string &client_id) { recur_mutex_lock compat_lock(file_mutex_); compat_file_lookup_.at(compat_handle_lookup_.at(handle))->client_id = client_id; @@ -286,7 +286,7 @@ void remote_open_file_table::set_client_id(const native_handle &handle, } void remote_open_file_table::set_compat_open_info( - const remote::file_handle &handle, const std::string &file_path) { + remote::file_handle handle, const std::string &file_path) { recur_mutex_lock compat_lock(file_mutex_); if (compat_handle_lookup_.contains(handle)) { return; diff --git a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp index e4a3dbd2..f9051899 100644 --- a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp +++ b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp @@ -74,7 +74,7 @@ auto remote_client::json_create_directory_snapshot(const std::string &path, } auto remote_client::json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, + const std::string &path, remote::file_handle handle, std::uint32_t page, json &json_data) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -96,7 +96,7 @@ auto remote_client::json_read_directory_snapshot( } auto remote_client::json_release_directory_snapshot( - const std::string &path, const remote::file_handle &handle) + const std::string &path, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); diff --git a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp index da718eba..916d8ea5 100644 --- a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp +++ b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp @@ -97,7 +97,7 @@ void remote_server::populate_stat(const char *path, bool directory, } // FUSE Layer -auto remote_server::fuse_access(const char *path, const std::int32_t &mask) +auto remote_server::fuse_access(const char *path, std::int32_t mask) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -132,7 +132,7 @@ auto remote_server::fuse_chflags(const char *path, std::uint32_t /*flags*/) } auto remote_server::fuse_chmod(const char *path, - const remote::file_mode & /*mode*/) + remote::file_mode /*mode*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -143,8 +143,8 @@ auto remote_server::fuse_chmod(const char *path, } auto remote_server::fuse_chown(const char *path, - const remote::user_id & /*uid*/, - const remote::group_id & /*gid*/) + remote::user_id /*uid*/, + remote::group_id /*gid*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -162,8 +162,8 @@ auto remote_server::fuse_destroy() -> packet::error_type { } /*packet::error_type remote_server::fuse_fallocate(const char *path, const -std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset -&length, const remote::file_handle &handle) { auto file_path = +std::int32_t &mode, remote::file_offset offset, const remote::file_offset +&length, remote::file_handle handle) { auto file_path = construct_path(path); auto res = HasOpenFileCompatInfo(handle, EBADF); if (res == 0) { res = _chsize_s(static_cast(handle), offset + length); } @@ -174,8 +174,7 @@ construct_path(path); auto res = HasOpenFileCompatInfo(handle, EBADF); if (res }*/ auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat, - bool &directory, - const remote::file_handle &handle) + bool &directory, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -202,7 +201,7 @@ auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat, auto remote_server::fuse_fsetattr_x(const char *path, const remote::setattr_x & /*attr*/, - const remote::file_handle & /*handle*/) + remote::file_handle /*handle*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -213,8 +212,8 @@ auto remote_server::fuse_fsetattr_x(const char *path, } auto remote_server::fuse_fsync(const char *path, - const std::int32_t & /*datasync*/, - const remote::file_handle &handle) + std::int32_t /*datasync*/, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -243,8 +242,8 @@ auto remote_server::fuse_fsync(const char *path, } auto remote_server::fuse_ftruncate(const char *path, - const remote::file_offset &size, - const remote::file_handle &handle) + remote::file_offset size, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -299,13 +298,13 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat, } /*packet::error_type remote_server::fuse_getxattr(const char *path, const char -*name, char *value, const remote::file_size &size) { auto file_path = +*name, char *value, remote::file_size size) { auto file_path = construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); return ret; } packet::error_type remote_server::fuse_getxattr_osx(const char *path, const char -*name, char *value, const remote::file_size &size, std::uint32_t position) { +*name, char *value, remote::file_size size, std::uint32_t position) { auto file_path = construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); return ret; @@ -331,14 +330,14 @@ auto remote_server::fuse_init() -> packet::error_type { } /*packet::error_type remote_server::fuse_listxattr(const char *path, char -*buffer, const remote::file_size &size) { auto file_path = +*buffer, remote::file_size size) { auto file_path = construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); return ret; }*/ auto remote_server::fuse_mkdir(const char *path, - const remote::file_mode & /*mode*/) + remote::file_mode /*mode*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -351,7 +350,7 @@ auto remote_server::fuse_mkdir(const char *path, return ret; } -auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle) +auto remote_server::fuse_opendir(const char *path, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -376,9 +375,9 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle) return ret; } -auto remote_server::fuse_create(const char *path, const remote::file_mode &mode, +auto remote_server::fuse_create(const char *path, remote::file_mode mode, const remote::open_flags &flags, - remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -415,7 +414,7 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode, } auto remote_server::fuse_open(const char *path, const remote::open_flags &flags, - remote::file_handle &handle) + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -446,9 +445,9 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags, } auto remote_server::fuse_read(const char *path, char *buffer, - const remote::file_size &read_size, - const remote::file_offset &read_offset, - const remote::file_handle &handle) + remote::file_size read_size, + remote::file_offset read_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -497,9 +496,9 @@ auto remote_server::fuse_rename(const char *from, const char *to) } auto remote_server::fuse_write(const char *path, const char *buffer, - const remote::file_size &write_size, - const remote::file_offset &write_offset, - const remote::file_handle &handle) + remote::file_size write_size, + remote::file_offset write_offset, + remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -534,16 +533,16 @@ auto remote_server::fuse_write(const char *path, const char *buffer, auto remote_server::fuse_write_base64( const char * /*path*/, const char * /*buffer*/, - const remote::file_size & /*write_size*/, - const remote::file_offset & /*write_offset*/, - const remote::file_handle & /*handle*/) -> packet::error_type { + remote::file_size /*write_size*/, + remote::file_offset /*write_offset*/, + remote::file_handle /*handle*/) -> packet::error_type { // DOES NOTHING return 0; } auto remote_server::fuse_readdir(const char *path, - const remote::file_offset &offset, - const remote::file_handle &handle, + remote::file_offset offset, + remote::file_handle handle, std::string &item_path) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -567,8 +566,7 @@ auto remote_server::fuse_readdir(const char *path, return ret; } -auto remote_server::fuse_release(const char *path, - const remote::file_handle &handle) +auto remote_server::fuse_release(const char *path, remote::file_handle handle) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -585,7 +583,7 @@ auto remote_server::fuse_release(const char *path, } auto remote_server::fuse_releasedir(const char *path, - const remote::file_handle & /*handle*/) + remote::file_handle /*handle*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -625,7 +623,7 @@ auto remote_server::fuse_setattr_x(const char *path, } auto remote_server::fuse_setbkuptime(const char *path, - const remote::file_time & /*bkuptime*/) + remote::file_time /*bkuptime*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -636,7 +634,7 @@ auto remote_server::fuse_setbkuptime(const char *path, } auto remote_server::fuse_setchgtime(const char *path, - const remote::file_time & /*chgtime*/) + remote::file_time /*chgtime*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -647,7 +645,7 @@ auto remote_server::fuse_setchgtime(const char *path, } auto remote_server::fuse_setcrtime(const char *path, - const remote::file_time & /*crtime*/) + remote::file_time /*crtime*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -665,14 +663,14 @@ auto remote_server::fuse_setvolname(const char *volname) -> packet::error_type { } /*packet::error_type remote_server::fuse_setxattr(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags) { auto file_path = construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); return ret; } packet::error_type remote_server::fuse_setxattr_osx(const char *path, const char -*name, const char *value, const remote::file_size &size, const std::int32_t +*name, const char *value, remote::file_size size, const std::int32_t &flags, const std::uint32_t &position) { auto file_path = construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); @@ -728,7 +726,7 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize, } auto remote_server::fuse_truncate(const char *path, - const remote::file_offset &size) + remote::file_offset size) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); @@ -865,9 +863,11 @@ auto remote_server::json_create_directory_snapshot(const std::string &path, return ret; } -auto remote_server::json_read_directory_snapshot( - const std::string &path, const remote::file_handle &handle, - std::uint32_t page, json &json_data) -> packet::error_type { +auto remote_server::json_read_directory_snapshot(const std::string &path, + remote::file_handle handle, + std::uint32_t page, + json &json_data) + -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); auto file_path = construct_path(path); @@ -897,7 +897,7 @@ auto remote_server::json_read_directory_snapshot( } auto remote_server::json_release_directory_snapshot( - const std::string &path, const remote::file_handle & /*handle*/) + const std::string &path, remote::file_handle /*handle*/) -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); diff --git a/repertory/librepertory/src/file_manager/file_manager.cpp b/repertory/librepertory/src/file_manager/file_manager.cpp index 410d1810..7d154ebc 100644 --- a/repertory/librepertory/src/file_manager/file_manager.cpp +++ b/repertory/librepertory/src/file_manager/file_manager.cpp @@ -77,8 +77,10 @@ file_manager::~file_manager() { } void file_manager::close(std::uint64_t handle) { + REPERTORY_USES_FUNCTION_NAME(); + unique_recur_mutex_lock file_lock(open_file_mtx_); - bool is_closed{false}; + bool is_closed{}; auto closeable_file = get_open_file_by_handle(handle, is_closed); if (not closeable_file) { return; @@ -88,7 +90,7 @@ void file_manager::close(std::uint64_t handle) { closeable_file->remove(handle); file_lock.lock(); - if (not(is_closed && closeable_file->get_open_file_count() == 0U)) { + if (not is_closed || closeable_file->get_open_file_count() != 0U) { return; } @@ -307,17 +309,23 @@ auto file_manager::get_next_handle() -> std::uint64_t { return next_handle_; } -auto file_manager::get_open_file_by_handle(std::uint64_t handle) const +auto file_manager::get_open_file_by_handle(std::uint64_t handle, + bool &is_closed) const -> std::shared_ptr { + REPERTORY_USES_FUNCTION_NAME(); + { auto file_iter = std::ranges::find_if( closed_file_lookup_, [&handle](auto &&item) -> bool { return item.second->has_handle(handle); }); - return (file_iter == closed_file_lookup_.end()) ? nullptr - : file_iter->second; + if (file_iter != closed_file_lookup_.end()) { + is_closed = true; + return file_iter->second; + } } + is_closed = false; auto file_iter = std::ranges::find_if(open_file_lookup_, [&handle](auto &&item) -> bool { return item.second->has_handle(handle); @@ -333,14 +341,33 @@ auto file_manager::get_open_file_count(const std::string &api_path) const : file_iter->second->get_open_file_count(); } +auto file_manager::get_open_file(const std::string &api_path, + std::shared_ptr &file) -> bool { + unique_recur_mutex_lock open_lock(open_file_mtx_); + if (open_file_lookup_.contains(api_path)) { + file = open_file_lookup_.at(api_path); + return true; + } + + if (closed_file_lookup_.contains(api_path)) { + file = closed_file_lookup_.at(api_path); + return true; + } + + return false; +} + auto file_manager::get_open_file(std::uint64_t handle, bool write_supported, std::shared_ptr &file) -> bool { + REPERTORY_USES_FUNCTION_NAME(); + if (write_supported && provider_.is_read_only()) { return false; } unique_recur_mutex_lock open_lock(open_file_mtx_); - auto file_ptr = get_open_file_by_handle(handle); + bool is_closed{}; + auto file_ptr = get_open_file_by_handle(handle, is_closed); if (not file_ptr) { return false; } @@ -353,7 +380,13 @@ auto file_manager::get_open_file(std::uint64_t handle, bool write_supported, : 0U, file_ptr->get_filesystem_item(), file_ptr->get_open_data(), provider_, *this); - open_file_lookup_[file_ptr->get_api_path()] = writeable_file; + writeable_file->set_unlinked(is_closed); + if (is_closed) { + writeable_file->set_unlinked_meta(file_ptr->get_unlinked_meta()); + closed_file_lookup_[file_ptr->get_api_path()] = writeable_file; + } else { + open_file_lookup_[file_ptr->get_api_path()] = writeable_file; + } file = writeable_file; return true; } @@ -428,7 +461,7 @@ auto file_manager::handle_file_rename(const std::string &from_api_path, auto ret = provider_.rename_file(from_api_path, to_api_path); if (ret != api_error::success) { - queue_upload(from_api_path, source_path, false); + queue_upload(from_api_path, source_path, false, false); return ret; } @@ -439,7 +472,7 @@ auto file_manager::handle_file_rename(const std::string &from_api_path, : provider_.set_item_meta(to_api_path, META_SOURCE, source_path); if (should_upload) { - queue_upload(to_api_path, source_path, false); + queue_upload(to_api_path, source_path, false, false); } return ret; @@ -497,7 +530,7 @@ auto file_manager::open(const std::string &api_path, bool directory, const auto create_and_add_handle = [&](std::shared_ptr cur_file) { handle = get_next_handle(); - cur_file->add(handle, ofd); + cur_file->add(handle, ofd, true); file = cur_file; }; @@ -626,14 +659,16 @@ auto file_manager::open(const std::string &api_path, bool directory, } void file_manager::queue_upload(const i_open_file &file) { - queue_upload(file.get_api_path(), file.get_source_path(), false); + queue_upload(file.get_api_path(), file.get_source_path(), file.is_unlinked(), + false); } void file_manager::queue_upload(const std::string &api_path, - const std::string &source_path, bool no_lock) { + const std::string &source_path, + bool is_unlinked, bool no_lock) { REPERTORY_USES_FUNCTION_NAME(); - if (provider_.is_read_only() || file.is_removed()) { + if (provider_.is_read_only() || is_unlinked) { return; } @@ -670,6 +705,12 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error { return res; } + api_meta_map meta{}; + res = provider_.get_item_meta(api_path, meta); + if (res != api_error::success) { + return res; + } + unique_recur_mutex_lock open_lock(open_file_mtx_); unique_mutex_lock upload_lock(upload_mtx_); @@ -685,30 +726,38 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error { auto file_iter = open_file_lookup_.find(api_path); if (file_iter == open_file_lookup_.end()) { + remove_source_and_shrink_cache(api_path, fsi.source_path, fsi.size, true); return api_error::success; } if (closed_file_lookup_.contains(api_path)) { - auto closed_file = closed_file_lookup_.at(api_path).second; - closed_file_lookup_[api_path] = file_iter.second; + auto closed_file = closed_file_lookup_.at(api_path); + closed_file_lookup_[api_path] = file_iter->second; for (auto &[handle, ofd] : closed_file->get_open_data()) { - closed_file_lookup_.at(api_path).add(handle, ofd); + closed_file_lookup_.at(api_path)->add(handle, ofd, false); } } else { - closed_file_lookup_[api_path] = file_iter.second; + closed_file_lookup_[api_path] = file_iter->second; } open_file_lookup_.erase(api_path); - auto closed_file = closed_file_lookup_.at(api_path).second; + auto closed_file = closed_file_lookup_.at(api_path); + auto allocated = closed_file->get_allocated(); closed_file->set_unlinked(true); + closed_file->set_unlinked_meta(meta); open_lock.unlock(); + if (not allocated) { + return api_error::success; + } + res = cache_size_mgr::instance().shrink(closed_file->get_file_size()); if (res != api_error::success) { - utils::error::raise_api_path_error(function_name, api_path, source_path, - res, "failed to shrink cache"); + utils::error::raise_api_path_error(function_name, api_path, + closed_file->get_source_path(), res, + "failed to shrink cache"); } return api_error::success; @@ -996,7 +1045,7 @@ void file_manager::start() { } for (const auto &entry : mgr_db_->get_upload_active_list()) { - queue_upload(entry.api_path, entry.source_path, false); + queue_upload(entry.api_path, entry.source_path, false, false); } for (const auto &entry : get_stored_downloads()) { @@ -1116,7 +1165,7 @@ void file_manager::stop() { void file_manager::store_resume(const i_open_file &file) { REPERTORY_USES_FUNCTION_NAME(); - if (provider_.is_read_only() || file.is_removed()) { + if (provider_.is_read_only() || file.is_unlinked()) { return; } @@ -1187,7 +1236,7 @@ void file_manager::upload_completed(const file_upload_completed &evt) { event_system::instance().raise( evt.api_path, evt.error, function_name, evt.source_path); - queue_upload(evt.api_path, evt.source_path, true); + queue_upload(evt.api_path, evt.source_path, false, true); upload_notify_.wait_for(upload_lock, queue_wait_secs); } } @@ -1242,7 +1291,7 @@ void file_manager::upload_handler() { default: { event_system::instance().raise( entry->api_path, res, function_name, entry->source_path); - queue_upload(entry->api_path, entry->source_path, true); + queue_upload(entry->api_path, entry->source_path, false, true); } break; } } diff --git a/repertory/librepertory/src/file_manager/open_file.cpp b/repertory/librepertory/src/file_manager/open_file.cpp index 93312a47..beaea559 100644 --- a/repertory/librepertory/src/file_manager/open_file.cpp +++ b/repertory/librepertory/src/file_manager/open_file.cpp @@ -538,8 +538,15 @@ auto open_file::native_operation( set_file_size(new_file_size); auto now = std::to_string(utils::time::get_time_now()); + if (is_unlinked()) { - return api_error::success: + auto meta = get_unlinked_meta(); + meta[META_CHANGED] = now; + meta[META_MODIFIED] = now; + meta[META_SIZE] = std::to_string(new_file_size); + meta[META_WRITTEN] = now; + set_unlinked_meta(meta); + return api_error::success; } res = get_provider().set_item_meta( @@ -780,11 +787,18 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, return set_api_error(res); } + auto now = std::to_string(utils::time::get_time_now()); if (is_unlinked()) { - return api_error::success: + auto meta = get_unlinked_meta(); + meta[META_CHANGED] = now; + meta[META_MODIFIED] = now; + meta[META_WRITTEN] = now; + set_unlinked_meta(meta); + set_modified(); + + return api_error::success; } - auto now = std::to_string(utils::time::get_time_now()); res = get_provider().set_item_meta(get_api_path(), { {META_CHANGED, now}, {META_MODIFIED, now}, diff --git a/repertory/librepertory/src/file_manager/open_file_base.cpp b/repertory/librepertory/src/file_manager/open_file_base.cpp index 9ffba852..7aa90fd2 100644 --- a/repertory/librepertory/src/file_manager/open_file_base.cpp +++ b/repertory/librepertory/src/file_manager/open_file_base.cpp @@ -92,11 +92,16 @@ open_file_base::open_file_base( } } -void open_file_base::add(std::uint64_t handle, open_file_data ofd) { +void open_file_base::add(std::uint64_t handle, open_file_data ofd, + bool notify) { REPERTORY_USES_FUNCTION_NAME(); recur_mutex_lock file_lock(file_mtx_); open_data_[handle] = ofd; + if (not notify) { + return; + } + if (open_data_.size() == 1U) { event_system::instance().raise( fsi_.api_path, fsi_.directory, function_name, fsi_.source_path); @@ -249,6 +254,11 @@ void open_file_base::set_unlinked(bool value) { unlinked_ = value; } +void open_file_base::set_unlinked_meta(api_meta_map meta) { + recur_mutex_lock file_lock(file_mtx_); + unlinked_meta_ = std::move(meta); +} + auto open_file_base::get_filesystem_item() const -> filesystem_item { recur_mutex_lock file_lock(file_mtx_); return fsi_; @@ -298,9 +308,14 @@ auto open_file_base::get_source_path() const -> std::string { return fsi_.source_path; } +auto open_file_base::get_unlinked_meta() const -> api_meta_map { + recur_mutex_lock file_lock(file_mtx_); + return unlinked_meta_; +} + auto open_file_base::has_handle(std::uint64_t handle) const -> bool { recur_mutex_lock file_lock(file_mtx_); - return open_data_.find(handle) != open_data_.end(); + return open_data_.contains(handle); } auto open_file_base::is_modified() const -> bool { @@ -327,7 +342,7 @@ void open_file_base::remove(std::uint64_t handle) { REPERTORY_USES_FUNCTION_NAME(); recur_mutex_lock file_lock(file_mtx_); - if (open_data_.find(handle) == open_data_.end()) { + if (not open_data_.contains(handle)) { return; } diff --git a/repertory/librepertory/src/types/repertory.cpp b/repertory/librepertory/src/types/repertory.cpp index 676cc803..895529c4 100644 --- a/repertory/librepertory/src/types/repertory.cpp +++ b/repertory/librepertory/src/types/repertory.cpp @@ -210,9 +210,11 @@ static const std::unordered_map LOOKUP = { {api_error::no_disk_space, "no_disk_space"}, {api_error::not_implemented, "not_implemented"}, {api_error::not_supported, "not_supported"}, + {api_error::no_tty, "no_tty"}, {api_error::os_error, "os_error"}, {api_error::out_of_memory, "out_of_memory"}, {api_error::permission_denied, "permission_denied"}, + {api_error::stale_descriptor, "stale_descriptor"}, {api_error::upload_failed, "upload_failed"}, {api_error::xattr_buffer_small, "xattr_buffer_small"}, {api_error::xattr_exists, "xattr_exists"}, diff --git a/repertory/librepertory/src/utils/unix/unix_utils.cpp b/repertory/librepertory/src/utils/unix/unix_utils.cpp index 1b7f8b57..16230dfe 100644 --- a/repertory/librepertory/src/utils/unix/unix_utils.cpp +++ b/repertory/librepertory/src/utils/unix/unix_utils.cpp @@ -76,6 +76,10 @@ auto from_api_error(api_error err) -> int { return -ENOTSUP; case api_error::not_implemented: return -ENOSYS; + case api_error::no_tty: + return -ENOTTY; + case api_error::stale_descriptor: + return -ESTALE; case api_error::upload_failed: return -ENETDOWN; case api_error::xattr_buffer_small: @@ -144,6 +148,10 @@ auto to_api_error(int err) -> api_error { return api_error::not_supported; case ENOSYS: return api_error::not_implemented; + case ESTALE: + return api_error::stale_descriptor; + case ENOTTY: + return api_error::no_tty; case ENETDOWN: return api_error::upload_failed; case ERANGE: @@ -176,6 +184,8 @@ auto unix_error_to_windows(int err) -> std::uint32_t { case EACCES: case EPERM: return STATUS_ACCESS_DENIED; + case ESTALE: + return STATUS_INVALID_HANDLE; case EBADF: return STATUS_INVALID_HANDLE; case EBUSY: @@ -209,9 +219,8 @@ auto unix_error_to_windows(int err) -> std::uint32_t { } } -void windows_create_to_unix(const UINT32 &create_options, - const UINT32 &granted_access, std::uint32_t &flags, - remote::file_mode &mode) { +void windows_create_to_unix(UINT32 create_options, UINT32 granted_access, + std::uint32_t &flags, remote::file_mode &mode) { mode = S_IRUSR | S_IWUSR; flags = O_CREAT | O_RDWR; if ((create_options & FILE_DIRECTORY_FILE) != 0U) { diff --git a/repertory/librepertory/src/utils/windows/windows_utils.cpp b/repertory/librepertory/src/utils/windows/windows_utils.cpp index 673ee58d..6f533d62 100644 --- a/repertory/librepertory/src/utils/windows/windows_utils.cpp +++ b/repertory/librepertory/src/utils/windows/windows_utils.cpp @@ -119,7 +119,7 @@ auto unix_access_mask_to_windows(std::int32_t mask) -> int { return mask & 6; } -auto unix_open_flags_to_flags_and_perms(const remote::file_mode & /*mode*/, +auto unix_open_flags_to_flags_and_perms(remote::file_mode /*mode*/, const remote::open_flags &flags, std::int32_t &perms) -> int { auto ret = _O_BINARY | _O_RANDOM; diff --git a/repertory/repertory_test/include/mocks/mock_open_file.hpp b/repertory/repertory_test/include/mocks/mock_open_file.hpp index dba74fa7..f65d78be 100644 --- a/repertory/repertory_test/include/mocks/mock_open_file.hpp +++ b/repertory/repertory_test/include/mocks/mock_open_file.hpp @@ -29,7 +29,8 @@ namespace repertory { class mock_open_file : public virtual i_closeable_open_file { public: - MOCK_METHOD(void, add, (std::uint64_t handle, open_file_data ofd), + MOCK_METHOD(void, add, + (std::uint64_t handle, open_file_data ofd, bool notify), (override)); MOCK_METHOD(bool, can_close, (), (const, override)); @@ -70,6 +71,8 @@ public: MOCK_METHOD(std::string, get_source_path, (), (const, override)); + MOCK_METHOD(api_meta_map, get_unlinked_meta, (), (const, override)); + MOCK_METHOD(bool, has_handle, (std::uint64_t handle), (const, override)); MOCK_METHOD(bool, is_complete, (), (const, override)); @@ -78,6 +81,8 @@ public: MOCK_METHOD(bool, is_modified, (), (const, override)); + MOCK_METHOD(bool, is_unlinked, (), (const, override)); + MOCK_METHOD(bool, is_write_supported, (), (const, override)); MOCK_METHOD(api_error, native_operation, (native_operation_callback callback), @@ -100,6 +105,10 @@ public: MOCK_METHOD(void, set_api_path, (const std::string &api_path), (override)); + MOCK_METHOD(void, set_unlinked, (bool value), (override)); + + MOCK_METHOD(void, set_unlinked_meta, (api_meta_map meta), (override)); + MOCK_METHOD(api_error, write, (std::uint64_t write_offset, const data_buffer &data, std::size_t &bytes_written), diff --git a/repertory/repertory_test/src/file_manager_test.cpp b/repertory/repertory_test/src/file_manager_test.cpp index eb0f7024..0fc252e4 100644 --- a/repertory/repertory_test/src/file_manager_test.cpp +++ b/repertory/repertory_test/src/file_manager_test.cpp @@ -92,6 +92,8 @@ std::atomic file_manager_test::inst{0U}; TEST_F(file_manager_test, can_start_and_stop) { EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); event_consumer consumer(service_start_begin::name, [](const i_event &evt) { const auto &evt2 = dynamic_cast(evt); @@ -128,6 +130,8 @@ TEST_F(file_manager_test, can_create_and_close_file) { cfg->set_enable_download_timeout(true); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); polling::instance().start(cfg.get()); @@ -233,6 +237,8 @@ TEST_F(file_manager_test, can_open_and_close_file) { cfg->set_enable_download_timeout(true); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); polling::instance().start(cfg.get()); @@ -335,6 +341,8 @@ TEST_F(file_manager_test, can_open_and_close_file) { TEST_F(file_manager_test, can_open_and_close_multiple_handles_for_same_file) { EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); polling::instance().start(cfg.get()); @@ -398,6 +406,9 @@ TEST_F(file_manager_test, can_open_and_close_multiple_handles_for_same_file) { TEST_F(file_manager_test, download_is_stored_after_write_if_partially_downloaded) { EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .Times(2) + .WillRepeatedly(Return(std::vector())); file_manager mgr(*cfg, mp); mgr.start(); @@ -549,6 +560,8 @@ TEST_F(file_manager_test, upload_occurs_after_write_if_fully_downloaded) { cfg->set_enable_download_timeout(true); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); polling::instance().start(cfg.get()); @@ -664,6 +677,8 @@ TEST_F(file_manager_test, upload_occurs_after_write_if_fully_downloaded) { TEST_F(file_manager_test, can_evict_file) { EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); file_manager mgr(*cfg, mp); mgr.start(); @@ -855,6 +870,8 @@ TEST_F(file_manager_test, evict_file_fails_if_source_path_is_empty) { TEST_F(file_manager_test, evict_file_fails_if_file_is_uploading) { EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); file_manager mgr(*cfg, mp); mgr.start(); @@ -946,6 +963,7 @@ TEST_F(file_manager_test, evict_file_fails_if_file_is_in_upload_queue) { file_manager mgr(*cfg, mp); mock_open_file open_file{}; + EXPECT_CALL(open_file, is_unlinked).WillRepeatedly(Return(false)); EXPECT_CALL(open_file, is_directory).WillRepeatedly(Return(false)); EXPECT_CALL(open_file, get_api_path) .WillRepeatedly(Return("/test_evict.txt")); @@ -981,6 +999,7 @@ TEST_F(file_manager_test, evict_file_fails_if_file_is_modified) { EXPECT_CALL(*file, get_source_path).WillRepeatedly(Return("/test_evict.src")); EXPECT_CALL(*file, is_directory).WillOnce(Return(false)); EXPECT_CALL(*file, is_modified).WillRepeatedly(Return(true)); + EXPECT_CALL(*file, is_unlinked).WillRepeatedly(Return(false)); EXPECT_CALL(*file, is_write_supported).WillRepeatedly(Return(true)); std::uint64_t handle{}; @@ -1392,6 +1411,26 @@ TEST_F(file_manager_test, can_remove_file) { } EXPECT_TRUE(utils::file::file("./test_remove.txt").exists()); + api_file api_f{ + .api_path = "/test_remove.txt", + .api_parent = "/", + .accessed_date = 0, + .changed_date = 0, + .creation_date = 0, + .file_size = 0, + .key = "", + .modified_date = 0, + .source_path = "", + }; + + EXPECT_CALL(mp, get_item_meta(_, _)) + .WillOnce([&api_f](const std::string &api_path, + api_meta_map &meta) -> api_error { + EXPECT_STREQ("/test_remove.txt", api_path.c_str()); + meta = provider_meta_creator(false, api_f); + return api_error::success; + }); + EXPECT_CALL(mp, get_filesystem_item) .WillOnce([](const std::string &api_path, bool directory, filesystem_item &fsi) -> api_error { @@ -1423,6 +1462,7 @@ TEST_F(file_manager_test, can_queue_and_remove_upload) { file_manager mgr(*cfg, mp); mock_open_file file{}; + EXPECT_CALL(file, is_unlinked).WillOnce(Return(false)); EXPECT_CALL(file, get_api_path).WillOnce(Return("/test_queue.txt")); EXPECT_CALL(file, get_source_path).WillOnce(Return("/test_queue.src")); @@ -1443,6 +1483,8 @@ TEST_F(file_manager_test, file_is_closed_after_download_timeout) { polling::instance().start(cfg.get()); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); file_manager mgr(*cfg, mp); mgr.start(); @@ -1547,6 +1589,7 @@ TEST_F(file_manager_test, remove_file_fails_if_provider_remove_file_fails) { file_manager mgr(*cfg, mp); + EXPECT_CALL(mp, get_item_meta(_, _)).WillOnce(Return(api_error::success)); EXPECT_CALL(mp, get_filesystem_item) .WillOnce([](const std::string &api_path, const bool &directory, filesystem_item &fsi) -> api_error { @@ -1564,11 +1607,34 @@ TEST_F(file_manager_test, remove_file_fails_if_provider_remove_file_fails) { EXPECT_EQ(api_error::item_not_found, mgr.remove_file("/test_remove.txt")); } +TEST_F(file_manager_test, remove_file_fails_if_get_item_meta_fails) { + EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + + file_manager mgr(*cfg, mp); + + EXPECT_CALL(mp, get_item_meta(_, _)).WillOnce(Return(api_error::error)); + EXPECT_CALL(mp, get_filesystem_item) + .WillOnce([](const std::string &api_path, const bool &directory, + filesystem_item &fsi) -> api_error { + EXPECT_STREQ("/test_remove.txt", api_path.c_str()); + EXPECT_FALSE(directory); + fsi.api_path = api_path; + fsi.api_parent = utils::path::get_parent_api_path(api_path); + fsi.directory = directory; + fsi.size = 0U; + return api_error::success; + }); + + EXPECT_EQ(api_error::error, mgr.remove_file("/test_remove.txt")); +} + TEST_F(file_manager_test, resize_greater_than_chunk_size_sets_new_chunks_to_read) { cfg->set_enable_download_timeout(true); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); + EXPECT_CALL(mp, get_pinned_files()) + .WillOnce(Return(std::vector())); polling::instance().start(cfg.get()); diff --git a/repertory/repertory_test/src/fuse_drive_unlink_test.cpp b/repertory/repertory_test/src/fuse_drive_unlink_test.cpp index 24d3b0e2..6818b543 100644 --- a/repertory/repertory_test/src/fuse_drive_unlink_test.cpp +++ b/repertory/repertory_test/src/fuse_drive_unlink_test.cpp @@ -39,10 +39,10 @@ TYPED_TEST(fuse_test, unlink_can_remove_file) { TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) { std::string name{"unlink"}; - auto path = this->create_file_and_test(name, 0644); + auto path = this->create_file_and_test(name); { - auto desc = ::open(path.c_str(), O_WRONLY); + auto desc = ::open(path.c_str(), O_RDWR); ASSERT_NE(desc, -1); this->write_all(desc, "HELLO"); ::close(desc); @@ -53,7 +53,10 @@ TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) { ASSERT_EQ(0, ::unlink(path.c_str())); - ASSERT_NE(-1, ::lseek(desc, 0, SEEK_END)); + auto res = ::lseek(desc, 0, SEEK_END); + fmt::println("lseek|{}|{}", res, errno); + + ASSERT_NE(-1, res); this->write_all(desc, " WORLD"); ASSERT_NE(-1, ::lseek(desc, 0, SEEK_SET)); diff --git a/repertory/repertory_test/src/open_file_test.cpp b/repertory/repertory_test/src/open_file_test.cpp index 49ec415c..80343dc2 100644 --- a/repertory/repertory_test/src/open_file_test.cpp +++ b/repertory/repertory_test/src/open_file_test.cpp @@ -637,10 +637,10 @@ TEST_F(open_file_test, can_add_handle) { open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr); #if defined(_WIN32) - o.add(1u, {}); + o.add(1u, {}, true); EXPECT_EQ(nullptr, o.get_open_data(1u).directory_buffer); #else - o.add(1u, O_RDWR | O_SYNC); + o.add(1u, O_RDWR | O_SYNC, true); EXPECT_EQ(O_RDWR | O_SYNC, o.get_open_data(1u)); #endif @@ -698,9 +698,9 @@ TEST_F(open_file_test, can_remove_handle) { open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr); #if defined(_WIN32) - o.add(1u, {}); + o.add(1u, {}, true); #else - o.add(1u, O_RDWR | O_SYNC); + o.add(1u, O_RDWR | O_SYNC, true); #endif o.remove(1u);