F_GETDELEG(2const)
π F_GETDELEG(2const) β bestie, let's talk delegations π
okay so this is a page about F_GETDELEG and F_SETDELEG, from the section 2 (system calls) const pages. Yes we're in the const zone. Slay. π
πΈ NAME πΈ
F_GETDELEG, F_SETDELEG β delegations π«Ά
π LIBRARY π
Standard C library (libc, -lc) β the free one, the classic, the main character β¨
β¨ SYNOPSIS β¨
#define _GNU_SOURCE
#include <fcntl.h>
int fcntl(int fd, F_SETDELEG, const struct delegation *deleg);
int fcntl(int fd, F_GETDELEG, struct delegation *deleg);
struct delegation {
__u32 d_flags;
__u16 d_type;
__u16 __pad;
};
okay so very important: you need that #define _GNU_SOURCE up top or it's not happening, bestie. and look at that struct β d_flags, d_type, __pad. the padding is lowkey doing nothing but we respect her π
π¦ DESCRIPTION π¦
So. F_SETDELEG and F_GETDELEG are the two commands that let you establish a new delegation, and retrieve the current delegation, on the open file description that the file descriptor fd is pointing at. π
And what even is a file delegation, you ask? Obsessed that you asked. π So a delegation is this whole mechanism where the process holding it β we call them the "delegation holder", she's main character energy β gets notified by way of a signal being delivered when another process β the "delegation breaker", boooo π
β tries to open(2) or truncate(2) the file that file descriptor refers to, or tries to unlink(2) or rename(2) the dentry that was originally opened for the file. literally the drama of it all.
And plot twist: delegations can be set on directory file descriptors too, bestie. The holder of a directory delegation gets notified if there's a create, delete, or rename of a dirent inside that directory. π
π F_SETDELEG π
This one sets or removes a file or directory delegation, depending on whatever value lives in deleg->d_type:
π F_RDLCK π
Establish a read delegation. This means the calling process gets notified when the file is opened for writing, or is truncated, unlinked or renamed. a read delegation can be placed only on a file descriptor that is opened read-only, ok? rules are rules.
If fd refers to a directory, then the calling process gets notified if there are changes to filenames within the directory, or when the directory itself gets renamed.
π₯ F_WRLCK π₯
Establish a write delegation. This notifies the caller when the file is opened for reading or writing, or is truncated, renamed or unlinked. A write delegation may be placed on a file only if there are no other open file descriptors for the file β no tagalongs allowed π. The file must be opened for write in order to set a write delegation on it. And write delegations cannot be set on directory file descriptors, periodt.
π§ F_UNLCK π§
Remove our delegation from the file. bye bestie π
π how they LIVE π
Like leases, delegations are associated with an open file description (go see open(2)). Which means duplicate file descriptors β the ones created by, say, fork(2) or dup(2) β refer to the same delegation, and that delegation can be modified or released using any of these descriptors. iconic.
Also, the delegation is released either by an explicit F_UNLCK operation on any of these duplicate file descriptors, or when all such file descriptors have been closed. like, all of them. every single one.
And a lil privilege check, no cap: an unprivileged process may establish a delegation only on a file whose UID (owner) matches the filesystem UID of the process. A process with the CAP_LEASE capability may establish delegations on arbitrary files and directories. okay gatekeeper π
π F_GETDELEG π
This one tells you what type of delegation is associated with the file descriptor fd, by setting deleg->d_type to either F_RDLCK, F_WRLCK, or F_UNLCK β meaning, respectively: a read delegation, a write delegation, or no delegation at all. she's giving detective energy π
π the break drama π
When a process (the "delegation breaker", again, boooo) does an activity that conflicts with a delegation established via F_SETDELEG, the system call gets blocked by the kernel, and the kernel notifies the delegation holder by sending it a signal (SIGIO by default, iykyk).
The delegation holder should respond to receiving this signal by doing whatever cleanup is required to prepare for the file to be accessed by another process β like, e.g., flushing cached buffers β and then either remove or downgrade its delegation.
- A delegation is removed by performing an
F_SETDELEGoperation specifyingdeleg->d_typeasF_UNLCK. - If the delegation holder currently holds a write delegation on the file, and the delegation breaker is opening the file for reading, then it is sufficient for the delegation holder to downgrade the delegation to a read delegation. This is done by performing an
F_SETDELEGoperation specifyingdeleg->d_typeasF_RDLCK.
And if the delegation holder fails to downgrade or remove the delegation within the number of seconds specified in /proc/sys/fs/lease-break-time? then the kernel forcibly removes or downgrades the delegation holder's delegation. the kernel does not play. π«
Once a delegation break has been initiated, F_GETDELEG returns the target delegation type in the deleg->d_type (either F_RDLCK or F_UNLCK, depending on what would be compatible with the delegation breaker) β and it keeps doing that until the delegation holder voluntarily downgrades or removes the delegation, or the kernel forcibly does so after the delegation break timer expires.
Once the delegation has been voluntarily or forcibly removed or downgraded, and assuming the delegation breaker has not unblocked its system call, the kernel permits the delegation breaker's system call to proceed. finally. π
and now the edge cases, because of course there are edge cases:
- If the delegation breaker's blocked system call is interrupted by a signal handler, then the system call fails with the error
EINTR, but the other steps still occur as described above. - If the delegation breaker is killed by a signal while blocked in
open(2)ortruncate(2), then the other steps still occur as described above. - If the delegation breaker specifies the
O_NONBLOCKflag when callingopen(2), then the call immediately fails with the errorEWOULDBLOCK, but the other steps still occur as described above.
π£ the signal tea π£
The default signal used to notify the delegation holder is SIGIO, but you can change that using F_SETSIG(2const). π
And if an F_SETSIG(2const) operation is performed β even one specifying SIGIO β and the signal handler is established using SA_SIGINFO, then the handler will receive a siginfo_t structure as its second argument, and the si_fd field of this argument will hold the file descriptor of the file with the delegation that has been accessed by another process. (Super useful if the caller is holding delegations against multiple files β like, you'd be lost without it, fr fr.)
π NOTES π
Delegations were designed to implement NFSv4 (RFC 8881) delegations for the Linux NFS server. so like, that's the origin story π¬
π RETURN VALUE π
On success, zero is returned. π«Ά
On error, -1 is returned, and errno is set to indicate the error.
A successful F_GETDELEG call will also update the deleg->d_type field. don't forget that part bestie π
π ERRORS π
Go see fcntl(2). These operations can also return the following errors:
EAGAINβ The file was held open in a way that conflicts with the requested delegation.EINVALβ The caller tried to set aF_WRLCKdelegation andfdrepresents a directory.EINVALβfddoesn't represent a file or directory.EINVALβ The underlying filesystem doesn't support delegations.
π STANDARDS π
Linux, IETF RFC 8881. β
π°οΈ HISTORY π°οΈ
Linux 6.19. brand new, freshly pressed, no cap πΈ
π SEE ALSO π
fcntl(2), F_SETLEASE(2const) β go read those next, bestie, they're the cousins π¦
π okay that's the whole page!! remember: every flag, every default, every error, we kept it all. no detail left behind. periodt. π β¨
much love from the Linux man-pages 6.20 girlies, dated 2026-01-23 β stay delegated, stay iconic, and don't forget to F_UNLCK when you're done πππ¦
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms