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 {
779779 return sqe;
780780 }
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
782797 /// Registers an array of file descriptors.
783798 /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must
784799 /// 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(
13651380 sqe.rw_flags = flags;
13661381}
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
13681392test "structs/offsets/entries" {
13691393 if (builtin.os.tag != .linux) return error.SkipZigTest;
13701394
......@@ -2456,3 +2480,46 @@ test "unlinkat" {
24562480 else => std.debug.panic("unexpected error: {}", .{err}),
24572481 };
24582482}
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}