Compare commits

...

2 Commits

Author SHA1 Message Date
Thomas Leonard
f9ba4caf3d
Merge pull request #693 from talex5/resolve-retry
eio_linux: retry openat2 on EAGAIN
2024-02-15 14:20:51 +00:00
Thomas Leonard
3adce92e8a eio_linux: retry openat2 on EAGAIN
CI fails sometimes with this error. The man-page says:

> the kernel could not ensure that a ".." component didn't escape (due
> to a race condition or potential attack). The caller may choose to
> retry the openat2() call.
2024-02-15 09:49:41 +00:00

View File

@ -270,15 +270,21 @@ let with_chunk ~fallback fn =
| None ->
fallback ()
let openat2 ~sw ?seekable ~access ~flags ~perm ~resolve ?dir path =
let use dir =
let res = Sched.enter "openat2" (enqueue_openat2 (access, flags, perm, resolve, dir, path)) in
let rec openat2 ~sw ?seekable ~access ~flags ~perm ~resolve ?dir path =
let use dir_opt =
let res = Sched.enter "openat2" (enqueue_openat2 (access, flags, perm, resolve, dir_opt, path)) in
if res < 0 then (
Switch.check sw; (* If cancelled, report that instead. *)
raise @@ Err.wrap_fs (Uring.error_of_errno res) "openat2" ""
);
let fd : Unix.file_descr = Obj.magic res in
Fd.of_unix ~sw ?seekable ~close_unix:true fd
match Uring.error_of_errno res with
| EAGAIN ->
(* Linux can return this due to a concurrent update.
It also seems to happen sometimes with no concurrent updates. *)
openat2 ~sw ?seekable ~access ~flags ~perm ~resolve ?dir path
| e -> raise @@ Err.wrap_fs e "openat2" ""
) else (
let fd : Unix.file_descr = Obj.magic res in
Fd.of_unix ~sw ?seekable ~close_unix:true fd
)
in
match dir with
| None -> use None