io_uring_prep_linkat(3)

πŸ’– io_uring_prep_linkat β€” a liburing manual page, bestie edition πŸ’–

okay so we're doing the io_uring_prep_linkat(3) page from the liburing Manual and honestly? it's a short one, it's cute, it's giving "two functions, one job, zero drama". let's go πŸ¦‹


✨ NAME ✨

io_uring_prep_linkat β€” get a linkat request all prepped and ready to slay


🌸 SYNOPSIS 🌸

#include <fcntl.h>
#include <unistd.h>
#include <liburing.h>

void io_uring_prep_linkat(struct io_uring_sqe *sqe,
                          int olddirfd,
                          const char *oldpath,
                          int newdirfd,
                          const char *newpath,
                          int flags);

void io_uring_prep_link(struct io_uring_sqe *sqe,
                        const char *oldpath,
                        const char *newpath,
                        int flags);

like. look at her. two little functions. πŸ’…


πŸ‘‘ DESCRIPTION πŸ‘‘

so io_uring_prep_linkat(3) is the one that prepares a linkat request, fr fr. it sets up the submission queue entry sqe so it uses:

  • the old directory file descriptor, which is the one olddirfd is pointing at πŸ‘€
  • the old path, which is the one oldpath is pointing at
  • the new directory file descriptor, which is the one newdirfd is pointing at
  • the new path, which is the one newpath is pointing at
  • and the flags you handed it in flags, obviously πŸ’…

then there's io_uring_prep_link(3), her slightly simpler sister. she prepares a link request, and she sets up the submission queue entry sqe to use the old path pointed to by oldpath and the new path pointed to by newpath β€” both relative to the current working directory β€” plus whatever you put in flags.

basically these two are out here preparing an async linkat(2) or link(2) request. if you want the actual lore, go read those man pages, they have the details. πŸ“–


πŸ’€ RETURN VALUE πŸ’€

None. that's it. that's the whole section. she returns nothing because she's too busy being iconic. ✨


😭 ERRORS 😭

the res field of the CQE is where the result of the operation lives. what values can show up there? go check the related man page, bestie, it's all documented there.

⚠️ now THIS part matters: with normal synchronous system calls, a failure gives you -1 and sets errno to the actual error value. io_uring never uses errno. never ever. instead it returns the negated errno directly in the res field of the CQE. so like, look at the sign, okay? it's not a vibe, it's a whole different convention. πŸ™ˆ

🧚 NOTES 🧚

okay so here's the tea with any request that passes in data inside a struct: that data has to remain valid until the request has been successfully submitted. that's it. it does not need to stay valid all the way until completion. once a request has been submitted, the in-kernel state is stable, periodt. πŸ’…

🚨 very early kernels β€” we're talking 5.4 and earlier β€” were extra and required the state to stay stable until the completion happened. so if you're on ancient kernel energy, mind that.

wanna know if your kernel is chill about this? applications can test for this behavior by inspecting the IORING_FEAT_SUBMIT_STABLE flag that gets passed back from io_uring_queue_init_params(3). iykyk. πŸ”₯


🌈 SEE ALSO 🌈


and that's the whole page, bestie 🫢 this was liburing-2.2, dated March 13, 2022 β€” go forth and link things asynchronously, you absolute main character πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from