The name_to_handle_at
() and open_by_handle_at
() system calls
split the functionality of openat(2) into two parts:
name_to_handle_at
() returns an opaque handle that corresponds to
a specified file; open_by_handle_at
() opens the file
corresponding to a handle returned by a previous call to
name_to_handle_at
() and returns an open file descriptor.
name_to_handle_at()
The name_to_handle_at
() system call returns a file handle and a
mount ID corresponding to the file specified by the dirfd and
pathname arguments. The file handle is returned via the argument
handle, which is a pointer to a structure of the following form:
struct file_handle {
unsigned int handle_bytes; /* Size of f_handle [in, out] */
int handle_type; /* Handle type [out] */
unsigned char f_handle[0]; /* File identifier (sized by
caller) [out] */
};
It is the caller's responsibility to allocate the structure with
a size large enough to hold the handle returned in f_handle.
Before the call, the handle_bytes field should be initialized to
contain the allocated size for f_handle. (The constant
MAX_HANDLE_SZ
, defined in <fcntl.h>, specifies the maximum
expected size for a file handle. It is not a guaranteed upper
limit as future filesystems may require more space.) Upon
successful return, the handle_bytes field is updated to contain
the number of bytes actually written to f_handle.
The caller can discover the required size for the file_handle
structure by making a call in which handle->handle_bytes is zero;
in this case, the call fails with the error EOVERFLOW
and
handle->handle_bytes is set to indicate the required size; the
caller can then use this information to allocate a structure of
the correct size (see EXAMPLES below). Some care is needed here
as EOVERFLOW
can also indicate that no file handle is available
for this particular name in a filesystem which does normally
support file-handle lookup. This case can be detected when the
EOVERFLOW
error is returned without handle_bytes being increased.
Other than the use of the handle_bytes field, the caller should
treat the file_handle structure as an opaque data type: the
handle_type and f_handle fields are needed only by a subsequent
call to open_by_handle_at
().
The flags argument is a bit mask constructed by ORing together
zero or more of AT_EMPTY_PATH
and AT_SYMLINK_FOLLOW
, described
below.
Together, the pathname and dirfd arguments identify the file for
which a handle is to be obtained. There are four distinct cases:
* If pathname is a nonempty string containing an absolute
pathname, then a handle is returned for the file referred to
by that pathname. In this case, dirfd is ignored.
* If pathname is a nonempty string containing a relative
pathname and dirfd has the special value AT_FDCWD
, then
pathname is interpreted relative to the current working
directory of the caller, and a handle is returned for the file
to which it refers.
* If pathname is a nonempty string containing a relative
pathname and dirfd is a file descriptor referring to a
directory, then pathname is interpreted relative to the
directory referred to by dirfd, and a handle is returned for
the file to which it refers. (See openat(2) for an
explanation of why "directory file descriptors" are useful.)
* If pathname is an empty string and flags specifies the value
AT_EMPTY_PATH
, then dirfd can be an open file descriptor
referring to any type of file, or AT_FDCWD
, meaning the
current working directory, and a handle is returned for the
file to which it refers.
The mount_id argument returns an identifier for the filesystem
mount that corresponds to pathname. This corresponds to the
first field in one of the records in /proc/self/mountinfo.
Opening the pathname in the fifth field of that record yields a
file descriptor for the mount point; that file descriptor can be
used in a subsequent call to open_by_handle_at
(). mount_id is
returned both for a successful call and for a call that results
in the error EOVERFLOW
.
By default, name_to_handle_at
() does not dereference pathname if
it is a symbolic link, and thus returns a handle for the link
itself. If AT_SYMLINK_FOLLOW
is specified in flags, pathname is
dereferenced if it is a symbolic link (so that the call returns a
handle for the file referred to by the link).
name_to_handle_at
() does not trigger a mount when the final
component of the pathname is an automount point. When a
filesystem supports both file handles and automount points, a
name_to_handle_at
() call on an automount point will return with
error EOVERFLOW
without having increased handle_bytes. This can
happen since Linux 4.13 with NFS when accessing a directory which
is on a separate filesystem on the server. In this case, the
automount can be triggered by adding a "/" to the end of the
pathname.
open_by_handle_at()
The open_by_handle_at
() system call opens the file referred to by
handle, a file handle returned by a previous call to
name_to_handle_at
().
The mount_fd argument is a file descriptor for any object (file,
directory, etc.) in the mounted filesystem with respect to which
handle should be interpreted. The special value AT_FDCWD
can be
specified, meaning the current working directory of the caller.
The flags argument is as for open(2). If handle refers to a
symbolic link, the caller must specify the O_PATH
flag, and the
symbolic link is not dereferenced; the O_NOFOLLOW
flag, if
specified, is ignored.
The caller must have the CAP_DAC_READ_SEARCH
capability to invoke
open_by_handle_at
().