Skip to content

Implement posix_getdents - #2677

Open
RajeshRk18 wants to merge 1 commit into
hermit-os:mainfrom
RajeshRk18:feat/posix-getdents
Open

Implement posix_getdents#2677
RajeshRk18 wants to merge 1 commit into
hermit-os:mainfrom
RajeshRk18:feat/posix-getdents

Conversation

@RajeshRk18

@RajeshRk18 RajeshRk18 commented Aug 24, 2026

Copy link
Copy Markdown

Closes #2034.

Adds sys_posix_getdents as specified by POSIX.1-2024 posix_getdents, alongside the existing sys_getdents64.

pub unsafe extern "C" fn sys_posix_getdents(fd: RawFd, buf: *mut PosixDent, nbyte: usize, flags: i32) -> isize

PosixDent matches struct posix_dent { d_ino, d_reclen, d_type, d_name[] } . flags must be 0 for now because POSIX defines no mandatory flags and DT_FORCE_TYPE is optional). Anything else returns EINVAL.

Implementation

  • The entry-serialization logic that was duplicated across mem.rs and virtio_fs.rs is now a single DirentFormat::write_entry, parameterized over the two entry formats. ObjectInterface::getdents takes the requested DirentFormat.
  • The default ObjectInterface::getdents now returns ENOTDIR instead of EINVAL, matching both POSIX and Linux getdents64(2) behavior for non-directory descriptors.

fixes surfaced by the new tests

  • DirectoryReader::getdents was unimplemented!(), so sys_opendir + sys_getdents64 panicked the kernel. It is now implemented.
  • MemDirectory::traverse_readdir never resolved the final path component.readdir("/tmp/gd") listed the contents of /tmp instead of /tmp/gd. Both went unnoticed because nothing exercised the sys_opendir path before.

Tests

New tests/getdents.rs integration test covers both syscalls through both the sys_opendir and O_DIRECTORY paths: entry layout/reclen for both formats, end-of-directory, partial reads with a one-entry buffer, rejected flags, EINVAL for a too-small buffer, and ENOTDIR for a file descriptor.

@RajeshRk18
RajeshRk18 marked this pull request as ready for review August 24, 2026 15:06

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark Results

Details
Benchmark Current: fb91b72 Previous: 2e23902 Performance Ratio
startup_benchmark Build Time 94.66 s 80.34 s 1.18
startup_benchmark File Size 0.79 MB 0.80 MB 0.99
Startup Time - 1 core 0.74 s (±0.01 s) 0.75 s (±0.02 s) 0.99
Startup Time - 2 cores 0.75 s (±0.02 s) 0.74 s (±0.02 s) 1.02
Startup Time - 4 cores 0.75 s (±0.01 s) 0.74 s (±0.02 s) 1.01
multithreaded_benchmark Build Time 95.40 s 82.11 s 1.16
multithreaded_benchmark File Size 0.88 MB 0.86 MB 1.03
Multithreaded Pi Efficiency - 2 Threads 65.37 % (±6.44 %) 85.89 % (±6.61 %) 0.76
Multithreaded Pi Efficiency - 4 Threads 40.16 % (±2.89 %) 43.43 % (±2.56 %) 0.92
Multithreaded Pi Efficiency - 8 Threads 19.96 % (±1.93 %) 25.76 % (±1.53 %) 0.77
micro_benchmarks Build Time 214.79 s 80.40 s 2.67
micro_benchmarks File Size 0.89 MB 0.86 MB 1.03
Scheduling time - 1 thread 195.18 ticks (±36.34 ticks) 62.65 ticks (±4.06 ticks) 3.12
Scheduling time - 2 threads 105.96 ticks (±23.25 ticks) 34.08 ticks (±4.10 ticks) 3.11
Micro - Time for syscall (getpid) 11.54 ticks (±6.00 ticks) 3.45 ticks (±0.58 ticks) 3.35
Memcpy speed - (built_in) block size 4096 58067.78 MByte/s (±41174.50 MByte/s) 82448.38 MByte/s (±56997.13 MByte/s) 0.70
Memcpy speed - (built_in) block size 1048576 13884.88 MByte/s (±11637.67 MByte/s) 30585.98 MByte/s (±24707.84 MByte/s) 0.45
Memcpy speed - (built_in) block size 16777216 11478.28 MByte/s (±9800.74 MByte/s) 26340.06 MByte/s (±21720.96 MByte/s) 0.44
Memset speed - (built_in) block size 4096 58571.80 MByte/s (±41504.68 MByte/s) 82292.76 MByte/s (±56891.50 MByte/s) 0.71
Memset speed - (built_in) block size 1048576 14284.13 MByte/s (±11911.84 MByte/s) 31323.85 MByte/s (±25145.86 MByte/s) 0.46
Memset speed - (built_in) block size 16777216 11805.78 MByte/s (±10012.50 MByte/s) 27104.68 MByte/s (±22209.94 MByte/s) 0.44
Memcpy speed - (rust) block size 4096 51137.89 MByte/s (±37079.66 MByte/s) 74097.96 MByte/s (±51811.44 MByte/s) 0.69
Memcpy speed - (rust) block size 1048576 14212.71 MByte/s (±12020.82 MByte/s) 30361.60 MByte/s (±24602.37 MByte/s) 0.47
Memcpy speed - (rust) block size 16777216 10645.96 MByte/s (±8928.89 MByte/s) 27625.34 MByte/s (±22806.88 MByte/s) 0.39
Memset speed - (rust) block size 4096 51257.40 MByte/s (±37149.43 MByte/s) 74373.47 MByte/s (±51976.48 MByte/s) 0.69
Memset speed - (rust) block size 1048576 14528.18 MByte/s (±12201.79 MByte/s) 31110.89 MByte/s (±25033.24 MByte/s) 0.47
Memset speed - (rust) block size 16777216 11133.34 MByte/s (±9368.49 MByte/s) 28386.93 MByte/s (±23265.03 MByte/s) 0.39
alloc_benchmarks Build Time 224.58 s 74.76 s 3.00
alloc_benchmarks File Size 0.87 MB 0.87 MB 0.99
Allocations - Allocation success 91.38 % 91.31 % 1.00
Allocations - Deallocation success 100.00 % 100.00 % 1
Allocations - Pre-fail Allocations 61.60 % 61.44 % 1.00
Allocations - Average Allocation time 20975.80 Ticks (±1322.15 Ticks) 5860.58 Ticks (±98.43 Ticks) 3.58
Allocations - Average Allocation time (no fail) 22854.28 Ticks (±1610.76 Ticks) 6554.81 Ticks (±92.86 Ticks) 3.49
Allocations - Average Deallocation time 10123.07 Ticks (±1259.24 Ticks) 1805.01 Ticks (±250.35 Ticks) 5.61
mutex_benchmark Build Time 216.52 s 79.82 s 2.71
mutex_benchmark File Size 0.89 MB 0.86 MB 1.03
Mutex Stress Test Average Time per Iteration - 1 Threads 34.82 ns (±7.91 ns) 12.10 ns (±0.41 ns) 2.88
Mutex Stress Test Average Time per Iteration - 2 Threads 32.22 ns (±10.40 ns) 40.26 ns (±1.68 ns) 0.80

This comment was automatically generated by workflow using github-action-benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement posix_getdents

2 participants