authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2026-08-01 13:41:45+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-01 23:46:10+02:00
log47c5f556c08c1b15c74dbaca743d17a3297bcdef
tree1fe7819435a81b5b9fb5b367d943a0a471f912ce
parentc854c6577a0720fc538f55d9e2a65621172035eb

Io.Uring: fix dir.hardLink

Unsupported flags is used resulting in invalid arguments: ```Zig thread 556130 panic: programmer bug caused syscall error: INVAL .../lib/std/Io/Threaded.zig:14258:34: 0x116f3fa in errnoBug (std.zig) if (is_debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err}); ^ .../lib/std/Io/Uring.zig:5583:44: 0x1281981 in linkat (std.zig) .INVAL => |err| return errnoBug(err), ^ .../lib/std/Io/Uring.zig:3555:21: 0x1289ab9 in dirHardLink (std.zig) return ev.linkat(``` ``` ```Zig test "linkat" { const gpa = testing.allocator; var uring: Io.Uring = undefined; try uring.init(gpa, .{}); defer uring.deinit(); var threaded = Io.Threaded.init(gpa, .{}); defer threaded.deinit(); for ([_]Io{ threaded.io(), uring.io() }) |io| { var tmp = testing.tmpDir(.{}); defer tmp.cleanup(); const dir = tmp.dir; const dir2 = try dir.createDirPathOpen(io, "folder/sub_folder", .{}); defer dir2.close(io); const file = try dir.createFile(io, "file", .{}); defer file.close(io); try dir.hardLink("file", dir2, "link", io, .{}); try file.hardLink(io, dir2, "link2", .{}); var stat = try dir.statFile(io, "folder/sub_folder/link", .{}); try testing.expectEqual(.file, stat.kind); stat = try dir.statFile(io, "folder/sub_folder/link2", .{}); try testing.expectEqual(.file, stat.kind); } } ```

1 files changed, 4 insertions(+), 2 deletions(-)

lib/std/Io/Uring.zig+4-2
......@@ -3561,7 +3561,7 @@ fn dirHardLink(
35613561 old_sub_path_posix,
35623562 new_dir.handle,
35633563 new_sub_path_posix,
3564 if (options.follow_symlinks) 0 else linux.AT.SYMLINK_NOFOLLOW,
3564 if (options.follow_symlinks) linux.AT.SYMLINK_FOLLOW else 0,
35653565 );
35663566}
35673567
......@@ -3993,7 +3993,7 @@ fn fileHardLink(
39933993 "",
39943994 new_dir.handle,
39953995 new_sub_path_posix,
3996 linux.AT.EMPTY_PATH | @as(u32, if (options.follow_symlinks) 0 else linux.AT.SYMLINK_NOFOLLOW),
3996 linux.AT.EMPTY_PATH | @as(u32, if (options.follow_symlinks) linux.AT.SYMLINK_FOLLOW else 0),
39973997 );
39983998}
39993999
......@@ -5545,6 +5545,8 @@ fn linkat(
55455545 new_path: [*:0]const u8,
55465546 flags: u32,
55475547) File.HardLinkError!void {
5548 // allowed flags: https://man7.org/linux/man-pages/man2/linkat.2.html
5549 assert(flags & ~(@as(u32, linux.AT.SYMLINK_FOLLOW | linux.AT.EMPTY_PATH)) == 0);
55485550 while (true) {
55495551 const thread = try cancel_region.awaitIoUring();
55505552 thread.enqueue().* = .{