authorgravatar for vincent@rischmann.frVincent Rischmann <vincent@rischmann.fr> 2021-12-12 18:30:13+01:00
committergravatar for vincent@rischmann.frVincent Rischmann <vincent@rischmann.fr> 2021-12-12 18:33:17+01:00
log1fd0542bee467e3810b39c7d755a8152806c7818
tree5425bcc62174662f0c799e99580c72299ebe1278
parent4e647dee9fc7a373bb88e9870e4a4b19e0dac5b9

os/linux/io_uring: implement mkdirat


1 files changed, 67 insertions(+), 0 deletions(-)

lib/std/os/linux/io_uring.zig+67
...@@ -779,6 +779,21 @@ pub const IO_Uring = struct {...@@ -779,6 +779,21 @@ pub const IO_Uring = struct {
779 return sqe;779 return sqe;
780 }780 }
781781
782 /// Queues (but does not submit) an SQE to perform a `mkdirat(2)`.
783 /// Returns a pointer to the SQE.
784 pub fn mkdirat(
785 self: *IO_Uring,
786 user_data: u64,
787 dir_fd: os.fd_t,
788 path: [*:0]const u8,
789 mode: os.mode_t,
790 ) !*io_uring_sqe {
791 const sqe = try self.get_sqe();
792 io_uring_prep_mkdirat(sqe, dir_fd, path, mode);
793 sqe.user_data = user_data;
794 return sqe;
795 }
796
782 /// Registers an array of file descriptors.797 /// Registers an array of file descriptors.
783 /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must798 /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must
784 /// retrieve a reference to the file, and once I/O has completed the file reference must be799 /// retrieve a reference to the file, and once I/O has completed the file reference must be
...@@ -1365,6 +1380,15 @@ pub fn io_uring_prep_unlinkat(...@@ -1365,6 +1380,15 @@ pub fn io_uring_prep_unlinkat(
1365 sqe.rw_flags = flags;1380 sqe.rw_flags = flags;
1366}1381}
13671382
1383pub fn io_uring_prep_mkdirat(
1384 sqe: *io_uring_sqe,
1385 dir_fd: os.fd_t,
1386 path: [*:0]const u8,
1387 mode: os.mode_t,
1388) void {
1389 io_uring_prep_rw(.MKDIRAT, sqe, dir_fd, @ptrToInt(path), mode, 0);
1390}
1391
1368test "structs/offsets/entries" {1392test "structs/offsets/entries" {
1369 if (builtin.os.tag != .linux) return error.SkipZigTest;1393 if (builtin.os.tag != .linux) return error.SkipZigTest;
13701394
...@@ -2456,3 +2480,46 @@ test "unlinkat" {...@@ -2456,3 +2480,46 @@ test "unlinkat" {
2456 else => std.debug.panic("unexpected error: {}", .{err}),2480 else => std.debug.panic("unexpected error: {}", .{err}),
2457 };2481 };
2458}2482}
2483
2484test "mkdirat" {
2485 if (builtin.os.tag != .linux) return error.SkipZigTest;
2486
2487 var ring = IO_Uring.init(1, 0) catch |err| switch (err) {
2488 error.SystemOutdated => return error.SkipZigTest,
2489 error.PermissionDenied => return error.SkipZigTest,
2490 else => return err,
2491 };
2492 defer ring.deinit();
2493
2494 const path = "test_io_uring_mkdirat";
2495
2496 defer std.fs.cwd().deleteDir(path) catch {};
2497
2498 // Submit mkdirat
2499
2500 var sqe = try ring.mkdirat(
2501 0x12121212,
2502 linux.AT.FDCWD,
2503 path,
2504 0o0755,
2505 );
2506 try testing.expectEqual(linux.IORING_OP.MKDIRAT, sqe.opcode);
2507 try testing.expectEqual(@as(i32, linux.AT.FDCWD), sqe.fd);
2508 try testing.expectEqual(@as(u32, 1), try ring.submit());
2509
2510 const cqe = try ring.copy_cqe();
2511 switch (cqe.err()) {
2512 .SUCCESS => {},
2513 // This kernel's io_uring does not yet implement mkdirat (kernel version < 5.15)
2514 .INVAL => return error.SkipZigTest,
2515 else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
2516 }
2517 try testing.expectEqual(linux.io_uring_cqe{
2518 .user_data = 0x12121212,
2519 .res = 0,
2520 .flags = 0,
2521 }, cqe);
2522
2523 // Validate that the directory exist
2524 _ = try std.fs.cwd().openDir(path, .{});
2525}