Skip to content

Commit bc47644

Browse files
authored
Simplify RawDir iteration (#515)
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com> Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
1 parent 5356380 commit bc47644

File tree

1 file changed

+23
-24
lines changed

1 file changed

+23
-24
lines changed

src/fs/raw_dir.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -172,34 +172,33 @@ impl<'buf, Fd: AsFd> RawDir<'buf, Fd> {
172172
/// GAT support once one becomes available.
173173
#[allow(unsafe_code)]
174174
pub fn next(&mut self) -> Option<io::Result<RawDirEntry>> {
175-
loop {
176-
if self.offset < self.initialized {
177-
let dirent_ptr = self.buf[self.offset..].as_ptr();
178-
// SAFETY:
179-
// - This data is initialized by the check above.
180-
// - Assumption: the kernel will not give us partial structs.
181-
// - Assumption: the kernel uses proper alignment between structs.
182-
// - The starting pointer is aligned (performed in RawDir::new)
183-
let dirent = unsafe { &*dirent_ptr.cast::<linux_dirent64>() };
184-
185-
self.offset += usize::from(dirent.d_reclen);
186-
187-
return Some(Ok(RawDirEntry {
188-
file_type: dirent.d_type,
189-
inode_number: dirent.d_ino,
190-
next_entry_cookie: dirent.d_off,
191-
// SAFETY: the kernel guarantees a NUL terminated string.
192-
file_name: unsafe { CStr::from_ptr(dirent.d_name.as_ptr().cast()) },
193-
}));
194-
}
195-
self.initialized = 0;
196-
self.offset = 0;
197-
175+
if self.offset >= self.initialized {
198176
match getdents_uninit(self.fd.as_fd(), self.buf) {
199177
Ok(bytes_read) if bytes_read == 0 => return None,
200-
Ok(bytes_read) => self.initialized = bytes_read,
178+
Ok(bytes_read) => {
179+
self.initialized = bytes_read;
180+
self.offset = 0;
181+
}
201182
Err(e) => return Some(Err(e)),
202183
}
203184
}
185+
186+
let dirent_ptr = self.buf[self.offset..].as_ptr();
187+
// SAFETY:
188+
// - This data is initialized by the check above.
189+
// - Assumption: the kernel will not give us partial structs.
190+
// - Assumption: the kernel uses proper alignment between structs.
191+
// - The starting pointer is aligned (performed in RawDir::new)
192+
let dirent = unsafe { &*dirent_ptr.cast::<linux_dirent64>() };
193+
194+
self.offset += usize::from(dirent.d_reclen);
195+
196+
Some(Ok(RawDirEntry {
197+
file_type: dirent.d_type,
198+
inode_number: dirent.d_ino,
199+
next_entry_cookie: dirent.d_off,
200+
// SAFETY: the kernel guarantees a NUL terminated string.
201+
file_name: unsafe { CStr::from_ptr(dirent.d_name.as_ptr().cast()) },
202+
}))
204203
}
205204
}

0 commit comments

Comments
 (0)