IoUring: implement outstanding flags and enumerations

Add SYNC_FILE_RANGE_* flags
add XATTR_* flags
Add Madvise for MADV_* constants
Add Fadvise enum type for POSIX_FADV_* constants

Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
Bernard Assan 2025-10-24 17:33:46 +00:00
parent 56bf5865fe
commit 7d72bdda8a
No known key found for this signature in database
GPG key ID: C2A2C53574321095
2 changed files with 172 additions and 62 deletions

View file

@ -499,6 +499,7 @@ pub const O = switch (native_arch) {
pub const Pipe2 = switch (native_arch) { pub const Pipe2 = switch (native_arch) {
.x86_64, .x86, .riscv32, .riscv64, .loongarch64, .hexagon, .or1k, .s390x => packed struct(u32) { .x86_64, .x86, .riscv32, .riscv64, .loongarch64, .hexagon, .or1k, .s390x => packed struct(u32) {
_: u7 = 0, _: u7 = 0,
/// Parameter to `pipe2` selecting notification pipe
notification_pipe: bool = false, notification_pipe: bool = false,
_9: u3 = 0, _9: u3 = 0,
nonblock: bool = false, nonblock: bool = false,
@ -510,6 +511,7 @@ pub const Pipe2 = switch (native_arch) {
}, },
.aarch64, .aarch64_be, .arm, .armeb, .thumb, .thumbeb, .m68k => packed struct(u32) { .aarch64, .aarch64_be, .arm, .armeb, .thumb, .thumbeb, .m68k => packed struct(u32) {
_: u7 = 0, _: u7 = 0,
/// Parameter to `pipe2` selecting notification pipe
notification_pipe: bool = false, notification_pipe: bool = false,
_9: u3 = 0, _9: u3 = 0,
nonblock: bool = false, nonblock: bool = false,
@ -521,6 +523,7 @@ pub const Pipe2 = switch (native_arch) {
}, },
.sparc64 => packed struct(u32) { .sparc64 => packed struct(u32) {
_: u11 = 0, _: u11 = 0,
/// Parameter to `pipe2` selecting notification pipe
notification_pipe: bool = false, notification_pipe: bool = false,
_13: u2 = 0, _13: u2 = 0,
nonblock: bool = false, nonblock: bool = false,
@ -534,6 +537,7 @@ pub const Pipe2 = switch (native_arch) {
_: u7 = 0, _: u7 = 0,
nonblock: bool = false, nonblock: bool = false,
_9: u2 = 0, _9: u2 = 0,
/// Parameter to `pipe2` selecting notification pipe
notification_pipe: bool = false, notification_pipe: bool = false,
_12: u4 = 0, _12: u4 = 0,
direct: bool = false, direct: bool = false,
@ -543,6 +547,7 @@ pub const Pipe2 = switch (native_arch) {
}, },
.powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) { .powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) {
_: u7 = 0, _: u7 = 0,
/// Parameter to `pipe2` selecting notification pipe
notification_pipe: bool = false, notification_pipe: bool = false,
_9: u3 = 0, _9: u3 = 0,
nonblock: bool = false, nonblock: bool = false,
@ -882,7 +887,6 @@ pub fn futex2_wake(
/// Identical to `FUTEX.CMP_REQUEUE`, except it is part of the futex2 family of calls. /// Identical to `FUTEX.CMP_REQUEUE`, except it is part of the futex2 family of calls.
/// ///
/// Requires at least kernel v6.7. /// Requires at least kernel v6.7.
// TODO: test to ensure I didn't break it
pub fn futex2_requeue( pub fn futex2_requeue(
/// The source and destination futexes. Must be a 2-element array. /// The source and destination futexes. Must be a 2-element array.
waiters: *const [2]Futex2.WaitOne, waiters: *const [2]Futex2.WaitOne,
@ -4182,9 +4186,19 @@ pub const Shut = enum(u32) {
pub const RDWR: u32 = @intFromEnum(Shut.rdwr); pub const RDWR: u32 = @intFromEnum(Shut.rdwr);
}; };
/// SYNC_FILE_RANGE_* flags /// flags for `sync_file_range(2)` syscall
/// matches SYNC_FILE_RANGE_* in kernel
pub const SyncFileRange = packed struct(u32) { pub const SyncFileRange = packed struct(u32) {
_: u32 = 0, // TODO: fill out wait_before: bool = false,
write: bool = false,
wait_after: bool = false,
_: u29 = 0,
pub const write_and_wait: SyncFileRange = .{
.wait_before = true,
.write = true,
.wait_after = true,
};
}; };
/// Deprecated alias to Sock /// Deprecated alias to Sock
@ -7005,9 +7019,18 @@ pub const Rename = packed struct(u32) {
_: u29 = 0, _: u29 = 0,
}; };
/// By default (i.e, flags is .{}), the extended attribute will be created
/// if it does not exist, or the value will be replaced if the attribute
/// already exists. To modify this semantics, one of the fields in `SetXattr`
/// can be specified in flags. Matches XATTR_* in kernel
pub const SetXattr = packed struct(u32) { pub const SetXattr = packed struct(u32) {
_: u32 = 0, // TODO: add flags /// set value, fail if attr already exists
create: bool = false,
/// set value, fail if attr does not exist
replace: bool = false,
_: u30 = 0,
}; };
pub const statx_timestamp = extern struct { pub const statx_timestamp = extern struct {
sec: i64, sec: i64,
nsec: u32, nsec: u32,
@ -8549,60 +8572,142 @@ pub const rlimit = extern struct {
max: rlim_t, max: rlim_t,
}; };
pub const MADV = struct { /// DEPRECATED alias for Madvise
pub const NORMAL = 0; pub const MADV = Madvise;
pub const RANDOM = 1;
pub const SEQUENTIAL = 2; // COMMIT: update MADV_* flags and type as enum
pub const WILLNEED = 3; /// advice flags for `madvise`
pub const DONTNEED = 4; /// matches MADV_* in kernel
pub const FREE = 8; pub const Madvise = enum(u32) {
pub const REMOVE = 9; /// no further special treatment
pub const DONTFORK = 10; normal = 0,
pub const DOFORK = 11; /// expect random page references
pub const MERGEABLE = 12; random = 1,
pub const UNMERGEABLE = 13; /// expect sequential page references
pub const HUGEPAGE = 14; sequential = 2,
pub const NOHUGEPAGE = 15; /// will need these pages
pub const DONTDUMP = 16; willneed = 3,
pub const DODUMP = 17; /// don't need these pages
pub const WIPEONFORK = 18; dontneed = 4,
pub const KEEPONFORK = 19; /// free pages only if memory pressure
pub const COLD = 20; free = 8,
pub const PAGEOUT = 21; /// remove these pages & resources
pub const HWPOISON = 100; remove = 9,
pub const SOFT_OFFLINE = 101; /// don't inherit across fork
dontfork = 10,
/// do inherit across fork
dofork = 11,
/// KSM may merge identical pages
mergeable = 12,
/// KSM may not merge identical pages
unmergeable = 13,
/// Worth backing with hugepages
hugepage = 14,
/// Not worth backing with hugepages
nohugepage = 15,
/// Explicity exclude from the core dump, overrides the coredump filter bits
dontdump = 16,
/// Clear the MADV_DONTDUMP flag
dodump = 17,
/// Zero memory on fork, child only
wipeonfork = 18,
/// Undo MADV_WIPEONFORK
keeponfork = 19,
/// deactivate these pages
cold = 20,
/// reclaim these pages
pageout = 21,
/// populate (prefault) page tables readable
populate_read = 22,
/// populate (prefault) page tables writable
populate_write = 23,
/// like DONTNEED, but drop locked pages too
dontneed_locked = 24,
/// Synchronous hugepage collapse
collapse = 25,
/// poison a page for testing
hwpoison = 100,
/// soft offline page for testing
soft_offline = 101,
/// fatal signal on access to range
guard_install = 102,
/// unguard range
guard_remove = 103,
_,
// DEPRECATED aliases for `Madvise`
pub const NORMAL: u32 = @intFromEnum(Madvise.normal);
pub const RANDOM: u32 = @intFromEnum(Madvise.random);
pub const SEQUENTIAL: u32 = @intFromEnum(Madvise.sequential);
pub const WILLNEED: u32 = @intFromEnum(Madvise.willneed);
pub const DONTNEED: u32 = @intFromEnum(Madvise.dontneed);
pub const FREE: u32 = @intFromEnum(Madvise.free);
pub const REMOVE: u32 = @intFromEnum(Madvise.remove);
pub const DONTFORK: u32 = @intFromEnum(Madvise.dontfork);
pub const DOFORK: u32 = @intFromEnum(Madvise.dofork);
pub const MERGEABLE: u32 = @intFromEnum(Madvise.mergeable);
pub const UNMERGEABLE: u32 = @intFromEnum(Madvise.unmergeable);
pub const HUGEPAGE: u32 = @intFromEnum(Madvise.hugepage);
pub const NOHUGEPAGE: u32 = @intFromEnum(Madvise.nohugepage);
pub const DONTDUMP: u32 = @intFromEnum(Madvise.dontdump);
pub const DODUMP: u32 = @intFromEnum(Madvise.dodump);
pub const WIPEONFORK: u32 = @intFromEnum(Madvise.wipeonfork);
pub const KEEPONFORK: u32 = @intFromEnum(Madvise.keeponfork);
pub const COLD: u32 = @intFromEnum(Madvise.cold);
pub const PAGEOUT: u32 = @intFromEnum(Madvise.pageout);
pub const HWPOISON: u32 = @intFromEnum(Madvise.hwpoison);
pub const SOFT_OFFLINE: u32 = @intFromEnum(Madvise.soft_offline);
}; };
pub const Madvice = enum(u32) { /// DEPRECATED alias to Fadvice
_, // TODO: add options pub const POSIX_FADV = Fadvise;
};
pub const Fadvice = enum(u32) {
_, // TODO: add options
};
pub const POSIX_FADV = switch (native_arch) { /// advice flags for `posix_fadvise`
.s390x => if (@typeInfo(usize).int.bits == 64) struct { /// matches POSIX_FADV_* in kernel
pub const NORMAL = 0; pub const Fadvise = switch (native_arch) {
pub const RANDOM = 1; .s390x => if (@typeInfo(usize).int.bits == 64) enum(u32) {
pub const SEQUENTIAL = 2; /// No further special treatment
pub const WILLNEED = 3; normal = 0,
pub const DONTNEED = 6; /// Expect random page references
pub const NOREUSE = 7; random = 1,
} else struct { /// Expect sequential page references
pub const NORMAL = 0; sequential = 2,
pub const RANDOM = 1; /// Will need these pages
pub const SEQUENTIAL = 2; willneed = 3,
pub const WILLNEED = 3; /// Don't need these pages
pub const DONTNEED = 4; dontneed = 6,
pub const NOREUSE = 5; /// Data will be accessed once
noreuse = 7,
_,
pub const NORMAL: u32 = @intFromEnum(Fadvise.normal);
pub const RANDOM: u32 = @intFromEnum(Fadvise.random);
pub const SEQUENTIAL: u32 = @intFromEnum(Fadvise.sequential);
pub const WILLNEED: u32 = @intFromEnum(Fadvise.willneed);
pub const DONTNEED: u32 = @intFromEnum(Fadvise.dontneed);
pub const NOREUSE: u32 = @intFromEnum(Fadvise.noreuse);
}, },
else => struct { else => enum(u32) {
pub const NORMAL = 0; /// No further special treatment
pub const RANDOM = 1; normal = 0,
pub const SEQUENTIAL = 2; /// Expect random page references
pub const WILLNEED = 3; random = 1,
pub const DONTNEED = 4; /// Expect sequential page references
pub const NOREUSE = 5; sequential = 2,
/// Will need these pages
willneed = 3,
/// Don't need these pages
dontneed = 4,
/// Data will be accessed once
noreuse = 5,
_,
pub const NORMAL: u32 = @intFromEnum(Fadvise.normal);
pub const RANDOM: u32 = @intFromEnum(Fadvise.random);
pub const SEQUENTIAL: u32 = @intFromEnum(Fadvise.sequential);
pub const WILLNEED: u32 = @intFromEnum(Fadvise.willneed);
pub const DONTNEED: u32 = @intFromEnum(Fadvise.dontneed);
pub const NOREUSE: u32 = @intFromEnum(Fadvise.noreuse);
}, },
}; };

View file

@ -1137,7 +1137,7 @@ pub fn fadvice(
fd: linux.fd_t, fd: linux.fd_t,
offset: u64, offset: u64,
len: u32, len: u32,
advice: linux.Fadvice, advice: linux.Fadvise,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
sqe.prep_fadvice(fd, offset, len, advice); sqe.prep_fadvice(fd, offset, len, advice);
@ -1151,7 +1151,7 @@ pub fn madvice(
self: *IoUring, self: *IoUring,
user_data: u64, user_data: u64,
memory: []u8, memory: []u8,
advice: linux.Fadvice, advice: linux.Madvise,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
sqe.prep_madvice(memory, advice); sqe.prep_madvice(memory, advice);
@ -1351,7 +1351,13 @@ pub fn provide_buffers(
buffer_id: usize, buffer_id: usize,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
sqe.prep_provide_buffers(buffers, buffer_size, buffers_count, group_id, buffer_id); sqe.prep_provide_buffers(
buffers,
buffer_size,
buffers_count,
group_id,
buffer_id,
);
sqe.user_data = user_data; sqe.user_data = user_data;
return sqe; return sqe;
} }
@ -1449,7 +1455,7 @@ pub fn sync_file_range(
fd: linux.fd_t, fd: linux.fd_t,
len: u32, len: u32,
offset: u64, offset: u64,
flags: linux.SyncFileRange, // TODO: add flags flags: linux.SyncFileRange,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
sqe.prep_sync_file_range(fd, len, offset, flags); sqe.prep_sync_file_range(fd, len, offset, flags);
@ -2220,7 +2226,6 @@ pub fn getsockopt(
); );
} }
// TODO: move buf_ring fns into BufferRing type
/// Registers a shared buffer ring to be used with provided buffers. `entries` /// Registers a shared buffer ring to be used with provided buffers. `entries`
/// number of `io_uring_buf` structures is mem mapped and shared by kernel. /// number of `io_uring_buf` structures is mem mapped and shared by kernel.
/// ///
@ -2967,7 +2972,7 @@ pub const Sqe = extern struct {
fd: linux.fd_t, fd: linux.fd_t,
offset: u64, offset: u64,
len: u32, len: u32,
advice: linux.Fadvice, advice: linux.Fadvise,
) void { ) void {
sqe.prep_rw(.fadvise, fd, undefined, len, offset); sqe.prep_rw(.fadvise, fd, undefined, len, offset);
sqe.rw_flags = @intFromEnum(advice); sqe.rw_flags = @intFromEnum(advice);
@ -2976,7 +2981,7 @@ pub const Sqe = extern struct {
pub fn prep_madvice( pub fn prep_madvice(
sqe: *Sqe, sqe: *Sqe,
memory: []u8, memory: []u8,
advice: linux.Madvice, advice: linux.Madvise,
) void { ) void {
sqe.prep_rw(.madvise, -1, @intFromPtr(memory.ptr), memory.len, 0); sqe.prep_rw(.madvise, -1, @intFromPtr(memory.ptr), memory.len, 0);
sqe.rw_flags = @intFromEnum(advice); sqe.rw_flags = @intFromEnum(advice);
@ -3047,7 +3052,7 @@ pub const Sqe = extern struct {
fd: linux.fd_t, fd: linux.fd_t,
len: u32, len: u32,
offset: u64, offset: u64,
flags: linux.SyncFileRange, // TODO: add flags flags: linux.SyncFileRange,
) void { ) void {
sqe.prep_rw(.sync_file_range, fd, undefined, len, offset); sqe.prep_rw(.sync_file_range, fd, undefined, len, offset);
sqe.rw_flags = @bitCast(flags); sqe.rw_flags = @bitCast(flags);