remote fixes
This commit is contained in:
parent
af339e6086
commit
2d74fb30de
@ -33,25 +33,32 @@ protected:
|
|||||||
virtual ~remote_open_file_table() = default;
|
virtual ~remote_open_file_table() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct compat_open_info {
|
struct compat_open_info final {
|
||||||
std::size_t count{0U};
|
|
||||||
std::string client_id;
|
std::string client_id;
|
||||||
|
std::vector<remote::file_handle> handles;
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct open_info {
|
struct open_info final {
|
||||||
std::size_t count{0U};
|
|
||||||
std::string client_id;
|
std::string client_id;
|
||||||
PVOID directory_buffer{nullptr};
|
PVOID directory_buffer{nullptr};
|
||||||
|
std::vector<native_handle> handles;
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<remote::file_handle, compat_open_info> compat_lookup_;
|
std::unordered_map<std::string, std::unique_ptr<compat_open_info>>
|
||||||
std::recursive_mutex compat_mutex_;
|
compat_file_lookup_;
|
||||||
|
std::unordered_map<remote::file_handle, std::string> compat_handle_lookup_;
|
||||||
|
|
||||||
|
private:
|
||||||
std::unordered_map<std::string, std::vector<std::uint64_t>> directory_lookup_;
|
std::unordered_map<std::string, std::vector<std::uint64_t>> directory_lookup_;
|
||||||
std::recursive_mutex directory_mutex_;
|
|
||||||
std::unordered_map<native_handle, open_info> file_lookup_;
|
private:
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<open_info>> file_lookup_;
|
||||||
|
std::unordered_map<native_handle, std::string> handle_lookup_;
|
||||||
|
|
||||||
|
private:
|
||||||
mutable std::recursive_mutex file_mutex_;
|
mutable std::recursive_mutex file_mutex_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -64,11 +71,11 @@ protected:
|
|||||||
PVOID *&buffer) -> bool;
|
PVOID *&buffer) -> bool;
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_open_file_path(const native_handle &handle)
|
||||||
get_open_file_path(const native_handle &handle) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto get_open_info(const native_handle &handle,
|
[[nodiscard]] auto get_open_info(const native_handle &handle, open_info &oi)
|
||||||
open_info &oi) -> bool;
|
-> bool;
|
||||||
|
|
||||||
[[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;
|
||||||
@ -77,20 +84,21 @@ protected:
|
|||||||
int error_return) -> int;
|
int error_return) -> int;
|
||||||
|
|
||||||
template <typename error_type>
|
template <typename error_type>
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto has_open_info(const native_handle &handle,
|
||||||
has_open_info(const native_handle &handle,
|
const error_type &error_return)
|
||||||
const error_type &error_return) -> error_type {
|
-> error_type {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock file_lock(file_mutex_);
|
||||||
return ((file_lookup_.find(handle) == file_lookup_.end()) ? error_return
|
return handle_lookup_.contains(handle) ? 0 : error_return;
|
||||||
: 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_all(const std::string &file_path);
|
void remove_all(const std::string &file_path);
|
||||||
|
|
||||||
|
void remove_and_close_all(const native_handle &handle);
|
||||||
|
|
||||||
void remove_compat_open_info(const remote::file_handle &handle);
|
void remove_compat_open_info(const remote::file_handle &handle);
|
||||||
|
|
||||||
auto remove_directory(const std::string &client_id,
|
auto remove_directory(const std::string &client_id, std::uint64_t handle)
|
||||||
std::uint64_t handle) -> bool;
|
-> bool;
|
||||||
|
|
||||||
void remove_open_info(const native_handle &handle);
|
void remove_open_info(const native_handle &handle);
|
||||||
|
|
||||||
@ -102,11 +110,11 @@ protected:
|
|||||||
void set_compat_open_info(const remote::file_handle &handle,
|
void set_compat_open_info(const remote::file_handle &handle,
|
||||||
const std::string &file_path);
|
const std::string &file_path);
|
||||||
|
|
||||||
void set_open_info(const native_handle &handle, open_info oi);
|
void set_open_info(const native_handle &handle, open_info op_info);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_open_file_count(const std::string &file_path) const
|
||||||
get_open_file_count(const std::string &file_path) const -> std::size_t;
|
-> std::size_t;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
@ -137,12 +137,12 @@ public:
|
|||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_client_id(file_desc, client_id);
|
this->set_client_id(file_desc, client_id);
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
this->set_client_id(
|
this->set_client_id(
|
||||||
static_cast<native_handle>(
|
static_cast<native_handle>(
|
||||||
reinterpret_cast<std::uintptr_t>(file_desc)),
|
reinterpret_cast<std::uintptr_t>(file_desc)),
|
||||||
client_id);
|
client_id);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
response.encode(file_desc);
|
response.encode(file_desc);
|
||||||
response.encode(file_info);
|
response.encode(file_info);
|
||||||
response.encode(normalized_name);
|
response.encode(normalized_name);
|
||||||
@ -277,12 +277,12 @@ public:
|
|||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_client_id(file_desc, client_id);
|
this->set_client_id(file_desc, client_id);
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
this->set_client_id(
|
this->set_client_id(
|
||||||
static_cast<native_handle>(
|
static_cast<native_handle>(
|
||||||
reinterpret_cast<std::uintptr_t>(file_desc)),
|
reinterpret_cast<std::uintptr_t>(file_desc)),
|
||||||
client_id);
|
client_id);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
response.encode(file_desc);
|
response.encode(file_desc);
|
||||||
response.encode(file_info);
|
response.encode(file_info);
|
||||||
response.encode(normalized_name);
|
response.encode(normalized_name);
|
||||||
@ -585,9 +585,9 @@ public:
|
|||||||
0) {
|
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 // !defined(_WIN32)
|
||||||
this->set_client_id(static_cast<native_handle>(handle), client_id);
|
this->set_client_id(static_cast<native_handle>(handle), client_id);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
response.encode(handle);
|
response.encode(handle);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -841,9 +841,9 @@ public:
|
|||||||
if ((ret = this->fuse_open(path.c_str(), 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 // !defined(_WIN32)
|
||||||
this->set_client_id(static_cast<native_handle>(handle), client_id);
|
this->set_client_id(static_cast<native_handle>(handle), client_id);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
response.encode(handle);
|
response.encode(handle);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -24,12 +24,13 @@
|
|||||||
#include "events/event_system.hpp"
|
#include "events/event_system.hpp"
|
||||||
#include "events/events.hpp"
|
#include "events/events.hpp"
|
||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
|
#include "utils/config.hpp"
|
||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
void remote_open_file_table::add_directory(const std::string &client_id,
|
void remote_open_file_table::add_directory(const std::string &client_id,
|
||||||
std::uint64_t handle) {
|
std::uint64_t handle) {
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
auto &list = directory_lookup_[client_id];
|
auto &list = directory_lookup_[client_id];
|
||||||
if (utils::collection::excludes(list, handle)) {
|
if (utils::collection::excludes(list, handle)) {
|
||||||
directory_lookup_[client_id].emplace_back(handle);
|
directory_lookup_[client_id].emplace_back(handle);
|
||||||
@ -37,14 +38,32 @@ void remote_open_file_table::add_directory(const std::string &client_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::close_all(const std::string &client_id) {
|
void remote_open_file_table::close_all(const std::string &client_id) {
|
||||||
std::vector<remote::file_handle> compat_handles;
|
unique_recur_mutex_lock lock(file_mutex_);
|
||||||
unique_recur_mutex_lock compat_lock(compat_mutex_);
|
auto compat_handles =
|
||||||
for (auto &&kv : compat_lookup_) {
|
std::accumulate(compat_file_lookup_.begin(), compat_file_lookup_.end(),
|
||||||
if (kv.second.client_id == client_id) {
|
std::vector<remote::file_handle>(),
|
||||||
compat_handles.emplace_back(kv.first);
|
[&client_id](auto &&list, auto &&value) {
|
||||||
}
|
auto &&op_info = value.second;
|
||||||
}
|
if (op_info->client_id == client_id) {
|
||||||
compat_lock.unlock();
|
list.insert(list.end(), op_info->handles.begin(),
|
||||||
|
op_info->handles.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
auto handles = std::accumulate(
|
||||||
|
file_lookup_.begin(), file_lookup_.end(), std::vector<native_handle>(),
|
||||||
|
[&client_id](auto &&list, auto &&value) {
|
||||||
|
auto &&op_info = value.second;
|
||||||
|
if (op_info->client_id == client_id) {
|
||||||
|
list.insert(list.end(), op_info->handles.begin(),
|
||||||
|
op_info->handles.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
for (auto &&handle : compat_handles) {
|
for (auto &&handle : compat_handles) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -55,32 +74,23 @@ void remote_open_file_table::close_all(const std::string &client_id) {
|
|||||||
remove_compat_open_info(handle);
|
remove_compat_open_info(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<native_handle> handles;
|
|
||||||
unique_recur_mutex_lock file_lock(file_mutex_);
|
|
||||||
for (auto &&kv : file_lookup_) {
|
|
||||||
if (kv.second.client_id == client_id) {
|
|
||||||
handles.emplace_back(kv.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_lock.unlock();
|
|
||||||
|
|
||||||
for (auto &&handle : handles) {
|
for (auto &&handle : handles) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
::CloseHandle(handle);
|
::CloseHandle(handle);
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
close(handle);
|
close(handle);
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
remove_open_info(handle);
|
remove_open_info(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::uint64_t> dirs;
|
std::vector<std::uint64_t> dirs;
|
||||||
unique_recur_mutex_lock directory_lock(directory_mutex_);
|
lock.lock();
|
||||||
for (auto &&kv : directory_lookup_) {
|
for (auto &&kv : directory_lookup_) {
|
||||||
if (kv.first == client_id) {
|
if (kv.first == client_id) {
|
||||||
dirs.insert(dirs.end(), kv.second.begin(), kv.second.end());
|
dirs.insert(dirs.end(), kv.second.begin(), kv.second.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
directory_lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
for (auto &&dir : dirs) {
|
for (auto &&dir : dirs) {
|
||||||
remove_directory(client_id, dir);
|
remove_directory(client_id, dir);
|
||||||
@ -90,123 +100,123 @@ void remote_open_file_table::close_all(const std::string &client_id) {
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
auto remote_open_file_table::get_directory_buffer(const native_handle &handle,
|
auto remote_open_file_table::get_directory_buffer(const native_handle &handle,
|
||||||
PVOID *&buffer) -> bool {
|
PVOID *&buffer) -> bool {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
if (file_lookup_.find(handle) != file_lookup_.end()) {
|
if (not handle_lookup_.contains(handle)) {
|
||||||
buffer = &file_lookup_[handle].directory_buffer;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
buffer = &file_lookup_.at(handle_lookup_.at(handle))->directory_buffer;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
auto remote_open_file_table::get_open_file_count(
|
auto remote_open_file_table::get_open_file_count(
|
||||||
const std::string &file_path) const -> std::size_t {
|
const std::string &file_path) const -> std::size_t {
|
||||||
unique_recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
const auto count = std::accumulate(
|
return (file_lookup_.contains(file_path)
|
||||||
file_lookup_.cbegin(), file_lookup_.cend(), std::size_t(0U),
|
? file_lookup_.at(file_path)->handles.size()
|
||||||
[&file_path](std::size_t total, const auto &kv) -> std::size_t {
|
: 0ULL) +
|
||||||
if (kv.second.path == file_path) {
|
(compat_file_lookup_.contains(file_path)
|
||||||
return ++total;
|
? compat_file_lookup_.at(file_path)->handles.size()
|
||||||
}
|
: 0ULL);
|
||||||
return total;
|
|
||||||
});
|
|
||||||
|
|
||||||
return std::accumulate(
|
|
||||||
compat_lookup_.cbegin(), compat_lookup_.cend(), count,
|
|
||||||
[&file_path](std::size_t total, const auto &kv) -> std::size_t {
|
|
||||||
if (kv.second.path == file_path) {
|
|
||||||
return ++total;
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_open_file_table::get_open_info(const native_handle &handle,
|
auto remote_open_file_table::get_open_info(const native_handle &handle,
|
||||||
open_info &oi) -> bool {
|
open_info &oi) -> bool {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
if (file_lookup_.find(handle) != file_lookup_.end()) {
|
if (not handle_lookup_.contains(handle)) {
|
||||||
oi = file_lookup_[handle];
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
oi = *file_lookup_.at(handle_lookup_.at(handle)).get();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_open_file_table::get_open_file_path(const native_handle &handle)
|
auto remote_open_file_table::get_open_file_path(const native_handle &handle)
|
||||||
-> std::string {
|
-> std::string {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
if (file_lookup_.find(handle) != file_lookup_.end()) {
|
if (not handle_lookup_.contains(handle)) {
|
||||||
return file_lookup_[handle].path;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return file_lookup_.at(handle_lookup_.at(handle))->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_open_file_table::has_open_directory(const std::string &client_id,
|
auto remote_open_file_table::has_open_directory(const std::string &client_id,
|
||||||
std::uint64_t handle) -> bool {
|
std::uint64_t handle) -> bool {
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
auto &list = directory_lookup_[client_id];
|
return (utils::collection::includes(directory_lookup_[client_id], handle));
|
||||||
return (utils::collection::includes(list, handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
const remote::file_handle &handle, int error_return) -> int {
|
||||||
recur_mutex_lock compat_lock(compat_mutex_);
|
recur_mutex_lock compat_lock(file_mutex_);
|
||||||
const auto res =
|
auto res = compat_handle_lookup_.contains(handle) ? 0 : -1;
|
||||||
((compat_lookup_.find(handle) == compat_lookup_.end()) ? -1 : 0);
|
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
errno = error_return;
|
errno = error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::remove_all(const std::string &file_path) {
|
void remote_open_file_table::remove_all(const std::string &file_path) {
|
||||||
unique_recur_mutex_lock file_lock(file_mutex_);
|
unique_recur_mutex_lock lock(file_mutex_);
|
||||||
const auto open_list = std::accumulate(
|
auto compat_open_list = std::accumulate(
|
||||||
file_lookup_.begin(), file_lookup_.end(), std::vector<native_handle>(),
|
compat_file_lookup_.begin(), compat_file_lookup_.end(),
|
||||||
[&file_path](std::vector<native_handle> v,
|
|
||||||
const auto &kv) -> std::vector<native_handle> {
|
|
||||||
if (kv.second.path == file_path) {
|
|
||||||
v.emplace_back(kv.first);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto compat_open_list = std::accumulate(
|
|
||||||
compat_lookup_.begin(), compat_lookup_.end(),
|
|
||||||
std::vector<remote::file_handle>(),
|
std::vector<remote::file_handle>(),
|
||||||
[&file_path](std::vector<remote::file_handle> v,
|
[&file_path](auto &&list, auto &&kv) -> std::vector<remote::file_handle> {
|
||||||
const auto &kv) -> std::vector<remote::file_handle> {
|
if (kv.first == file_path) {
|
||||||
if (kv.second.path == file_path) {
|
auto *op_info = kv.second.get();
|
||||||
v.emplace_back(kv.first);
|
list.insert(list.end(), op_info->handles.begin(),
|
||||||
|
op_info->handles.end());
|
||||||
}
|
}
|
||||||
return v;
|
return list;
|
||||||
});
|
});
|
||||||
file_lock.unlock();
|
|
||||||
|
|
||||||
for (auto &&handle : open_list) {
|
auto open_list = std::accumulate(
|
||||||
remove_open_info(handle);
|
file_lookup_.begin(), file_lookup_.end(), std::vector<native_handle>(),
|
||||||
}
|
[&file_path](auto &&list, auto &&kv) -> std::vector<native_handle> {
|
||||||
|
if (kv.first == file_path) {
|
||||||
|
auto *op_info = kv.second.get();
|
||||||
|
list.insert(list.end(), op_info->handles.begin(),
|
||||||
|
op_info->handles.end());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
for (auto &&handle : compat_open_list) {
|
for (auto &&handle : compat_open_list) {
|
||||||
remove_compat_open_info(handle);
|
remove_compat_open_info(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &&handle : open_list) {
|
||||||
|
remove_open_info(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::remove_compat_open_info(
|
void remote_open_file_table::remove_compat_open_info(
|
||||||
const remote::file_handle &handle) {
|
const remote::file_handle &handle) {
|
||||||
recur_mutex_lock compat_lock(compat_mutex_);
|
recur_mutex_lock compat_lock(file_mutex_);
|
||||||
if (compat_lookup_[handle].count > 0) {
|
if (not compat_handle_lookup_.contains(handle)) {
|
||||||
compat_lookup_[handle].count--;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not compat_lookup_[handle].count) {
|
auto *op_info =
|
||||||
compat_lookup_.erase(handle);
|
compat_file_lookup_.at(compat_handle_lookup_.at(handle)).get();
|
||||||
|
utils::collection::remove_element(op_info->handles, handle);
|
||||||
|
compat_handle_lookup_.erase(handle);
|
||||||
|
|
||||||
|
if (not op_info->handles.empty()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto path = op_info->path;
|
||||||
|
compat_file_lookup_.erase(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_open_file_table::remove_directory(const std::string &client_id,
|
auto remote_open_file_table::remove_directory(const std::string &client_id,
|
||||||
std::uint64_t handle) -> bool {
|
std::uint64_t handle) -> bool {
|
||||||
recur_mutex_lock directory_lock(directory_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
auto &list = directory_lookup_[client_id];
|
auto &list = directory_lookup_[client_id];
|
||||||
if (utils::collection::includes(list, handle)) {
|
if (utils::collection::includes(list, handle)) {
|
||||||
utils::collection::remove_element(list, handle);
|
utils::collection::remove_element(list, handle);
|
||||||
@ -220,48 +230,93 @@ auto remote_open_file_table::remove_directory(const std::string &client_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::remove_open_info(const native_handle &handle) {
|
void remote_open_file_table::remove_open_info(const native_handle &handle) {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
if (file_lookup_[handle].count > 0) {
|
if (not handle_lookup_.contains(handle)) {
|
||||||
file_lookup_[handle].count--;
|
return;
|
||||||
}
|
}
|
||||||
if (not file_lookup_[handle].count) {
|
|
||||||
|
auto *op_info = file_lookup_.at(handle_lookup_.at(handle)).get();
|
||||||
|
utils::collection::remove_element(op_info->handles, handle);
|
||||||
|
handle_lookup_.erase(handle);
|
||||||
|
|
||||||
|
if (not op_info->handles.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (file_lookup_[handle].directory_buffer) {
|
if (op_info->directory_buffer) {
|
||||||
FspFileSystemDeleteDirectoryBuffer(
|
FspFileSystemDeleteDirectoryBuffer(&op_info->directory_buffer);
|
||||||
&file_lookup_[handle].directory_buffer);
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
file_lookup_.erase(handle);
|
|
||||||
|
auto path = op_info->path;
|
||||||
|
file_lookup_.erase(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_open_file_table::remove_and_close_all(const native_handle &handle) {
|
||||||
|
unique_recur_mutex_lock lock(file_mutex_);
|
||||||
|
if (not handle_lookup_.contains(handle)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto op_info = *file_lookup_.at(handle_lookup_.at(handle));
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
for (auto &&open_handle : op_info.handles) {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
::CloseHandle(open_handle);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
close(open_handle);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
remove_open_info(open_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) {
|
const remote::file_handle &handle, const std::string &client_id) {
|
||||||
recur_mutex_lock compat_lock(compat_mutex_);
|
recur_mutex_lock compat_lock(file_mutex_);
|
||||||
compat_lookup_[handle].client_id = client_id;
|
compat_file_lookup_.at(compat_handle_lookup_.at(handle))->client_id =
|
||||||
|
client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::set_client_id(const native_handle &handle,
|
void remote_open_file_table::set_client_id(const native_handle &handle,
|
||||||
const std::string &client_id) {
|
const std::string &client_id) {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
file_lookup_[handle].client_id = client_id;
|
file_lookup_.at(handle_lookup_.at(handle))->client_id = client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
const remote::file_handle &handle, const std::string &file_path) {
|
||||||
recur_mutex_lock compat_lock(compat_mutex_);
|
recur_mutex_lock compat_lock(file_mutex_);
|
||||||
if (compat_lookup_.find(handle) == compat_lookup_.end()) {
|
if (compat_handle_lookup_.contains(handle)) {
|
||||||
compat_lookup_[handle] = {0, "", file_path};
|
return;
|
||||||
}
|
}
|
||||||
compat_lookup_[handle].count++;
|
|
||||||
|
if (not compat_file_lookup_.contains(file_path)) {
|
||||||
|
compat_file_lookup_[file_path] =
|
||||||
|
std::make_unique<compat_open_info>(compat_open_info{
|
||||||
|
"",
|
||||||
|
{},
|
||||||
|
file_path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
compat_handle_lookup_[handle] = file_path;
|
||||||
|
compat_file_lookup_.at(file_path)->handles.emplace_back(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_open_file_table::set_open_info(const native_handle &handle,
|
void remote_open_file_table::set_open_info(const native_handle &handle,
|
||||||
open_info oi) {
|
open_info op_info) {
|
||||||
recur_mutex_lock file_lock(file_mutex_);
|
recur_mutex_lock lock(file_mutex_);
|
||||||
if (file_lookup_.find(handle) == file_lookup_.end()) {
|
if (handle_lookup_.contains(handle)) {
|
||||||
file_lookup_[handle] = std::move(oi);
|
return;
|
||||||
}
|
}
|
||||||
file_lookup_[handle].count++;
|
|
||||||
|
if (not file_lookup_.contains(op_info.path)) {
|
||||||
|
file_lookup_[op_info.path] = std::make_unique<open_info>(op_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_lookup_[handle] = op_info.path;
|
||||||
|
file_lookup_.at(op_info.path)->handles.emplace_back(handle);
|
||||||
}
|
}
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
@ -160,10 +160,12 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
|
|||||||
auto ret{
|
auto ret{
|
||||||
packet_client_.send(function_name, request, response, service_flags),
|
packet_client_.send(function_name, request, response, service_flags),
|
||||||
};
|
};
|
||||||
|
|
||||||
DECODE_OR_IGNORE(&response, was_closed);
|
DECODE_OR_IGNORE(&response, was_closed);
|
||||||
if (was_closed != 0U) {
|
if (was_closed != 0U) {
|
||||||
remove_all(file_path);
|
remove_all(file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -222,11 +224,16 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
|
|||||||
DECODE_OR_IGNORE(&response, *file_info);
|
DECODE_OR_IGNORE(&response, *file_info);
|
||||||
DECODE_OR_IGNORE(&response, normalized_name);
|
DECODE_OR_IGNORE(&response, normalized_name);
|
||||||
DECODE_OR_IGNORE(&response, exists);
|
DECODE_OR_IGNORE(&response, exists);
|
||||||
|
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
*file_desc = reinterpret_cast<PVOID>(handle);
|
*file_desc = reinterpret_cast<PVOID>(handle);
|
||||||
set_open_info(
|
set_open_info(to_handle(*file_desc),
|
||||||
to_handle(*file_desc),
|
open_info{
|
||||||
open_info{0, "", nullptr, utils::string::to_utf8(file_name)});
|
"",
|
||||||
|
nullptr,
|
||||||
|
{},
|
||||||
|
utils::string::to_utf8(file_name),
|
||||||
|
});
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (exists) {
|
if (exists) {
|
||||||
::SetLastError(ERROR_ALREADY_EXISTS);
|
::SetLastError(ERROR_ALREADY_EXISTS);
|
||||||
@ -390,9 +397,13 @@ auto remote_client::winfsp_open(PWSTR file_name, UINT32 create_options,
|
|||||||
|
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
*file_desc = reinterpret_cast<PVOID>(handle);
|
*file_desc = reinterpret_cast<PVOID>(handle);
|
||||||
set_open_info(
|
set_open_info(to_handle(*file_desc),
|
||||||
to_handle(*file_desc),
|
open_info{
|
||||||
open_info{0, "", nullptr, utils::string::to_utf8(file_name)});
|
"",
|
||||||
|
nullptr,
|
||||||
|
{},
|
||||||
|
utils::string::to_utf8(file_name),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,12 +945,12 @@ auto remote_server::winfsp_cleanup(PVOID file_desc, PWSTR /*file_name*/,
|
|||||||
auto *handle = reinterpret_cast<HANDLE>(file_desc);
|
auto *handle = reinterpret_cast<HANDLE>(file_desc);
|
||||||
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE);
|
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE);
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
if ((flags & FileSystemBase::CleanupDelete) != 0U) {
|
if ((flags & FspCleanupDelete) != 0U) {
|
||||||
::CloseHandle(handle);
|
remove_and_close_all(file_desc);
|
||||||
remove_open_info(file_desc);
|
|
||||||
was_closed = TRUE;
|
was_closed = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1005,8 +1005,12 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
|
|||||||
if (handle != INVALID_HANDLE_VALUE) {
|
if (handle != INVALID_HANDLE_VALUE) {
|
||||||
*file_desc = reinterpret_cast<PVOID>(handle);
|
*file_desc = reinterpret_cast<PVOID>(handle);
|
||||||
normalized_name = utils::string::to_utf8(file_name);
|
normalized_name = utils::string::to_utf8(file_name);
|
||||||
set_open_info(*file_desc,
|
set_open_info(*file_desc, open_info{
|
||||||
open_info{0, "", nullptr, utils::string::to_utf8(file_path)});
|
"",
|
||||||
|
nullptr,
|
||||||
|
{},
|
||||||
|
utils::string::to_utf8(file_path),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret =
|
auto ret =
|
||||||
@ -1140,8 +1144,12 @@ auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
|
|||||||
if (handle != INVALID_HANDLE_VALUE) {
|
if (handle != INVALID_HANDLE_VALUE) {
|
||||||
*file_desc = reinterpret_cast<PVOID>(handle);
|
*file_desc = reinterpret_cast<PVOID>(handle);
|
||||||
normalized_name = utils::string::to_utf8(file_name);
|
normalized_name = utils::string::to_utf8(file_name);
|
||||||
set_open_info(*file_desc,
|
set_open_info(*file_desc, open_info{
|
||||||
open_info{0, "", nullptr, utils::string::to_utf8(file_path)});
|
"",
|
||||||
|
nullptr,
|
||||||
|
{},
|
||||||
|
utils::string::to_utf8(file_path),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret =
|
auto ret =
|
||||||
|
@ -203,15 +203,15 @@ VOID winfsp_drive::Cleanup(PVOID file_node, PVOID file_desc,
|
|||||||
FspFileSystemDeleteDirectoryBuffer(&directory_buffer);
|
FspFileSystemDeleteDirectoryBuffer(&directory_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (directory) {
|
if (not directory) {
|
||||||
if (provider_.get_directory_item_count(api_path) == 0) {
|
return handle_error(fm_->remove_file(api_path));
|
||||||
return handle_error(provider_.remove_directory(api_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle_error(api_error::directory_not_empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle_error(fm_->remove_file(api_path));
|
if (provider_.get_directory_item_count(api_path) == 0) {
|
||||||
|
return handle_error(provider_.remove_directory(api_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_error(api_error::directory_not_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((flags & FspCleanupSetArchiveBit) != 0U) && not directory) {
|
if (((flags & FspCleanupSetArchiveBit) != 0U) && not directory) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user