fix directory caching
This commit is contained in:
parent
2a3a0aa689
commit
8655becf1e
@ -33,8 +33,9 @@ public:
|
|||||||
using execute_callback = std::function<void(directory_iterator &)>;
|
using execute_callback = std::function<void(directory_iterator &)>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct open_directory {
|
struct open_directory final {
|
||||||
std::shared_ptr<directory_iterator> iterator{};
|
std::shared_ptr<directory_iterator> iterator;
|
||||||
|
std::vector<std::uint64_t> handles{};
|
||||||
std::chrono::system_clock::time_point last_update{
|
std::chrono::system_clock::time_point last_update{
|
||||||
std::chrono::system_clock::now()};
|
std::chrono::system_clock::now()};
|
||||||
};
|
};
|
||||||
@ -60,15 +61,15 @@ public:
|
|||||||
void execute_action(const std::string &api_path,
|
void execute_action(const std::string &api_path,
|
||||||
const execute_callback &execute);
|
const execute_callback &execute);
|
||||||
|
|
||||||
[[nodiscard]] auto get_directory(directory_iterator *iterator)
|
[[nodiscard]] auto
|
||||||
-> std::shared_ptr<directory_iterator>;
|
get_directory(std::uint64_t handle) -> std::shared_ptr<directory_iterator>;
|
||||||
|
|
||||||
[[nodiscard]] auto remove_directory(const std::string &api_path)
|
[[nodiscard]] auto remove_directory(const std::string &api_path)
|
||||||
-> std::shared_ptr<directory_iterator>;
|
-> std::shared_ptr<directory_iterator>;
|
||||||
|
|
||||||
void remove_directory(directory_iterator *iterator);
|
void remove_directory(std::uint64_t handle);
|
||||||
|
|
||||||
void set_directory(const std::string &api_path,
|
void set_directory(const std::string &api_path, std::uint64_t handle,
|
||||||
std::shared_ptr<directory_iterator> iterator);
|
std::shared_ptr<directory_iterator> iterator);
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
directory_cache directory_cache_;
|
directory_cache directory_cache_;
|
||||||
|
std::atomic<std::uint64_t> next_handle_{0U};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] auto construct_path(std::string path) -> std::string;
|
[[nodiscard]] auto construct_path(std::string path) -> std::string;
|
||||||
@ -46,6 +47,8 @@ private:
|
|||||||
|
|
||||||
[[nodiscard]] static auto empty_as_zero(const json &data) -> std::string;
|
[[nodiscard]] static auto empty_as_zero(const json &data) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_next_handle() -> std::uint64_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
populate_file_info(const std::string &api_path,
|
populate_file_info(const std::string &api_path,
|
||||||
remote::file_info &file_info) -> packet::error_type;
|
remote::file_info &file_info) -> packet::error_type;
|
||||||
@ -58,9 +61,6 @@ private:
|
|||||||
|
|
||||||
[[nodiscard]] auto update_to_windows_format(json &item) -> json &;
|
[[nodiscard]] auto update_to_windows_format(json &item) -> json &;
|
||||||
|
|
||||||
protected:
|
|
||||||
void delete_open_directory(void *dir) override;
|
|
||||||
|
|
||||||
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, const std::int32_t &mask)
|
||||||
|
@ -59,8 +59,6 @@ protected:
|
|||||||
|
|
||||||
void close_all(const std::string &client_id);
|
void close_all(const std::string &client_id);
|
||||||
|
|
||||||
virtual void delete_open_directory(void *dir) = 0;
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
[[nodiscard]] auto get_directory_buffer(const native_handle &handle,
|
[[nodiscard]] auto get_directory_buffer(const native_handle &handle,
|
||||||
PVOID *&buffer) -> bool;
|
PVOID *&buffer) -> bool;
|
||||||
|
@ -26,9 +26,7 @@
|
|||||||
#include "comm/packet/client_pool.hpp"
|
#include "comm/packet/client_pool.hpp"
|
||||||
#include "comm/packet/packet.hpp"
|
#include "comm/packet/packet.hpp"
|
||||||
#include "comm/packet/packet_server.hpp"
|
#include "comm/packet/packet_server.hpp"
|
||||||
#include "drives/directory_iterator.hpp"
|
|
||||||
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
|
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
|
||||||
#include "drives/remote/i_remote_json.hpp"
|
|
||||||
#include "drives/remote/remote_open_file_table.hpp"
|
#include "drives/remote/remote_open_file_table.hpp"
|
||||||
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
|
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
|
||||||
#include "types/remote.hpp"
|
#include "types/remote.hpp"
|
||||||
@ -546,7 +544,7 @@ public:
|
|||||||
remote::file_mode mode;
|
remote::file_mode mode;
|
||||||
DECODE_OR_RETURN(request, mode);
|
DECODE_OR_RETURN(request, mode);
|
||||||
|
|
||||||
return this->fuse_chmod(&path[0], mode);
|
return this->fuse_chmod(path.c_str(), mode);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_chown",
|
{"::fuse_chown",
|
||||||
@ -564,7 +562,7 @@ public:
|
|||||||
remote::group_id gid{};
|
remote::group_id gid{};
|
||||||
DECODE_OR_RETURN(request, gid);
|
DECODE_OR_RETURN(request, gid);
|
||||||
|
|
||||||
return this->fuse_chown(&path[0], uid, gid);
|
return this->fuse_chown(path.c_str(), uid, gid);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_create",
|
{"::fuse_create",
|
||||||
@ -620,8 +618,8 @@ public:
|
|||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
return this->fuse_fallocate(&path[0], mode, offset,
|
return this->fuse_fallocate(path.c_str(), mode,
|
||||||
length, handle);
|
offset, length, handle);
|
||||||
}});*/
|
}});*/
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_fgetattr",
|
{"::fuse_fgetattr",
|
||||||
@ -688,7 +686,7 @@ public:
|
|||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
return this->fuse_fsync(&path[0], dataSync, handle);
|
return this->fuse_fsync(path.c_str(), dataSync, handle);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_ftruncate",
|
{"::fuse_ftruncate",
|
||||||
@ -706,7 +704,7 @@ public:
|
|||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
return this->fuse_ftruncate(&path[0], size, handle);
|
return this->fuse_ftruncate(path.c_str(), size, handle);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_getattr",
|
{"::fuse_getattr",
|
||||||
@ -726,7 +724,7 @@ public:
|
|||||||
|
|
||||||
remote::stat st{};
|
remote::stat st{};
|
||||||
bool directory = false;
|
bool directory = false;
|
||||||
ret = this->fuse_getattr(&path[0], st, directory);
|
ret = this->fuse_getattr(path.c_str(), st, directory);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
st.st_uid = uid;
|
st.st_uid = uid;
|
||||||
st.st_gid = gid;
|
st.st_gid = gid;
|
||||||
@ -749,7 +747,7 @@ public:
|
|||||||
remote::file_size size;
|
remote::file_size size;
|
||||||
DECODE_OR_RETURN(request, size);
|
DECODE_OR_RETURN(request, size);
|
||||||
|
|
||||||
return this->fuse_getxattr(&path[0], &name[0],
|
return this->fuse_getxattr(path.c_str(), &name[0],
|
||||||
nullptr, size);
|
nullptr, size);
|
||||||
}});
|
}});
|
||||||
handlerLookup_.insert({"::fuse_getxattr_osx",
|
handlerLookup_.insert({"::fuse_getxattr_osx",
|
||||||
@ -769,8 +767,8 @@ public:
|
|||||||
std::uint32_t position;
|
std::uint32_t position;
|
||||||
DECODE_OR_RETURN(request, position);
|
DECODE_OR_RETURN(request, position);
|
||||||
|
|
||||||
return this->fuse_getxattr_osx(&path[0], &name[0],
|
return this->fuse_getxattr_osx(path.c_str(),
|
||||||
nullptr, size, position);
|
&name[0], nullptr, size, position);
|
||||||
}});*/
|
}});*/
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_getxtimes",
|
{"::fuse_getxtimes",
|
||||||
@ -784,7 +782,8 @@ public:
|
|||||||
|
|
||||||
remote::file_time bkuptime{};
|
remote::file_time bkuptime{};
|
||||||
remote::file_time crtime{};
|
remote::file_time crtime{};
|
||||||
if ((ret = this->fuse_getxtimes(&path[0], bkuptime, crtime)) == 0) {
|
if ((ret = this->fuse_getxtimes(path.c_str(), bkuptime, crtime)) ==
|
||||||
|
0) {
|
||||||
response.encode(bkuptime);
|
response.encode(bkuptime);
|
||||||
response.encode(crtime);
|
response.encode(crtime);
|
||||||
}
|
}
|
||||||
@ -807,7 +806,7 @@ public:
|
|||||||
remote::file_size size;
|
remote::file_size size;
|
||||||
DECODE_OR_RETURN(request, size);
|
DECODE_OR_RETURN(request, size);
|
||||||
|
|
||||||
return this->fuse_listxattr(&path[0], nullptr,
|
return this->fuse_listxattr(path.c_str(), nullptr,
|
||||||
size);
|
size);
|
||||||
}});*/
|
}});*/
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
@ -823,7 +822,7 @@ public:
|
|||||||
remote::file_mode mode;
|
remote::file_mode mode;
|
||||||
DECODE_OR_RETURN(request, mode);
|
DECODE_OR_RETURN(request, mode);
|
||||||
|
|
||||||
return this->fuse_mkdir(&path[0], mode);
|
return this->fuse_mkdir(path.c_str(), mode);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_open",
|
{"::fuse_open",
|
||||||
@ -839,7 +838,7 @@ public:
|
|||||||
DECODE_OR_RETURN(request, flags);
|
DECODE_OR_RETURN(request, flags);
|
||||||
|
|
||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
if ((ret = this->fuse_open(&path[0], flags, handle)) >= 0) {
|
if ((ret = this->fuse_open(path.c_str(), flags, handle)) >= 0) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_compat_client_id(handle, client_id);
|
this->set_compat_client_id(handle, client_id);
|
||||||
#else
|
#else
|
||||||
@ -860,7 +859,7 @@ public:
|
|||||||
DECODE_OR_RETURN(request, path);
|
DECODE_OR_RETURN(request, path);
|
||||||
|
|
||||||
remote::file_handle handle = 0;
|
remote::file_handle handle = 0;
|
||||||
if ((ret = this->fuse_opendir(&path[0], handle)) >= 0) {
|
if ((ret = this->fuse_opendir(path.c_str(), handle)) >= 0) {
|
||||||
this->add_directory(client_id, reinterpret_cast<void *>(handle));
|
this->add_directory(client_id, reinterpret_cast<void *>(handle));
|
||||||
response.encode(handle);
|
response.encode(handle);
|
||||||
}
|
}
|
||||||
@ -886,10 +885,9 @@ public:
|
|||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
if ((ret =
|
if ((ret = this->fuse_read(path.c_str(), buffer.data(), read_size,
|
||||||
this->fuse_read(&path[0], reinterpret_cast<char *>(&buffer),
|
read_offset, handle)) > 0) {
|
||||||
read_size, read_offset, handle)) > 0) {
|
response.encode(buffer.data(), buffer.size());
|
||||||
response.encode(&buffer[0], buffer.size());
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}});
|
}});
|
||||||
@ -911,10 +909,10 @@ public:
|
|||||||
|
|
||||||
if (this->has_open_directory(client_id,
|
if (this->has_open_directory(client_id,
|
||||||
reinterpret_cast<void *>(handle))) {
|
reinterpret_cast<void *>(handle))) {
|
||||||
std::string filePath;
|
std::string file_path;
|
||||||
ret = this->fuse_readdir(&path[0], offset, handle, filePath);
|
ret = this->fuse_readdir(path.c_str(), offset, handle, file_path);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
response.encode(filePath);
|
response.encode(file_path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = -EBADF;
|
ret = -EBADF;
|
||||||
@ -935,7 +933,7 @@ public:
|
|||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
return this->fuse_release(&path[0], handle);
|
return this->fuse_release(path.c_str(), handle);
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_releasedir",
|
{"::fuse_releasedir",
|
||||||
@ -950,7 +948,7 @@ public:
|
|||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
DECODE_OR_RETURN(request, handle);
|
DECODE_OR_RETURN(request, handle);
|
||||||
|
|
||||||
ret = this->fuse_releasedir(&path[0], handle);
|
ret = this->fuse_releasedir(path.c_str(), handle);
|
||||||
if (this->remove_directory(client_id,
|
if (this->remove_directory(client_id,
|
||||||
reinterpret_cast<void *>(handle))) {
|
reinterpret_cast<void *>(handle))) {
|
||||||
return ret;
|
return ret;
|
||||||
@ -968,7 +966,8 @@ public:
|
|||||||
std::string name;
|
std::string name;
|
||||||
DECODE_OR_RETURN(request, name);
|
DECODE_OR_RETURN(request, name);
|
||||||
|
|
||||||
return this->fuse_removexattr(&path[0], &name[0]);
|
return this->fuse_removexattr(path.c_str(),
|
||||||
|
&name[0]);
|
||||||
}});*/
|
}});*/
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
{"::fuse_rename",
|
{"::fuse_rename",
|
||||||
@ -1093,7 +1092,7 @@ public:
|
|||||||
std::int32_t flags;
|
std::int32_t flags;
|
||||||
DECODE_OR_RETURN(request, flags);
|
DECODE_OR_RETURN(request, flags);
|
||||||
|
|
||||||
ret = this->fuse_setxattr(&path[0], &name[0],
|
ret = this->fuse_setxattr(path.c_str(), &name[0],
|
||||||
&value[0], size, flags);
|
&value[0], size, flags);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -1125,8 +1124,8 @@ public:
|
|||||||
std::uint32_t position;
|
std::uint32_t position;
|
||||||
DECODE_OR_RETURN(request, position);
|
DECODE_OR_RETURN(request, position);
|
||||||
|
|
||||||
ret = this->fuse_setxattr_osx(&path[0], &name[0],
|
ret = this->fuse_setxattr_osx(path.c_str(),
|
||||||
&value[0], size, flags, position);
|
&name[0], &value[0], size, flags, position);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}});*/
|
}});*/
|
||||||
@ -1430,12 +1429,6 @@ protected:
|
|||||||
path = utils::path::create_api_path(path.substr(mount_location_.size()));
|
path = utils::path::create_api_path(path.substr(mount_location_.size()));
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_open_directory(void *dir) override {
|
|
||||||
if (dir != nullptr) {
|
|
||||||
delete reinterpret_cast<directory_iterator *>(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
@ -46,9 +46,6 @@ private:
|
|||||||
static auto to_handle(PVOID file_desc) -> native_handle;
|
static auto to_handle(PVOID file_desc) -> native_handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
|
||||||
void delete_open_directory(void * /*dir*/) override {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto json_create_directory_snapshot(const std::string &path, json &json_data)
|
auto json_create_directory_snapshot(const std::string &path, json &json_data)
|
||||||
-> packet::error_type override;
|
-> packet::error_type override;
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
#include "drives/directory_cache.hpp"
|
#include "drives/directory_cache.hpp"
|
||||||
|
|
||||||
#include "drives/directory_iterator.hpp"
|
#include "drives/directory_iterator.hpp"
|
||||||
#include "events/event_system.hpp"
|
|
||||||
#include "events/events.hpp"
|
|
||||||
#include "types/repertory.hpp"
|
#include "types/repertory.hpp"
|
||||||
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
void directory_cache::execute_action(const std::string &api_path,
|
void directory_cache::execute_action(const std::string &api_path,
|
||||||
@ -35,19 +34,18 @@ void directory_cache::execute_action(const std::string &api_path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto directory_cache::get_directory(directory_iterator *iterator)
|
auto directory_cache::get_directory(std::uint64_t handle)
|
||||||
-> std::shared_ptr<directory_iterator> {
|
-> std::shared_ptr<directory_iterator> {
|
||||||
if (iterator != nullptr) {
|
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock directory_lock(directory_mutex_);
|
||||||
const auto it =
|
auto it = std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||||
std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
[handle](auto &&kv) -> bool {
|
||||||
[&iterator](const auto &kv) -> bool {
|
auto &&handles = kv.second.handles;
|
||||||
return kv.second.iterator.get() == iterator;
|
return std::find(handles.begin(), handles.end(),
|
||||||
|
handle) != kv.second.handles.end();
|
||||||
});
|
});
|
||||||
if (it != directory_lookup_.end()) {
|
if (it != directory_lookup_.end()) {
|
||||||
return it->second.iterator;
|
return it->second.iterator;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -65,16 +63,18 @@ auto directory_cache::remove_directory(const std::string &api_path)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void directory_cache::remove_directory(directory_iterator *iterator) {
|
void directory_cache::remove_directory(std::uint64_t handle) {
|
||||||
if (iterator != nullptr) {
|
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock directory_lock(directory_mutex_);
|
||||||
const auto it =
|
auto it = std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
||||||
std::find_if(directory_lookup_.begin(), directory_lookup_.end(),
|
[handle](auto &&kv) -> bool {
|
||||||
[&iterator](const auto &kv) -> bool {
|
auto &&handles = kv.second.handles;
|
||||||
return kv.second.iterator.get() == iterator;
|
return std::find(handles.begin(), handles.end(),
|
||||||
|
handle) != kv.second.handles.end();
|
||||||
});
|
});
|
||||||
if (it != directory_lookup_.end()) {
|
if (it != directory_lookup_.end()) {
|
||||||
directory_lookup_.erase(it->first);
|
utils::remove_element_from(it->second.handles, handle);
|
||||||
|
if (it->second.handles.empty()) {
|
||||||
|
directory_lookup_.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,8 +102,11 @@ void directory_cache::service_function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void directory_cache::set_directory(
|
void directory_cache::set_directory(
|
||||||
const std::string &api_path, std::shared_ptr<directory_iterator> iterator) {
|
const std::string &api_path, std::uint64_t handle,
|
||||||
|
std::shared_ptr<directory_iterator> iterator) {
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock directory_lock(directory_mutex_);
|
||||||
directory_lookup_[api_path] = {std::move(iterator)};
|
auto &entry = directory_lookup_[api_path];
|
||||||
|
entry.iterator = std::move(iterator);
|
||||||
|
entry.handles.push_back(handle);
|
||||||
}
|
}
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
@ -669,8 +669,8 @@ auto fuse_drive::opendir_impl(std::string api_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
||||||
file_info->fh = reinterpret_cast<std::uint64_t>(iter.get());
|
file_info->fh = fm_->get_next_handle();
|
||||||
directory_cache_->set_directory(api_path, iter);
|
directory_cache_->set_directory(api_path, file_info->fh, iter);
|
||||||
|
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
@ -716,8 +716,7 @@ auto fuse_drive::readdir_impl(std::string api_path, void *buf,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iter = directory_cache_->get_directory(
|
auto iter = directory_cache_->get_directory(file_info->fh);
|
||||||
reinterpret_cast<directory_iterator *>(file_info->fh));
|
|
||||||
if (iter == nullptr) {
|
if (iter == nullptr) {
|
||||||
return api_error::invalid_handle;
|
return api_error::invalid_handle;
|
||||||
}
|
}
|
||||||
@ -751,13 +750,12 @@ auto fuse_drive::release_impl(std::string /*api_path*/,
|
|||||||
|
|
||||||
auto fuse_drive::releasedir_impl(
|
auto fuse_drive::releasedir_impl(
|
||||||
std::string /*api_path*/, struct fuse_file_info *file_info) -> api_error {
|
std::string /*api_path*/, struct fuse_file_info *file_info) -> api_error {
|
||||||
auto iter = directory_cache_->get_directory(
|
auto iter = directory_cache_->get_directory(file_info->fh);
|
||||||
reinterpret_cast<directory_iterator *>(file_info->fh));
|
|
||||||
if (iter == nullptr) {
|
if (iter == nullptr) {
|
||||||
return api_error::invalid_handle;
|
return api_error::invalid_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
directory_cache_->remove_directory(iter.get());
|
directory_cache_->remove_directory(file_info->fh);
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,12 +73,6 @@ auto remote_server::construct_path(const std::wstring &path) -> std::string {
|
|||||||
return construct_path(utils::string::to_utf8(path));
|
return construct_path(utils::string::to_utf8(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_server::delete_open_directory(void *dir) {
|
|
||||||
directory_cache_.remove_directory(
|
|
||||||
reinterpret_cast<directory_iterator *>(dir));
|
|
||||||
remote_server_base::delete_open_directory(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto remote_server::empty_as_zero(const json &data) -> std::string {
|
auto remote_server::empty_as_zero(const json &data) -> std::string {
|
||||||
if (data.empty() || data.get<std::string>().empty()) {
|
if (data.empty() || data.get<std::string>().empty()) {
|
||||||
return "0";
|
return "0";
|
||||||
@ -86,6 +80,14 @@ auto remote_server::empty_as_zero(const json &data) -> std::string {
|
|||||||
return data.get<std::string>();
|
return data.get<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto remote_server::get_next_handle() -> std::uint64_t {
|
||||||
|
if (++next_handle_ == 0U) {
|
||||||
|
return ++next_handle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_handle_;
|
||||||
|
}
|
||||||
|
|
||||||
auto remote_server::populate_file_info(const std::string &api_path,
|
auto remote_server::populate_file_info(const std::string &api_path,
|
||||||
remote::file_info &file_info)
|
remote::file_info &file_info)
|
||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
@ -621,9 +623,9 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
|
|||||||
auto list = drive_.get_directory_items(utils::path::create_api_path(path));
|
auto list = drive_.get_directory_items(utils::path::create_api_path(path));
|
||||||
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
||||||
|
|
||||||
directory_cache_.set_directory(path, iter);
|
handle = get_next_handle();
|
||||||
|
directory_cache_.set_directory(path, handle, iter);
|
||||||
|
|
||||||
handle = reinterpret_cast<remote::file_handle>(iter.get());
|
|
||||||
res = 0;
|
res = 0;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
@ -682,8 +684,7 @@ auto remote_server::fuse_readdir(const char *path,
|
|||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
res = -1;
|
res = -1;
|
||||||
} else {
|
} else {
|
||||||
auto iter = directory_cache_.get_directory(
|
auto iter = directory_cache_.get_directory(handle);
|
||||||
reinterpret_cast<directory_iterator *>(handle));
|
|
||||||
if (iter != nullptr) {
|
if (iter != nullptr) {
|
||||||
res = iter->get(static_cast<std::size_t>(offset), item_path);
|
res = iter->get(static_cast<std::size_t>(offset), item_path);
|
||||||
} else {
|
} else {
|
||||||
@ -721,8 +722,7 @@ auto remote_server::fuse_releasedir(
|
|||||||
|
|
||||||
const auto file_path = construct_path(path);
|
const auto file_path = construct_path(path);
|
||||||
|
|
||||||
directory_cache_.remove_directory(
|
directory_cache_.remove_directory(handle);
|
||||||
reinterpret_cast<directory_iterator *>(handle));
|
|
||||||
|
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1569,9 +1569,10 @@ auto remote_server::json_create_directory_snapshot(
|
|||||||
if (utils::file::is_directory(file_path)) {
|
if (utils::file::is_directory(file_path)) {
|
||||||
auto list = drive_.get_directory_items(api_path);
|
auto list = drive_.get_directory_items(api_path);
|
||||||
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
auto iter = std::make_shared<directory_iterator>(std::move(list));
|
||||||
directory_cache_.set_directory(api_path, iter);
|
auto handle = get_next_handle();
|
||||||
|
directory_cache_.set_directory(api_path, handle, iter);
|
||||||
|
|
||||||
json_data["handle"] = reinterpret_cast<remote::file_handle>(iter.get());
|
json_data["handle"] = handle;
|
||||||
json_data["path"] = path;
|
json_data["path"] = path;
|
||||||
json_data["page_count"] = utils::divide_with_ceiling(
|
json_data["page_count"] = utils::divide_with_ceiling(
|
||||||
iter->get_count(), REPERTORY_DIRECTORY_PAGE_SIZE);
|
iter->get_count(), REPERTORY_DIRECTORY_PAGE_SIZE);
|
||||||
@ -1589,22 +1590,25 @@ auto remote_server::json_read_directory_snapshot(
|
|||||||
std::uint32_t page, json &json_data) -> packet::error_type {
|
std::uint32_t page, json &json_data) -> packet::error_type {
|
||||||
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
|
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
|
||||||
|
|
||||||
|
int res{-EBADF};
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
const auto file_path = construct_path(path);
|
||||||
auto *iterator = reinterpret_cast<directory_iterator *>(handle);
|
auto iter = directory_cache_.get_directory(handle);
|
||||||
|
if (iter != nullptr) {
|
||||||
std::size_t offset{};
|
std::size_t offset{};
|
||||||
int res{};
|
|
||||||
json item_json;
|
json item_json;
|
||||||
while ((json_data["directory_list"].size() < REPERTORY_DIRECTORY_PAGE_SIZE) &&
|
while (
|
||||||
(res = iterator->get_json(
|
(json_data["directory_list"].size() < REPERTORY_DIRECTORY_PAGE_SIZE) &&
|
||||||
(page * REPERTORY_DIRECTORY_PAGE_SIZE) + offset++, item_json)) ==
|
(res = iter->get_json((page * REPERTORY_DIRECTORY_PAGE_SIZE) + offset++,
|
||||||
0) {
|
item_json)) == 0) {
|
||||||
json_data["directory_list"].emplace_back(item_json);
|
json_data["directory_list"].emplace_back(item_json);
|
||||||
}
|
}
|
||||||
json_data["handle"] = reinterpret_cast<remote::file_handle>(iterator);
|
json_data["handle"] = handle;
|
||||||
json_data["path"] = path;
|
json_data["path"] = path;
|
||||||
json_data["page"] = page;
|
json_data["page"] = page;
|
||||||
json_data["page_count"] = utils::divide_with_ceiling(
|
json_data["page_count"] = utils::divide_with_ceiling(
|
||||||
iterator->get_count(), REPERTORY_DIRECTORY_PAGE_SIZE);
|
iter->get_count(), REPERTORY_DIRECTORY_PAGE_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);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1616,8 +1620,7 @@ auto remote_server::json_release_directory_snapshot(
|
|||||||
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
|
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
const auto file_path = construct_path(path);
|
||||||
directory_cache_.remove_directory(
|
directory_cache_.remove_directory(handle);
|
||||||
reinterpret_cast<directory_iterator *>(handle));
|
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,6 @@ auto remote_open_file_table::remove_directory(const std::string &client_id,
|
|||||||
auto &list = directory_lookup_[client_id];
|
auto &list = directory_lookup_[client_id];
|
||||||
if (utils::collection_includes(list, dir)) {
|
if (utils::collection_includes(list, dir)) {
|
||||||
utils::remove_element_from(list, dir);
|
utils::remove_element_from(list, dir);
|
||||||
delete_open_directory(dir);
|
|
||||||
if (directory_lookup_[client_id].empty()) {
|
if (directory_lookup_[client_id].empty()) {
|
||||||
directory_lookup_.erase(client_id);
|
directory_lookup_.erase(client_id);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user