@@ -1516,6 +1516,137 @@ pub fn link(
15161516 return try self .linkat (user_data , linux .At .fdcwd , old_path , linux .At .fdcwd , new_path , flags );
15171517}
15181518
1519+ /// Queues (but does not submit) an SQE to send a CQE to an io_uring file
1520+ /// descriptor. The use case for this can be anything from simply waking up
1521+ /// someone waiting on the targeted ring, or it can be used to pass messages
1522+ /// between the two rings
1523+ /// Returns a pointer to the SQE.
1524+ pub fn msg_ring (
1525+ self : * IoUring ,
1526+ user_data : u64 ,
1527+ fd : linux.fd_t ,
1528+ len : u32 ,
1529+ data : u64 ,
1530+ flags : uflags.MsgRing ,
1531+ ) ! * Sqe {
1532+ const sqe = try self .get_sqe ();
1533+ sqe .prep_msg_ring (fd , len , data , flags );
1534+ sqe .user_data = user_data ;
1535+ return sqe ;
1536+ }
1537+
1538+ /// Queues (but does not submit) an SQE to send a CQE to an io_uring file
1539+ /// descriptor. See `msg_ring`
1540+ /// This has and additonal `cqe_flags` parameter that allows you to set the CQE
1541+ /// flags field cqe.flags when sending a message
1542+ /// Returns a pointer to the SQE.
1543+ pub fn msg_ring_cqe_flags (
1544+ self : * IoUring ,
1545+ user_data : u64 ,
1546+ fd : linux.fd_t ,
1547+ len : u32 ,
1548+ data : u64 ,
1549+ msg_flags : uflags.MsgRing ,
1550+ cqe_flags : Cqe.Flags ,
1551+ ) ! * Sqe {
1552+ const sqe = try self .get_sqe ();
1553+ sqe .prep_msg_ring_cqe_flags (
1554+ fd ,
1555+ len ,
1556+ data ,
1557+ msg_flags ,
1558+ cqe_flags ,
1559+ );
1560+ sqe .user_data = user_data ;
1561+ return sqe ;
1562+ }
1563+
1564+ /// Queues (but does not submit) an SQE to to send a direct file descriptor to
1565+ /// another ring.
1566+ /// This has and additonal `cqe_flags` parameter that allows you to set the CQE
1567+ /// flags field cqe.flags when sending a message
1568+ /// Returns a pointer to the SQE.
1569+ pub fn msg_ring_fd (
1570+ self : * IoUring ,
1571+ user_data : u64 ,
1572+ fd : linux.fd_t ,
1573+ source_fd : linux.fd_t ,
1574+ target_fd : linux.fd_t ,
1575+ data : u64 ,
1576+ flags : uflags.MsgRing ,
1577+ ) ! * Sqe {
1578+ const sqe = try self .get_sqe ();
1579+ sqe .prep_msg_ring_fd (
1580+ fd ,
1581+ source_fd ,
1582+ target_fd ,
1583+ data ,
1584+ flags ,
1585+ );
1586+ sqe .user_data = user_data ;
1587+ return sqe ;
1588+ }
1589+
1590+ /// Queues (but does not submit) an SQE to send a direct file descriptor to
1591+ /// another ring. See `msg_ring_fd()`
1592+ /// `msg_ring_fd_alloc()` is similar to `msg_ring_fd()`, but doesn't specify a
1593+ /// target_fd for the descriptor. Instead, this target_fd is allocated in the
1594+ /// target ring and returned in the CQE res field.
1595+ /// Returns a pointer to the SQE.
1596+ pub fn msg_ring_fd_alloc (
1597+ self : * IoUring ,
1598+ user_data : u64 ,
1599+ fd : linux.fd_t ,
1600+ source_fd : linux.fd_t ,
1601+ data : u64 ,
1602+ flags : uflags.MsgRing ,
1603+ ) ! * Sqe {
1604+ const sqe = try self .get_sqe ();
1605+ sqe .prep_msg_ring_fd_alloc (
1606+ fd ,
1607+ source_fd ,
1608+ data ,
1609+ flags ,
1610+ );
1611+ sqe .user_data = user_data ;
1612+ return sqe ;
1613+ }
1614+
1615+ /// Queues (but does not submit) an SQE to prepares a request to get an
1616+ /// extended attribute value
1617+ /// Returns a pointer to the SQE.
1618+ pub fn getxattr (
1619+ self : * IoUring ,
1620+ user_data : u64 ,
1621+ name : []const u8 ,
1622+ value : []const u8 ,
1623+ path : []const u8 ,
1624+ len : u32 ,
1625+ ) ! * Sqe {
1626+ const sqe = try self .get_sqe ();
1627+ sqe .prep_getxattr (name , value , path , len );
1628+ sqe .user_data = user_data ;
1629+ return sqe ;
1630+ }
1631+
1632+ /// Queues (but does not submit) an SQE to prepares a request to set an
1633+ /// extended attribute value
1634+ /// Returns a pointer to the SQE.
1635+ pub fn setxattr (
1636+ self : * IoUring ,
1637+ user_data : u64 ,
1638+ name : []const u8 ,
1639+ value : []const u8 ,
1640+ path : []const u8 ,
1641+ flags : linux.SetXattr ,
1642+ len : u32 ,
1643+ ) ! * Sqe {
1644+ const sqe = try self .get_sqe ();
1645+ sqe .prep_setxattr (name , value , path , flags , len );
1646+ sqe .user_data = user_data ;
1647+ return sqe ;
1648+ }
1649+
15191650/// Queues (but does not submit) an SQE to perform a `waitid(2)`.
15201651/// Returns a pointer to the SQE.
15211652pub fn waitid (
@@ -2819,6 +2950,116 @@ pub const Sqe = extern struct {
28192950 sqe .rw_flags = @bitCast (flags );
28202951 }
28212952
2953+ pub fn prep_msg_ring (
2954+ sqe : * Sqe ,
2955+ fd : linux.fd_t ,
2956+ len : u32 ,
2957+ data : u64 ,
2958+ flags : uflags.MsgRing ,
2959+ ) void {
2960+ sqe .prep_rw (
2961+ .msg_ring ,
2962+ fd ,
2963+ undefined ,
2964+ len ,
2965+ data ,
2966+ );
2967+ sqe .rw_flags = @bitCast (flags );
2968+ }
2969+
2970+ pub fn prep_msg_ring_cqe_flags (
2971+ sqe : * Sqe ,
2972+ fd : linux.fd_t ,
2973+ len : u32 ,
2974+ data : u64 ,
2975+ msg_flags : uflags.MsgRing ,
2976+ cqe_flags : Cqe.Flags ,
2977+ ) void {
2978+ const enable_flags_pass = blk : {
2979+ var flags = msg_flags ;
2980+ flags .flags_pass = true ;
2981+ break :blk flags ;
2982+ };
2983+ sqe .prep_msg_ring (fd , len , data , enable_flags_pass );
2984+ // sqe.file_index in liburing maps to splice_fd_in in Zig sqe
2985+ sqe .splice_fd_in = @intCast (@as (u32 , @bitCast (cqe_flags )));
2986+ }
2987+
2988+ pub fn prep_msg_ring_fd (
2989+ sqe : * Sqe ,
2990+ fd : linux.fd_t ,
2991+ source_fd : linux.fd_t ,
2992+ target_fd : linux.fd_t ,
2993+ data : u64 ,
2994+ flags : uflags.MsgRing ,
2995+ ) void {
2996+ sqe .prep_rw (
2997+ .msg_ring ,
2998+ fd ,
2999+ @ptrFromInt (@intFromEnum (MsgRingCmd .send_fd )),
3000+ 0 ,
3001+ data ,
3002+ );
3003+ sqe .addr3 = @intCast (source_fd );
3004+ sqe .rw_flags = @bitCast (flags );
3005+ sqe .set_target_fixed_file (@intCast (target_fd ));
3006+ }
3007+
3008+ pub fn prep_msg_ring_fd_alloc (
3009+ sqe : * Sqe ,
3010+ fd : linux.fd_t ,
3011+ source_fd : linux.fd_t ,
3012+ data : u64 ,
3013+ flags : uflags.MsgRing ,
3014+ ) void {
3015+ sqe .prep_rw (
3016+ .msg_ring ,
3017+ fd ,
3018+ @ptrFromInt (@intFromEnum (MsgRingCmd .send_fd )),
3019+ 0 ,
3020+ data ,
3021+ );
3022+ sqe .addr3 = @intCast (source_fd );
3023+ sqe .rw_flags = @bitCast (flags );
3024+ sqe .set_target_fixed_file (constants .FILE_INDEX_ALLOC );
3025+ }
3026+
3027+ pub fn prep_getxattr (
3028+ sqe : * Sqe ,
3029+ name : []const u8 ,
3030+ value : []const u8 ,
3031+ path : []const u8 ,
3032+ len : u32 ,
3033+ ) void {
3034+ sqe .prep_rw (
3035+ .getxattr ,
3036+ 0 ,
3037+ @intFromPtr (name .ptr ),
3038+ len ,
3039+ @intFromPtr (value .ptr ),
3040+ );
3041+ sqe .addr3 = @intFromPtr (path .ptr );
3042+ }
3043+
3044+ pub fn prep_setxattr (
3045+ sqe : * Sqe ,
3046+ name : []const u8 ,
3047+ value : []const u8 ,
3048+ path : []const u8 ,
3049+ flags : linux.SetXattr ,
3050+ len : u32 ,
3051+ ) void {
3052+ sqe .prep_rw (
3053+ .setxattr ,
3054+ 0 ,
3055+ @intFromPtr (name .ptr ),
3056+ len ,
3057+ @intFromPtr (value .ptr ),
3058+ );
3059+ sqe .addr3 = @intFromPtr (path .ptr );
3060+ sqe .rw_flags = @bitCast (flags );
3061+ }
3062+
28223063 pub fn prep_files_update (
28233064 sqe : * Sqe ,
28243065 fds : []const linux.fd_t ,
0 commit comments