---
name: "F_SETDELEG"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/F_GETDELEG"
---

# F\_SETDELEG(2const)

delegations

Part of [F\_GETDELEG(2const)](/F_GETDELEG/2const.md).

## NAME

F\_GETDELEG, F\_SETDELEG - delegations

## LIBRARY

Standard C library (*libc*, *-lc*)

## 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;
};
```

## DESCRIPTION

**F\_SETDELEG** and **F\_GETDELEG** are used to establish a new delegation, and retrieve the current delegation, on the open file description referred to by the file descriptor *fd*.

A file delegation is a mechanism whereby the process holding the delegation (the "delegation holder") is notified (via delivery of a signal) when a process (the "delegation breaker") tries to [**open**(2)](/open/2.md) or [**truncate**(2)](/truncate/2.md) the file referred to by that file descriptor, or tries to [**unlink**(2)](/unlink/2.md) or [**rename**(2)](/rename/2.md) the dentry that was originally opened for the file.

Delegations can also be set on directory file descriptors. The holder of a directory delegation will be notified if there is a create, delete, or rename of a dirent within the directory.

- **F\_SETDELEG**

  Set or remove a file or directory delegation according to the value specified in *deleg-\>d\_type*:

  - **F\_RDLCK**

    Establish a read delegation. This will cause the calling process to be 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.

  -

    If *fd* refers to a directory, then the calling process will be notified if there are changes to filenames within the directory, or when the directory itself is renamed.

  - **F\_WRLCK**

    Establish a write delegation. This will cause the caller to be notified 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. The file must be opened for write in order to set a write delegation on it. Write delegations cannot be set on directory file descriptors.

  - **F\_UNLCK**

    Remove our delegation from the file.

Like leases, delegations are associated with an open file description (see [**open**(2)](/open/2.md)). This means that duplicate file descriptors (created by, for example, [**fork**(2)](/fork/2.md) or [**dup**(2)](/dup/2.md)) refer to the same delegation, and this delegation may be modified or released using any of these descriptors. Furthermore, the delegation is released by either an explicit **F\_UNLCK** operation on any of these duplicate file descriptors, or when all such file descriptors have been closed.

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.

- **F\_GETDELEG**

  Indicates 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**, indicating, respectively, a read delegation, a write delegation, or no delegation.

When a process (the "delegation breaker") performs an activity that conflicts with a delegation established via **F\_SETDELEG**, the system call is blocked by the kernel and the kernel notifies the delegation holder by sending it a signal (**SIGIO** by default). The delegation holder should respond to receipt of this signal by doing whatever cleanup is required in preparation for the file to be accessed by another process (e.g., flushing cached buffers) and then either remove or downgrade its delegation. A delegation is removed by performing an **F\_SETDELEG** operation specifying *deleg-\>d\_type* as **F\_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\_SETDELEG** operation specifying *deleg-\>d\_type* as **F\_RDLCK**.

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.

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) 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.

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)](/open/2.md) or [**truncate**(2)](/truncate/2.md), then the other steps still occur as described above. If the delegation breaker specifies the **O\_NONBLOCK** flag when calling [**open**(2)](/open/2.md), then the call immediately fails with the error **EWOULDBLOCK**, but the other steps still occur as described above.

The default signal used to notify the delegation holder is **SIGIO**, but this can be changed using [**F\_SETSIG**(2const)](/F_SETSIG/2const.md). If a [**F\_SETSIG**(2const)](/F_SETSIG/2const.md) 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. (This is useful if the caller holds delegations against multiple files.)

## NOTES

Delegations were designed to implement NFSv4 (RFC 8881) delegations for the Linux NFS server.

## 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.

## ERRORS

See [**fcntl**(2)](/fcntl/2.md). 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 a **F\_WRLCK** delegation and *fd* represents a directory.

- **EINVAL**

  *fd* doesn't represent a file or directory.

- **EINVAL**

  The underlying filesystem doesn't support delegations.

## STANDARDS

Linux, IETF RFC 8881.

## HISTORY

Linux 6.19.

## SEE ALSO

[**fcntl**(2)](/fcntl/2.md)**,** [**F\_SETLEASE**(2const)](/F_SETLEASE/2const.md)
