Skip to content

Commit 6a4cee3

Browse files
committed
Add XattrSource to decide how to prepare set/getxattr operations
Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
1 parent caf492e commit 6a4cee3

File tree

1 file changed

+143
-83
lines changed

1 file changed

+143
-83
lines changed

lib/std/os/linux/IoUring.zig

Lines changed: 143 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,35 +1636,121 @@ pub fn msg_ring_fd_alloc(
16361636

16371637
/// Queues (but does not submit) an SQE to prepares a request to get an
16381638
/// extended attribute value
1639+
/// The `from` parameter is used to decide the source to get the extended
1640+
/// attributes from
16391641
/// Returns a pointer to the SQE.
16401642
pub fn getxattr(
16411643
self: *IoUring,
16421644
user_data: u64,
16431645
name: []const u8,
16441646
value: []const u8,
1645-
path: []const u8,
1647+
from: XattrSource,
16461648
len: u32,
16471649
) !*Sqe {
16481650
const sqe = try self.get_sqe();
1649-
sqe.prep_getxattr(name, value, path, len);
1651+
switch (from) {
1652+
.path => |path_| sqe.prep_getxattr(name, value, path_, len),
1653+
.fd => |fd_| sqe.prep_fgetxattr(name, value, fd_, len),
1654+
}
16501655
sqe.user_data = user_data;
16511656
return sqe;
16521657
}
16531658

16541659
/// Queues (but does not submit) an SQE to prepares a request to set an
16551660
/// extended attribute value
1661+
/// The `on` parameter is used to decide the source to set the extended
1662+
/// attributes on
16561663
/// Returns a pointer to the SQE.
16571664
pub fn setxattr(
16581665
self: *IoUring,
16591666
user_data: u64,
16601667
name: []const u8,
16611668
value: []const u8,
1662-
path: []const u8,
1669+
on: XattrSource,
16631670
flags: linux.SetXattr,
16641671
len: u32,
16651672
) !*Sqe {
16661673
const sqe = try self.get_sqe();
1667-
sqe.prep_setxattr(name, value, path, flags, len);
1674+
switch (on) {
1675+
.path => |path_| sqe.prep_setxattr(name, value, path_, flags, len),
1676+
.fd => |fd_| sqe.prep_fsetxattr(name, value, fd_, flags, len),
1677+
}
1678+
sqe.user_data = user_data;
1679+
return sqe;
1680+
}
1681+
1682+
/// Prepares a socket creation request.
1683+
/// New socket fd will be returned in completion result.
1684+
/// Available since 5.19
1685+
pub fn socket(
1686+
self: *IoUring,
1687+
user_data: u64,
1688+
domain: linux.Af,
1689+
socket_type: linux.Sock,
1690+
protocol: linux.IpProto,
1691+
/// flags is unused
1692+
flags: u32,
1693+
) !*Sqe {
1694+
const sqe = try self.get_sqe();
1695+
sqe.prep_socket(domain, socket_type, protocol, flags);
1696+
sqe.user_data = user_data;
1697+
return sqe;
1698+
}
1699+
1700+
/// Prepares a socket creation request for registered file at index `file_index`.
1701+
/// Available since 5.19
1702+
pub fn socket_direct(
1703+
self: *IoUring,
1704+
user_data: u64,
1705+
domain: linux.Af,
1706+
socket_type: linux.Sock,
1707+
protocol: linux.IpProto,
1708+
/// flags is unused
1709+
flags: u32,
1710+
file_index: u32,
1711+
) !*Sqe {
1712+
const sqe = try self.get_sqe();
1713+
sqe.prep_socket_direct(domain, socket_type, protocol, flags, file_index);
1714+
sqe.user_data = user_data;
1715+
return sqe;
1716+
}
1717+
1718+
/// Prepares a socket creation request for registered file, index chosen by
1719+
/// kernel (file index alloc).
1720+
/// File index will be returned in CQE res field.
1721+
/// Available since 5.19
1722+
pub fn socket_direct_alloc(
1723+
self: *IoUring,
1724+
user_data: u64,
1725+
domain: linux.Af,
1726+
socket_type: linux.Sock,
1727+
protocol: linux.IpProto,
1728+
/// flags unused
1729+
flags: u32,
1730+
) !*Sqe {
1731+
const sqe = try self.get_sqe();
1732+
sqe.prep_socket_direct_alloc(domain, socket_type, protocol, flags);
1733+
sqe.user_data = user_data;
1734+
return sqe;
1735+
}
1736+
1737+
/// Prepares an cmd request for a socket.
1738+
/// See: https://man7.org/linux/man-pages/man3/io_uring_prep_cmd.3.html
1739+
/// Available since 6.7.
1740+
pub fn cmd_sock(
1741+
self: *IoUring,
1742+
user_data: u64,
1743+
cmd_op: SocketOp,
1744+
fd: linux.fd_t,
1745+
level: linux.Sol,
1746+
optname: linux.So,
1747+
/// pointer to the option value
1748+
optval: u64,
1749+
/// size of the option value
1750+
optlen: u32,
1751+
) !*Sqe {
1752+
const sqe = try self.get_sqe();
1753+
sqe.prep_cmd_sock(cmd_op, fd, level, optname, optval, optlen);
16681754
sqe.user_data = user_data;
16691755
return sqe;
16701756
}
@@ -1678,7 +1764,8 @@ pub fn waitid(
16781764
id: i32,
16791765
infop: *linux.siginfo_t,
16801766
options: linux.W,
1681-
flags: u32, // They are currently unused, and hence 0 should be passed
1767+
/// They are currently unused, and hence 0 should be passed
1768+
flags: u32,
16821769
) !*Sqe {
16831770
const sqe = try self.get_sqe();
16841771
sqe.prep_waitid(id_type, id, infop, options, flags);
@@ -1932,8 +2019,7 @@ pub fn register_ifq(self: *IoUring, ifq_reg: *ZcrxIfqRegister) !void {
19322019
try handle_registration_result(res);
19332020
}
19342021

1935-
pub fn register_resize_rings(self: *IoUring, params: *Params) !void {
1936-
_ = params; // autofix
2022+
pub fn register_resize_rings(self: *IoUring, _: *Params) !void {
19372023
assert(self.fd >= 0);
19382024
return error.Unimplemented;
19392025
}
@@ -1981,78 +2067,6 @@ fn handle_registration_result(res: usize) !void {
19812067
}
19822068
}
19832069

1984-
/// Prepares a socket creation request.
1985-
/// New socket fd will be returned in completion result.
1986-
/// Available since 5.19
1987-
pub fn socket(
1988-
self: *IoUring,
1989-
user_data: u64,
1990-
domain: linux.Af,
1991-
socket_type: linux.Sock,
1992-
protocol: linux.IpProto,
1993-
flags: u32, // flags is unused
1994-
) !*Sqe {
1995-
const sqe = try self.get_sqe();
1996-
sqe.prep_socket(domain, socket_type, protocol, flags);
1997-
sqe.user_data = user_data;
1998-
return sqe;
1999-
}
2000-
2001-
/// Prepares a socket creation request for registered file at index `file_index`.
2002-
/// Available since 5.19
2003-
pub fn socket_direct(
2004-
self: *IoUring,
2005-
user_data: u64,
2006-
domain: linux.Af,
2007-
socket_type: linux.Sock,
2008-
protocol: linux.IpProto,
2009-
/// flags is unused
2010-
flags: u32,
2011-
file_index: u32,
2012-
) !*Sqe {
2013-
const sqe = try self.get_sqe();
2014-
sqe.prep_socket_direct(domain, socket_type, protocol, flags, file_index);
2015-
sqe.user_data = user_data;
2016-
return sqe;
2017-
}
2018-
2019-
/// Prepares a socket creation request for registered file, index chosen by
2020-
/// kernel (file index alloc).
2021-
/// File index will be returned in CQE res field.
2022-
/// Available since 5.19
2023-
pub fn socket_direct_alloc(
2024-
self: *IoUring,
2025-
user_data: u64,
2026-
domain: linux.Af,
2027-
socket_type: linux.Sock,
2028-
protocol: linux.IpProto,
2029-
flags: u32, // flags unused
2030-
) !*Sqe {
2031-
const sqe = try self.get_sqe();
2032-
sqe.prep_socket_direct_alloc(domain, socket_type, protocol, flags);
2033-
sqe.user_data = user_data;
2034-
return sqe;
2035-
}
2036-
2037-
/// Prepares an cmd request for a socket.
2038-
/// See: https://man7.org/linux/man-pages/man3/io_uring_prep_cmd.3.html
2039-
/// Available since 6.7.
2040-
pub fn cmd_sock(
2041-
self: *IoUring,
2042-
user_data: u64,
2043-
cmd_op: SocketOp,
2044-
fd: linux.fd_t,
2045-
level: linux.Sol,
2046-
optname: linux.So,
2047-
optval: u64, // pointer to the option value
2048-
optlen: u32, // size of the option value
2049-
) !*Sqe {
2050-
const sqe = try self.get_sqe();
2051-
sqe.prep_cmd_sock(cmd_op, fd, level, optname, optval, optlen);
2052-
sqe.user_data = user_data;
2053-
return sqe;
2054-
}
2055-
20562070
/// Prepares set socket option for the optname argument, at the protocol
20572071
/// level specified by the level argument.
20582072
/// Available since 6.7.n
@@ -3064,6 +3078,22 @@ pub const Sqe = extern struct {
30643078
sqe.addr3 = @intFromPtr(path.ptr);
30653079
}
30663080

3081+
pub fn prep_fgetxattr(
3082+
sqe: *Sqe,
3083+
name: []const u8,
3084+
value: []const u8,
3085+
fd: linux.fd_t,
3086+
len: u32,
3087+
) void {
3088+
sqe.prep_rw(
3089+
.fgetxattr,
3090+
fd,
3091+
@intFromPtr(name.ptr),
3092+
len,
3093+
@intFromPtr(value.ptr),
3094+
);
3095+
}
3096+
30673097
pub fn prep_setxattr(
30683098
sqe: *Sqe,
30693099
name: []const u8,
@@ -3083,6 +3113,24 @@ pub const Sqe = extern struct {
30833113
sqe.rw_flags = @bitCast(flags);
30843114
}
30853115

3116+
pub fn prep_fsetxattr(
3117+
sqe: *Sqe,
3118+
name: []const u8,
3119+
value: []const u8,
3120+
fd: linux.fd_t,
3121+
flags: linux.SetXattr,
3122+
len: u32,
3123+
) void {
3124+
sqe.prep_rw(
3125+
.fsetxattr,
3126+
fd,
3127+
@intFromPtr(name.ptr),
3128+
len,
3129+
@intFromPtr(value.ptr),
3130+
);
3131+
sqe.rw_flags = @bitCast(flags);
3132+
}
3133+
30863134
pub fn prep_files_update(
30873135
sqe: *Sqe,
30883136
fds: []const linux.fd_t,
@@ -3126,7 +3174,8 @@ pub const Sqe = extern struct {
31263174
domain: linux.Af,
31273175
socket_type: linux.Sock,
31283176
protocol: linux.IpProto,
3129-
flags: u32, // flags is unused
3177+
/// flags is unused
3178+
flags: u32,
31303179
) void {
31313180
sqe.prep_rw(.socket, @intFromEnum(domain), 0, @intFromEnum(protocol), @as(u32, @bitCast(socket_type)));
31323181
sqe.rw_flags = flags;
@@ -3137,7 +3186,8 @@ pub const Sqe = extern struct {
31373186
domain: linux.Af,
31383187
socket_type: linux.Sock,
31393188
protocol: linux.IpProto,
3140-
flags: u32, // flags is unused
3189+
/// flags is unused
3190+
flags: u32,
31413191
file_index: u32,
31423192
) void {
31433193
prep_socket(sqe, domain, socket_type, protocol, flags);
@@ -3149,7 +3199,8 @@ pub const Sqe = extern struct {
31493199
domain: linux.Af,
31503200
socket_type: linux.Sock,
31513201
protocol: linux.IpProto,
3152-
flags: u32, // flags is unused
3202+
/// flags is unused
3203+
flags: u32,
31533204
) void {
31543205
prep_socket(sqe, domain, socket_type, protocol, flags);
31553206
set_target_fixed_file(sqe, constants.FILE_INDEX_ALLOC);
@@ -3161,7 +3212,8 @@ pub const Sqe = extern struct {
31613212
id: i32,
31623213
infop: *linux.siginfo_t,
31633214
options: linux.W,
3164-
flags: u32, // flags is unused
3215+
/// flags is unused
3216+
flags: u32,
31653217
) void {
31663218
sqe.prep_rw(.waitid, id, 0, @intFromEnum(id_type), @intFromPtr(infop));
31673219
sqe.rw_flags = flags;
@@ -3532,6 +3584,14 @@ pub const WriteBuffer = union(enum) {
35323584
iovecs: []const posix.iovec_const,
35333585
};
35343586

3587+
/// Used to select how get/setxttr should be handled.
3588+
pub const XattrSource = union(enum) {
3589+
/// Get/Set xattr associated with the given path in the filesystem
3590+
path: []const u8,
3591+
/// Get/Set xattr for the opened file referenced by this fd
3592+
fd: linux.fd_t,
3593+
};
3594+
35353595
/// Used to select how the recv call should be handled.
35363596
pub const RecvBuffer = union(enum) {
35373597
/// io_uring will recv directly into this buffer

0 commit comments

Comments
 (0)