implemented posix-compliant unlink() with fuse hard_remove

This commit is contained in:
2025-09-25 11:23:48 -05:00
parent ed01f3de12
commit b58314c6d3
39 changed files with 814 additions and 565 deletions

View File

@@ -198,6 +198,7 @@ pistream
pkgconfig pkgconfig
plarge_integer plarge_integer
plex plex
posix
println println
project_enable_fontconfig project_enable_fontconfig
project_enable_gtkmm project_enable_gtkmm

View File

@@ -28,7 +28,8 @@
* Added check version support to remote mounts * Added check version support to remote mounts
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux * Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
* Fixed intermittent client hang on remote mount server disconnect * 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 ## v2.0.7-release

View File

@@ -47,7 +47,7 @@ private:
public: public:
#if !defined(_WIN32) #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, fuse_fill_dir_t filler_function, void *buffer,
populate_stat_callback populate_stat) -> int; populate_stat_callback populate_stat) -> int;
#endif // !defined(_WIN32) #endif // !defined(_WIN32)

View File

@@ -159,6 +159,10 @@ private:
[[nodiscard]] static auto init_(struct fuse_conn_info *conn) -> void *; [[nodiscard]] static auto init_(struct fuse_conn_info *conn) -> void *;
#endif // FUSE_USE_VERSION >= 30 #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 mkdir_(const char *path, mode_t mode) -> int;
[[nodiscard]] static auto open_(const char *path, [[nodiscard]] static auto open_(const char *path,
@@ -394,6 +398,13 @@ protected:
virtual auto init_impl(struct fuse_conn_info *conn) -> void *; virtual auto init_impl(struct fuse_conn_info *conn) -> void *;
#endif // FUSE_USE_VERSION >= 30 #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*/, [[nodiscard]] virtual auto mkdir_impl(std::string /*api_path*/,
mode_t /*mode*/) -> api_error { mode_t /*mode*/) -> api_error {
return api_error::not_implemented; return api_error::not_implemented;
@@ -471,14 +482,14 @@ protected:
getxattr_impl(std::string /*api_path*/, const char * /*name*/, getxattr_impl(std::string /*api_path*/, const char * /*name*/,
char * /*value*/, size_t /*size*/, uint32_t /*position*/, char * /*value*/, size_t /*size*/, uint32_t /*position*/,
int & /*attribute_size*/) -> api_error { int & /*attribute_size*/) -> api_error {
return api_error::not_implemented; return api_error::xattr_not_found;
} }
#else // !defined(__APPLE__) #else // !defined(__APPLE__)
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
getxattr_impl(std::string /*api_path*/, const char * /*name*/, getxattr_impl(std::string /*api_path*/, const char * /*name*/,
char * /*value*/, size_t /*size*/, int & /*attribute_size*/) char * /*value*/, size_t /*size*/, int & /*attribute_size*/)
-> api_error { -> api_error {
return api_error::not_implemented; return api_error::xattr_not_found;
} }
#endif // defined(__APPLE__) #endif // defined(__APPLE__)

View File

@@ -150,6 +150,10 @@ protected:
auto init_impl(struct fuse_conn_info *conn) -> void * override; auto init_impl(struct fuse_conn_info *conn) -> void * override;
#endif // FUSE_USE_VERSION >= 30 #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) [[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode)
-> api_error override; -> api_error override;
@@ -307,6 +311,10 @@ public:
std::string &value) const std::string &value) const
-> api_error override; -> 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_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;

View File

