With v6.19, userland will be able to request a delegation on a file or directory. These new objects act a lot like file leases, but are based on NFSv4 file and directory delegations. Add new F_GETDELEG and F_SETDELEG manpages to document them. Signed-off-by: Jeff Layton --- man/man2/fcntl.2 | 5 + man/man2const/F_GETDELEG.2const | 246 ++++++++++++++++++++++++++++++++++++++++ man/man2const/F_SETDELEG.2const | 1 + 3 files changed, 252 insertions(+) diff --git a/man/man2/fcntl.2 b/man/man2/fcntl.2 index 7f34e332ef9070867c4cdb51e8c5d4991b4fac22..f05d559da149e6a4cc8ae935ffa32111deabd94d 100644 --- a/man/man2/fcntl.2 +++ b/man/man2/fcntl.2 @@ -78,6 +78,11 @@ indicating that the kernel does not recognize this value. .BR F_SETLEASE (2const) .TQ .BR F_GETLEASE (2const) +.SS Delegations +.TP +.BR F_SETDELEG (2const) +.TQ +.BR F_GETDELEG (2const) .SS File and directory change notification (dnotify) .TP .BR F_NOTIFY (2const) diff --git a/man/man2const/F_GETDELEG.2const b/man/man2const/F_GETDELEG.2const new file mode 100644 index 0000000000000000000000000000000000000000..43bfac5707b189a4e16b7068674d5ddc0ec98913 --- /dev/null +++ b/man/man2const/F_GETDELEG.2const @@ -0,0 +1,246 @@ +.\" Copyright, the authors of the Linux man-pages project +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH F_GETDELEG 2const (date) "Linux man-pages (unreleased)" +.SH NAME +F_GETDELEG, +F_SETDELEG +\- +delegations +.SH LIBRARY +Standard C library +.RI ( libc ,\~ \-lc ) +.SH SYNOPSIS +.nf +.B #define _GNU_SOURCE +.B #include + +.fi +.EX +struct delegation { + __u32 d_flags; + __u16 d_type; + __u16 __pad; +}; +.EE +.P +.nf +.BI "int fcntl(int " fd ", F_SETDELEG, const struct delegation *" deleg ); +.BI "int fcntl(int " fd ", F_GETDELEG, struct delegation *" deleg ); +.fi +.SH DESCRIPTION +.B F_SETDELEG +and +.B 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 +.IR fd . +.P +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 +.BR open (2) +or +.BR truncate (2) +the file referred to by that file descriptor, or attempts to +.BR unlink (2) +or +.BR rename (2) +the dentry that was originally opened for the file. +.P +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. +.TP +.B F_SETDELEG +Set or remove a file or directory delegation according to the +value specified in +.IR deleg->d_type : +.RS +.TP +.B 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 +.IR 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. +.TP +.B 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. +.TP +.B F_UNLCK +Remove our delegation from the file. +.RE +.P +Like leases, delegations are associated with an open file description (see +.BR open (2)). +This means that duplicate file descriptors (created by, for example, +.BR fork (2) +or +.BR dup (2)) +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 +.B F_UNLCK +operation on any of these duplicate file descriptors, +or when all such file descriptors have been closed. +.P +An unprivileged process may take out a delegation only on a file whose UID (owner) matches the filesystem UID of the process. +A process with the +.B CAP_LEASE +capability may take out delegations on arbitrary files or directories. +.TP +.B F_GETDELEG +Indicates what type of delegation is associated with the file descriptor +.I fd +by setting the +.IR d_type +field in +.IR deleg +to either +.BR F_RDLCK , +.BR F_WRLCK , +or +.BR F_UNLCK , +indicating, respectively, a read delegation, a write delegation, or no delegation. +.P +When a process (the "delegation breaker") performs an activity that conflicts with a delegation +established via +.BR F_SETDELEG , +the system call is blocked by the kernel and +the kernel notifies the delegation holder by sending it a signal +.RB ( 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 +.B F_SETDELEG +operation specifying +.I d_type +in +.I deleg +as +.BR 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 +.B F_SETDELEG +operation specifying +.I d_type +in +.I deleg +as +.BR F_RDLCK . +.P +If the delegation holder fails to downgrade or remove the delegation within +the number of seconds specified in +.IR /proc/sys/fs/lease\-break\-time , +then the kernel forcibly removes or downgrades the delegation holder's delegation. +.P +Once a delegation break has been initiated, +.B F_GETDELEG +returns the target delegation type in the +.I d_type +field in +.I deleg +(either +.B F_RDLCK +or +.BR 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. +.P +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. +.P +If the delegation breaker's blocked system call +is interrupted by a signal handler, +then the system call fails with the error +.BR EINTR , +but the other steps still occur as described above. +If the delegation breaker is killed by a signal while blocked in +.BR open (2) +or +.BR truncate (2), +then the other steps still occur as described above. +If the delegation breaker specifies the +.B O_NONBLOCK +flag when calling +.BR open (2), +then the call immediately fails with the error +.BR EWOULDBLOCK , +but the other steps still occur as described above. +.P +The default signal used to notify the delegation holder is +.BR SIGIO , +but this can be changed using the +.B F_SETSIG +operation to +.BR fcntl (). +If a +.B F_SETSIG +operation is performed (even one specifying +.BR SIGIO ), +and the signal +handler is established using +.BR SA_SIGINFO , +then the handler will receive a +.I siginfo_t +structure as its second argument, and the +.I 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.) +.SH NOTES +Delegations were designed to implement NFSv4 delegations for the Linux NFS server. +.SH RETURN VALUE +On success zero is returned. On error, \-1 is returned, and +.I errno +is set to indicate the error. A successful +.B F_GETDELEG +call will also update the +.I deleg->d_type +field. +.SH ERRORS +See +.BR fcntl (2). +These operations can also return the following errors: +.TP +.B EAGAIN +The operation was prohibited because the file was held open in a way that conflicts with the requested delegation. +.TP +.B EINVAL +The operation was prohibited because the caller tried to set a +.B F_WRLCK +delegation and +.I fd +represents a directory, +or +.I fd +doesn't represent a file or directory, or +the underlying filesystem doesn't support delegations. +.SH STANDARDS +Linux, IETF RFC\ 8881. +.SH HISTORY +Linux 6.19. +.SH SEE ALSO +.BR fcntl (2) , +.BR F_SETLEASE (2const) diff --git a/man/man2const/F_SETDELEG.2const b/man/man2const/F_SETDELEG.2const new file mode 100644 index 0000000000000000000000000000000000000000..acabdfc139fb3d753dbf3061c31d59332d046c63 --- /dev/null +++ b/man/man2const/F_SETDELEG.2const @@ -0,0 +1 @@ +.so man2const/F_GETDELEG.2const -- 2.52.0