[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
|
* \#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
|
* \#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
|
* \#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
|
### Changes from v2.0.5-rc
|
||||||
|
|
||||||
|
@ -346,15 +346,16 @@ public:
|
|||||||
DECODE_OR_RETURN(request, length);
|
DECODE_OR_RETURN(request, length);
|
||||||
|
|
||||||
data_buffer buffer(length);
|
data_buffer buffer(length);
|
||||||
UINT32 bytes_transferred{0};
|
UINT32 bytes_transferred{0U};
|
||||||
ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
|
ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
|
||||||
&bytes_transferred);
|
&bytes_transferred);
|
||||||
if (ret == STATUS_SUCCESS) {
|
response.encode(bytes_transferred);
|
||||||
response.encode(bytes_transferred);
|
buffer.resize(bytes_transferred);
|
||||||
if (bytes_transferred != 0U) {
|
|
||||||
response.encode(buffer.data(), bytes_transferred);
|
if ((ret == STATUS_SUCCESS) && (bytes_transferred != 0U)) {
|
||||||
}
|
response.encode(buffer.data(), bytes_transferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "drives/directory_iterator.hpp"
|
#include "drives/directory_iterator.hpp"
|
||||||
#include "drives/remote/remote_open_file_table.hpp"
|
#include "drives/remote/remote_open_file_table.hpp"
|
||||||
#include "events/event_system.hpp"
|
#include "events/event_system.hpp"
|
||||||
#include "events/types/debug_log.hpp"
|
|
||||||
#include "events/types/remote_server_event.hpp"
|
#include "events/types/remote_server_event.hpp"
|
||||||
#include "platform/platform.hpp"
|
#include "platform/platform.hpp"
|
||||||
#include "types/remote.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) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
auto res = pread64(static_cast<native_handle>(handle), buffer, length,
|
auto res = pread64(static_cast<native_handle>(handle), buffer, length,
|
||||||
static_cast<off_t>(offset));
|
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) {
|
if (res >= 0) {
|
||||||
*bytes_transferred = static_cast<UINT32>(res);
|
*bytes_transferred = static_cast<UINT32>(res);
|
||||||
} else {
|
} else {
|
||||||
ret =
|
ret =
|
||||||
static_cast<packet::error_type>(utils::unix_error_to_windows(errno));
|
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(
|
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),
|
utils::string::to_utf8(file_name),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#if defined(_WIN32)
|
|
||||||
else {
|
|
||||||
ret = STATUS_OBJECT_NAME_COLLISION;
|
|
||||||
}
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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)) {
|
if (get_directory_buffer(reinterpret_cast<native_handle>(file_desc), ptr)) {
|
||||||
return static_cast<packet::error_type>(STATUS_SUCCESS);
|
return static_cast<packet::error_type>(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return static_cast<packet::error_type>(STATUS_INVALID_HANDLE);
|
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 {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
*bytes_transferred = 0U;
|
||||||
|
|
||||||
packet request;
|
packet request;
|
||||||
request.encode(file_desc);
|
request.encode(file_desc);
|
||||||
request.encode(offset);
|
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),
|
packet_client_.send(function_name, request, response, service_flags),
|
||||||
};
|
};
|
||||||
DECODE_OR_IGNORE(&response, *bytes_transferred);
|
DECODE_OR_IGNORE(&response, *bytes_transferred);
|
||||||
if (ret == STATUS_SUCCESS) {
|
if ((ret == STATUS_SUCCESS) && (*bytes_transferred != 0U)) {
|
||||||
ret = response.decode(buffer, *bytes_transferred);
|
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;
|
return ret;
|
||||||
@ -529,6 +521,8 @@ auto remote_client::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
*bytes_transferred = 0U;
|
||||||
|
|
||||||
packet request;
|
packet request;
|
||||||
request.encode(file_desc);
|
request.encode(file_desc);
|
||||||
request.encode(length);
|
request.encode(length);
|
||||||
|
@ -1221,6 +1221,7 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
? STATUS_SUCCESS
|
? STATUS_SUCCESS
|
||||||
: FspNtStatusFromWin32(::GetLastError());
|
: FspNtStatusFromWin32(::GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != STATUS_SUCCESS) {
|
if (ret != STATUS_SUCCESS) {
|
||||||
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
|
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
|
||||||
get_open_file_path(file_desc), ret);
|
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()));
|
wcsncpy(ofi->NormalizedName, file_path.data(), wcslen(file_path.c_str()));
|
||||||
ofi->NormalizedNameSize =
|
ofi->NormalizedNameSize =
|
||||||
static_cast<UINT16>(wcslen(file_path.c_str()) * sizeof(WCHAR));
|
static_cast<UINT16>(wcslen(file_path.c_str()) * sizeof(WCHAR));
|
||||||
|
if (exists != 0U) {
|
||||||
|
ret = STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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,
|
auto remote_winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc,
|
||||||
PVOID buffer, UINT64 offset, ULONG length,
|
PVOID buffer, UINT64 offset, ULONG length,
|
||||||
PULONG bytes_transferred) -> NTSTATUS {
|
PULONG bytes_transferred) -> NTSTATUS {
|
||||||
return remote_instance_->winfsp_read(
|
auto ret = remote_instance_->winfsp_read(
|
||||||
file_desc, buffer, offset, length,
|
file_desc, buffer, offset, length,
|
||||||
reinterpret_cast<PUINT32>(bytes_transferred));
|
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,
|
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(); }
|
open_file::~open_file() { close(); }
|
||||||
|
|
||||||
auto open_file::adjust_cache_size(std::uint64_t file_size,
|
auto open_file::adjust_cache_size(std::uint64_t file_size, bool shrink)
|
||||||
bool shrink) -> api_error {
|
-> api_error {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
if (file_size == get_file_size()) {
|
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 =
|
read_size =
|
||||||
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
||||||
if (read_size == 0U) {
|
if (read_size == 0U) {
|
||||||
|
data.resize(0U);
|
||||||
return api_error::success;
|
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 =
|
read_size =
|
||||||
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
||||||
if (read_size == 0U) {
|
if (read_size == 0U) {
|
||||||
|
data.resize(0U);
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,9 +334,14 @@ static void test_overlapped_file(auto &&mount_location, auto &&file_path,
|
|||||||
EXPECT_EQ(0,
|
EXPECT_EQ(0,
|
||||||
std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read));
|
std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read));
|
||||||
|
|
||||||
|
LARGE_INTEGER size{};
|
||||||
|
::GetFileSizeEx(handle, &size);
|
||||||
|
|
||||||
read_buffer.clear();
|
read_buffer.clear();
|
||||||
read_buffer.resize(buffer_size);
|
read_buffer.resize(buffer_size);
|
||||||
overlapped.Offset = 3U * bytes_per_sector;
|
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,
|
ret = ::ReadFile(handle, read_buffer.data(), bytes_per_sector, &bytes_read,
|
||||||
&overlapped);
|
&overlapped);
|
||||||
EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError() ||
|
EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError() ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user