@@ -26,6 +26,8 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
inline constexpr const int repertory_ioctl_fd_command = 0x102010;
class i_fuse_drive { class i_fuse_drive {
INTERFACE_SETUP(i_fuse_drive); INTERFACE_SETUP(i_fuse_drive);
@@ -57,6 +59,10 @@ public:
std::string &value) const std::string &value) const
-> api_error = 0; -> 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_drive_space() const -> std::uint64_t = 0;
[[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0;

View File

@@ -30,166 +30,170 @@ class i_remote_instance : public virtual i_remote_json {
INTERFACE_SETUP(i_remote_instance); INTERFACE_SETUP(i_remote_instance);
public: public:
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_access(const char *path, std::int32_t mask)
fuse_access(const char *path, -> packet::error_type = 0;
const 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 [[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 auto fuse_destroy() -> packet::error_type = 0;
/*[[nodiscard]] virtual packet::error_type fuse_fallocate(const char *path, /*[[nodiscard]] virtual packet::error_type fuse_fallocate(const char *path,
const std::int32_t &mode, const remote::file_offset &offset, const std::int32_t mode, remote::file_offset offset, const
remote::file_offset &length, const remote::file_offset &length, const remote::file_offset length, remote::file_offset length, const
remote::file_handle &handle) = 0;*/ remote::file_handle handle) = 0;*/
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, 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 [[nodiscard]] virtual auto fuse_fsetattr_x(const char *path,
fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) -> packet::error_type = 0; remote::file_handle handle)
-> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_fsync(const char *path, std::int32_t datasync,
fuse_fsync(const char *path, const std::int32_t &datasync, remote::file_handle handle)
const remote::file_handle &handle) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_ftruncate(const char *path,
fuse_ftruncate(const char *path, const remote::file_offset &size, remote::file_offset size,
const remote::file_handle &handle) -> packet::error_type = 0; remote::file_handle handle)
-> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_getattr(const char *path,
fuse_getattr(const char *path, remote::stat &r_stat, remote::stat &r_stat, bool &directory)
bool &directory) -> packet::error_type = 0; -> packet::error_type = 0;
/*[[nodiscard]] virtual packet::error_type fuse_getxattr(const char *path, /*[[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, [[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;*/ position) = 0;*/
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_getxtimes(const char *path,
fuse_getxtimes(const char *path, remote::file_time &bkuptime, remote::file_time &bkuptime,
remote::file_time &crtime) -> packet::error_type = 0; remote::file_time &crtime)
-> packet::error_type = 0;
[[nodiscard]] virtual auto fuse_init() -> packet::error_type = 0; [[nodiscard]] virtual auto fuse_init() -> packet::error_type = 0;
[[nodiscard]] /*virtual packet::error_type fuse_listxattr(const char *path, [[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 [[nodiscard]] virtual auto
fuse_mkdir(const char *path, fuse_mkdir(const char *path, remote::file_mode mode)
const remote::file_mode &mode) -> packet::error_type = 0; -> 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 [[nodiscard]] virtual auto
fuse_open(const char *path, const remote::open_flags &flags, fuse_read(const char *path, char *buffer, remote::file_size read_size,
remote::file_handle &handle) -> packet::error_type = 0; remote::file_offset read_offset, remote::file_handle handle)
-> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
fuse_opendir(const char *path, fuse_readdir(const char *path, remote::file_offset offset,
remote::file_handle &handle) -> packet::error_type = 0; remote::file_handle handle, std::string &item_path)
-> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_release(const char *path,
fuse_read(const char *path, char *buffer, const remote::file_size &read_size, remote::file_handle handle)
const remote::file_offset &read_offset, -> packet::error_type = 0;
const remote::file_handle &handle) -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_releasedir(const char *path,
fuse_readdir(const char *path, const remote::file_offset &offset, remote::file_handle handle)
const remote::file_handle &handle, -> packet::error_type = 0;
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 packet::error_type fuse_removexattr(const char *path, //[[nodiscard]] virtual packet::error_type fuse_removexattr(const char *path,
// const char *name) = // const char *name) =
// 0; // 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_rename(const char *from, const char *to)
fuse_rename(const char *from, const char *to) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_rmdir(const char *path)
fuse_rmdir(const char *path) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_setattr_x(const char *path,
fuse_setattr_x(const char *path, remote::setattr_x &attr)
remote::setattr_x &attr) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_setbkuptime(const char *path,
fuse_setbkuptime(const char *path, remote::file_time bkuptime)
const remote::file_time &bkuptime) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_setchgtime(const char *path,
fuse_setchgtime(const char *path, remote::file_time chgtime)
const remote::file_time &chgtime) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_setcrtime(const char *path,
fuse_setcrtime(const char *path, remote::file_time crtime)
const remote::file_time &crtime) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_setvolname(const char *volname)
fuse_setvolname(const char *volname) -> packet::error_type = 0; -> packet::error_type = 0;
/*[[nodiscard]] virtual packet::error_type fuse_setxattr(const char *path, /*[[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; std::int32_t &flags) = 0;
[[nodiscard]] virtual packet::error_type fuse_setxattr_osx(const char *path, [[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;*/ std::int32_t &flags, std::uint32_t position) = 0;*/
[[nodiscard]] virtual auto [[nodiscard]] virtual auto fuse_statfs(const char *path, std::uint64_t frsize,
fuse_statfs(const char *path, std::uint64_t frsize, remote::statfs &r_stat)
remote::statfs &r_stat) -> packet::error_type = 0; -> packet::error_type = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
fuse_statfs_x(const char *path, std::uint64_t bsize, fuse_statfs_x(const char *path, std::uint64_t bsize, remote::statfs_x &r_stat)
remote::statfs_x &r_stat) -> packet::error_type = 0; -> 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 [[nodiscard]] virtual auto
fuse_truncate(const char *path, fuse_write(const char *path, const char *buffer, remote::file_size writeSize,
const remote::file_offset &size) -> packet::error_type = 0; remote::file_offset writeOffset, remote::file_handle handle)
-> packet::error_type = 0;
[[nodiscard]] virtual auto [[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 virtual void set_fuse_uid_gid(remote::user_id uid, remote::group_id gid) = 0;
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;
}; };
using remote_instance_factory = using remote_instance_factory =

View File

@@ -43,43 +43,41 @@ private:
public: public:
[[nodiscard]] auto check() -> packet::error_type; [[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; -> packet::error_type override;
[[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override; -> 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; -> packet::error_type override;
[[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid,
const remote::group_id &gid) remote::group_id gid)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_destroy() -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override;
[[nodiscard]] /*packet::error_type fuse_fallocate(const char *path, const [[nodiscard]] /*packet::error_type fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const std::int32_t &mode, remote::file_offset offset, const
remote::file_offset &length, const remote::file_handle remote::file_offset length, const remote::file_handle
&handle) override ;*/ &handle) override ;*/
[[nodiscard]] auto [[nodiscard]] auto
fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory,
const remote::file_handle &handle) remote::file_handle handle) -> packet::error_type override;
-> packet::error_type override;
[[nodiscard]] auto fuse_fsetattr_x(const char *path, [[nodiscard]] auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_ftruncate(const char *path, [[nodiscard]] auto fuse_ftruncate(const char *path, remote::file_offset size,
const remote::file_offset &size, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat,
@@ -87,10 +85,10 @@ public:
-> packet::error_type override; -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char /*[[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 [[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 ;*/ override ;*/
[[nodiscard]] auto fuse_getxtimes(const char *path, [[nodiscard]] auto fuse_getxtimes(const char *path,
@@ -101,17 +99,17 @@ public:
[[nodiscard]] auto fuse_init() -> packet::error_type override; [[nodiscard]] auto fuse_init() -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_listxattr(const char *path, char /*[[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; -> 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; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto fuse_create(const char *path, remote::file_mode mode,
fuse_create(const char *path, const remote::file_mode &mode, const remote::open_flags &flags,
const remote::open_flags &flags, remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_open(const char *path, [[nodiscard]] auto fuse_open(const char *path,
@@ -119,26 +117,24 @@ public:
remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_read(const char *path, char *buffer, [[nodiscard]] auto
const remote::file_size &read_size, fuse_read(const char *path, char *buffer, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_rename(const char *from, const char *to) [[nodiscard]] auto fuse_rename(const char *from, const char *to)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto fuse_readdir(const char *path, remote::file_offset offset,
fuse_readdir(const char *path, const remote::file_offset &offset, remote::file_handle handle,
const remote::file_handle &handle, std::string &item_path) std::string &item_path)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_release(const char *path, [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_releasedir(const char *path, [[nodiscard]] auto fuse_releasedir(const char *path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const
@@ -152,26 +148,25 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setbkuptime(const char *path, [[nodiscard]] auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime) remote::file_time bkuptime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setchgtime(const char *path, [[nodiscard]] auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime) remote::file_time chgtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setcrtime(const char *path, [[nodiscard]] auto fuse_setcrtime(const char *path, remote::file_time crtime)
const remote::file_time &crtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setvolname(const char *volname) [[nodiscard]] auto fuse_setvolname(const char *volname)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] /*packet::error_type fuse_setxattr(const char *path, const char [[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 ; &flags) override ;
[[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const [[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 ;*/ std::int32_t &flags, std::uint32_t position) override ;*/
[[nodiscard]] auto [[nodiscard]] auto
@@ -182,8 +177,7 @@ public:
remote::statfs_x &r_stat) remote::statfs_x &r_stat)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_truncate(const char *path, [[nodiscard]] auto fuse_truncate(const char *path, remote::file_offset size)
const remote::file_offset &size)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_unlink(const char *path) [[nodiscard]] auto fuse_unlink(const char *path)
@@ -193,33 +187,32 @@ public:
std::uint64_t op0, std::uint64_t op1) std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write(const char *path, const char *buffer, [[nodiscard]] auto
const remote::file_size &write_size, fuse_write(const char *path, const char *buffer, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_create_directory_snapshot(const std::string &path, [[nodiscard]] auto json_create_directory_snapshot(const std::string &path,
json &json_data) json &json_data)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_read_directory_snapshot( [[nodiscard]] auto json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type override; std::uint32_t page,
json &json_data)
[[nodiscard]] auto
json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id &uid, [[nodiscard]] auto json_release_directory_snapshot(const std::string &path,
const remote::group_id &gid) override; 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 remote_fuse
} // namespace repertory } // namespace repertory

View File

@@ -53,8 +53,8 @@ private:
remote::file_info &r_info) remote::file_info &r_info)
-> packet::error_type; -> packet::error_type;
void populate_file_info(const std::string &api_path, const UINT64 &file_size, void populate_file_info(const std::string &api_path, UINT64 file_size,
const UINT32 &attributes, remote::file_info &r_info); UINT32 attributes, remote::file_info &r_info);
static void populate_stat(const struct stat64 &u_stat, remote::stat &r_stat); static void populate_stat(const struct stat64 &u_stat, remote::stat &r_stat);
@@ -63,48 +63,46 @@ private:
public: public:
// FUSE Layer // 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; -> packet::error_type override;
[[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override; -> 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; -> packet::error_type override;
[[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid,
const remote::group_id &gid) remote::group_id gid)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto fuse_create(const char *path, remote::file_mode mode,
fuse_create(const char *path, const remote::file_mode &mode, const remote::open_flags &flags,
const remote::open_flags &flags, remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_destroy() -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_fallocate(const char *path, const /*[[nodiscard]] packet::error_type fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const std::int32_t &mode, remote::file_offset offset, const
remote::file_offset &length, const remote::file_handle &handle) override remote::file_offset length, remote::file_handle handle) override
;*/ ;*/
[[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat,
bool &directory, bool &directory, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_fsetattr_x(const char *path, [[nodiscard]] auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_ftruncate(const char *path, [[nodiscard]] auto fuse_ftruncate(const char *path, remote::file_offset size,
const remote::file_offset &size, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat,
@@ -112,10 +110,10 @@ public:
-> packet::error_type override; -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char /*[[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 [[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 ;*/ override ;*/
[[nodiscard]] auto fuse_getxtimes(const char *path, [[nodiscard]] auto fuse_getxtimes(const char *path,
@@ -126,10 +124,10 @@ public:
[[nodiscard]] auto fuse_init() -> packet::error_type override; [[nodiscard]] auto fuse_init() -> packet::error_type override;
[[nodiscard]] /*packet::error_type fuse_listxattr(const char *path, char [[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 [[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; -> packet::error_type override;
[[nodiscard]] auto fuse_open(const char *path, [[nodiscard]] auto fuse_open(const char *path,
@@ -140,26 +138,24 @@ public:
[[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; -> packet::error_type override;
[[nodiscard]] auto fuse_read(const char *path, char *buffer, [[nodiscard]] auto
const remote::file_size &read_size, fuse_read(const char *path, char *buffer, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_rename(const char *from, const char *to) [[nodiscard]] auto fuse_rename(const char *from, const char *to)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto fuse_readdir(const char *path, remote::file_offset offset,
fuse_readdir(const char *path, const remote::file_offset &offset, remote::file_handle handle,
const remote::file_handle &handle, std::string &item_path) std::string &item_path)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_release(const char *path, [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_releasedir(const char *path, [[nodiscard]] auto fuse_releasedir(const char *path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const
@@ -173,26 +169,25 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setbkuptime(const char *path, [[nodiscard]] auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime) remote::file_time bkuptime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setchgtime(const char *path, [[nodiscard]] auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime) remote::file_time chgtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setcrtime(const char *path, [[nodiscard]] auto fuse_setcrtime(const char *path, remote::file_time crtime)
const remote::file_time &crtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setvolname(const char *volname) [[nodiscard]] auto fuse_setvolname(const char *volname)
-> packet::error_type override; -> packet::error_type override;
/*[[nodiscard]] packet::error_type fuse_setxattr(const char *path, const char /*[[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 ; &flags) override ;
[[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const [[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 ;*/ std::int32_t &flags, std::uint32_t position) override ;*/
[[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize, [[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize,
@@ -203,8 +198,7 @@ public:
remote::statfs_x &r_stat) remote::statfs_x &r_stat)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_truncate(const char *path, [[nodiscard]] auto fuse_truncate(const char *path, remote::file_offset size)
const remote::file_offset &size)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_unlink(const char *path) [[nodiscard]] auto fuse_unlink(const char *path)
@@ -214,20 +208,18 @@ public:
std::uint64_t op0, std::uint64_t op1) std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write(const char *path, const char *buffer, [[nodiscard]] auto
const remote::file_size &write_size, fuse_write(const char *path, const char *buffer, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id &, void set_fuse_uid_gid(remote::user_id, remote::group_id) override {}
const remote::group_id &) override {}
// JSON Layer // JSON Layer
[[nodiscard]] auto winfsp_get_dir_buffer(PVOID /*file_desc*/, [[nodiscard]] auto winfsp_get_dir_buffer(PVOID /*file_desc*/,
@@ -240,13 +232,14 @@ public:
json &json_data) json &json_data)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_read_directory_snapshot( [[nodiscard]] auto json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type override; std::uint32_t page,
json &json_data)
-> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto json_release_directory_snapshot(const std::string &path,
json_release_directory_snapshot(const std::string &path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
// WinFSP Layer // WinFSP Layer

View File

@@ -34,12 +34,12 @@ public:
json &json_data) -> packet::error_type = 0; json &json_data) -> packet::error_type = 0;
[[nodiscard]] virtual auto json_read_directory_snapshot( [[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; std::uint32_t page, json &json_data) -> packet::error_type = 0;
[[nodiscard]] virtual auto json_release_directory_snapshot( [[nodiscard]] virtual auto json_release_directory_snapshot(
const std::string &path, const std::string &path,
const remote::file_handle &handle) -> packet::error_type = 0; remote::file_handle handle) -> packet::error_type = 0;
}; };
} // namespace repertory } // namespace repertory

View File

@@ -80,7 +80,7 @@ protected:
[[nodiscard]] auto has_open_directory(const std::string &client_id, [[nodiscard]] auto has_open_directory(const std::string &client_id,
std::uint64_t handle) -> bool; 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; int error_return) -> int;
template <typename error_type> template <typename error_type>
@@ -95,7 +95,7 @@ protected:
void remove_and_close_all(const native_handle &handle); 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) auto remove_directory(const std::string &client_id, std::uint64_t handle)
-> bool; -> bool;
@@ -104,10 +104,10 @@ protected:
void set_client_id(const native_handle &handle, const std::string &client_id); 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); 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); const std::string &file_path);
void set_open_info(const native_handle &handle, open_info op_info); void set_open_info(const native_handle &handle, open_info op_info);

View File

@@ -55,12 +55,12 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_read_directory_snapshot( [[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; std::uint32_t page, json &json_data) -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto
json_release_directory_snapshot(const std::string &path, json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) [[nodiscard]] auto winfsp_can_delete(PVOID file_desc, PWSTR file_name)

View File

@@ -58,42 +58,41 @@ private:
public: public:
// FUSE Layer // 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; -> packet::error_type override;
[[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override; -> 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; -> packet::error_type override;
[[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, [[nodiscard]] auto fuse_chown(const char *path, remote::user_id uid,
const remote::group_id &gid) remote::group_id gid)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_destroy() -> packet::error_type override; [[nodiscard]] auto fuse_destroy() -> packet::error_type override;
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t /*packet::error_type fuse_fallocate(const char *path, const std::int32_t
&mode, const remote::file_offset &offset, const remote::file_offset &mode, remote::file_offset offset, const remote::file_offset
&length, const remote::file_handle &handle) override ;*/ &length, remote::file_handle handle) override ;*/
[[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat,
bool &directory, bool &directory, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_fsetattr_x(const char *path, [[nodiscard]] auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, [[nodiscard]] auto fuse_fsync(const char *path, std::int32_t datasync,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_ftruncate(const char *path, [[nodiscard]] auto fuse_ftruncate(const char *path,
const remote::file_offset &size, remote::file_offset size,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat,
@@ -101,10 +100,10 @@ public:
-> packet::error_type override; -> packet::error_type override;
/*packet::error_type fuse_getxattr(const char *path, const char *name, char /*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 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, [[nodiscard]] auto fuse_getxtimes(const char *path,
remote::file_time &bkuptime, remote::file_time &bkuptime,
@@ -114,57 +113,55 @@ public:
[[nodiscard]] auto fuse_init() -> packet::error_type override; [[nodiscard]] auto fuse_init() -> packet::error_type override;
/*packet::error_type fuse_listxattr(const char *path, char *buffer, /*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; -> 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; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto
fuse_create(const char *path, const remote::file_mode &mode, fuse_create(const char *path, remote::file_mode mode,
const remote::open_flags &flags, remote::file_handle &handle) const remote::open_flags &flags, remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_open(const char *path, [[nodiscard]] auto fuse_open(const char *path,
const remote::open_flags &flags, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_read(const char *path, char *buffer, [[nodiscard]] auto
const remote::file_size &read_size, fuse_read(const char *path, char *buffer, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_rename(const char *from, const char *to) [[nodiscard]] auto fuse_rename(const char *from, const char *to)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write(const char *path, const char *buffer, [[nodiscard]] auto fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer, [[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto
fuse_readdir(const char *path, const remote::file_offset &offset, fuse_readdir(const char *path, remote::file_offset offset,
const remote::file_handle &handle, std::string &item_path) remote::file_handle handle, std::string &item_path)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_release(const char *path, [[nodiscard]] auto fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_releasedir(const char *path, [[nodiscard]] auto fuse_releasedir(const char *path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type override; -> packet::error_type override;
/*packet::error_type fuse_removexattr(const char *path, const char *name) /*packet::error_type fuse_removexattr(const char *path, const char *name)
@@ -177,26 +174,26 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setbkuptime(const char *path, [[nodiscard]] auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime) remote::file_time bkuptime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setchgtime(const char *path, [[nodiscard]] auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime) remote::file_time chgtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setcrtime(const char *path, [[nodiscard]] auto fuse_setcrtime(const char *path,
const remote::file_time &crtime) remote::file_time crtime)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_setvolname(const char *volname) [[nodiscard]] auto fuse_setvolname(const char *volname)
-> packet::error_type override; -> packet::error_type override;
/*packet::error_type fuse_setxattr(const char *path, const char *name, const /*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 ; override ;
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const 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 ;*/ std::uint32_t position) override ;*/
[[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize, [[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize,
@@ -208,7 +205,7 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_truncate(const char *path, [[nodiscard]] auto fuse_truncate(const char *path,
const remote::file_offset &size) remote::file_offset size)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto fuse_unlink(const char *path) [[nodiscard]] auto fuse_unlink(const char *path)
@@ -218,21 +215,22 @@ public:
std::uint64_t op0, std::uint64_t op1) std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override; -> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id & /* uid */, void set_fuse_uid_gid(remote::user_id /* uid */,
const remote::group_id & /* gid */) override {} remote::group_id /* gid */) override {}
// JSON Layer // JSON Layer
[[nodiscard]] auto json_create_directory_snapshot(const std::string &path, [[nodiscard]] auto json_create_directory_snapshot(const std::string &path,
json &json_data) json &json_data)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_read_directory_snapshot( [[nodiscard]] auto json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type override; std::uint32_t page,
json &json_data)
-> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto json_release_directory_snapshot(const std::string &path,
json_release_directory_snapshot(const std::string &path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type override; -> packet::error_type override;
// WinFSP Layer // WinFSP Layer

View File

@@ -77,7 +77,8 @@ private:
private: private:
void close_timed_out_files(); 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<i_closeable_open_file>; -> std::shared_ptr<i_closeable_open_file>;
[[nodiscard]] auto get_open_file_count(const std::string &api_path) const [[nodiscard]] auto get_open_file_count(const std::string &api_path) const
@@ -92,7 +93,7 @@ private:
-> api_error; -> api_error;
void queue_upload(const std::string &api_path, const std::string &source_path, 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, void remove_resume(const std::string &api_path,
const std::string &source_path, bool no_lock); const std::string &source_path, bool no_lock);
@@ -145,6 +146,9 @@ public:
[[nodiscard]] auto get_directory_items(const std::string &api_path) const [[nodiscard]] auto get_directory_items(const std::string &api_path) const
-> directory_item_list override; -> directory_item_list override;
[[nodiscard]] auto get_open_file(const std::string &api_path,
std::shared_ptr<i_open_file> &file) -> bool;
[[nodiscard]] auto get_open_file(std::uint64_t handle, bool write_supported, [[nodiscard]] auto get_open_file(std::uint64_t handle, bool write_supported,
std::shared_ptr<i_open_file> &file) -> bool; std::shared_ptr<i_open_file> &file) -> bool;

View File

@@ -64,13 +64,17 @@ public:
[[nodiscard]] virtual auto get_source_path() const -> std::string = 0; [[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_complete() const -> bool = 0;
[[nodiscard]] virtual auto is_directory() 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 [[nodiscard]] virtual auto
native_operation(native_operation_callback callback) -> api_error = 0; 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); INTERFACE_SETUP(i_closeable_open_file);
public: 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; [[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_modified() const -> bool = 0;
[[nodiscard]] virtual auto is_unlinked() const -> bool = 0;
virtual void remove(std::uint64_t handle) = 0; virtual void remove(std::uint64_t handle) = 0;
virtual void remove_all() = 0; virtual void remove_all() = 0;
virtual void set_unlinked(bool value) = 0; virtual void set_unlinked(bool value) = 0;
virtual void set_unlinked_meta(api_meta_map meta) = 0;
}; };
} // namespace repertory } // namespace repertory

View File

@@ -111,8 +111,6 @@ public:
[[nodiscard]] auto is_complete() const -> bool override; [[nodiscard]] auto is_complete() const -> bool override;
[[nodiscard]] auto is_removed() const -> bool override;
[[nodiscard]] auto is_write_supported() const -> bool override { [[nodiscard]] auto is_write_supported() const -> bool override {
return true; return true;
} }
@@ -133,8 +131,6 @@ public:
[[nodiscard]] auto resize(std::uint64_t new_file_size) -> api_error override; [[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, [[nodiscard]] auto write(std::uint64_t write_offset, const data_buffer &data,
std::size_t &bytes_written) -> api_error override; std::size_t &bytes_written) -> api_error override;
}; };

View File

@@ -119,9 +119,8 @@ private:
}; };
bool modified_{false}; bool modified_{false};
bool removed_{false}; bool removed_{false};
#if !defined(_WIN32)
bool unlinked_{false}; bool unlinked_{false};
#endif // !defined(_WIN32) api_meta_map unlinked_meta_;
private: private:
void file_io_thread(); void file_io_thread();
@@ -167,7 +166,7 @@ protected:
void wait_for_io(stop_type_callback stop_requested_cb); void wait_for_io(stop_type_callback stop_requested_cb);
public: 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; [[nodiscard]] auto can_close() const -> bool override;
@@ -205,6 +204,8 @@ public:
[[nodiscard]] auto get_source_path() const -> std::string override; [[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 has_handle(std::uint64_t handle) const -> bool override;
[[nodiscard]] auto is_directory() 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_api_path(const std::string &api_path) override;
void set_unlinked(bool value) override; void set_unlinked(bool value) override;
void set_unlinked_meta(api_meta_map meta) override;
}; };
} // namespace repertory } // namespace repertory

View File

@@ -125,9 +125,11 @@ enum class api_error {
no_disk_space, no_disk_space,
not_implemented, not_implemented,
not_supported, not_supported,
no_tty,
os_error, os_error,
out_of_memory, out_of_memory,
permission_denied, permission_denied,
stale_descriptor,
upload_failed, upload_failed,
xattr_buffer_small, xattr_buffer_small,
xattr_exists, xattr_exists,

View File

@@ -45,9 +45,8 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
[[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t; [[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t;
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(UINT32 create_options, UINT32 granted_access,
const UINT32 &granted_access, std::uint32_t &flags, std::uint32_t &flags, remote::file_mode &mode);
remote::file_mode &mode);
} // namespace repertory::utils } // namespace repertory::utils
#endif // !defined(_WIN32) #endif // !defined(_WIN32)

View File

@@ -45,7 +45,7 @@ namespace repertory::utils {
[[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int; [[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int;
[[nodiscard]] auto [[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, const remote::open_flags &flags,
std::int32_t &perms) -> int; std::int32_t &perms) -> int;
} // namespace repertory::utils } // namespace repertory::utils

View File

@@ -26,7 +26,7 @@
namespace repertory { namespace repertory {
#if !defined(_WIN32) #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, fuse_fill_dir_t filler_function,
void *buffer, void *buffer,
populate_stat_callback populate_stat) populate_stat_callback populate_stat)

View File

@@ -52,6 +52,7 @@ fuse_base::fuse_base(app_config &config) : config_(config) {
fuse_ops_.fsync = fuse_base::fsync_; fuse_ops_.fsync = fuse_base::fsync_;
fuse_ops_.getattr = fuse_base::getattr_; fuse_ops_.getattr = fuse_base::getattr_;
fuse_ops_.init = fuse_base::init_; fuse_ops_.init = fuse_base::init_;
fuse_ops_.ioctl = fuse_base::ioctl_;
fuse_ops_.mkdir = fuse_base::mkdir_; fuse_ops_.mkdir = fuse_base::mkdir_;
fuse_ops_.open = fuse_base::open_; fuse_ops_.open = fuse_base::open_;
fuse_ops_.opendir = fuse_base::opendir_; fuse_ops_.opendir = fuse_base::opendir_;
@@ -211,8 +212,9 @@ auto fuse_base::execute_callback(
const std::function<api_error(std::string from_api_file, const std::function<api_error(std::string from_api_file,
std::string to_api_path)> &cb, std::string to_api_path)> &cb,
bool disable_logging) -> int { bool disable_logging) -> int {
auto from_api_file = utils::path::create_api_path(from ? from : ""); auto from_api_file =
auto to_api_file = utils::path::create_api_path(to ? to : ""); 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)); auto res = utils::from_api_error(cb(from_api_file, to_api_file));
raise_fuse_event(function_name, raise_fuse_event(function_name,
"from|" + from_api_file + "|to|" + to_api_file, res, "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, std::string_view function_name, const char *path,
const std::function<api_error(std::string api_path)> &cb, const std::function<api_error(std::string api_path)> &cb,
bool disable_logging) -> int { 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)); auto res = utils::from_api_error(cb(api_path));
raise_fuse_event(function_name, api_path, res, disable_logging); raise_fuse_event(function_name, api_path, res, disable_logging);
return res; return res;
@@ -389,6 +391,17 @@ auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
return this; 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 { auto fuse_base::mkdir_(const char *path, mode_t mode) -> int {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();

View File

@@ -44,6 +44,7 @@
#include "utils/base64.hpp" #include "utils/base64.hpp"
#include "utils/collection.hpp" #include "utils/collection.hpp"
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/config.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/time.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; return api_error::invalid_handle;
} }
auto is_unlinked{
not open_file->is_directory() && open_file->is_unlinked(),
};
api_meta_map meta{}; api_meta_map meta{};
auto res = provider_.get_item_meta(api_path, meta); if (is_unlinked) {
if (res != api_error::success) { meta = open_file->get_unlinked_meta();
return res; } 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, fuse_drive_base::populate_stat(api_path, open_file->get_file_size(), meta,
open_file->is_directory(), provider_, u_stat); open_file->is_directory(), provider_, u_stat);
if (is_unlinked) {
u_stat->st_nlink = 0;
}
return api_error::success; return api_error::success;
} }
@@ -498,9 +510,36 @@ auto fuse_drive::get_item_meta(const std::string &api_path,
return ret; return ret;
} }
auto fuse_drive::get_item_stat(std::uint64_t handle,
struct stat64 *u_stat) const -> api_error {
std::shared_ptr<i_open_file> 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 #if FUSE_USE_VERSION >= 30
auto fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat, 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<std::uint64_t>(REPERTORY_INVALID_HANDLE)) {
return fgetattr_impl(api_path, u_stat, f_info);
}
#else #else
auto fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat) auto fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat)
-> api_error { -> api_error {
@@ -637,6 +676,20 @@ auto fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
return ret; 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 { auto fuse_drive::is_processing(const std::string &api_path) const -> bool {
return fm_->is_processing(api_path); 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, const char *buffer, size_t write_size,
off_t write_offset, struct fuse_file_info *f_info, off_t write_offset, struct fuse_file_info *f_info,
std::size_t &bytes_written) -> api_error { std::size_t &bytes_written) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
std::shared_ptr<i_open_file> open_file; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(f_info->fh, true, open_file)) { if (not fm_->get_open_file(f_info->fh, true, open_file)) {
return api_error::item_not_found; return api_error::item_not_found;

View File

@@ -37,7 +37,7 @@ auto remote_client::check() -> packet::error_type {
return packet_client_.send(function_name, request, service_flags); 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_chown(const char *path, const remote::user_id &uid, auto remote_client::fuse_chown(const char *path, remote::user_id uid,
const remote::group_id &gid) remote::group_id gid) -> packet::error_type {
-> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
packet request; 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 /*packet::error_type remote_client::fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset std::int32_t &mode, remote::file_offset offset, const remote::file_offset
&length, const remote::file_handle &handle) { packet request; &length, remote::file_handle handle) { packet request;
request.encode(path); request.encode(path);
request.encode(mode); request.encode(mode);
request.encode(offset); 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, auto remote_client::fuse_fgetattr(const char *path, remote::stat &r_stat,
bool &directory, bool &directory, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -124,10 +122,12 @@ auto remote_client::fuse_fgetattr(const char *path, remote::stat &r_stat,
auto ret = auto ret =
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) { if (ret == 0) {
if ((ret = response.decode(r_stat)) == 0) { ret = response.decode(r_stat);
std::uint8_t d{}; if (ret == 0) {
if ((ret = response.decode(d)) == 0) { std::uint8_t is_dir{};
directory = static_cast<bool>(d); ret = response.decode(is_dir);
if (ret == 0) {
directory = static_cast<bool>(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, auto remote_client::fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_fsync(const char *path, const std::int32_t &datasync, auto remote_client::fuse_fsync(const char *path, std::int32_t datasync,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_ftruncate(const char *path, auto remote_client::fuse_ftruncate(const char *path, remote::file_offset size,
const remote::file_offset &size, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -193,10 +192,12 @@ auto remote_client::fuse_getattr(const char *path, remote::stat &r_stat,
auto ret = auto ret =
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) { if (ret == 0) {
if ((ret = response.decode(r_stat)) == 0) { ret = response.decode(r_stat);
std::uint8_t d = 0; if (ret == 0) {
if ((ret = response.decode(d)) == 0) { std::uint8_t is_dir{};
directory = static_cast<bool>(d); ret = response.decode(is_dir);
if (ret == 0) {
directory = static_cast<bool>(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 /*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<std::size_t>::max()) { ret = -ERANGE; } else { if (size > std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else {
packet request; request.encode(path); request.encode(name); packet request; request.encode(path); request.encode(name);
request.encode(size); request.encode(size);
@@ -226,7 +227,7 @@ response.CurrentPointer(), static_cast<std::size_t>(size2));
} }
packet::error_type remote_client::fuse_getxattr_osx(const char *path, const char 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<std::size_t>::max()) packet::error_type ret = 0; if (size > std::numeric_limits<std::size_t>::max())
{ ret = -ERANGE; } else { packet request; request.encode(path); { ret = -ERANGE; } else { packet request; request.encode(path);
request.encode(name); 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 /*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<std::size_t>::max()) { ret = -ERANGE; } else { packet std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { packet
request; request.encode(path); request.encode(size); request; request.encode(path); request.encode(size);
@@ -297,7 +298,7 @@ static_cast<std::size_t>(size2));
return ret; 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -327,7 +328,7 @@ auto remote_client::fuse_opendir(const char *path, remote::file_handle &handle)
return ret; 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, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type { -> 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, auto remote_client::fuse_read(const char *path, char *buffer,
const remote::file_size &read_size, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_client::fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_client::fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_readdir(const char *path, auto remote_client::fuse_readdir(const char *path, remote::file_offset offset,
const remote::file_offset &offset, remote::file_handle handle,
const remote::file_handle &handle,
std::string &item_path) -> packet::error_type { std::string &item_path) -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -471,8 +471,7 @@ auto remote_client::fuse_readdir(const char *path,
return ret; return ret;
} }
auto remote_client::fuse_release(const char *path, auto remote_client::fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -485,7 +484,7 @@ auto remote_client::fuse_release(const char *path,
} }
auto remote_client::fuse_releasedir(const char *path, auto remote_client::fuse_releasedir(const char *path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_client::fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime) remote::file_time bkuptime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_setchgtime(const char *path, auto remote_client::fuse_setchgtime(const char *path, remote::file_time chgtime)
const remote::file_time &chgtime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); return packet_client_.send(function_name, request, service_flags);
} }
auto remote_client::fuse_setcrtime(const char *path, auto remote_client::fuse_setcrtime(const char *path, remote::file_time crtime)
const remote::file_time &crtime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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 /*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 > &flags) { packet::error_type ret = 0; if (size >
std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { packet std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { packet
request; request.encode(path); request.encode(name); request.encode(size); 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 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 &flags, const std::uint32_t &position) override { packet::error_type ret = 0; if
(size > std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { (size > std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else {
packet request; request.encode(path); request.Encode(name); 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; return ret;
} }
auto remote_client::fuse_truncate(const char *path, auto remote_client::fuse_truncate(const char *path, remote::file_offset size)
const remote::file_offset &size)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -702,9 +698,11 @@ auto remote_client::json_create_directory_snapshot(const std::string &path,
return ret; return ret;
} }
auto remote_client::json_read_directory_snapshot( auto remote_client::json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type { std::uint32_t page,
json &json_data)
-> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
packet request; packet request;
@@ -723,8 +721,8 @@ auto remote_client::json_read_directory_snapshot(
return ret; return ret;
} }
auto remote_client::json_release_directory_snapshot( auto remote_client::json_release_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -736,8 +734,8 @@ auto remote_client::json_release_directory_snapshot(
return packet_client_.send(function_name, request, service_flags); return packet_client_.send(function_name, request, service_flags);
} }
void remote_client::set_fuse_uid_gid(const remote::user_id &uid, void remote_client::set_fuse_uid_gid(remote::user_id uid,
const remote::group_id &gid) { remote::group_id gid) {
uid_ = uid; uid_ = uid;
gid_ = gid; gid_ = gid;
} }

View File

@@ -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, auto remote_fuse_drive::fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *f_info) -> api_error { struct fuse_file_info *f_info) -> api_error {
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_fsync(api_path.c_str(), datasync, f_info->fh)); 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 #if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat, 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 { -> api_error {
if (f_info != nullptr && f_info->fh != 0 &&
f_info->fh != static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE)) {
return fgetattr_impl(api_path, u_stat, f_info);
}
#else // FUSE_USE_VERSION < 30 #else // FUSE_USE_VERSION < 30
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat) auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *u_stat)
-> api_error { -> 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)); std::memset(p_stat.get(), 0, sizeof(struct stat));
if (item_path == ".") { if (item_path == ".") {
#if FUSE_USE_VERSION >= 30 #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 #else // FUSE_USE_VERSION < 30
stat_res = getattr_impl(api_path, p_stat.get()); stat_res = getattr_impl(api_path, p_stat.get());
#endif // FUSE_USE_VERSION >= 30 #endif // FUSE_USE_VERSION >= 30
@@ -422,7 +425,7 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
} else { } else {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
stat_res = getattr_impl(utils::path::get_parent_api_path(api_path), 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 #else // FUSE_USE_VERSION < 30
stat_res = getattr_impl(utils::path::get_parent_api_path(api_path), stat_res = getattr_impl(utils::path::get_parent_api_path(api_path),
p_stat.get()); p_stat.get());

View File

@@ -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, void remote_server::populate_file_info(const std::string &api_path,
const UINT64 &file_size, UINT64 file_size, UINT32 attributes,
const UINT32 &attributes,
remote::file_info &r_info) { remote::file_info &r_info) {
REPERTORY_USES_FUNCTION_NAME(); 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; 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -221,7 +220,7 @@ auto remote_server::fuse_chflags(const char *path, std::uint32_t flags)
return ret; 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -232,9 +231,8 @@ auto remote_server::fuse_chmod(const char *path, const remote::file_mode &mode)
return ret; return ret;
} }
auto remote_server::fuse_chown(const char *path, const remote::user_id &uid, auto remote_server::fuse_chown(const char *path, remote::user_id uid,
const remote::group_id &gid) remote::group_id gid) -> packet::error_type {
-> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); 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; 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, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
@@ -256,10 +254,10 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode,
if (res >= 0) { if (res >= 0) {
handle = static_cast<remote::file_handle>(res); handle = static_cast<remote::file_handle>(res);
set_open_info(res, open_info{ set_open_info(res, open_info{
"", .client_id = "",
nullptr, .directory_buffer = nullptr,
{}, .handles = {},
file_path, .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 /*packet::error_type remote_server::fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset std::int32_t &mode, remote::file_offset offset, const remote::file_offset
&length, const remote::file_handle &handle) { const auto file_path = &length, remote::file_handle handle) { const auto file_path =
ConstructPath(path); auto ret = HasOpenFileInfo(handle, -EBADF); if (ret == 0) { ConstructPath(path); auto ret = HasOpenFileInfo(handle, -EBADF); if (ret == 0) {
#if defined(__APPLE__) #if defined(__APPLE__)
ret = STATUS_NOT_IMPLEMENTED; ret = STATUS_NOT_IMPLEMENTED;
@@ -313,22 +311,35 @@ length); ret = ((res < 0) ? -errno : 0); #endif
return ret; return ret;
}*/ }*/
auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat, auto remote_server::fuse_fgetattr(const char * /* path */, remote::stat &r_stat,
bool &directory, bool &directory, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
r_stat = {}; r_stat = {};
auto file_path = construct_path(path); auto res = -1;
auto file_path = get_open_file_path(static_cast<native_handle>(handle));
auto res = has_open_info(static_cast<native_handle>(handle), EBADF); if (file_path.empty()) {
if (res == 0) { errno = EBADF;
directory = utils::file::directory(file_path).exists(); } else {
struct stat64 u_stat{}; struct stat64 u_stat{};
res = fstat64(static_cast<native_handle>(handle), &u_stat); res = fstat64(static_cast<native_handle>(handle), &u_stat);
if (res == -1 && errno == ESTALE) {
std::uint64_t internal_handle{};
res = ioctl(static_cast<native_handle>(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) { if (res == 0) {
directory = S_ISDIR(u_stat.st_mode);
populate_stat(u_stat, r_stat); 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, auto remote_server::fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr, const remote::setattr_x &attr,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -434,42 +445,34 @@ auto remote_server::fuse_fsetattr_x(const char *path,
return ret; return ret;
} }
auto remote_server::fuse_fsync(const char *path, const std::int32_t &datasync, auto remote_server::fuse_fsync(const char *path, std::int32_t datasync,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); auto file_path = construct_path(path);
auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) {
#if defined(__APPLE__) #if defined(__APPLE__)
res = datasync ? fcntl(static_cast<native_handle>(handle), F_FULLFSYNC) auto res = datasync ? fcntl(static_cast<native_handle>(handle), F_FULLFSYNC)
: fsync(static_cast<native_handle>(handle)); : fsync(static_cast<native_handle>(handle));
#else // !defined(__APPLE__) #else // !defined(__APPLE__)
res = datasync ? fdatasync(static_cast<native_handle>(handle)) auto res = datasync ? fdatasync(static_cast<native_handle>(handle))
: fsync(static_cast<native_handle>(handle)); : fsync(static_cast<native_handle>(handle));
#endif // defined(__APPLE__) #endif // defined(__APPLE__)
}
auto ret = ((res < 0) ? -errno : 0); auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
} }
auto remote_server::fuse_ftruncate(const char *path, auto remote_server::fuse_ftruncate(const char *path, remote::file_offset size,
const remote::file_offset &size, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); auto file_path = construct_path(path);
auto res =
auto res = has_open_info(static_cast<native_handle>(handle), EBADF); ftruncate(static_cast<native_handle>(handle), static_cast<off_t>(size));
if (res == 0) {
res =
ftruncate(static_cast<native_handle>(handle), static_cast<off_t>(size));
}
auto ret = ((res < 0) ? -errno : 0); auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); 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 api_path = utils::path::create_api_path(path);
auto file_path = construct_path(api_path); auto file_path = construct_path(api_path);
auto parent_api_path = utils::path::get_parent_api_path(api_path);
r_stat = {}; r_stat = {};
directory = utils::file::directory(file_path).exists();
struct stat64 u_stat{}; struct stat64 u_stat{};
auto res = stat64(file_path.c_str(), &u_stat); auto res = stat64(file_path.c_str(), &u_stat);
if (res == 0) { if (res == 0) {
directory = S_ISDIR(u_stat.st_mode);
populate_stat(u_stat, r_stat); 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 /*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 = utils::path::create_api_path(path); const auto file_path =
ConstructPath(api_path); const auto parentApiPath = ConstructPath(api_path); const auto parentApiPath =
utils::path::get_parent_api_path(api_path); 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 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__) && const auto file_path = ConstructPath(path); #if defined(__APPLE__) &&
defined(HAS_SETXATTR) defined(HAS_SETXATTR)
// TODO: CheckParentAccess(api_path, X_OK) // 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 /*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 ConstructPath(path); #if defined(HAS_SETXATTR) #if defined(__APPLE__) const auto
res = listxattr(file_path.c_str(), buffer, size, FSOPT_NOFOLLOW); #else const 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 < 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; 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -625,12 +626,13 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
if (res >= 0) { if (res >= 0) {
handle = static_cast<remote::file_handle>(res); handle = static_cast<remote::file_handle>(res);
set_open_info(res, open_info{ set_open_info(res, open_info{
"", .client_id = "",
nullptr, .directory_buffer = nullptr,
{}, .handles = {},
file_path, .path = file_path,
}); });
} }
auto ret = ((res < 0) ? -errno : 0); auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
return 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, auto remote_server::fuse_read(const char *path, char *buffer,
const remote::file_size &read_size, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); auto file_path = construct_path(path);
auto &data = *reinterpret_cast<data_buffer *>(buffer); auto &data = *reinterpret_cast<data_buffer *>(buffer);
ssize_t bytes_read{has_open_info(static_cast<native_handle>(handle), EBADF)}; data.resize(read_size);
if (bytes_read == 0) { auto bytes_read = pread64(static_cast<native_handle>(handle), data.data(),
data.resize(read_size); read_size, static_cast<off_t>(read_offset));
bytes_read = pread64(static_cast<native_handle>(handle), data.data(),
read_size, static_cast<off_t>(read_offset));
}
auto ret = ((bytes_read < 0) ? -errno : bytes_read); auto ret = ((bytes_read < 0) ? -errno : bytes_read);
if (ret < 0) { if (ret < 0) {
@@ -699,9 +698,8 @@ auto remote_server::fuse_rename(const char *from, const char *to)
return ret; return ret;
} }
auto remote_server::fuse_readdir(const char *path, auto remote_server::fuse_readdir(const char *path, remote::file_offset offset,
const remote::file_offset &offset, remote::file_handle handle,
const remote::file_handle &handle,
std::string &item_path) -> packet::error_type { std::string &item_path) -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -725,19 +723,15 @@ auto remote_server::fuse_readdir(const char *path,
return ret; return ret;
} }
auto remote_server::fuse_release(const char *path, auto remote_server::fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
packet::error_type ret = 0; packet::error_type ret = 0;
auto file_path = construct_path(path); auto file_path = construct_path(path);
auto res = has_open_info(static_cast<native_handle>(handle), EBADF); auto res = close(static_cast<native_handle>(handle));
if (res == 0) { remove_open_info(static_cast<native_handle>(handle));
res = close(static_cast<native_handle>(handle));
remove_open_info(static_cast<native_handle>(handle));
}
ret = ((res < 0) ? -errno : 0); ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); 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, auto remote_server::fuse_releasedir(const char *path,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime) remote::file_time bkuptime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -812,8 +806,7 @@ auto remote_server::fuse_setbkuptime(const char *path,
return ret; return ret;
} }
auto remote_server::fuse_setchgtime(const char *path, auto remote_server::fuse_setchgtime(const char *path, remote::file_time chgtime)
const remote::file_time &chgtime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -833,8 +826,7 @@ auto remote_server::fuse_setchgtime(const char *path,
return ret; return ret;
} }
auto remote_server::fuse_setcrtime(const char *path, auto remote_server::fuse_setcrtime(const char *path, remote::file_time crtime)
const remote::file_time &crtime)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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 /*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__{} || &flags) { const auto file_path = ConstructPath(path); #if defined(__APPLE__{} ||
!defined(HAS_SETXATTR) auto ret = STATUS_NOT_IMPLEMENTED; #else const auto res = !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) ? 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 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 = &flags, const std::uint32_t &position) { const auto file_path =
ConstructPath(path); #if defined(__APPLE__) && defined(HAS_SETXATTR) const auto ConstructPath(path); #if defined(__APPLE__) && defined(HAS_SETXATTR) const auto
res = setxattr(file_path.c_str(), name, value, size, position, flags); auto ret 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; return 0;
} }
auto remote_server::fuse_truncate(const char *path, auto remote_server::fuse_truncate(const char *path, remote::file_offset size)
const remote::file_offset &size)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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); auto file_path = construct_path(path);
struct timespec tv2[2] = {{0, 0}}; std::array<struct timespec, 2U> tv2{};
const auto process_timespec = [](auto op, const auto &src, auto &dst) { const auto process_timespec = [](auto cur_op, const auto &src, auto &dst) {
if ((op == UTIME_NOW) || (op == UTIME_OMIT)) { if ((cur_op == UTIME_NOW) || (cur_op == UTIME_OMIT)) {
dst.tv_nsec = static_cast<time_t>(op); dst.tv_nsec = static_cast<time_t>(cur_op);
dst.tv_sec = 0; dst.tv_sec = 0;
return; 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(op0, tv[0U], tv2[0U]);
process_timespec(op1, tv[1U], tv2[1U]); 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); auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
} }
auto remote_server::fuse_write(const char *path, const char *buffer, auto remote_server::fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); auto file_path = construct_path(path);
ssize_t bytes_written{ auto bytes_written = pwrite64(static_cast<native_handle>(handle), buffer,
has_open_info(static_cast<native_handle>(handle), EBADF)}; write_size, static_cast<off_t>(write_offset));
if (bytes_written == 0) {
bytes_written = pwrite64(static_cast<native_handle>(handle), buffer,
write_size, static_cast<off_t>(write_offset));
}
auto ret = ((bytes_written < 0) ? -errno : bytes_written); auto ret = ((bytes_written < 0) ? -errno : bytes_written);
if (ret < 0) { if (ret < 0) {
@@ -1000,11 +987,12 @@ auto remote_server::fuse_write(const char *path, const char *buffer,
return static_cast<packet::error_type>(ret); return static_cast<packet::error_type>(ret);
} }
auto remote_server::fuse_write_base64( auto remote_server::fuse_write_base64(const char * /*path*/,
const char * /*path*/, const char * /*buffer*/, const char * /*buffer*/,
const remote::file_size & /*write_size*/, remote::file_size /*write_size*/,
const remote::file_offset & /*write_offset*/, remote::file_offset /*write_offset*/,
const remote::file_handle & /*handle*/) -> packet::error_type { remote::file_handle /*handle*/)
-> packet::error_type {
// DOES NOTHING // DOES NOTHING
return 0; return 0;
} }
@@ -1662,9 +1650,11 @@ auto remote_server::json_create_directory_snapshot(const std::string &path,
return ret; return ret;
} }
auto remote_server::json_read_directory_snapshot( auto remote_server::json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type { std::uint32_t page,
json &json_data)
-> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
int res{-EBADF}; int res{-EBADF};
@@ -1693,8 +1683,8 @@ auto remote_server::json_read_directory_snapshot(
return ret; return ret;
} }
auto remote_server::json_release_directory_snapshot( auto remote_server::json_release_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();

View File

@@ -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( 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_); recur_mutex_lock compat_lock(file_mutex_);
auto res = compat_handle_lookup_.contains(handle) ? 0 : -1; auto res = compat_handle_lookup_.contains(handle) ? 0 : -1;
if (res == -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( 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_); recur_mutex_lock compat_lock(file_mutex_);
if (not compat_handle_lookup_.contains(handle)) { if (not compat_handle_lookup_.contains(handle)) {
return; 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( 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_); recur_mutex_lock compat_lock(file_mutex_);
compat_file_lookup_.at(compat_handle_lookup_.at(handle))->client_id = compat_file_lookup_.at(compat_handle_lookup_.at(handle))->client_id =
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( 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_); recur_mutex_lock compat_lock(file_mutex_);
if (compat_handle_lookup_.contains(handle)) { if (compat_handle_lookup_.contains(handle)) {
return; return;

View File

@@ -74,7 +74,7 @@ auto remote_client::json_create_directory_snapshot(const std::string &path,
} }
auto remote_client::json_read_directory_snapshot( 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 { std::uint32_t page, json &json_data) -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -96,7 +96,7 @@ auto remote_client::json_read_directory_snapshot(
} }
auto remote_client::json_release_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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();

View File

@@ -97,7 +97,7 @@ void remote_server::populate_stat(const char *path, bool directory,
} }
// FUSE Layer // 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_chmod(const char *path,
const remote::file_mode & /*mode*/) remote::file_mode /*mode*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -143,8 +143,8 @@ auto remote_server::fuse_chmod(const char *path,
} }
auto remote_server::fuse_chown(const char *path, auto remote_server::fuse_chown(const char *path,
const remote::user_id & /*uid*/, remote::user_id /*uid*/,
const remote::group_id & /*gid*/) remote::group_id /*gid*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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 /*packet::error_type remote_server::fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset std::int32_t &mode, remote::file_offset offset, const remote::file_offset
&length, const remote::file_handle &handle) { auto file_path = &length, remote::file_handle handle) { auto file_path =
construct_path(path); auto res = HasOpenFileCompatInfo(handle, EBADF); if (res construct_path(path); auto res = HasOpenFileCompatInfo(handle, EBADF); if (res
== 0) { res = _chsize_s(static_cast<int>(handle), offset + length); == 0) { res = _chsize_s(static_cast<int>(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, auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat,
bool &directory, bool &directory, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_fsetattr_x(const char *path,
const remote::setattr_x & /*attr*/, const remote::setattr_x & /*attr*/,
const remote::file_handle & /*handle*/) remote::file_handle /*handle*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_fsync(const char *path,
const std::int32_t & /*datasync*/, std::int32_t /*datasync*/,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -243,8 +242,8 @@ auto remote_server::fuse_fsync(const char *path,
} }
auto remote_server::fuse_ftruncate(const char *path, auto remote_server::fuse_ftruncate(const char *path,
const remote::file_offset &size, remote::file_offset size,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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 /*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; construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED;
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); return ret; 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 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 = auto file_path = construct_path(path); auto ret =
STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
file_path, ret); return ret; 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 /*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; construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED;
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
}*/ }*/
auto remote_server::fuse_mkdir(const char *path, auto remote_server::fuse_mkdir(const char *path,
const remote::file_mode & /*mode*/) remote::file_mode /*mode*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -351,7 +350,7 @@ auto remote_server::fuse_mkdir(const char *path,
return ret; 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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -376,9 +375,9 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
return ret; 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, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_read(const char *path, char *buffer,
const remote::file_size &read_size, remote::file_size read_size,
const remote::file_offset &read_offset, remote::file_offset read_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size, remote::file_size write_size,
const remote::file_offset &write_offset, remote::file_offset write_offset,
const remote::file_handle &handle) remote::file_handle handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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( auto remote_server::fuse_write_base64(
const char * /*path*/, const char * /*buffer*/, const char * /*path*/, const char * /*buffer*/,
const remote::file_size & /*write_size*/, remote::file_size /*write_size*/,
const remote::file_offset & /*write_offset*/, remote::file_offset /*write_offset*/,
const remote::file_handle & /*handle*/) -> packet::error_type { remote::file_handle /*handle*/) -> packet::error_type {
// DOES NOTHING // DOES NOTHING
return 0; return 0;
} }
auto remote_server::fuse_readdir(const char *path, auto remote_server::fuse_readdir(const char *path,
const remote::file_offset &offset, remote::file_offset offset,
const remote::file_handle &handle, remote::file_handle handle,
std::string &item_path) -> packet::error_type { std::string &item_path) -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -567,8 +566,7 @@ auto remote_server::fuse_readdir(const char *path,
return ret; return ret;
} }
auto remote_server::fuse_release(const char *path, auto remote_server::fuse_release(const char *path, remote::file_handle handle)
const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -585,7 +583,7 @@ auto remote_server::fuse_release(const char *path,
} }
auto remote_server::fuse_releasedir(const char *path, auto remote_server::fuse_releasedir(const char *path,
const remote::file_handle & /*handle*/) remote::file_handle /*handle*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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, auto remote_server::fuse_setbkuptime(const char *path,
const remote::file_time & /*bkuptime*/) remote::file_time /*bkuptime*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -636,7 +634,7 @@ auto remote_server::fuse_setbkuptime(const char *path,
} }
auto remote_server::fuse_setchgtime(const char *path, auto remote_server::fuse_setchgtime(const char *path,
const remote::file_time & /*chgtime*/) remote::file_time /*chgtime*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -647,7 +645,7 @@ auto remote_server::fuse_setchgtime(const char *path,
} }
auto remote_server::fuse_setcrtime(const char *path, auto remote_server::fuse_setcrtime(const char *path,
const remote::file_time & /*crtime*/) remote::file_time /*crtime*/)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); 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 /*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 = &flags) { auto file_path = construct_path(path); auto ret =
STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, STATUS_NOT_IMPLEMENTED; RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
file_path, ret); return ret; file_path, ret); return ret;
} }
packet::error_type remote_server::fuse_setxattr_osx(const char *path, const char 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 = &flags, const std::uint32_t &position) { auto file_path =
construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED; construct_path(path); auto ret = STATUS_NOT_IMPLEMENTED;
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); 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, auto remote_server::fuse_truncate(const char *path,
const remote::file_offset &size) remote::file_offset size)
-> packet::error_type { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -865,9 +863,11 @@ auto remote_server::json_create_directory_snapshot(const std::string &path,
return ret; return ret;
} }
auto remote_server::json_read_directory_snapshot( auto remote_server::json_read_directory_snapshot(const std::string &path,
const std::string &path, const remote::file_handle &handle, remote::file_handle handle,
std::uint32_t page, json &json_data) -> packet::error_type { std::uint32_t page,
json &json_data)
-> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_path = construct_path(path); auto file_path = construct_path(path);
@@ -897,7 +897,7 @@ auto remote_server::json_read_directory_snapshot(
} }
auto remote_server::json_release_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 { -> packet::error_type {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();

View File

@@ -77,8 +77,10 @@ file_manager::~file_manager() {
} }
void file_manager::close(std::uint64_t handle) { void file_manager::close(std::uint64_t handle) {
REPERTORY_USES_FUNCTION_NAME();
unique_recur_mutex_lock file_lock(open_file_mtx_); 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); auto closeable_file = get_open_file_by_handle(handle, is_closed);
if (not closeable_file) { if (not closeable_file) {
return; return;
@@ -88,7 +90,7 @@ void file_manager::close(std::uint64_t handle) {
closeable_file->remove(handle); closeable_file->remove(handle);
file_lock.lock(); 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; return;
} }
@@ -307,17 +309,23 @@ auto file_manager::get_next_handle() -> std::uint64_t {
return next_handle_; 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<i_closeable_open_file> { -> std::shared_ptr<i_closeable_open_file> {
REPERTORY_USES_FUNCTION_NAME();
{ {
auto file_iter = std::ranges::find_if( auto file_iter = std::ranges::find_if(
closed_file_lookup_, [&handle](auto &&item) -> bool { closed_file_lookup_, [&handle](auto &&item) -> bool {
return item.second->has_handle(handle); return item.second->has_handle(handle);
}); });
return (file_iter == closed_file_lookup_.end()) ? nullptr if (file_iter != closed_file_lookup_.end()) {
: file_iter->second; is_closed = true;
return file_iter->second;
}
} }
is_closed = false;
auto file_iter = auto file_iter =
std::ranges::find_if(open_file_lookup_, [&handle](auto &&item) -> bool { std::ranges::find_if(open_file_lookup_, [&handle](auto &&item) -> bool {
return item.second->has_handle(handle); 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(); : file_iter->second->get_open_file_count();
} }
auto file_manager::get_open_file(const std::string &api_path,
std::shared_ptr<i_open_file> &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, auto file_manager::get_open_file(std::uint64_t handle, bool write_supported,
std::shared_ptr<i_open_file> &file) -> bool { std::shared_ptr<i_open_file> &file) -> bool {
REPERTORY_USES_FUNCTION_NAME();
if (write_supported && provider_.is_read_only()) { if (write_supported && provider_.is_read_only()) {
return false; return false;
} }
unique_recur_mutex_lock open_lock(open_file_mtx_); 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) { if (not file_ptr) {
return false; return false;
} }
@@ -353,7 +380,13 @@ auto file_manager::get_open_file(std::uint64_t handle, bool write_supported,
: 0U, : 0U,
file_ptr->get_filesystem_item(), file_ptr->get_open_data(), provider_, file_ptr->get_filesystem_item(), file_ptr->get_open_data(), provider_,
*this); *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; file = writeable_file;
return true; 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); auto ret = provider_.rename_file(from_api_path, to_api_path);
if (ret != api_error::success) { if (ret != api_error::success) {
queue_upload(from_api_path, source_path, false); queue_upload(from_api_path, source_path, false, false);
return ret; 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); : provider_.set_item_meta(to_api_path, META_SOURCE, source_path);
if (should_upload) { if (should_upload) {
queue_upload(to_api_path, source_path, false); queue_upload(to_api_path, source_path, false, false);
} }
return ret; return ret;
@@ -497,7 +530,7 @@ auto file_manager::open(const std::string &api_path, bool directory,
const auto create_and_add_handle = const auto create_and_add_handle =
[&](std::shared_ptr<i_closeable_open_file> cur_file) { [&](std::shared_ptr<i_closeable_open_file> cur_file) {
handle = get_next_handle(); handle = get_next_handle();
cur_file->add(handle, ofd); cur_file->add(handle, ofd, true);
file = cur_file; 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) { 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, 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(); REPERTORY_USES_FUNCTION_NAME();
if (provider_.is_read_only() || file.is_removed()) { if (provider_.is_read_only() || is_unlinked) {
return; return;
} }
@@ -670,6 +705,12 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
return res; 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_recur_mutex_lock open_lock(open_file_mtx_);
unique_mutex_lock upload_lock(upload_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); auto file_iter = open_file_lookup_.find(api_path);
if (file_iter == open_file_lookup_.end()) { if (file_iter == open_file_lookup_.end()) {
remove_source_and_shrink_cache(api_path, fsi.source_path, fsi.size, true);
return api_error::success; return api_error::success;
} }
if (closed_file_lookup_.contains(api_path)) { if (closed_file_lookup_.contains(api_path)) {
auto closed_file = closed_file_lookup_.at(api_path).second; auto closed_file = closed_file_lookup_.at(api_path);
closed_file_lookup_[api_path] = file_iter.second; closed_file_lookup_[api_path] = file_iter->second;
for (auto &[handle, ofd] : closed_file->get_open_data()) { 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 { } else {
closed_file_lookup_[api_path] = file_iter.second; closed_file_lookup_[api_path] = file_iter->second;
} }
open_file_lookup_.erase(api_path); 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(true);
closed_file->set_unlinked_meta(meta);
open_lock.unlock(); open_lock.unlock();
if (not allocated) {
return api_error::success;
}
res = cache_size_mgr::instance().shrink(closed_file->get_file_size()); res = cache_size_mgr::instance().shrink(closed_file->get_file_size());
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error(function_name, api_path, source_path, utils::error::raise_api_path_error(function_name, api_path,
res, "failed to shrink cache"); closed_file->get_source_path(), res,
"failed to shrink cache");
} }
return api_error::success; return api_error::success;
@@ -996,7 +1045,7 @@ void file_manager::start() {
} }
for (const auto &entry : mgr_db_->get_upload_active_list()) { 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()) { 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) { void file_manager::store_resume(const i_open_file &file) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
if (provider_.is_read_only() || file.is_removed()) { if (provider_.is_read_only() || file.is_unlinked()) {
return; return;
} }
@@ -1187,7 +1236,7 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
event_system::instance().raise<file_upload_retry>( event_system::instance().raise<file_upload_retry>(
evt.api_path, evt.error, function_name, evt.source_path); 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); upload_notify_.wait_for(upload_lock, queue_wait_secs);
} }
} }
@@ -1242,7 +1291,7 @@ void file_manager::upload_handler() {
default: { default: {
event_system::instance().raise<file_upload_retry>( event_system::instance().raise<file_upload_retry>(
entry->api_path, res, function_name, entry->source_path); 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; } break;
} }
} }

View File

@@ -538,8 +538,15 @@ auto open_file::native_operation(
set_file_size(new_file_size); set_file_size(new_file_size);
auto now = std::to_string(utils::time::get_time_now()); auto now = std::to_string(utils::time::get_time_now());
if (is_unlinked()) { 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( 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); return set_api_error(res);
} }
auto now = std::to_string(utils::time::get_time_now());
if (is_unlinked()) { 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(), { res = get_provider().set_item_meta(get_api_path(), {
{META_CHANGED, now}, {META_CHANGED, now},
{META_MODIFIED, now}, {META_MODIFIED, now},

View File

@@ -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(); REPERTORY_USES_FUNCTION_NAME();
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
open_data_[handle] = ofd; open_data_[handle] = ofd;
if (not notify) {
return;
}
if (open_data_.size() == 1U) { if (open_data_.size() == 1U) {
event_system::instance().raise<filesystem_item_opened>( event_system::instance().raise<filesystem_item_opened>(
fsi_.api_path, fsi_.directory, function_name, fsi_.source_path); fsi_.api_path, fsi_.directory, function_name, fsi_.source_path);
@@ -249,6 +254,11 @@ void open_file_base::set_unlinked(bool value) {
unlinked_ = 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 { auto open_file_base::get_filesystem_item() const -> filesystem_item {
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
return fsi_; return fsi_;
@@ -298,9 +308,14 @@ auto open_file_base::get_source_path() const -> std::string {
return fsi_.source_path; 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 { auto open_file_base::has_handle(std::uint64_t handle) const -> bool {
recur_mutex_lock file_lock(file_mtx_); 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 { 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(); REPERTORY_USES_FUNCTION_NAME();
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
if (open_data_.find(handle) == open_data_.end()) { if (not open_data_.contains(handle)) {
return; return;
} }

View File

@@ -210,9 +210,11 @@ static const std::unordered_map<api_error, std::string> LOOKUP = {
{api_error::no_disk_space, "no_disk_space"}, {api_error::no_disk_space, "no_disk_space"},
{api_error::not_implemented, "not_implemented"}, {api_error::not_implemented, "not_implemented"},
{api_error::not_supported, "not_supported"}, {api_error::not_supported, "not_supported"},
{api_error::no_tty, "no_tty"},
{api_error::os_error, "os_error"}, {api_error::os_error, "os_error"},
{api_error::out_of_memory, "out_of_memory"}, {api_error::out_of_memory, "out_of_memory"},
{api_error::permission_denied, "permission_denied"}, {api_error::permission_denied, "permission_denied"},
{api_error::stale_descriptor, "stale_descriptor"},
{api_error::upload_failed, "upload_failed"}, {api_error::upload_failed, "upload_failed"},
{api_error::xattr_buffer_small, "xattr_buffer_small"}, {api_error::xattr_buffer_small, "xattr_buffer_small"},
{api_error::xattr_exists, "xattr_exists"}, {api_error::xattr_exists, "xattr_exists"},

View File

@@ -76,6 +76,10 @@ auto from_api_error(api_error err) -> int {
return -ENOTSUP; return -ENOTSUP;
case api_error::not_implemented: case api_error::not_implemented:
return -ENOSYS; return -ENOSYS;
case api_error::no_tty:
return -ENOTTY;
case api_error::stale_descriptor:
return -ESTALE;
case api_error::upload_failed: case api_error::upload_failed:
return -ENETDOWN; return -ENETDOWN;
case api_error::xattr_buffer_small: case api_error::xattr_buffer_small:
@@ -144,6 +148,10 @@ auto to_api_error(int err) -> api_error {
return api_error::not_supported; return api_error::not_supported;
case ENOSYS: case ENOSYS:
return api_error::not_implemented; return api_error::not_implemented;
case ESTALE:
return api_error::stale_descriptor;
case ENOTTY:
return api_error::no_tty;
case ENETDOWN: case ENETDOWN:
return api_error::upload_failed; return api_error::upload_failed;
case ERANGE: case ERANGE:
@@ -176,6 +184,8 @@ auto unix_error_to_windows(int err) -> std::uint32_t {
case EACCES: case EACCES:
case EPERM: case EPERM:
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
case ESTALE:
return STATUS_INVALID_HANDLE;
case EBADF: case EBADF:
return STATUS_INVALID_HANDLE; return STATUS_INVALID_HANDLE;
case EBUSY: 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, void windows_create_to_unix(UINT32 create_options, UINT32 granted_access,
const UINT32 &granted_access, std::uint32_t &flags, std::uint32_t &flags, remote::file_mode &mode) {
remote::file_mode &mode) {
mode = S_IRUSR | S_IWUSR; mode = S_IRUSR | S_IWUSR;
flags = O_CREAT | O_RDWR; flags = O_CREAT | O_RDWR;
if ((create_options & FILE_DIRECTORY_FILE) != 0U) { if ((create_options & FILE_DIRECTORY_FILE) != 0U) {

View File

@@ -119,7 +119,7 @@ auto unix_access_mask_to_windows(std::int32_t mask) -> int {
return mask & 6; 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, const remote::open_flags &flags,
std::int32_t &perms) -> int { std::int32_t &perms) -> int {
auto ret = _O_BINARY | _O_RANDOM; auto ret = _O_BINARY | _O_RANDOM;

View File

@@ -29,7 +29,8 @@
namespace repertory { namespace repertory {
class mock_open_file : public virtual i_closeable_open_file { class mock_open_file : public virtual i_closeable_open_file {
public: 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)); (override));
MOCK_METHOD(bool, can_close, (), (const, override)); MOCK_METHOD(bool, can_close, (), (const, override));
@@ -70,6 +71,8 @@ public:
MOCK_METHOD(std::string, get_source_path, (), (const, override)); 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, has_handle, (std::uint64_t handle), (const, override));
MOCK_METHOD(bool, is_complete, (), (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_modified, (), (const, override));
MOCK_METHOD(bool, is_unlinked, (), (const, override));
MOCK_METHOD(bool, is_write_supported, (), (const, override)); MOCK_METHOD(bool, is_write_supported, (), (const, override));
MOCK_METHOD(api_error, native_operation, (native_operation_callback callback), 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_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, MOCK_METHOD(api_error, write,
(std::uint64_t write_offset, const data_buffer &data, (std::uint64_t write_offset, const data_buffer &data,
std::size_t &bytes_written), std::size_t &bytes_written),

View File

@@ -92,6 +92,8 @@ std::atomic<std::size_t> file_manager_test::inst{0U};
TEST_F(file_manager_test, can_start_and_stop) { TEST_F(file_manager_test, can_start_and_stop) {
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
event_consumer consumer(service_start_begin::name, [](const i_event &evt) { event_consumer consumer(service_start_begin::name, [](const i_event &evt) {
const auto &evt2 = dynamic_cast<const service_start_begin &>(evt); const auto &evt2 = dynamic_cast<const service_start_begin &>(evt);
@@ -128,6 +130,8 @@ TEST_F(file_manager_test, can_create_and_close_file) {
cfg->set_enable_download_timeout(true); cfg->set_enable_download_timeout(true);
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
polling::instance().start(cfg.get()); 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); cfg->set_enable_download_timeout(true);
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
polling::instance().start(cfg.get()); 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) { 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, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
polling::instance().start(cfg.get()); 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, TEST_F(file_manager_test,
download_is_stored_after_write_if_partially_downloaded) { download_is_stored_after_write_if_partially_downloaded) {
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.Times(2)
.WillRepeatedly(Return(std::vector<std::string>()));
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
mgr.start(); mgr.start();
@@ -549,6 +560,8 @@ TEST_F(file_manager_test, upload_occurs_after_write_if_fully_downloaded) {
cfg->set_enable_download_timeout(true); cfg->set_enable_download_timeout(true);
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
polling::instance().start(cfg.get()); 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) { TEST_F(file_manager_test, can_evict_file) {
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
mgr.start(); 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) { TEST_F(file_manager_test, evict_file_fails_if_file_is_uploading) {
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
mgr.start(); 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); file_manager mgr(*cfg, mp);
mock_open_file open_file{}; 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, is_directory).WillRepeatedly(Return(false));
EXPECT_CALL(open_file, get_api_path) EXPECT_CALL(open_file, get_api_path)
.WillRepeatedly(Return("/test_evict.txt")); .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, get_source_path).WillRepeatedly(Return("/test_evict.src"));
EXPECT_CALL(*file, is_directory).WillOnce(Return(false)); EXPECT_CALL(*file, is_directory).WillOnce(Return(false));
EXPECT_CALL(*file, is_modified).WillRepeatedly(Return(true)); 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)); EXPECT_CALL(*file, is_write_supported).WillRepeatedly(Return(true));
std::uint64_t handle{}; 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()); 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) EXPECT_CALL(mp, get_filesystem_item)
.WillOnce([](const std::string &api_path, bool directory, .WillOnce([](const std::string &api_path, bool directory,
filesystem_item &fsi) -> api_error { filesystem_item &fsi) -> api_error {
@@ -1423,6 +1462,7 @@ TEST_F(file_manager_test, can_queue_and_remove_upload) {
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
mock_open_file file{}; 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_api_path).WillOnce(Return("/test_queue.txt"));
EXPECT_CALL(file, get_source_path).WillOnce(Return("/test_queue.src")); 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()); polling::instance().start(cfg.get());
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
mgr.start(); mgr.start();
@@ -1547,6 +1589,7 @@ TEST_F(file_manager_test, remove_file_fails_if_provider_remove_file_fails) {
file_manager mgr(*cfg, mp); file_manager mgr(*cfg, mp);
EXPECT_CALL(mp, get_item_meta(_, _)).WillOnce(Return(api_error::success));
EXPECT_CALL(mp, get_filesystem_item) EXPECT_CALL(mp, get_filesystem_item)
.WillOnce([](const std::string &api_path, const bool &directory, .WillOnce([](const std::string &api_path, const bool &directory,
filesystem_item &fsi) -> api_error { 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")); 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, TEST_F(file_manager_test,
resize_greater_than_chunk_size_sets_new_chunks_to_read) { resize_greater_than_chunk_size_sets_new_chunks_to_read) {
cfg->set_enable_download_timeout(true); cfg->set_enable_download_timeout(true);
EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_read_only()).WillRepeatedly(Return(false));
EXPECT_CALL(mp, get_pinned_files())
.WillOnce(Return(std::vector<std::string>()));
polling::instance().start(cfg.get()); polling::instance().start(cfg.get());

View File

@@ -39,10 +39,10 @@ TYPED_TEST(fuse_test, unlink_can_remove_file) {
TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) { TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) {
std::string name{"unlink"}; 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); ASSERT_NE(desc, -1);
this->write_all(desc, "HELLO"); this->write_all(desc, "HELLO");
::close(desc); ::close(desc);
@@ -53,7 +53,10 @@ TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) {
ASSERT_EQ(0, ::unlink(path.c_str())); 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"); this->write_all(desc, " WORLD");
ASSERT_NE(-1, ::lseek(desc, 0, SEEK_SET)); ASSERT_NE(-1, ::lseek(desc, 0, SEEK_SET));

View File

@@ -637,10 +637,10 @@ TEST_F(open_file_test, can_add_handle) {
open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr); open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr);
#if defined(_WIN32) #if defined(_WIN32)
o.add(1u, {}); o.add(1u, {}, true);
EXPECT_EQ(nullptr, o.get_open_data(1u).directory_buffer); EXPECT_EQ(nullptr, o.get_open_data(1u).directory_buffer);
#else #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)); EXPECT_EQ(O_RDWR | O_SYNC, o.get_open_data(1u));
#endif #endif
@@ -698,9 +698,9 @@ TEST_F(open_file_test, can_remove_handle) {
open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr); open_file o(test_chunk_size, 0U, fsi, provider, upload_mgr);
#if defined(_WIN32) #if defined(_WIN32)
o.add(1u, {}); o.add(1u, {}, true);
#else #else
o.add(1u, O_RDWR | O_SYNC); o.add(1u, O_RDWR | O_SYNC, true);
#endif #endif
o.remove(1u); o.remove(1u);