diff --git a/CHANGELOG.md b/CHANGELOG.md index 329a15c4..0c9c152a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * \#45 [bug] Windows-to-Linux remote mount is not handling attempts to remove a non-empty directory properly * \#46 [bug] Changes to maximum cache size should be updated live * \#47 [bug] Windows-to-Linux remote mount is allowing directory rename when directory is not empty +* \#48 [bug] Windows-to-Linux remote mount overlapped I/O is not detecting EOF for read operations ### Changes from v2.0.5-rc diff --git a/repertory/librepertory/include/drives/remote/remote_server_base.hpp b/repertory/librepertory/include/drives/remote/remote_server_base.hpp index cdd93e52..d0218660 100644 --- a/repertory/librepertory/include/drives/remote/remote_server_base.hpp +++ b/repertory/librepertory/include/drives/remote/remote_server_base.hpp @@ -346,15 +346,16 @@ public: DECODE_OR_RETURN(request, length); data_buffer buffer(length); - UINT32 bytes_transferred{0}; + UINT32 bytes_transferred{0U}; ret = this->winfsp_read(file_desc, buffer.data(), offset, length, &bytes_transferred); - if (ret == STATUS_SUCCESS) { - response.encode(bytes_transferred); - if (bytes_transferred != 0U) { - response.encode(buffer.data(), bytes_transferred); - } + response.encode(bytes_transferred); + buffer.resize(bytes_transferred); + + if ((ret == STATUS_SUCCESS) && (bytes_transferred != 0U)) { + response.encode(buffer.data(), bytes_transferred); } + return ret; }}); handler_lookup_.insert( diff --git a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp index 1c79e967..8ac3b4dd 100644 --- a/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp +++ b/repertory/librepertory/src/drives/fuse/remotefuse/remote_server.cpp @@ -28,7 +28,6 @@ #include "drives/directory_iterator.hpp" #include "drives/remote/remote_open_file_table.hpp" #include "events/event_system.hpp" -#include "events/types/debug_log.hpp" #include "events/types/remote_server_event.hpp" #include "platform/platform.hpp" #include "types/remote.hpp" @@ -1379,18 +1378,12 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, if (ret == STATUS_SUCCESS) { auto res = pread64(static_cast(handle), buffer, length, static_cast(offset)); - event_system::instance().raise( - function_name, - fmt::format("read|offset|{}|len|{}|res|{}", offset, length, res)); if (res >= 0) { *bytes_transferred = static_cast(res); } else { ret = static_cast(utils::unix_error_to_windows(errno)); } - event_system::instance().raise( - function_name, - fmt::format("read|offset|{}|len|{}|res|{}", offset, length, res)); } RAISE_REMOTE_FUSE_SERVER_EVENT( diff --git a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp index 3746efce..ecca9bae 100644 --- a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp +++ b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_client.cpp @@ -198,11 +198,6 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options, utils::string::to_utf8(file_name), }); } -#if defined(_WIN32) - else { - ret = STATUS_OBJECT_NAME_COLLISION; - } -#endif // defined(_WIN32) } return ret; @@ -232,7 +227,8 @@ auto remote_client::winfsp_get_dir_buffer([[maybe_unused]] PVOID file_desc, if (get_directory_buffer(reinterpret_cast(file_desc), ptr)) { return static_cast(STATUS_SUCCESS); } -#endif +#endif // defined(_WIN32) + return static_cast(STATUS_INVALID_HANDLE); } @@ -392,6 +388,8 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); + *bytes_transferred = 0U; + packet request; request.encode(file_desc); request.encode(offset); @@ -403,14 +401,8 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, packet_client_.send(function_name, request, response, service_flags), }; DECODE_OR_IGNORE(&response, *bytes_transferred); - if (ret == STATUS_SUCCESS) { + if ((ret == STATUS_SUCCESS) && (*bytes_transferred != 0U)) { ret = response.decode(buffer, *bytes_transferred); -#if defined(_WIN32) - if ((ret == STATUS_SUCCESS) && - ((*bytes_transferred == 0U) || (*bytes_transferred != length))) { - ::SetLastError(ERROR_HANDLE_EOF); - } -#endif } return ret; @@ -529,6 +521,8 @@ auto remote_client::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, -> packet::error_type { REPERTORY_USES_FUNCTION_NAME(); + *bytes_transferred = 0U; + packet request; request.encode(file_desc); request.encode(length); diff --git a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp index 55b63269..273506ea 100644 --- a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp +++ b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_server.cpp @@ -1221,6 +1221,7 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, ? STATUS_SUCCESS : FspNtStatusFromWin32(::GetLastError()); } + if (ret != STATUS_SUCCESS) { RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, get_open_file_path(file_desc), ret); diff --git a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_winfsp_drive.cpp b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_winfsp_drive.cpp index 060c4bcf..5ccf1566 100644 --- a/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_winfsp_drive.cpp +++ b/repertory/librepertory/src/drives/winfsp/remotewinfsp/remote_winfsp_drive.cpp @@ -143,6 +143,9 @@ auto remote_winfsp_drive::Create(PWSTR file_name, UINT32 create_options, wcsncpy(ofi->NormalizedName, file_path.data(), wcslen(file_path.c_str())); ofi->NormalizedNameSize = static_cast(wcslen(file_path.c_str()) * sizeof(WCHAR)); + if (exists != 0U) { + ret = STATUS_OBJECT_NAME_COLLISION; + } } return ret; @@ -346,9 +349,15 @@ void remote_winfsp_drive::populate_file_info(const json &item, auto remote_winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length, PULONG bytes_transferred) -> NTSTATUS { - return remote_instance_->winfsp_read( + auto ret = remote_instance_->winfsp_read( file_desc, buffer, offset, length, reinterpret_cast(bytes_transferred)); + fmt::println("read|len|{}|ret|{}|bytes|{}", length, ret, *bytes_transferred); + if ((ret == STATUS_SUCCESS) && (*bytes_transferred != length)) { + ::SetLastError(ERROR_HANDLE_EOF); + } + + return ret; } auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc, diff --git a/repertory/librepertory/src/file_manager/open_file.cpp b/repertory/librepertory/src/file_manager/open_file.cpp index a91e23d0..05ec04f9 100644 --- a/repertory/librepertory/src/file_manager/open_file.cpp +++ b/repertory/librepertory/src/file_manager/open_file.cpp @@ -122,8 +122,8 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file::~open_file() { close(); } -auto open_file::adjust_cache_size(std::uint64_t file_size, - bool shrink) -> api_error { +auto open_file::adjust_cache_size(std::uint64_t file_size, bool shrink) + -> api_error { REPERTORY_USES_FUNCTION_NAME(); if (file_size == get_file_size()) { @@ -554,6 +554,7 @@ auto open_file::read(std::size_t read_size, std::uint64_t read_offset, read_size = utils::calculate_read_size(get_file_size(), read_size, read_offset); if (read_size == 0U) { + data.resize(0U); return api_error::success; } diff --git a/repertory/librepertory/src/file_manager/ring_buffer_base.cpp b/repertory/librepertory/src/file_manager/ring_buffer_base.cpp index 34e1daf3..d1bebd8b 100644 --- a/repertory/librepertory/src/file_manager/ring_buffer_base.cpp +++ b/repertory/librepertory/src/file_manager/ring_buffer_base.cpp @@ -207,6 +207,7 @@ auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset, read_size = utils::calculate_read_size(get_file_size(), read_size, read_offset); if (read_size == 0U) { + data.resize(0U); return api_error::success; } diff --git a/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp b/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp index aa684990..5695e951 100644 --- a/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp +++ b/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp @@ -334,9 +334,14 @@ static void test_overlapped_file(auto &&mount_location, auto &&file_path, EXPECT_EQ(0, std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read)); + LARGE_INTEGER size{}; + ::GetFileSizeEx(handle, &size); + read_buffer.clear(); read_buffer.resize(buffer_size); overlapped.Offset = 3U * bytes_per_sector; + fmt::println("size|{}|offset|{}|buf_size|{}", size.QuadPart, + overlapped.Offset, buffer_size); ret = ::ReadFile(handle, read_buffer.data(), bytes_per_sector, &bytes_read, &overlapped); EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError() ||