From 452e134a86944a787f3f50fc43f0f8f0890a1b17 Mon Sep 17 00:00:00 2001 From: Kai Mast Date: Sun, 2 Jul 2023 17:34:49 -0400 Subject: [PATCH 1/3] Add read_to_end functionality --- src/fs/file.rs | 27 +++++++++++++++++++++++++++ src/io/write.rs | 2 +- tests/fs_file.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/fs/file.rs b/src/fs/file.rs index 9cd47f21..e7e8a1c0 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -444,6 +444,33 @@ impl File { (Ok(()), buf.into_inner()) } + /// Fills a vector with the contents of the file + /// from the given position to the end + /// + /// If this function encounters any form of I/O or other error, an error + /// variant will be returned. + /// On error the buffer will contain the partial data that was + /// read up until this point. + pub async fn read_at_to_end(&self, mut pos: u64, mut result: Vec) -> crate::BufResult<(), Vec> { + let mut buffer = vec![0u8; 1024]; + + loop { + let (res, buf) = self.read_at(buffer, pos).await; + + match res { + Ok(0) => { + return (Ok(()), result) + } + Ok(n) => { + buffer = buf; + result.extend_from_slice(&buffer[..n]); + pos += n as u64; + } + Err(err) => return (Err(err), result), + } + } + } + /// Like [`read_at`], but using a pre-mapped buffer /// registered with [`FixedBufRegistry`]. /// diff --git a/src/io/write.rs b/src/io/write.rs index 9063282b..6c607f75 100644 --- a/src/io/write.rs +++ b/src/io/write.rs @@ -49,7 +49,7 @@ impl UnsubmittedWrite { buf, }, WriteTransform { - _phantom: PhantomData::default(), + _phantom: PhantomData, }, opcode::Write::new(types::Fd(fd.raw_fd()), ptr, len as _) .offset(offset as _) diff --git a/tests/fs_file.rs b/tests/fs_file.rs index 6ec14d43..08622834 100644 --- a/tests/fs_file.rs +++ b/tests/fs_file.rs @@ -37,6 +37,23 @@ fn basic_read() { }); } +#[test] +fn read_exact_buf_too_long() { + tokio_uring::start(async { + let data = HELLO.repeat(1); + let buf = Vec::with_capacity(data.len() * 2); + + let mut tempfile = tempfile(); + tempfile.write_all(&data).unwrap(); + + let file = File::open(tempfile.path()).await.unwrap(); + let (res, _buf) = file.read_exact_at(buf, 0).await; + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().kind(), std::io::ErrorKind::UnexpectedEof); + }); +} + #[test] fn basic_read_exact() { tokio_uring::start(async { @@ -53,6 +70,23 @@ fn basic_read_exact() { }); } +#[test] +fn basic_read_to_end() { + tokio_uring::start(async { + let data = HELLO.repeat(1); + + let mut tempfile = tempfile(); + tempfile.write_all(&data).unwrap(); + + let file = File::open(tempfile.path()).await.unwrap(); + + let buf = vec![]; + let (res, buf) = file.read_at_to_end(0, buf).await; + res.unwrap(); + assert_eq!(buf, data); + }); +} + #[test] fn basic_write() { tokio_uring::start(async { From 2a3bed72c339ce27f127dbc891b8c0f372967f01 Mon Sep 17 00:00:00 2001 From: Kai Mast Date: Sun, 2 Jul 2023 17:40:53 -0400 Subject: [PATCH 2/3] Cargo fmt --- src/buf/fixed/plumbing/registry.rs | 2 +- src/fs/file.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/buf/fixed/plumbing/registry.rs b/src/buf/fixed/plumbing/registry.rs index ff8ffe30..4f88746e 100644 --- a/src/buf/fixed/plumbing/registry.rs +++ b/src/buf/fixed/plumbing/registry.rs @@ -74,7 +74,7 @@ impl Registry { pub(crate) fn check_out(&mut self, index: usize) -> Option { let state = self.states.get_mut(index)?; let BufState::Free { init_len } = *state else { - return None + return None; }; *state = BufState::CheckedOut; diff --git a/src/fs/file.rs b/src/fs/file.rs index e7e8a1c0..c4e06378 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -451,16 +451,18 @@ impl File { /// variant will be returned. /// On error the buffer will contain the partial data that was /// read up until this point. - pub async fn read_at_to_end(&self, mut pos: u64, mut result: Vec) -> crate::BufResult<(), Vec> { + pub async fn read_at_to_end( + &self, + mut pos: u64, + mut result: Vec, + ) -> crate::BufResult<(), Vec> { let mut buffer = vec![0u8; 1024]; loop { let (res, buf) = self.read_at(buffer, pos).await; match res { - Ok(0) => { - return (Ok(()), result) - } + Ok(0) => return (Ok(()), result), Ok(n) => { buffer = buf; result.extend_from_slice(&buffer[..n]); From 660c7be14c64446d5c291422b56de5f5c982a9dd Mon Sep 17 00:00:00 2001 From: Kai Mast Date: Mon, 22 Jul 2024 11:09:44 -0700 Subject: [PATCH 3/3] Use larger buffer for read_to_end --- src/fs/file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fs/file.rs b/src/fs/file.rs index c4e06378..bf3f561f 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -456,7 +456,7 @@ impl File { mut pos: u64, mut result: Vec, ) -> crate::BufResult<(), Vec> { - let mut buffer = vec![0u8; 1024]; + let mut buffer = vec![0u8; 4096]; loop { let (res, buf) = self.read_at(buffer, pos).await;