[bug] Windows-to-Linux remote mount overlapped I/O is not detecting EOF for read operations #48
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
This commit is contained in:
parent
45080aa32f
commit
ece42df528
@ -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
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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<native_handle>(handle), buffer, length,
|
||||
static_cast<off_t>(offset));
|
||||
event_system::instance().raise<debug_log>(
|
||||
function_name,
|
||||
fmt::format("read|offset|{}|len|{}|res|{}", offset, length, res));
|
||||
if (res >= 0) {
|
||||
*bytes_transferred = static_cast<UINT32>(res);
|
||||
} else {
|
||||
ret =
|
||||
static_cast<packet::error_type>(utils::unix_error_to_windows(errno));
|
||||
}
|
||||
event_system::instance().raise<debug_log>(
|
||||
function_name,
|
||||
fmt::format("read|offset|{}|len|{}|res|{}", offset, length, res));
|
||||
}
|
||||
|
||||
RAISE_REMOTE_FUSE_SERVER_EVENT(
|
||||
|
@ -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<native_handle>(file_desc), ptr)) {
|
||||
return static_cast<packet::error_type>(STATUS_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
return static_cast<packet::error_type>(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);
|
||||
|
@ -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);
|
||||
|
@ -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<UINT16>(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<PUINT32>(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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user