block: fix short read and short write in AsyncAdaptor

The original code relied on the default `read_vectored` or
`write_vectored` implementations from the standard library.

The default implementation of those functions only uses the first
non-empty buffer. That's not correct when there are more than one
buffers.

Fixes: #6876
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2024-12-20 23:42:35 +00:00 committed by Rob Bradford
parent 72452707ee
commit b2f40afc69

View File

@ -668,9 +668,11 @@ where
file.seek(SeekFrom::Start(offset as u64)) file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::ReadVectored)?; .map_err(AsyncIoError::ReadVectored)?;
// Read vectored let mut r = 0;
file.read_vectored(slices.as_mut_slice()) for b in slices.iter_mut() {
.map_err(AsyncIoError::ReadVectored)? r += file.read(b).map_err(AsyncIoError::ReadVectored)?;
}
r
}; };
completion_list.push_back((user_data, result as i32)); completion_list.push_back((user_data, result as i32));
@ -703,9 +705,11 @@ where
file.seek(SeekFrom::Start(offset as u64)) file.seek(SeekFrom::Start(offset as u64))
.map_err(AsyncIoError::WriteVectored)?; .map_err(AsyncIoError::WriteVectored)?;
// Write vectored let mut r = 0;
file.write_vectored(slices.as_slice()) for b in slices.iter() {
.map_err(AsyncIoError::WriteVectored)? r += file.write(b).map_err(AsyncIoError::WriteVectored)?;
}
r
}; };
completion_list.push_back((user_data, result as i32)); completion_list.push_back((user_data, result as i32));